diff options
| author | su_v <suv-sf@users.sourceforge.net> | 2013-03-08 08:59:37 +0000 |
|---|---|---|
| committer | ~suv <suv-sf@users.sourceforge.net> | 2013-03-08 08:59:37 +0000 |
| commit | d8a3b36b43e0700126a7a25a1d38858d1a1d4836 (patch) | |
| tree | eaf5a86ac5542fc33ed8bb697a615e08ddd2ae01 /src | |
| parent | changes_2013_02_25a.patch (diff) | |
| parent | Drop deprecated get_vbox method in Gtk::Dialog (diff) | |
| download | inkscape-d8a3b36b43e0700126a7a25a1d38858d1a1d4836.tar.gz inkscape-d8a3b36b43e0700126a7a25a1d38858d1a1d4836.zip | |
merge from trunk (r12181)
(bzr r11668.1.53)
Diffstat (limited to 'src')
94 files changed, 2463 insertions, 1458 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3cc3df1bc..a8925e24f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -188,7 +188,6 @@ set(inkscape_SRC composite-undo-stack-observer.cpp conditions.cpp conn-avoid-ref.cpp - connection-points.cpp connector-context.cpp console-output-undo-observer.cpp context-fns.cpp @@ -332,7 +331,6 @@ set(inkscape_SRC composite-undo-stack-observer.h conditions.h conn-avoid-ref.h - connection-points.h connection-pool.h connector-context.h console-output-undo-observer.h diff --git a/src/Makefile.am b/src/Makefile.am index 2baace5e0..09f2ea8eb 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -37,15 +37,13 @@ noinst_LIBRARIES = \ all_libs = \ $(noinst_LIBRARIES) \ $(INKSCAPE_LIBS) \ + $(EXIF_LIBS) \ $(GNOME_VFS_LIBS) \ $(XFT_LIBS) \ $(FREETYPE_LIBS) \ $(kdeldadd) \ $(win32ldflags) \ $(CARBON_LDFLAGS) \ - $(PERL_LIBS) \ - $(PYTHON_LIBS) \ - $(INKBOARD_LIBS) \ $(LIBWPG_LIBS) \ $(LIBVISIO_LIBS) \ $(LIBCDR_LIBS) \ @@ -64,13 +62,12 @@ BUILT_SOURCES = # Extra files to distribute EXTRA_DIST = -INCLUDES = \ - $(PERL_CFLAGS) $(PYTHON_CFLAGS) \ +AM_CPPFLAGS = \ + $(EXIF_CFLAGS) \ $(FREETYPE_CFLAGS) \ $(GNOME_PRINT_CFLAGS) \ $(GNOME_VFS_CFLAGS) \ $(IMAGEMAGICK_CFLAGS) \ - $(INKBOARD_CFLAGS) \ $(LIBWPG_CFLAGS) \ $(LIBVISIO_CFLAGS) \ $(LIBCDR_CFLAGS) \ @@ -86,8 +83,7 @@ INCLUDES = \ $(WIN32_CFLAGS) \ -I$(srcdir)/bind/javainc \ -I$(srcdir)/bind/javainc/linux \ - -I$(builddir)/extension/dbus \ - $(AM_CPPFLAGS) + -I$(builddir)/extension/dbus CXXTEST_TEMPLATE = $(srcdir)/cxxtest-template.tpl CXXTESTGENFLAGS = --root --have-eh --template=$(CXXTEST_TEMPLATE) diff --git a/src/desktop.h b/src/desktop.h index 93cf3201c..27176868f 100644 --- a/src/desktop.h +++ b/src/desktop.h @@ -214,16 +214,6 @@ public: return _layer_changed_signal.connect(slot); } - // Whiteboard changes - -#ifdef WITH_INKBOARD - Inkscape::Whiteboard::SessionManager* whiteboard_session_manager() { - return _whiteboard_session_manager; - } - - Inkscape::Whiteboard::SessionManager* _whiteboard_session_manager; -#endif - /** * Return new desktop object. * \pre namedview != NULL. diff --git a/src/device-manager.cpp b/src/device-manager.cpp index a9394a5f6..a07231805 100644 --- a/src/device-manager.cpp +++ b/src/device-manager.cpp @@ -14,6 +14,7 @@ #include "device-manager.h" #include "preferences.h" #include <gtk/gtk.h> +#include <glibmm/regex.h> #define noDEBUG_VERBOSE 1 diff --git a/src/display/cairo-utils.cpp b/src/display/cairo-utils.cpp index 8eeee0277..a55b05fe3 100644 --- a/src/display/cairo-utils.cpp +++ b/src/display/cairo-utils.cpp @@ -26,6 +26,7 @@ #include "color.h" #include "style.h" #include "helper/geom-curves.h" +#include "display/cairo-templates.h" namespace { @@ -633,6 +634,22 @@ static guint32 linear_to_srgb( const guint32 c, const guint32 a ) { return premul_alpha( c2, a ); } +struct SurfaceSrgbToLinear { + + guint32 operator()(guint32 in) { + EXTRACT_ARGB32(in, a,r,g,b) ; // Unneeded semi-colon for indenting + if( a != 0 ) { + r = srgb_to_linear( r, a ); + g = srgb_to_linear( g, a ); + b = srgb_to_linear( b, a ); + } + ASSEMBLE_ARGB32(out, a,r,g,b); + return out; + } +private: + /* None */ +}; + int ink_cairo_surface_srgb_to_linear(cairo_surface_t *surface) { cairo_surface_flush(surface); @@ -641,23 +658,41 @@ int ink_cairo_surface_srgb_to_linear(cairo_surface_t *surface) int stride = cairo_image_surface_get_stride(surface); unsigned char *data = cairo_image_surface_get_data(surface); + ink_cairo_surface_filter( surface, surface, SurfaceSrgbToLinear() ); + /* TODO convert this to OpenMP somehow */ - for (int y = 0; y < height; ++y, data += stride) { - for (int x = 0; x < width; ++x) { - guint32 px = *reinterpret_cast<guint32*>(data + 4*x); - EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting - if( a != 0 ) { - r = srgb_to_linear( r, a ); - g = srgb_to_linear( g, a ); - b = srgb_to_linear( b, a ); - } - ASSEMBLE_ARGB32(px2, a,r,g,b); - *reinterpret_cast<guint32*>(data + 4*x) = px2; - } - } + // for (int y = 0; y < height; ++y, data += stride) { + // for (int x = 0; x < width; ++x) { + // guint32 px = *reinterpret_cast<guint32*>(data + 4*x); + // EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting + // if( a != 0 ) { + // r = srgb_to_linear( r, a ); + // g = srgb_to_linear( g, a ); + // b = srgb_to_linear( b, a ); + // } + // ASSEMBLE_ARGB32(px2, a,r,g,b); + // *reinterpret_cast<guint32*>(data + 4*x) = px2; + // } + // } return width * height; } +struct SurfaceLinearToSrgb { + + guint32 operator()(guint32 in) { + EXTRACT_ARGB32(in, a,r,g,b) ; // Unneeded semi-colon for indenting + if( a != 0 ) { + r = linear_to_srgb( r, a ); + g = linear_to_srgb( g, a ); + b = linear_to_srgb( b, a ); + } + ASSEMBLE_ARGB32(out, a,r,g,b); + return out; + } +private: + /* None */ +}; + int ink_cairo_surface_linear_to_srgb(cairo_surface_t *surface) { cairo_surface_flush(surface); @@ -666,20 +701,22 @@ int ink_cairo_surface_linear_to_srgb(cairo_surface_t *surface) int stride = cairo_image_surface_get_stride(surface); unsigned char *data = cairo_image_surface_get_data(surface); - /* TODO convert this to OpenMP somehow */ - for (int y = 0; y < height; ++y, data += stride) { - for (int x = 0; x < width; ++x) { - guint32 px = *reinterpret_cast<guint32*>(data + 4*x); - EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting - if( a != 0 ) { - r = linear_to_srgb( r, a ); - g = linear_to_srgb( g, a ); - b = linear_to_srgb( b, a ); - } - ASSEMBLE_ARGB32(px2, a,r,g,b); - *reinterpret_cast<guint32*>(data + 4*x) = px2; - } - } + ink_cairo_surface_filter( surface, surface, SurfaceLinearToSrgb() ); + + // /* TODO convert this to OpenMP somehow */ + // for (int y = 0; y < height; ++y, data += stride) { + // for (int x = 0; x < width; ++x) { + // guint32 px = *reinterpret_cast<guint32*>(data + 4*x); + // EXTRACT_ARGB32(px, a,r,g,b) ; // Unneeded semi-colon for indenting + // if( a != 0 ) { + // r = linear_to_srgb( r, a ); + // g = linear_to_srgb( g, a ); + // b = linear_to_srgb( b, a ); + // } + // ASSEMBLE_ARGB32(px2, a,r,g,b); + // *reinterpret_cast<guint32*>(data + 4*x) = px2; + // } + // } return width * height; } diff --git a/src/display/canvas-axonomgrid.cpp b/src/display/canvas-axonomgrid.cpp index bfc6f27c4..170684328 100644 --- a/src/display/canvas-axonomgrid.cpp +++ b/src/display/canvas-axonomgrid.cpp @@ -12,11 +12,20 @@ * smaller than 90 degrees (measured from horizontal, 0 degrees being a line extending * to the right). The x-axis will always have an angle between 0 and 90 degrees. */ - + +#if HAVE_CONFIG_H +# include "config.h" +#endif #include <gtkmm/box.h> #include <gtkmm/label.h> -#include <gtkmm/table.h> + +#if WITH_GTKMM_3_0 +# include <gtkmm/grid.h> +#else +# include <gtkmm/table.h> +#endif + #include <glibmm/i18n.h> #include "display/canvas-axonomgrid.h" @@ -83,28 +92,60 @@ namespace Inkscape { #define SPACE_SIZE_X 15 #define SPACE_SIZE_Y 10 static inline void +#if WITH_GTKMM_3_0 +attach_all(Gtk::Grid &table, Gtk::Widget const *const arr[], unsigned size, int start = 0) +#else attach_all(Gtk::Table &table, Gtk::Widget const *const arr[], unsigned size, int start = 0) +#endif { for (unsigned i=0, r=start; i<size/sizeof(Gtk::Widget*); i+=2) { if (arr[i] && arr[i+1]) { +#if WITH_GTKMM_3_0 + (const_cast<Gtk::Widget&>(*arr[i])).set_hexpand(); + (const_cast<Gtk::Widget&>(*arr[i])).set_valign(Gtk::ALIGN_CENTER); + table.attach(const_cast<Gtk::Widget&>(*arr[i]), 1, r, 1, 1); + + (const_cast<Gtk::Widget&>(*arr[i+1])).set_hexpand(); + (const_cast<Gtk::Widget&>(*arr[i+1])).set_valign(Gtk::ALIGN_CENTER); + table.attach(const_cast<Gtk::Widget&>(*arr[i+1]), 2, r, 1, 1); +#else table.attach (const_cast<Gtk::Widget&>(*arr[i]), 1, 2, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); table.attach (const_cast<Gtk::Widget&>(*arr[i+1]), 2, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); +#endif } else { if (arr[i+1]) { +#if WITH_GTKMM_3_0 + (const_cast<Gtk::Widget&>(*arr[i+1])).set_hexpand(); + (const_cast<Gtk::Widget&>(*arr[i+1])).set_valign(Gtk::ALIGN_CENTER); + table.attach(const_cast<Gtk::Widget&>(*arr[i+1]), 1, r, 2, 1); +#else table.attach (const_cast<Gtk::Widget&>(*arr[i+1]), 1, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); +#endif } else if (arr[i]) { Gtk::Label& label = reinterpret_cast<Gtk::Label&> (const_cast<Gtk::Widget&>(*arr[i])); label.set_alignment (0.0); +#if WITH_GTKMM_3_0 + label.set_hexpand(); + label.set_valign(Gtk::ALIGN_CENTER); + table.attach(label, 0, r, 3, 1); +#else table.attach (label, 0, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); +#endif } else { Gtk::HBox *space = manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); +#if WITH_GTKMM_3_0 + space->set_halign(Gtk::ALIGN_CENTER); + space->set_valign(Gtk::ALIGN_CENTER); + table.attach(*space, 0, r, 1, 1); +#else table.attach (*space, 0, 1, r, r+1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0,0,0); +#endif } } ++r; @@ -306,14 +347,17 @@ CanvasAxonomGrid::onReprAttrChanged(Inkscape::XML::Node */*repr*/, gchar const * updateWidgets(); } - - - Gtk::Widget * CanvasAxonomGrid::newSpecificWidget() { +#if WITH_GTKMM_3_0 + Gtk::Grid *table = Gtk::manage(new Gtk::Grid()); + table->set_row_spacing(2); + table->set_column_spacing(2); +#else Gtk::Table * table = Gtk::manage( new Gtk::Table(1,1) ); table->set_spacings(2); +#endif _wr.setUpdating (true); diff --git a/src/display/canvas-grid.cpp b/src/display/canvas-grid.cpp index 5fd38a473..c53890f9f 100644 --- a/src/display/canvas-grid.cpp +++ b/src/display/canvas-grid.cpp @@ -13,10 +13,19 @@ * Don't be shy to correct things. */ +#if HAVE_CONFIG_H +# include "config.h" +#endif + #include <glibmm/i18n.h> #include <gtkmm/box.h> #include <gtkmm/label.h> -#include <gtkmm/table.h> + +#if WITH_GTKMM_3_0 +# include <gtkmm/grid.h> +#else +# include <gtkmm/table.h> +#endif #include "ui/widget/registered-widget.h" #include "desktop.h" @@ -410,29 +419,60 @@ void CanvasGrid::setOrigin(Geom::Point const &origin_px) **/ #define SPACE_SIZE_X 15 #define SPACE_SIZE_Y 10 -static inline void -attach_all(Gtk::Table &table, Gtk::Widget const *const arr[], unsigned size, int start = 0) +#if WITH_GTKMM_3_0 +static inline void attach_all(Gtk::Grid &table, Gtk::Widget const *const arr[], unsigned size, int start = 0) +#else +static inline void attach_all(Gtk::Table &table, Gtk::Widget const *const arr[], unsigned size, int start = 0) +#endif { for (unsigned i=0, r=start; i<size/sizeof(Gtk::Widget*); i+=2) { if (arr[i] && arr[i+1]) { +#if WITH_GTKMM_3_0 + (const_cast<Gtk::Widget&>(*arr[i])).set_hexpand(); + (const_cast<Gtk::Widget&>(*arr[i])).set_valign(Gtk::ALIGN_CENTER); + table.attach(const_cast<Gtk::Widget&>(*arr[i]), 1, r, 1, 1); + + (const_cast<Gtk::Widget&>(*arr[i+1])).set_hexpand(); + (const_cast<Gtk::Widget&>(*arr[i+1])).set_valign(Gtk::ALIGN_CENTER); + table.attach(const_cast<Gtk::Widget&>(*arr[i+1]), 2, r, 1, 1); +#else table.attach (const_cast<Gtk::Widget&>(*arr[i]), 1, 2, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); table.attach (const_cast<Gtk::Widget&>(*arr[i+1]), 2, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); +#endif } else { if (arr[i+1]) { +#if WITH_GTKMM_3_0 + (const_cast<Gtk::Widget&>(*arr[i+1])).set_hexpand(); + (const_cast<Gtk::Widget&>(*arr[i+1])).set_valign(Gtk::ALIGN_CENTER); + table.attach(const_cast<Gtk::Widget&>(*arr[i+1]), 1, r, 2, 1); +#else table.attach (const_cast<Gtk::Widget&>(*arr[i+1]), 1, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); +#endif } else if (arr[i]) { Gtk::Label& label = reinterpret_cast<Gtk::Label&> (const_cast<Gtk::Widget&>(*arr[i])); label.set_alignment (0.0); +#if WITH_GTKMM_3_0 + label.set_hexpand(); + label.set_valign(Gtk::ALIGN_CENTER); + table.attach(label, 0, r, 3, 1); +#else table.attach (label, 0, 3, r, r+1, Gtk::FILL|Gtk::EXPAND, (Gtk::AttachOptions)0,0,0); +#endif } else { Gtk::HBox *space = manage (new Gtk::HBox); space->set_size_request (SPACE_SIZE_X, SPACE_SIZE_Y); +#if WITH_GTKMM_3_0 + space->set_halign(Gtk::ALIGN_CENTER); + space->set_valign(Gtk::ALIGN_CENTER); + table.attach(*space, 0, r, 1, 1); +#else table.attach (*space, 0, 1, r, r+1, (Gtk::AttachOptions)0, (Gtk::AttachOptions)0,0,0); +#endif } } ++r; @@ -688,7 +728,14 @@ CanvasXYGrid::onReprAttrChanged(Inkscape::XML::Node */*repr*/, gchar const */*ke Gtk::Widget * CanvasXYGrid::newSpecificWidget() { +#if WITH_GTKMM_3_0 + Gtk::Grid * table = Gtk::manage( new Gtk::Grid() ); + table->set_row_spacing(2); + table->set_column_spacing(2); +#else Gtk::Table * table = Gtk::manage( new Gtk::Table(1,1) ); + table->set_spacings(2); +#endif Inkscape::UI::Widget::RegisteredUnitMenu *_rumg = Gtk::manage( new Inkscape::UI::Widget::RegisteredUnitMenu( _("Grid _units:"), "units", _wr, repr, doc) ); @@ -715,9 +762,7 @@ CanvasXYGrid::newSpecificWidget() Inkscape::UI::Widget::RegisteredSuffixedInteger *_rsi = Gtk::manage( new Inkscape::UI::Widget::RegisteredSuffixedInteger( _("_Major grid line every:"), "", _("lines"), "empspacing", _wr, repr, doc) ); - table->set_spacings(2); - -_wr.setUpdating (true); + _wr.setUpdating (true); _rsu_ox->setDigits(5); _rsu_ox->setIncrements(0.1, 1.0); @@ -779,7 +824,7 @@ _wr.setUpdating (true); _rsu_ox->setProgrammatically = false; _rsu_oy->setProgrammatically = false; _rsu_sx->setProgrammatically = false; - _rsu_sx->setProgrammatically = false; + _rsu_sy->setProgrammatically = false; return table; } diff --git a/src/display/nr-filter-turbulence.cpp b/src/display/nr-filter-turbulence.cpp index 76b877fbc..333074f55 100644 --- a/src/display/nr-filter-turbulence.cpp +++ b/src/display/nr-filter-turbulence.cpp @@ -283,7 +283,12 @@ private: // other constants static int const BSize = 0x100; static int const BMask = 0xff; + +#if __cplusplus < 201103L static double const PerlinOffset = 4096.0; +#else + static double constexpr PerlinOffset = 4096.0; +#endif Geom::Rect _tile; Geom::Point _baseFreq; diff --git a/src/dom/io/bufferstream.cpp b/src/dom/io/bufferstream.cpp index 7baab4814..3389bd80e 100644 --- a/src/dom/io/bufferstream.cpp +++ b/src/dom/io/bufferstream.cpp @@ -146,7 +146,7 @@ void BufferOutputStream::flush() /** * Writes the specified byte to this output stream. */ -int BufferOutputStream::put(XMLCh ch) +int BufferOutputStream::put(gunichar ch) { if (closed) return -1; diff --git a/src/dom/io/bufferstream.h b/src/dom/io/bufferstream.h index 9a36b30e2..0ac06b362 100644 --- a/src/dom/io/bufferstream.h +++ b/src/dom/io/bufferstream.h @@ -102,7 +102,7 @@ public: virtual void flush(); - virtual int put(XMLCh ch); + virtual int put(gunichar ch); virtual std::vector<unsigned char> &getBuffer() { return buffer; } diff --git a/src/dom/io/domstream.cpp b/src/dom/io/domstream.cpp index de221f855..b9ff7e9d2 100644 --- a/src/dom/io/domstream.cpp +++ b/src/dom/io/domstream.cpp @@ -424,12 +424,11 @@ static int dprintf(Writer &outs, const DOMString &fmt, va_list ap) //# B A S I C I N P U T S T R E A M //######################################################################### - /** * - */ -BasicInputStream::BasicInputStream(const InputStream &sourceStream) - : source((InputStream &)sourceStream) + */ +BasicInputStream::BasicInputStream(InputStream &sourceStream) + : source(sourceStream) { closed = false; } @@ -438,7 +437,7 @@ BasicInputStream::BasicInputStream(const InputStream &sourceStream) * Returns the number of bytes that can be read (or skipped over) from * this input stream without blocking by the next caller of a method for * this input stream. - */ + */ int BasicInputStream::available() { if (closed) @@ -446,11 +445,11 @@ int BasicInputStream::available() return source.available(); } - + /** * Closes this input stream and releases any system resources * associated with the stream. - */ + */ void BasicInputStream::close() { if (closed) @@ -458,10 +457,10 @@ void BasicInputStream::close() source.close(); closed = true; } - + /** * Reads the next byte of data from the input stream. -1 if EOF - */ + */ int BasicInputStream::get() { if (closed) @@ -477,9 +476,9 @@ int BasicInputStream::get() /** * - */ -BasicOutputStream::BasicOutputStream(const OutputStream &destinationStream) - : destination((OutputStream &)destinationStream) + */ +BasicOutputStream::BasicOutputStream(OutputStream &destinationStream) + : destination(destinationStream) { closed = false; } @@ -487,7 +486,7 @@ BasicOutputStream::BasicOutputStream(const OutputStream &destinationStream) /** * Closes this output stream and releases any system resources * associated with this stream. - */ + */ void BasicOutputStream::close() { if (closed) @@ -495,40 +494,33 @@ void BasicOutputStream::close() destination.close(); closed = true; } - + /** * Flushes this output stream and forces any buffered output * bytes to be written out. - */ + */ void BasicOutputStream::flush() { if (closed) return; destination.flush(); } - + /** * Writes the specified byte to this output stream. - */ -int BasicOutputStream::put(XMLCh ch) + */ +int BasicOutputStream::put(gunichar ch) { if (closed) return -1; - if (destination.put(ch) < 0) - return -1; - return 1; + destination.put(ch); + return 1; } - //######################################################################### //# B A S I C R E A D E R //######################################################################### - - -/** - * - */ BasicReader::BasicReader(Reader &sourceReader) { source = &sourceReader; @@ -538,7 +530,7 @@ BasicReader::BasicReader(Reader &sourceReader) * Returns the number of bytes that can be read (or skipped over) from * this reader without blocking by the next caller of a method for * this reader. - */ + */ int BasicReader::available() { if (source) @@ -547,69 +539,65 @@ int BasicReader::available() return 0; } - + /** * Closes this reader and releases any system resources * associated with the reader. - */ + */ void BasicReader::close() { if (source) source->close(); } - + /** * Reads the next byte of data from the reader. - */ -int BasicReader::get() + */ +gunichar BasicReader::get() { if (source) return source->get(); else - return -1; + return (gunichar)-1; } - - - - - + /** * Reads a line of data from the reader. - */ -DOMString BasicReader::readLine() + */ +Glib::ustring BasicReader::readLine() { - DOMString str; + Glib::ustring str; while (available() > 0) { - XMLCh ch = get(); + gunichar ch = get(); if (ch == '\n') break; str.push_back(ch); } return str; } - + /** * Reads a line of data from the reader. - */ -DOMString BasicReader::readWord() + */ +Glib::ustring BasicReader::readWord() { - DOMString str; + Glib::ustring str; while (available() > 0) { - XMLCh ch = get(); - if (uni_is_space(ch)) + gunichar ch = get(); + if (!g_unichar_isprint(ch)) break; str.push_back(ch); } return str; } + - -static bool getLong(DOMString &str, long *val) +static bool getLong(Glib::ustring &str, long *val) { - const char *begin = str.c_str(); + const char *begin = str.raw().c_str(); char *end; long ival = strtol(begin, &end, 10); if (str == end) @@ -618,25 +606,23 @@ static bool getLong(DOMString &str, long *val) return true; } -static bool getULong(const DOMString &str, unsigned long *val) +static bool getULong(Glib::ustring &str, unsigned long *val) { - DOMString tmp = str; - char *begin = (char *)tmp.c_str(); + const char *begin = str.raw().c_str(); char *end; unsigned long ival = strtoul(begin, &end, 10); - if (begin == end) + if (str == end) return false; *val = ival; return true; } -static bool getDouble(const DOMString &str, double *val) +static bool getDouble(Glib::ustring &str, double *val) { - DOMString tmp = str; - const char *begin = tmp.c_str(); + const char *begin = str.raw().c_str(); char *end; double ival = strtod(begin, &end); - if (begin == end) + if (str == end) return false; *val = ival; return true; @@ -644,13 +630,9 @@ static bool getDouble(const DOMString &str, double *val) - -/** - * - */ -Reader &BasicReader::readBool (bool& val ) +const Reader &BasicReader::readBool (bool& val ) { - DOMString buf = readWord(); + Glib::ustring buf = readWord(); if (buf == "true") val = true; else @@ -658,96 +640,72 @@ Reader &BasicReader::readBool (bool& val ) return *this; } -/** - * - */ -Reader &BasicReader::readShort (short& val ) +const Reader &BasicReader::readShort (short& val ) { - DOMString buf = readWord(); + Glib::ustring buf = readWord(); long ival; if (getLong(buf, &ival)) val = (short) ival; return *this; } -/** - * - */ -Reader &BasicReader::readUnsignedShort (unsigned short& val ) +const Reader &BasicReader::readUnsignedShort (unsigned short& val ) { - DOMString buf = readWord(); + Glib::ustring buf = readWord(); unsigned long ival; if (getULong(buf, &ival)) val = (unsigned short) ival; return *this; } -/** - * - */ -Reader &BasicReader::readInt (int& val ) +const Reader &BasicReader::readInt (int& val ) { - DOMString buf = readWord(); + Glib::ustring buf = readWord(); long ival; if (getLong(buf, &ival)) val = (int) ival; return *this; } -/** - * - */ -Reader &BasicReader::readUnsignedInt (unsigned int& val ) +const Reader &BasicReader::readUnsignedInt (unsigned int& val ) { - DOMString buf = readWord(); + Glib::ustring buf = readWord(); unsigned long ival; if (getULong(buf, &ival)) val = (unsigned int) ival; return *this; } -/** - * - */ -Reader &BasicReader::readLong (long& val ) +const Reader &BasicReader::readLong (long& val ) { - DOMString buf = readWord(); + Glib::ustring buf = readWord(); long ival; if (getLong(buf, &ival)) val = ival; return *this; } -/** - * - */ -Reader &BasicReader::readUnsignedLong (unsigned long& val ) +const Reader &BasicReader::readUnsignedLong (unsigned long& val ) { - DOMString buf = readWord(); + Glib::ustring buf = readWord(); unsigned long ival; if (getULong(buf, &ival)) val = ival; return *this; } -/** - * - */ -Reader &BasicReader::readFloat (float& val ) +const Reader &BasicReader::readFloat (float& val ) { - DOMString buf = readWord(); + Glib::ustring buf = readWord(); double ival; if (getDouble(buf, &ival)) val = (float)ival; return *this; } -/** - * - */ -Reader &BasicReader::readDouble (double& val ) +const Reader &BasicReader::readDouble (double& val ) { - DOMString buf = readWord(); + Glib::ustring buf = readWord(); double ival; if (getDouble(buf, &ival)) val = ival; @@ -761,12 +719,12 @@ Reader &BasicReader::readDouble (double& val ) //######################################################################### -InputStreamReader::InputStreamReader(const InputStream &inputStreamSource) - : inputStream((InputStream &)inputStreamSource) +InputStreamReader::InputStreamReader(InputStream &inputStreamSource) + : inputStream(inputStreamSource) { } - + /** * Close the underlying OutputStream @@ -775,7 +733,7 @@ void InputStreamReader::close() { inputStream.close(); } - + /** * Flush the underlying OutputStream */ @@ -783,15 +741,15 @@ int InputStreamReader::available() { return inputStream.available(); } - + /** * Overloaded to receive its bytes from an InputStream * rather than a Reader */ -int InputStreamReader::get() +gunichar InputStreamReader::get() { //Do we need conversions here? - int ch = (XMLCh)inputStream.get(); + gunichar ch = (gunichar)inputStream.get(); return ch; } @@ -818,7 +776,7 @@ StdReader::~StdReader() delete inputStream; } - + /** * Close the underlying OutputStream @@ -827,7 +785,7 @@ void StdReader::close() { inputStream->close(); } - + /** * Flush the underlying OutputStream */ @@ -835,22 +793,21 @@ int StdReader::available() { return inputStream->available(); } - + /** * Overloaded to receive its bytes from an InputStream * rather than a Reader */ -int StdReader::get() +gunichar StdReader::get() { //Do we need conversions here? - XMLCh ch = (XMLCh)inputStream->get(); + gunichar ch = (gunichar)inputStream->get(); return ch; } - //######################################################################### //# B A S I C W R I T E R //######################################################################### @@ -886,7 +843,7 @@ void BasicWriter::flush() /** * Writes the specified byte to this output writer. */ -int BasicWriter::put(XMLCh ch) +int BasicWriter::put(gunichar ch) { if (destination && destination->put(ch)>=0) return 1; @@ -1079,7 +1036,7 @@ void OutputStreamWriter::flush() * Overloaded to redirect the output chars from the next Writer * in the chain to an OutputStream instead. */ -int OutputStreamWriter::put(XMLCh ch) +int OutputStreamWriter::put(gunichar ch) { //Do we need conversions here? int intCh = (int) ch; @@ -1133,11 +1090,10 @@ void StdWriter::flush() * Overloaded to redirect the output chars from the next Writer * in the chain to an OutputStream instead. */ -int StdWriter::put(XMLCh ch) +int StdWriter::put(gunichar ch) { //Do we need conversions here? - int intCh = (int) ch; - if (outputStream->put(intCh) < 0) + if (outputStream->put(ch) < 0) return -1; return 1; } @@ -1146,13 +1102,6 @@ int StdWriter::put(XMLCh ch) - - - - - - - //############################################### //# O P E R A T O R S //############################################### @@ -1166,31 +1115,31 @@ int StdWriter::put(XMLCh ch) -Reader& operator>> (Reader &reader, bool& val ) +const Reader& operator>> (Reader &reader, bool& val ) { return reader.readBool(val); } -Reader& operator>> (Reader &reader, short &val) +const Reader& operator>> (Reader &reader, short &val) { return reader.readShort(val); } -Reader& operator>> (Reader &reader, unsigned short &val) +const Reader& operator>> (Reader &reader, unsigned short &val) { return reader.readUnsignedShort(val); } -Reader& operator>> (Reader &reader, int &val) +const Reader& operator>> (Reader &reader, int &val) { return reader.readInt(val); } -Reader& operator>> (Reader &reader, unsigned int &val) +const Reader& operator>> (Reader &reader, unsigned int &val) { return reader.readUnsignedInt(val); } -Reader& operator>> (Reader &reader, long &val) +const Reader& operator>> (Reader &reader, long &val) { return reader.readLong(val); } -Reader& operator>> (Reader &reader, unsigned long &val) +const Reader& operator>> (Reader &reader, unsigned long &val) { return reader.readUnsignedLong(val); } -Reader& operator>> (Reader &reader, float &val) +const Reader& operator>> (Reader &reader, float &val) { return reader.readFloat(val); } -Reader& operator>> (Reader &reader, double &val) +const Reader& operator>> (Reader &reader, double &val) { return reader.readDouble(val); } diff --git a/src/dom/io/domstream.h b/src/dom/io/domstream.h index 1a93e73b2..a021676fa 100644 --- a/src/dom/io/domstream.h +++ b/src/dom/io/domstream.h @@ -44,23 +44,21 @@ namespace dom namespace io { - - -class StreamException +class StreamException : public std::exception { public: - StreamException(const DOMString &theReason) throw() - : reason(theReason) - {} + StreamException(const char *theReason) throw() + { reason = theReason; } + StreamException(Glib::ustring &theReason) throw() + { reason = theReason; } virtual ~StreamException() throw() { } - char const *what() + char const *what() const throw() { return reason.c_str(); } - + private: - - DOMString reason; + Glib::ustring reason; }; @@ -95,14 +93,14 @@ public: * to be read */ virtual int available() = 0; - + /** * Do whatever it takes to 'close' this input stream * The most likely implementation of this method will be * for endpoints that use a resource for their data. */ virtual void close() = 0; - + /** * Read one byte from this input stream. This is a blocking * call. If no data is currently available, this call will @@ -113,7 +111,7 @@ public: * This call returns -1 on end-of-file. */ virtual int get() = 0; - + }; // class InputStream @@ -129,22 +127,22 @@ class BasicInputStream : public InputStream public: - BasicInputStream(const InputStream &sourceStream); - + BasicInputStream(InputStream &sourceStream); + virtual ~BasicInputStream() {} - + virtual int available(); - + virtual void close(); - + virtual int get(); - + protected: bool closed; InputStream &source; - + private: @@ -161,10 +159,10 @@ public: int available() { return 0; } - + void close() { /* do nothing */ } - + int get() { return getchar(); } @@ -174,7 +172,6 @@ public: - //######################################################################### //# O U T P U T S T R E A M //######################################################################### @@ -207,18 +204,18 @@ public: * 3. close the destination stream */ virtual void close() = 0; - + /** * This call should push any pending data it might have to * the destination stream. It should NOT call flush() on * the destination stream. */ virtual void flush() = 0; - + /** * Send one byte to the destination stream. */ - virtual int put(XMLCh ch) = 0; + virtual int put(gunichar ch) = 0; }; // class OutputStream @@ -233,15 +230,15 @@ class BasicOutputStream : public OutputStream public: - BasicOutputStream(const OutputStream &destinationStream); - + BasicOutputStream(OutputStream &destinationStream); + virtual ~BasicOutputStream() {} virtual void close(); - + virtual void flush(); - - virtual int put(XMLCh ch); + + virtual int put(gunichar ch); protected: @@ -263,12 +260,12 @@ public: void close() { } - + void flush() { } - - int put(XMLCh ch) - { putchar(ch); return 1; } + + int put(gunichar ch) + { return putchar(ch); } }; @@ -279,7 +276,6 @@ public: //# R E A D E R //######################################################################### - /** * This interface and its descendants are for unicode character-oriented input * @@ -301,33 +297,42 @@ public: virtual int available() = 0; - + virtual void close() = 0; - - virtual int get() = 0; - - virtual DOMString readLine() = 0; - - virtual DOMString readWord() = 0; - + + virtual gunichar get() = 0; + + virtual Glib::ustring readLine() = 0; + + virtual Glib::ustring readWord() = 0; + /* Input formatting */ - virtual Reader& readBool (bool& val ) = 0; - - virtual Reader& readShort (short &val) = 0; - - virtual Reader& readUnsignedShort (unsigned short &val) = 0; - - virtual Reader& readInt (int &val) = 0; - - virtual Reader& readUnsignedInt (unsigned int &val) = 0; - - virtual Reader& readLong (long &val) = 0; - - virtual Reader& readUnsignedLong (unsigned long &val) = 0; - - virtual Reader& readFloat (float &val) = 0; - - virtual Reader& readDouble (double &val) = 0; + virtual const Reader& readBool (bool& val ) = 0; + virtual const Reader& operator>> (bool& val ) = 0; + + virtual const Reader& readShort (short &val) = 0; + virtual const Reader& operator>> (short &val) = 0; + + virtual const Reader& readUnsignedShort (unsigned short &val) = 0; + virtual const Reader& operator>> (unsigned short &val) = 0; + + virtual const Reader& readInt (int &val) = 0; + virtual const Reader& operator>> (int &val) = 0; + + virtual const Reader& readUnsignedInt (unsigned int &val) = 0; + virtual const Reader& operator>> (unsigned int &val) = 0; + + virtual const Reader& readLong (long &val) = 0; + virtual const Reader& operator>> (long &val) = 0; + + virtual const Reader& readUnsignedLong (unsigned long &val) = 0; + virtual const Reader& operator>> (unsigned long &val) = 0; + + virtual const Reader& readFloat (float &val) = 0; + virtual const Reader& operator>> (float &val) = 0; + + virtual const Reader& readDouble (double &val) = 0; + virtual const Reader& operator>> (double &val) = 0; }; // interface Reader @@ -343,37 +348,56 @@ class BasicReader : public Reader public: BasicReader(Reader &sourceStream); - + virtual ~BasicReader() {} virtual int available(); - + virtual void close(); - - virtual int get(); - - virtual DOMString readLine(); - - virtual DOMString readWord(); - + + virtual gunichar get(); + + virtual Glib::ustring readLine(); + + virtual Glib::ustring readWord(); + /* Input formatting */ - virtual Reader& readBool (bool& val ); - - virtual Reader& readShort (short &val) ; - - virtual Reader& readUnsignedShort (unsigned short &val) ; - - virtual Reader& readInt (int &val) ; - - virtual Reader& readUnsignedInt (unsigned int &val) ; - - virtual Reader& readLong (long &val) ; - - virtual Reader& readUnsignedLong (unsigned long &val) ; - - virtual Reader& readFloat (float &val) ; - - virtual Reader& readDouble (double &val) ; + virtual const Reader& readBool (bool& val ); + virtual const Reader& operator>> (bool& val ) + { return readBool(val); } + + virtual const Reader& readShort (short &val); + virtual const Reader& operator>> (short &val) + { return readShort(val); } + + virtual const Reader& readUnsignedShort (unsigned short &val); + virtual const Reader& operator>> (unsigned short &val) + { return readUnsignedShort(val); } + + virtual const Reader& readInt (int &val); + virtual const Reader& operator>> (int &val) + { return readInt(val); } + + virtual const Reader& readUnsignedInt (unsigned int &val); + virtual const Reader& operator>> (unsigned int &val) + { return readUnsignedInt(val); } + + virtual const Reader& readLong (long &val); + virtual const Reader& operator>> (long &val) + { return readLong(val); } + + virtual const Reader& readUnsignedLong (unsigned long &val); + virtual const Reader& operator>> (unsigned long &val) + { return readUnsignedLong(val); } + + virtual const Reader& readFloat (float &val); + virtual const Reader& operator>> (float &val) + { return readFloat(val); } + + virtual const Reader& readDouble (double &val); + virtual const Reader& operator>> (double &val) + { return readDouble(val); } + protected: @@ -388,27 +412,6 @@ private: -Reader& operator>> (Reader &reader, bool& val ); - -Reader& operator>> (Reader &reader, short &val); - -Reader& operator>> (Reader &reader, unsigned short &val); - -Reader& operator>> (Reader &reader, int &val); - -Reader& operator>> (Reader &reader, unsigned int &val); - -Reader& operator>> (Reader &reader, long &val); - -Reader& operator>> (Reader &reader, unsigned long &val); - -Reader& operator>> (Reader &reader, float &val); - -Reader& operator>> (Reader &reader, double &val); - - - - /** * Class for placing a Reader on an open InputStream * @@ -417,14 +420,14 @@ class InputStreamReader : public BasicReader { public: - InputStreamReader(const InputStream &inputStreamSource); - + InputStreamReader(InputStream &inputStreamSource); + /*Overload these 3 for your implementation*/ virtual int available(); - + virtual void close(); - - virtual int get(); + + virtual gunichar get(); private: @@ -445,13 +448,13 @@ public: StdReader(); virtual ~StdReader(); - + /*Overload these 3 for your implementation*/ virtual int available(); - + virtual void close(); - - virtual int get(); + + virtual gunichar get(); private: @@ -463,8 +466,6 @@ private: - - //######################################################################### //# W R I T E R //######################################################################### @@ -492,7 +493,7 @@ public: virtual void flush() = 0; - virtual int put(XMLCh ch) = 0; + virtual int put(gunichar ch) = 0; /* Formatted output */ virtual Writer& printf(const DOMString &fmt, ...) = 0; @@ -542,7 +543,7 @@ public: virtual void flush(); - virtual int put(XMLCh ch); + virtual int put(gunichar ch); @@ -635,7 +636,7 @@ public: virtual void flush(); - virtual int put(XMLCh ch); + virtual int put(gunichar ch); private: @@ -663,7 +664,7 @@ public: virtual void flush(); - virtual int put(XMLCh ch); + virtual int put(gunichar ch); private: diff --git a/src/dom/io/stringstream.cpp b/src/dom/io/stringstream.cpp index c6e47045e..ca058a575 100644 --- a/src/dom/io/stringstream.cpp +++ b/src/dom/io/stringstream.cpp @@ -140,7 +140,7 @@ void StringOutputStream::flush() /** * Writes the specified byte to this output stream. */ -int StringOutputStream::put(XMLCh ch) +int StringOutputStream::put(gunichar ch) { buffer.push_back(ch); return 1; diff --git a/src/dom/io/stringstream.h b/src/dom/io/stringstream.h index f6ed89e65..9ba24fc26 100644 --- a/src/dom/io/stringstream.h +++ b/src/dom/io/stringstream.h @@ -100,7 +100,7 @@ public: virtual void flush(); - virtual int put(XMLCh ch); + virtual int put(gunichar ch); virtual DOMString &getString() { return buffer; } diff --git a/src/dom/io/uristream.cpp b/src/dom/io/uristream.cpp index 09b0ac361..f6172d9e0 100644 --- a/src/dom/io/uristream.cpp +++ b/src/dom/io/uristream.cpp @@ -235,10 +235,10 @@ void UriReader::close() throw(StreamException) /** * */ -int UriReader::get() throw(StreamException) +gunichar UriReader::get() throw(StreamException) { - int ch = (int)inputStream->get(); - return ch; + //int ch = (int)inputStream->get(); + return inputStream->get();//ch; } @@ -372,7 +372,7 @@ void UriOutputStream::flush() throw(StreamException) /** * Writes the specified byte to this output stream. */ -int UriOutputStream::put(XMLCh ch) throw(StreamException) +int UriOutputStream::put(gunichar ch) throw(StreamException) { if (closed) return -1; @@ -440,10 +440,9 @@ void UriWriter::flush() throw(StreamException) /** * */ -int UriWriter::put(XMLCh ch) throw(StreamException) +int UriWriter::put(gunichar ch) throw(StreamException) { - int ich = (int)ch; - if (outputStream->put(ich) < 0) + if (outputStream->put(ch) < 0) return -1; return 1; } diff --git a/src/dom/io/uristream.h b/src/dom/io/uristream.h index 8d60468a5..51227acc9 100644 --- a/src/dom/io/uristream.h +++ b/src/dom/io/uristream.h @@ -111,7 +111,7 @@ public: virtual void close() throw(StreamException); - virtual int get() throw(StreamException); + virtual gunichar get() throw(StreamException); private: @@ -143,7 +143,7 @@ public: virtual void flush() throw(StreamException); - virtual int put(XMLCh ch) throw(StreamException); + virtual int put(gunichar ch) throw(StreamException); private: @@ -181,7 +181,7 @@ public: virtual void flush() throw(StreamException); - virtual int put(XMLCh ch) throw(StreamException); + virtual int put(gunichar ch) throw(StreamException); private: diff --git a/src/extension/CMakeLists.txt b/src/extension/CMakeLists.txt index 273067e80..f6311721d 100644 --- a/src/extension/CMakeLists.txt +++ b/src/extension/CMakeLists.txt @@ -36,10 +36,9 @@ set(extension_SRC internal/cairo-render-context.cpp internal/cairo-renderer.cpp internal/cairo-renderer-pdf-out.cpp + internal/cdr-input.cpp internal/emf-inout.cpp internal/emf-print.cpp - internal/wmf-inout.cpp - internal/wmf-print.cpp internal/gdkpixbuf-input.cpp internal/gimpgrad.cpp internal/grid.cpp @@ -54,6 +53,8 @@ set(extension_SRC internal/svg.cpp internal/svgz.cpp internal/vsd-input.cpp + internal/wmf-inout.cpp + internal/wmf-print.cpp internal/filter/filter-all.cpp internal/filter/filter-file.cpp @@ -102,11 +103,10 @@ set(extension_SRC internal/cairo-render-context.h internal/cairo-renderer-pdf-out.h internal/cairo-renderer.h + internal/cdr-input.h internal/clear-n_.h internal/emf-inout.h internal/emf-print.h - internal/wmf-inout.h - internal/wmf-print.h internal/filter/bevels.h internal/filter/blurs.h internal/filter/bumps.h @@ -138,6 +138,8 @@ set(extension_SRC internal/svg.h internal/svgz.h internal/vsd-input.h + internal/wmf-inout.h + internal/wmf-print.h script/InkscapeScript.h ) diff --git a/src/extension/error-file.cpp b/src/extension/error-file.cpp index 2a56f55e8..778295f47 100644 --- a/src/extension/error-file.cpp +++ b/src/extension/error-file.cpp @@ -56,7 +56,11 @@ ErrorFileNotice::ErrorFileNotice (void) : g_free(ext_error_file); set_message(dialog_text, true); +#if WITH_GTKMM_3_0 + Gtk::Box * vbox = get_content_area(); +#else Gtk::Box * vbox = get_vbox(); +#endif /* This is some filler text, needs to change before relase */ Inkscape::Preferences *prefs = Inkscape::Preferences::get(); diff --git a/src/extension/extension.cpp b/src/extension/extension.cpp index 4e2c5b9e4..28f556e75 100644 --- a/src/extension/extension.cpp +++ b/src/extension/extension.cpp @@ -19,12 +19,16 @@ # include "config.h" #endif - #include <glibmm/i18n.h> #include <gtkmm/box.h> #include <gtkmm/label.h> #include <gtkmm/frame.h> -#include <gtkmm/table.h> + +#if WITH_GTKMM_3_0 +# include <gtkmm/grid.h> +#else +# include <gtkmm/table.h> +#endif #include "inkscape.h" #include "extension/implementation/implementation.h" @@ -720,7 +724,12 @@ Extension::get_info_widget(void) Gtk::Frame * info = Gtk::manage(new Gtk::Frame("General Extension Information")); retval->pack_start(*info, true, true, 5); +#if WITH_GTKMM_3_0 + Gtk::Grid * table = Gtk::manage(new Gtk::Grid()); +#else Gtk::Table * table = Gtk::manage(new Gtk::Table()); +#endif + info->add(*table); int row = 0; @@ -733,8 +742,11 @@ Extension::get_info_widget(void) return retval; } -void -Extension::add_val(Glib::ustring labelstr, Glib::ustring valuestr, Gtk::Table * table, int * row) +#if WITH_GTKMM_3_0 +void Extension::add_val(Glib::ustring labelstr, Glib::ustring valuestr, Gtk::Grid * table, int * row) +#else +void Extension::add_val(Glib::ustring labelstr, Glib::ustring valuestr, Gtk::Table * table, int * row) +#endif { Gtk::Label * label; Gtk::Label * value; @@ -742,8 +754,14 @@ Extension::add_val(Glib::ustring labelstr, Glib::ustring valuestr, Gtk::Table * (*row)++; label = Gtk::manage(new Gtk::Label(labelstr)); value = Gtk::manage(new Gtk::Label(valuestr)); + +#if WITH_GTKMM_3_0 + table->attach(*label, 0, (*row) - 1, 1, 1); + table->attach(*value, 1, (*row) - 1, 1, 1); +#else table->attach(*label, 0, 1, (*row) - 1, *row); table->attach(*value, 1, 2, (*row) - 1, *row); +#endif label->show(); value->show(); diff --git a/src/extension/extension.h b/src/extension/extension.h index 78999631a..dcabb3df7 100644 --- a/src/extension/extension.h +++ b/src/extension/extension.h @@ -22,7 +22,12 @@ #include <sigc++/signal.h> namespace Gtk { +#if WITH_GTKMM_3_0 + class Grid; +#else class Table; +#endif + class VBox; class Widget; } @@ -285,8 +290,11 @@ public: Gtk::VBox * get_help_widget(void); Gtk::VBox * get_params_widget(void); protected: +#if WITH_GTKMM_3_0 + inline static void add_val(Glib::ustring labelstr, Glib::ustring valuestr, Gtk::Grid * table, int * row); +#else inline static void add_val(Glib::ustring labelstr, Glib::ustring valuestr, Gtk::Table * table, int * row); - +#endif }; diff --git a/src/extension/implementation/script.cpp b/src/extension/implementation/script.cpp index d3aeace55..3ac1e06ab 100644 --- a/src/extension/implementation/script.cpp +++ b/src/extension/implementation/script.cpp @@ -23,6 +23,8 @@ #include <gtkmm/main.h> #include <gtkmm/scrolledwindow.h> #include <gtkmm/textview.h> +#include <glibmm/miscutils.h> +#include <glibmm/convert.h> #include <unistd.h> #include <errno.h> @@ -852,7 +854,11 @@ void Script::checkStderr (const Glib::ustring &data, GtkWidget *dlg = GTK_WIDGET(warning.gobj()); sp_transientize(dlg); +#if WITH_GTKMM_3_0 + Gtk::Box * vbox = warning.get_content_area(); +#else Gtk::Box * vbox = warning.get_vbox(); +#endif /* Gtk::TextView * textview = new Gtk::TextView(Gtk::TextBuffer::create()); */ Gtk::TextView * textview = new Gtk::TextView(); @@ -956,7 +962,14 @@ int Script::execute (const std::list<std::string> &in_command, // assemble the rest of argv std::copy(in_params.begin(), in_params.end(), std::back_inserter(argv)); if (!filein.empty()) { - argv.push_back(filein); + if(Glib::path_is_absolute(filein)) + argv.push_back(filein); + else { + std::vector<std::string> buildargs; + buildargs.push_back(Glib::get_current_dir()); + buildargs.push_back(filein); + argv.push_back(Glib::build_filename(buildargs)); + } } int stdout_pipe, stderr_pipe; diff --git a/src/extension/implementation/script.h b/src/extension/implementation/script.h index f52683623..270c361af 100644 --- a/src/extension/implementation/script.h +++ b/src/extension/implementation/script.h @@ -15,6 +15,9 @@ #include "implementation.h" #include <gtkmm/enums.h> +#include <glibmm/main.h> +#include <glibmm/spawn.h> +#include <glibmm/fileutils.h> namespace Inkscape { namespace XML { diff --git a/src/extension/internal/filter/paint.h b/src/extension/internal/filter/paint.h index ad396e08f..f04dd92f9 100644 --- a/src/extension/internal/filter/paint.h +++ b/src/extension/internal/filter/paint.h @@ -88,7 +88,7 @@ public: "<param name=\"noise\" gui-text=\"" N_("Noise reduction:") "\" type=\"int\" appearance=\"full\" min=\"1\" max=\"1000\">10</param>\n" "<param name=\"smooth\" gui-text=\"" N_("Smoothness:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0.01\" max=\"10.00\">1</param>\n" "</page>\n" - "<page name=\"graintab\" _gui-text=\""N_("Grain") "\">\n" + "<page name=\"graintab\" _gui-text=\"" N_("Grain") "\">\n" "<param name=\"grain\" gui-text=\"" N_("Grain mode") "\" type=\"boolean\" >true</param>\n" "<param name=\"grainxf\" gui-text=\"" N_("Horizontal frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1000\">1000</param>\n" "<param name=\"grainyf\" gui-text=\"" N_("Vertical frequency:") "\" type=\"float\" appearance=\"full\" precision=\"2\" min=\"0\" max=\"1000\">1000</param>\n" diff --git a/src/extension/internal/odf.cpp b/src/extension/internal/odf.cpp index 0639ae8d0..bd74ba47c 100644 --- a/src/extension/internal/odf.cpp +++ b/src/extension/internal/odf.cpp @@ -83,8 +83,8 @@ #include "dom/io/stringstream.h" +#include "inkscape-version.h" #include "document.h" - #include "extension/extension.h" @@ -1240,7 +1240,8 @@ bool OdfOutput::writeMeta(ZipFile &zf) outs.printf("xmlns:anim=\"urn:oasis:names:tc:opendocument:xmlns:animation:1.0\"\n"); outs.printf("office:version=\"1.0\">\n"); outs.printf("<office:meta>\n"); - outs.printf(" <meta:generator>Inkscape.org - 0.45</meta:generator>\n"); + Glib::ustring tmp = Glib::ustring(" <meta:generator>Inkscape.org - ") + Inkscape::version_string + "</meta:generator>\n"; + outs.writeString(tmp); outs.printf(" <meta:initial-creator>%#s</meta:initial-creator>\n", creator.c_str()); outs.printf(" <meta:creation-date>%#s</meta:creation-date>\n", date.c_str()); @@ -1465,7 +1466,7 @@ bool OdfOutput::writeStyle(ZipFile &zf) outs.printf("<!--\n"); outs.printf("*************************************************************************\n"); outs.printf(" E N D O F F I L E\n"); - outs.printf(" Have a nice day - ishmal\n"); + outs.printf(" Have a nice day\n"); outs.printf("*************************************************************************\n"); outs.printf("-->\n"); outs.printf("\n"); @@ -2170,7 +2171,7 @@ bool OdfOutput::writeStyleFooter(Writer &outs) outs.printf("<!--\n"); outs.printf("*************************************************************************\n"); outs.printf(" E N D O F F I L E\n"); - outs.printf(" Have a nice day - ishmal\n"); + outs.printf(" Have a nice day\n"); outs.printf("*************************************************************************\n"); outs.printf("-->\n"); outs.printf("\n"); @@ -2281,7 +2282,7 @@ bool OdfOutput::writeContentFooter(Writer &outs) outs.printf("<!--\n"); outs.printf("*************************************************************************\n"); outs.printf(" E N D O F F I L E\n"); - outs.printf(" Have a nice day - ishmal\n"); + outs.printf(" Have a nice day\n"); outs.printf("*************************************************************************\n"); outs.printf("-->\n"); outs.printf("\n"); @@ -2441,27 +2442,6 @@ OdfOutput::check (Inkscape::Extension::Extension */*module*/) -//######################################################################## -//# I N P U T -//######################################################################## - - - -//####################### -//# L A T E R !!! :-) -//####################### - - - - - - - - - - - - } //namespace Internal } //namespace Extension diff --git a/src/extension/internal/pdf-input-cairo.cpp b/src/extension/internal/pdf-input-cairo.cpp index 0a9dd8399..c83ebad82 100644 --- a/src/extension/internal/pdf-input-cairo.cpp +++ b/src/extension/internal/pdf-input-cairo.cpp @@ -108,7 +108,7 @@ PdfImportCairoDialog::PdfImportCairoDialog(PopplerDocument *doc) #if WITH_GTKMM_3_0 _fallbackPrecisionSlider_adj = Gtk::Adjustment::create(2, 1, 256, 1, 10, 10); - _fallbackPrecisionSlider = Gtk::manage(new Gtk::HScale(_fallbackPrecisionSlider_adj)); + _fallbackPrecisionSlider = Gtk::manage(new Gtk::Scale(_fallbackPrecisionSlider_adj)); #else _fallbackPrecisionSlider_adj = Gtk::manage(new class Gtk::Adjustment(2, 1, 256, 1, 10, 10)); _fallbackPrecisionSlider = Gtk::manage(new class Gtk::HScale(*_fallbackPrecisionSlider_adj)); @@ -224,9 +224,17 @@ PdfImportCairoDialog::PdfImportCairoDialog(PopplerDocument *doc) vbox1->pack_start(*_importSettingsFrame, Gtk::PACK_EXPAND_PADDING, 0); hbox1->pack_start(*vbox1); hbox1->pack_start(*_previewArea, Gtk::PACK_EXPAND_WIDGET, 4); + +#if WITH_GTKMM_3_0 + get_content_area()->set_homogeneous(false); + get_content_area()->set_spacing(0); + get_content_area()->pack_start(*hbox1); +#else this->get_vbox()->set_homogeneous(false); this->get_vbox()->set_spacing(0); this->get_vbox()->pack_start(*hbox1); +#endif + this->set_title(_("PDF Import Settings")); this->set_modal(true); sp_transientize(GTK_WIDGET(this->gobj())); //Make transient diff --git a/src/extension/internal/pdf-input-cairo.h b/src/extension/internal/pdf-input-cairo.h index 81e9a8f00..66f1e5e7e 100644 --- a/src/extension/internal/pdf-input-cairo.h +++ b/src/extension/internal/pdf-input-cairo.h @@ -37,6 +37,14 @@ #include "../implementation/implementation.h" +namespace Gtk { +#if WITH_GTKMM_3_0 + class Scale; +#else + class HScale; +#endif +} + namespace Inkscape { namespace UI { @@ -85,10 +93,11 @@ private: class Inkscape::UI::Widget::Frame * _pageSettingsFrame; class Gtk::Label * _labelPrecision; class Gtk::Label * _labelPrecisionWarning; - class Gtk::HScale * _fallbackPrecisionSlider; #if WITH_GTKMM_3_0 + class Gtk::Scale * _fallbackPrecisionSlider; Glib::RefPtr<Gtk::Adjustment> _fallbackPrecisionSlider_adj; #else + class Gtk::HScale * _fallbackPrecisionSlider; class Gtk::Adjustment *_fallbackPrecisionSlider_adj; #endif class Gtk::Label * _labelPrecisionComment; diff --git a/src/extension/internal/pdfinput/pdf-input.cpp b/src/extension/internal/pdfinput/pdf-input.cpp index 90d53c6b0..531cda20a 100644 --- a/src/extension/internal/pdfinput/pdf-input.cpp +++ b/src/extension/internal/pdfinput/pdf-input.cpp @@ -124,7 +124,7 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/) #if WITH_GTKMM_3_0 _fallbackPrecisionSlider_adj = Gtk::Adjustment::create(2, 1, 256, 1, 10, 10); - _fallbackPrecisionSlider = Gtk::manage(new class Gtk::HScale(_fallbackPrecisionSlider_adj)); + _fallbackPrecisionSlider = Gtk::manage(new class Gtk::Scale(_fallbackPrecisionSlider_adj)); #else _fallbackPrecisionSlider_adj = Gtk::manage(new class Gtk::Adjustment(2, 1, 256, 1, 10, 10)); _fallbackPrecisionSlider = Gtk::manage(new class Gtk::HScale(*_fallbackPrecisionSlider_adj)); @@ -240,9 +240,17 @@ PdfImportDialog::PdfImportDialog(PDFDoc *doc, const gchar */*uri*/) vbox1->pack_start(*_importSettingsFrame, Gtk::PACK_EXPAND_PADDING, 0); hbox1->pack_start(*vbox1); hbox1->pack_start(*_previewArea, Gtk::PACK_EXPAND_WIDGET, 4); + +#if WITH_GTKMM_3_0 + get_content_area()->set_homogeneous(false); + get_content_area()->set_spacing(0); + get_content_area()->pack_start(*hbox1); +#else this->get_vbox()->set_homogeneous(false); this->get_vbox()->set_spacing(0); this->get_vbox()->pack_start(*hbox1); +#endif + this->set_title(_("PDF Import Settings")); this->set_modal(true); sp_transientize(GTK_WIDGET(this->gobj())); //Make transient diff --git a/src/extension/internal/pdfinput/pdf-input.h b/src/extension/internal/pdfinput/pdf-input.h index e9da5b27c..3710e4667 100644 --- a/src/extension/internal/pdfinput/pdf-input.h +++ b/src/extension/internal/pdfinput/pdf-input.h @@ -39,7 +39,11 @@ namespace Gtk { class DrawingArea; class Frame; class HBox; +#if WITH_GTKMM_3_0 + class Scale; +#else class HScale; +#endif class VBox; class Label; } @@ -95,10 +99,11 @@ private: class Inkscape::UI::Widget::Frame * _pageSettingsFrame; class Gtk::Label * _labelPrecision; class Gtk::Label * _labelPrecisionWarning; - class Gtk::HScale * _fallbackPrecisionSlider; #if WITH_GTKMM_3_0 + class Gtk::Scale * _fallbackPrecisionSlider; Glib::RefPtr<Gtk::Adjustment> _fallbackPrecisionSlider_adj; #else + class Gtk::HScale * _fallbackPrecisionSlider; class Gtk::Adjustment *_fallbackPrecisionSlider_adj; #endif class Gtk::Label * _labelPrecisionComment; diff --git a/src/extension/prefdialog.cpp b/src/extension/prefdialog.cpp index 649dc398a..f3c6508af 100644 --- a/src/extension/prefdialog.cpp +++ b/src/extension/prefdialog.cpp @@ -67,7 +67,12 @@ PrefDialog::PrefDialog (Glib::ustring name, gchar const * help, Gtk::Widget * co hbox->pack_start(*controls, true, true, 6); hbox->show(); + +#if WITH_GTKMM_3_0 + this->get_content_area()->pack_start(*hbox, true, true, 6); +#else this->get_vbox()->pack_start(*hbox, true, true, 6); +#endif /* Gtk::Button * help_button = add_button(Gtk::Stock::HELP, Gtk::RESPONSE_HELP); @@ -95,14 +100,24 @@ PrefDialog::PrefDialog (Glib::ustring name, gchar const * help, Gtk::Widget * co #endif sep->show(); + +#if WITH_GTKMM_3_0 + this->get_content_area()->pack_start(*sep, true, true, 4); +#else this->get_vbox()->pack_start(*sep, true, true, 4); +#endif hbox = Gtk::manage(new Gtk::HBox()); _button_preview = _param_preview->get_widget(NULL, NULL, &_signal_preview); _button_preview->show(); hbox->pack_start(*_button_preview, true, true,6); hbox->show(); + +#if WITH_GTKMM_3_0 + this->get_content_area()->pack_start(*hbox, true, true, 6); +#else this->get_vbox()->pack_start(*hbox, true, true, 6); +#endif Gtk::Box * hbox = dynamic_cast<Gtk::Box *>(_button_preview); if (hbox != NULL) { diff --git a/src/extension/system.cpp b/src/extension/system.cpp index 60cd21d71..56cc6d1af 100644 --- a/src/extension/system.cpp +++ b/src/extension/system.cpp @@ -22,6 +22,7 @@ #include <interface.h> #include <unistd.h> +#include <glibmm/miscutils.h> #include "system.h" #include "preferences.h" @@ -69,34 +70,6 @@ static Extension *build_from_reprdoc(Inkscape::XML::Document *doc, Implementatio */ SPDocument *open(Extension *key, gchar const *filename) { - // Convert to absolute pathname to tolerate chdir(). - bool relpath = (filename[0] != '/'); -#ifdef WIN32 - relpath &= (filename[0] != '\\') && !(isalpha(filename[0]) && (filename[1] == ':')); -#endif - - // Do not consider an URI as a relative path. - if (relpath) { - gchar const * cp = filename; - - while (isalpha(*cp) || isdigit(*cp) || *cp == '+' || *cp == '-' || *cp == '.') - cp++; - - relpath = *cp != ':' || cp[1] != '/' || cp[2] != '/'; - } - - if (relpath) { - gchar * curdir = NULL; -#ifndef WIN32 - curdir = getcwd(NULL, 0); -#else - curdir = _getcwd(NULL, 0); -#endif - - filename = g_build_filename(curdir, filename, NULL); - free(curdir); - } - Input *imod = NULL; if (key == NULL) { @@ -138,9 +111,6 @@ SPDocument *open(Extension *key, gchar const *filename) } if (!imod->prefs(filename)) { - if (relpath){ - free((void *) filename); - } return NULL; } @@ -163,9 +133,6 @@ SPDocument *open(Extension *key, gchar const *filename) imod->set_gui(true); } - if (relpath){ - free((void *) filename); - } return doc; } diff --git a/src/file.cpp b/src/file.cpp index 468d02eba..97087c1a1 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -81,10 +81,6 @@ using Inkscape::DocumentUndo; #include "extension/dbus/dbus-init.h" #endif -//#ifdef WITH_INKBOARD -//#include "jabber_whiteboard/session-manager.h" -//#endif - #ifdef WIN32 #include <windows.h> #endif diff --git a/src/ink-comboboxentry-action.cpp b/src/ink-comboboxentry-action.cpp index fd146926f..320472347 100644 --- a/src/ink-comboboxentry-action.cpp +++ b/src/ink-comboboxentry-action.cpp @@ -303,11 +303,18 @@ ink_comboboxentry_action_class_init (Ink_ComboBoxEntry_ActionClass *klass) static void ink_comboboxentry_action_init (Ink_ComboBoxEntry_Action *action) { action->active = -1; - action->text = NULL; + action->text = strdup(""); action->entry_completion = NULL; action->indicator = NULL; action->popup = false; + action->info = NULL; + action->info_cb = NULL; + action->info_cb_id = 0; + action->info_cb_blocked = false; action->warning = NULL; + action->warning_cb = NULL; + action->warning_cb_id = 0; + action->warning_cb_blocked = false; action->altx_name = NULL; action->focusWidget = NULL; } @@ -370,7 +377,8 @@ GtkWidget* create_tool_item( GtkAction* action ) ink_comboboxentry_action->combobox = GTK_COMBO_BOX (comboBoxEntry); - gtk_combo_box_set_active( GTK_COMBO_BOX( comboBoxEntry ), ink_comboboxentry_action->active ); + //gtk_combo_box_set_active( GTK_COMBO_BOX( comboBoxEntry ), ink_comboboxentry_action->active ); + gtk_combo_box_set_active( GTK_COMBO_BOX( comboBoxEntry ), 0 ); g_signal_connect( G_OBJECT(comboBoxEntry), "changed", G_CALLBACK(combo_box_changed_cb), action ); @@ -432,7 +440,6 @@ GtkWidget* create_tool_item( GtkAction* action ) // Add signal for GtkEntry to check if finished typing. g_signal_connect( G_OBJECT(child), "activate", G_CALLBACK(entry_activate_cb), action ); g_signal_connect( G_OBJECT(child), "key-press-event", G_CALLBACK(keypress_cb), action ); - } gtk_activatable_set_related_action( GTK_ACTIVATABLE (item), GTK_ACTION( action ) ); @@ -476,66 +483,141 @@ gchar* ink_comboboxentry_action_get_active_text( Ink_ComboBoxEntry_Action* actio return text; } -gboolean ink_comboboxentry_action_set_active_text( Ink_ComboBoxEntry_Action* ink_comboboxentry_action, const gchar* text ) { +/* + * For the font-family list we need to handle two cases: + * Text is in list store: + * In this case we use row number as the font-family list can have duplicate + * entries, one in the document font part and one in the system font part. In + * order that scrolling through the list works properly we must distinguish + * between the two. + * Text is not in the list store (i.e. default font-family is not on system): + * In this case we have a row number of -1, and the text must be set by hand. + */ +gboolean ink_comboboxentry_action_set_active_text( Ink_ComboBoxEntry_Action* action, const gchar* text, int row ) { - g_free( ink_comboboxentry_action->text ); - ink_comboboxentry_action->text = g_strdup( text ); + if( strcmp( action->text, text ) != 0 ) { + g_free( action->text ); + action->text = g_strdup( text ); + } // Get active row or -1 if none - ink_comboboxentry_action->active = get_active_row_from_text( ink_comboboxentry_action, ink_comboboxentry_action->text ); + if( row < 0 ) { + row = get_active_row_from_text( action, action->text ); + } + action->active = row; // Set active row, check that combobox has been created. - if( ink_comboboxentry_action->combobox ) { - gtk_combo_box_set_active( GTK_COMBO_BOX( ink_comboboxentry_action->combobox ), ink_comboboxentry_action->active ); + if( action->combobox ) { + gtk_combo_box_set_active( GTK_COMBO_BOX( action->combobox ), action->active ); } // Fiddle with entry - if( ink_comboboxentry_action->entry ) { + if( action->entry ) { // Explicitly set text in GtkEntry box (won't be set if text not in list). - gtk_entry_set_text( ink_comboboxentry_action->entry, text ); + gtk_entry_set_text( action->entry, text ); // Show or hide warning -- this might be better moved to text-toolbox.cpp - bool clear = true; + if( action->info_cb_id != 0 && + !action->info_cb_blocked ) { + g_signal_handler_block (G_OBJECT(action->entry), + action->info_cb_id ); + action->info_cb_blocked = true; + } + if( action->warning_cb_id != 0 && + !action->warning_cb_blocked ) { + g_signal_handler_block (G_OBJECT(action->entry), + action->warning_cb_id ); + action->warning_cb_blocked = true; + } - if( ink_comboboxentry_action->warning != NULL ) { - Glib::ustring missing = check_comma_separated_text( ink_comboboxentry_action ); + bool set = false; + if( action->warning != NULL ) { + Glib::ustring missing = check_comma_separated_text( action ); if( !missing.empty() ) { - GtkStockItem item; - gboolean isStock = gtk_stock_lookup( GTK_STOCK_DIALOG_WARNING, &item ); - if (isStock) { - gtk_entry_set_icon_from_stock( ink_comboboxentry_action->entry, + GtkStockItem item; + gboolean isStock = gtk_stock_lookup( GTK_STOCK_DIALOG_WARNING, &item ); + if (isStock) { + gtk_entry_set_icon_from_stock( action->entry, + GTK_ENTRY_ICON_SECONDARY, + GTK_STOCK_DIALOG_WARNING ); + } else { + gtk_entry_set_icon_from_icon_name( action->entry, GTK_ENTRY_ICON_SECONDARY, GTK_STOCK_DIALOG_WARNING ); - } else { - gtk_entry_set_icon_from_icon_name( ink_comboboxentry_action->entry, - GTK_ENTRY_ICON_SECONDARY, - GTK_STOCK_DIALOG_WARNING ); + } + // Can't add tooltip until icon set + Glib::ustring warning = action->warning; + warning += ": "; + warning += missing; + gtk_entry_set_icon_tooltip_text( action->entry, + GTK_ENTRY_ICON_SECONDARY, + warning.c_str() ); + + if( action->warning_cb ) { + + // Add callback if we haven't already + if( action->warning_cb_id == 0 ) { + action->warning_cb_id = + g_signal_connect( G_OBJECT(action->entry), + "icon-press", + G_CALLBACK(action->warning_cb), + action); } - // Can't add tooltip until icon set - Glib::ustring warning = ink_comboboxentry_action->warning; - warning += ": "; - warning += missing; - gtk_entry_set_icon_tooltip_text( ink_comboboxentry_action->entry, - GTK_ENTRY_ICON_SECONDARY, - warning.c_str() ); - clear = false; + // Unblock signal + if( action->warning_cb_blocked ) { + g_signal_handler_unblock (G_OBJECT(action->entry), + action->warning_cb_id ); + action->warning_cb_blocked = false; + } + } + set = true; } } - if( clear ) { - gtk_entry_set_icon_from_icon_name( GTK_ENTRY(ink_comboboxentry_action->entry), + if( !set && action->info != NULL ) { + gtk_entry_set_icon_from_icon_name( GTK_ENTRY(action->entry), + GTK_ENTRY_ICON_SECONDARY, + GTK_STOCK_SELECT_ALL ); + gtk_entry_set_icon_from_stock( GTK_ENTRY(action->entry), + GTK_ENTRY_ICON_SECONDARY, + GTK_STOCK_SELECT_ALL ); + gtk_entry_set_icon_tooltip_text( action->entry, + GTK_ENTRY_ICON_SECONDARY, + action->info ); + + if( action->info_cb ) { + // Add callback if we haven't already + if( action->info_cb_id == 0 ) { + action->info_cb_id = + g_signal_connect( G_OBJECT(action->entry), + "icon-press", + G_CALLBACK(action->info_cb), + action); + } + // Unblock signal + if( action->info_cb_blocked ) { + g_signal_handler_unblock (G_OBJECT(action->entry), + action->info_cb_id ); + action->info_cb_blocked = false; + } + } + set = true; + } + + if( !set ) { + gtk_entry_set_icon_from_icon_name( GTK_ENTRY(action->entry), GTK_ENTRY_ICON_SECONDARY, NULL ); - gtk_entry_set_icon_from_stock( GTK_ENTRY(ink_comboboxentry_action->entry), + gtk_entry_set_icon_from_stock( GTK_ENTRY(action->entry), GTK_ENTRY_ICON_SECONDARY, NULL ); } } // Return if active text in list - gboolean found = ( ink_comboboxentry_action->active != -1 ); + gboolean found = ( action->active != -1 ); return found; } @@ -611,6 +693,24 @@ void ink_comboboxentry_action_set_tooltip( Ink_ComboBoxEntry_Action* action, } +void ink_comboboxentry_action_set_info( Ink_ComboBoxEntry_Action* action, const gchar* info ) { + + g_free( action->info ); + action->info = g_strdup( info ); + + // Widget may not have been created.... + if( action->entry ) { + gtk_entry_set_icon_tooltip_text( GTK_ENTRY(action->entry), + GTK_ENTRY_ICON_SECONDARY, + action->info ); + } +} + +void ink_comboboxentry_action_set_info_cb( Ink_ComboBoxEntry_Action* action, gpointer info_cb ) { + + action->info_cb = info_cb; +} + void ink_comboboxentry_action_set_warning( Ink_ComboBoxEntry_Action* action, const gchar* warning ) { g_free( action->warning ); @@ -624,6 +724,11 @@ void ink_comboboxentry_action_set_warning( Ink_ComboBoxEntry_Action* action, } } +void ink_comboboxentry_action_set_warning_cb( Ink_ComboBoxEntry_Action* action, gpointer warning_cb ) { + + action->warning_cb = warning_cb; +} + void ink_comboboxentry_action_set_altx_name( Ink_ComboBoxEntry_Action* action, const gchar* altx_name ) { g_free( action->altx_name ); @@ -728,22 +833,27 @@ static void combo_box_changed_cb( GtkComboBox* widget, gpointer data ) { // We only react here if an item is selected. // Get action - Ink_ComboBoxEntry_Action *act = INK_COMBOBOXENTRY_ACTION( data ); + Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION( data ); // Check if item selected: gint newActive = gtk_combo_box_get_active(widget); - if( newActive >= 0 ) { + if( newActive >= 0 && newActive != action->active ) { - if( newActive != act->active ) { - act->active = newActive; - g_free( act->text ); - GtkWidget *entry = gtk_bin_get_child (GTK_BIN (widget)); - act->text = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry))); + action->active = newActive; - // Now let the world know - g_signal_emit( G_OBJECT(act), signals[CHANGED], 0 ); + GtkTreeIter iter; + if( gtk_combo_box_get_active_iter( GTK_COMBO_BOX( action->combobox ), &iter ) ) { + gchar* text = 0; + gtk_tree_model_get( action->model, &iter, 0, &text, -1 ); + gtk_entry_set_text( action->entry, text ); + + g_free( action->text ); + action->text = text; } + + // Now let the world know + g_signal_emit( G_OBJECT(action), signals[CHANGED], 0 ); } } @@ -752,29 +862,29 @@ static void entry_activate_cb( GtkEntry* widget, gpointer data ) { // Get text from entry box.. check if it matches a menu entry. // Get action - Ink_ComboBoxEntry_Action *ink_comboboxentry_action = INK_COMBOBOXENTRY_ACTION( data ); + Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION( data ); // Get text - g_free( ink_comboboxentry_action->text ); - ink_comboboxentry_action->text = g_strdup( gtk_entry_get_text( widget ) ); + g_free( action->text ); + action->text = g_strdup( gtk_entry_get_text( widget ) ); // Get row - ink_comboboxentry_action->active = - get_active_row_from_text( ink_comboboxentry_action, ink_comboboxentry_action->text ); + action->active = + get_active_row_from_text( action, action->text ); // Set active row - gtk_combo_box_set_active( GTK_COMBO_BOX( ink_comboboxentry_action->combobox), ink_comboboxentry_action->active ); + gtk_combo_box_set_active( GTK_COMBO_BOX( action->combobox), action->active ); // Now let the world know - g_signal_emit( G_OBJECT(ink_comboboxentry_action), signals[CHANGED], 0 ); + g_signal_emit( G_OBJECT(action), signals[CHANGED], 0 ); } static gboolean match_selected_cb( GtkEntryCompletion* /*widget*/, GtkTreeModel* model, GtkTreeIter* iter, gpointer data ) { // Get action - Ink_ComboBoxEntry_Action *ink_comboboxentry_action = INK_COMBOBOXENTRY_ACTION( data ); - GtkEntry *entry = ink_comboboxentry_action->entry; + Ink_ComboBoxEntry_Action *action = INK_COMBOBOXENTRY_ACTION( data ); + GtkEntry *entry = action->entry; if( entry) { gchar *family = 0; @@ -784,18 +894,18 @@ static gboolean match_selected_cb( GtkEntryCompletion* /*widget*/, GtkTreeModel* gtk_entry_set_text (GTK_ENTRY (entry), family ); // Set text in GtkAction - g_free( ink_comboboxentry_action->text ); - ink_comboboxentry_action->text = family; + g_free( action->text ); + action->text = family; // Get row - ink_comboboxentry_action->active = - get_active_row_from_text( ink_comboboxentry_action, ink_comboboxentry_action->text ); + action->active = + get_active_row_from_text( action, action->text ); // Set active row - gtk_combo_box_set_active( GTK_COMBO_BOX( ink_comboboxentry_action->combobox), ink_comboboxentry_action->active ); + gtk_combo_box_set_active( GTK_COMBO_BOX( action->combobox), action->active ); // Now let the world know - g_signal_emit( G_OBJECT(ink_comboboxentry_action), signals[CHANGED], 0 ); + g_signal_emit( G_OBJECT(action), signals[CHANGED], 0 ); return true; } diff --git a/src/ink-comboboxentry-action.h b/src/ink-comboboxentry-action.h index f0dc0ee7e..a66f0790e 100644 --- a/src/ink-comboboxentry-action.h +++ b/src/ink-comboboxentry-action.h @@ -58,7 +58,14 @@ struct _Ink_ComboBoxEntry_Action { gint entry_width;// Width of GtkEntry in characters. gint extra_width;// Extra Width of GtkComboBox.. to widen drop-down list in list mode. gboolean popup; // Do we pop-up an entry-completion dialog? - gchar *warning; // Text for warning that entry isn't in list. + gchar *info; // Text for tooltip info about entry. + gpointer info_cb; // Callback for clicking info icon. + gint info_cb_id; + gboolean info_cb_blocked; + gchar *warning; // Text for tooltip warning that entry isn't in list. + gpointer warning_cb; // Callback for clicking warning icon. + gint warning_cb_id; + gboolean warning_cb_blocked; gchar *altx_name; // Target for Alt-X keyboard shortcut. GtkWidget *focusWidget; }; @@ -84,7 +91,7 @@ GtkTreeModel *ink_comboboxentry_action_get_model( Ink_ComboBoxEntry_Action* GtkComboBox *ink_comboboxentry_action_get_comboboxentry( Ink_ComboBoxEntry_Action* action ); gchar* ink_comboboxentry_action_get_active_text( Ink_ComboBoxEntry_Action* action ); -gboolean ink_comboboxentry_action_set_active_text( Ink_ComboBoxEntry_Action* action, const gchar* text ); +gboolean ink_comboboxentry_action_set_active_text( Ink_ComboBoxEntry_Action* action, const gchar* text, int row=-1 ); void ink_comboboxentry_action_set_entry_width( Ink_ComboBoxEntry_Action* action, gint entry_width ); void ink_comboboxentry_action_set_extra_width( Ink_ComboBoxEntry_Action* action, gint extra_width ); @@ -92,8 +99,11 @@ void ink_comboboxentry_action_set_extra_width( Ink_ComboBoxEntry_Action* act void ink_comboboxentry_action_popup_enable( Ink_ComboBoxEntry_Action* action ); void ink_comboboxentry_action_popup_disable( Ink_ComboBoxEntry_Action* action ); -void ink_comboboxentry_action_set_warning( Ink_ComboBoxEntry_Action* action, const gchar* warning ); -void ink_comboboxentry_action_set_tooltip( Ink_ComboBoxEntry_Action* action, const gchar* tooltip ); +void ink_comboboxentry_action_set_info( Ink_ComboBoxEntry_Action* action, const gchar* info ); +void ink_comboboxentry_action_set_info_cb( Ink_ComboBoxEntry_Action* action, gpointer info_cb ); +void ink_comboboxentry_action_set_warning( Ink_ComboBoxEntry_Action* action, const gchar* warning_cb ); +void ink_comboboxentry_action_set_warning_cb(Ink_ComboBoxEntry_Action* action, gpointer warning ); +void ink_comboboxentry_action_set_tooltip( Ink_ComboBoxEntry_Action* action, const gchar* tooltip ); void ink_comboboxentry_action_set_altx_name( Ink_ComboBoxEntry_Action* action, const gchar* altx_name ); diff --git a/src/inkscape.cpp b/src/inkscape.cpp index fc823f8b7..449220357 100644 --- a/src/inkscape.cpp +++ b/src/inkscape.cpp @@ -37,6 +37,8 @@ #include <glib/gstdio.h> #include <glib.h> #include <glibmm/i18n.h> +#include <glibmm/miscutils.h> +#include <glibmm/convert.h> #include <gtkmm/messagedialog.h> #include <gtk/gtk.h> #include <signal.h> diff --git a/src/interface.cpp b/src/interface.cpp index 823119953..bf497b407 100644 --- a/src/interface.cpp +++ b/src/interface.cpp @@ -458,47 +458,21 @@ static GtkWidget *sp_ui_menu_append_item_from_verb(GtkMenu *menu, Inkscape::Verb item = gtk_separator_menu_item_new(); } else { - unsigned int shortcut; action = verb->get_action(view); if (!action) return NULL; - shortcut = sp_shortcut_get_primary(verb); - if (shortcut!=GDK_KEY_VoidSymbol) { - gchar* c = sp_shortcut_get_label(shortcut); -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *const hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 16); - gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); -#else - GtkWidget *const hb = gtk_hbox_new(FALSE, 16); -#endif - GtkWidget *const name_lbl = gtk_label_new(""); - gtk_label_set_markup_with_mnemonic(GTK_LABEL(name_lbl), action->name); - gtk_misc_set_alignment(reinterpret_cast<GtkMisc *>(name_lbl), 0.0, 0.5); - gtk_box_pack_start(reinterpret_cast<GtkBox *>(hb), name_lbl, TRUE, TRUE, 0); - GtkWidget *const accel_lbl = gtk_label_new(c); - gtk_misc_set_alignment(reinterpret_cast<GtkMisc *>(accel_lbl), 1.0, 0.5); - gtk_box_pack_end(reinterpret_cast<GtkBox *>(hb), accel_lbl, FALSE, FALSE, 0); - gtk_widget_show_all(hb); - if (radio) { - item = gtk_radio_menu_item_new (group); - } else { - item = gtk_image_menu_item_new(); - } - gtk_container_add(reinterpret_cast<GtkContainer *>(item), hb); - g_free(c); + if (radio) { + item = gtk_radio_menu_item_new_with_mnemonic(group, action->name); } else { - if (radio) { - item = gtk_radio_menu_item_new (group); - } else { - item = gtk_image_menu_item_new (); - } - GtkWidget *const name_lbl = gtk_label_new(""); - gtk_label_set_markup_with_mnemonic(GTK_LABEL(name_lbl), action->name); - gtk_misc_set_alignment(reinterpret_cast<GtkMisc *>(name_lbl), 0.0, 0.5); - gtk_container_add(reinterpret_cast<GtkContainer *>(item), name_lbl); + item = gtk_image_menu_item_new_with_mnemonic(action->name); } + GtkAccelGroup *accel_group = sp_shortcut_get_accel_group(); + gtk_menu_set_accel_group(menu, accel_group); + + sp_shortcut_add_accelerator(item, sp_shortcut_get_primary(verb)); + action->signal_set_sensitive.connect( sigc::bind<0>( sigc::ptr_fun(>k_widget_set_sensitive), @@ -698,45 +672,16 @@ sp_ui_menu_append_check_item_from_verb(GtkMenu *menu, Inkscape::UI::View::View * { unsigned int shortcut = (verb) ? sp_shortcut_get_primary(verb) : 0; SPAction *action = (verb) ? verb->get_action(view) : 0; - GtkWidget *item = gtk_check_menu_item_new(); - - - if (verb && shortcut!=GDK_KEY_VoidSymbol) { - gchar* c = sp_shortcut_get_label(shortcut); - -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *hb = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 16); - gtk_box_set_homogeneous(GTK_BOX(hb), FALSE); -#else - GtkWidget *hb = gtk_hbox_new(FALSE, 16); -#endif + GtkWidget *item = gtk_check_menu_item_new_with_mnemonic(action ? action->name : label); - { - GtkWidget *l = gtk_label_new_with_mnemonic(action ? action->name : label); - gtk_misc_set_alignment((GtkMisc *) l, 0.0, 0.5); - gtk_box_pack_start((GtkBox *) hb, l, TRUE, TRUE, 0); - } - - { - GtkWidget *l = gtk_label_new(c); - gtk_misc_set_alignment((GtkMisc *) l, 1.0, 0.5); - gtk_box_pack_end((GtkBox *) hb, l, FALSE, FALSE, 0); - } - - gtk_widget_show_all(hb); - - gtk_container_add((GtkContainer *) item, hb); - g_free(c); - } else { - GtkWidget *l = gtk_label_new_with_mnemonic(action ? action->name : label); - gtk_misc_set_alignment((GtkMisc *) l, 0.0, 0.5); - gtk_container_add((GtkContainer *) item, l); - } #if 0 if (!action->sensitive) { gtk_widget_set_sensitive(item, FALSE); } #endif + + sp_shortcut_add_accelerator(item, shortcut); + gtk_widget_show(item); gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); @@ -1594,14 +1539,16 @@ sp_ui_menu_item_set_name(GtkWidget *data, Glib::ustring const &name) //- a GtkHBox, whose first child is a label displaying name if the menu //item has an accel key //- a GtkLabel if the menu has no accel key - if (GTK_IS_LABEL(child)) { - gtk_label_set_markup_with_mnemonic(GTK_LABEL (child), name.c_str()); - } else if (GTK_IS_HBOX(child)) { - gtk_label_set_markup_with_mnemonic( - GTK_LABEL (gtk_container_get_children(GTK_CONTAINER (child))->data), - name.c_str()); - }//else sp_ui_menu_append_item_from_verb has been modified and can set - //a menu item in yet another way... + if (child != NULL){ + if (GTK_IS_LABEL(child)) { + gtk_label_set_markup_with_mnemonic(GTK_LABEL (child), name.c_str()); + } else if (GTK_IS_HBOX(child)) { + gtk_label_set_markup_with_mnemonic( + GTK_LABEL (gtk_container_get_children(GTK_CONTAINER (child))->data), + name.c_str()); + }//else sp_ui_menu_append_item_from_verb has been modified and can set + //a menu item in yet another way... + } } } @@ -1726,40 +1673,13 @@ void ContextMenu::AppendItemFromVerb(Inkscape::Verb *verb)//, SPDesktop *view)// append(*item); } else { action = verb->get_action(view); - if (!action) - { + if (!action) { return; } - Gtk::ImageMenuItem *item = NULL; - unsigned int shortcut = sp_shortcut_get_primary(verb); - if (shortcut!=GDK_KEY_VoidSymbol) { - gchar* c = sp_shortcut_get_label(shortcut); - Gtk::HBox *const hb = manage(new Gtk::HBox (FALSE, 16)); - Gtk::Label *const name_lbl = manage(new Gtk::Label(action->name, true)); - name_lbl->set_alignment(0.0, 0.5); - hb->pack_start(*name_lbl, TRUE, TRUE, 0); - Gtk::Label *const accel_lbl = manage(new Gtk::Label(c)); - accel_lbl->set_alignment(1.0, 0.5); - hb->pack_end(*accel_lbl, FALSE, FALSE, 0); - hb->show_all(); - // if (radio) { - // item = gtk_radio_menu_item_new (group); - // } else { - item = new Gtk::ImageMenuItem(); - // } - item->add(*hb); - g_free(c); - } else { - // if (radio) { - // item = gtk_radio_menu_item_new (group); - // } else { - item = manage(new Gtk::ImageMenuItem()); - // } - Gtk::Label *const name_lbl = manage(new Gtk::Label(action->name, true)); - name_lbl->set_alignment(0.0, 0.5); - item->add(*name_lbl); - } + Gtk::ImageMenuItem *item = manage(new Gtk::ImageMenuItem(action->name, true)); + + sp_shortcut_add_accelerator(GTK_WIDGET(item->gobj()), sp_shortcut_get_primary(verb)); action->signal_set_sensitive.connect(sigc::mem_fun(*this, &ContextMenu::set_sensitive)); action->signal_set_name.connect(sigc::mem_fun(*item, &ContextMenu::set_name)); diff --git a/src/io/base64stream.cpp b/src/io/base64stream.cpp index 667487c35..28c819347 100644 --- a/src/io/base64stream.cpp +++ b/src/io/base64stream.cpp @@ -290,12 +290,12 @@ void Base64OutputStream::putCh(int ch) /** * Writes the specified byte to this output stream. */ -void Base64OutputStream::put(int ch) +int Base64OutputStream::put(gunichar ch) { if (closed) { //probably throw an exception here - return; + return -1; } outBuf <<= 8; @@ -322,6 +322,7 @@ void Base64OutputStream::put(int ch) bitCount = 0; outBuf = 0L; } + return 1; } diff --git a/src/io/base64stream.h b/src/io/base64stream.h index 554a92fe2..4bc99acac 100644 --- a/src/io/base64stream.h +++ b/src/io/base64stream.h @@ -88,7 +88,7 @@ public: virtual void flush(); - virtual void put(int ch); + virtual int put(gunichar ch); /** * Sets the maximum line length for base64 output. If diff --git a/src/io/gzipstream.cpp b/src/io/gzipstream.cpp index f9e30de91..8db7155db 100644 --- a/src/io/gzipstream.cpp +++ b/src/io/gzipstream.cpp @@ -433,19 +433,19 @@ void GzipOutputStream::flush() /** * Writes the specified byte to this output stream. */ -void GzipOutputStream::put(int ch) +int GzipOutputStream::put(gunichar ch) { if (closed) { //probably throw an exception here - return; + return -1; } //Add char to buffer inputBuf.push_back(ch); totalIn++; - + return 1; } diff --git a/src/io/gzipstream.h b/src/io/gzipstream.h index 89c5f64f3..390ec1225 100644 --- a/src/io/gzipstream.h +++ b/src/io/gzipstream.h @@ -98,7 +98,7 @@ public: virtual void flush(); - virtual void put(int ch); + virtual int put(gunichar ch); private: diff --git a/src/io/inkscapestream.cpp b/src/io/inkscapestream.cpp index 65f24cf59..4c7fa4d49 100644 --- a/src/io/inkscapestream.cpp +++ b/src/io/inkscapestream.cpp @@ -125,11 +125,12 @@ void BasicOutputStream::flush() /** * Writes the specified byte to this output stream. */ -void BasicOutputStream::put(int ch) +int BasicOutputStream::put(gunichar ch) { if (closed) - return; + return -1; destination.put(ch); + return 1; } @@ -137,8 +138,6 @@ void BasicOutputStream::put(int ch) //######################################################################### //# B A S I C R E A D E R //######################################################################### - - /** * */ @@ -183,10 +182,6 @@ gunichar BasicReader::get() } - - - - /** * Reads a line of data from the reader. */ @@ -255,13 +250,6 @@ static bool getDouble(Glib::ustring &str, double *val) - - - - -/** - * - */ const Reader &BasicReader::readBool (bool& val ) { Glib::ustring buf = readWord(); @@ -272,9 +260,6 @@ const Reader &BasicReader::readBool (bool& val ) return *this; } -/** - * - */ const Reader &BasicReader::readShort (short& val ) { Glib::ustring buf = readWord(); @@ -284,9 +269,6 @@ const Reader &BasicReader::readShort (short& val ) return *this; } -/** - * - */ const Reader &BasicReader::readUnsignedShort (unsigned short& val ) { Glib::ustring buf = readWord(); @@ -296,9 +278,6 @@ const Reader &BasicReader::readUnsignedShort (unsigned short& val ) return *this; } -/** - * - */ const Reader &BasicReader::readInt (int& val ) { Glib::ustring buf = readWord(); @@ -308,9 +287,6 @@ const Reader &BasicReader::readInt (int& val ) return *this; } -/** - * - */ const Reader &BasicReader::readUnsignedInt (unsigned int& val ) { Glib::ustring buf = readWord(); @@ -320,9 +296,6 @@ const Reader &BasicReader::readUnsignedInt (unsigned int& val ) return *this; } -/** - * - */ const Reader &BasicReader::readLong (long& val ) { Glib::ustring buf = readWord(); @@ -332,9 +305,6 @@ const Reader &BasicReader::readLong (long& val ) return *this; } -/** - * - */ const Reader &BasicReader::readUnsignedLong (unsigned long& val ) { Glib::ustring buf = readWord(); @@ -344,9 +314,6 @@ const Reader &BasicReader::readUnsignedLong (unsigned long& val ) return *this; } -/** - * - */ const Reader &BasicReader::readFloat (float& val ) { Glib::ustring buf = readWord(); @@ -356,9 +323,6 @@ const Reader &BasicReader::readFloat (float& val ) return *this; } -/** - * - */ const Reader &BasicReader::readDouble (double& val ) { Glib::ustring buf = readWord(); @@ -775,9 +739,7 @@ void OutputStreamWriter::flush() */ void OutputStreamWriter::put(gunichar ch) { - //Do we need conversions here? - int intCh = (int) ch; - outputStream.put(intCh); + outputStream.put(ch); } //######################################################################### @@ -827,9 +789,7 @@ void StdWriter::flush() */ void StdWriter::put(gunichar ch) { - //Do we need conversions here? - int intCh = (int) ch; - outputStream->put(intCh); + outputStream->put(ch); } diff --git a/src/io/inkscapestream.h b/src/io/inkscapestream.h index 37c41552f..d19dbbe95 100644 --- a/src/io/inkscapestream.h +++ b/src/io/inkscapestream.h @@ -189,7 +189,7 @@ public: /** * Send one byte to the destination stream. */ - virtual void put(int ch) = 0; + virtual int put(gunichar ch) = 0; }; // class OutputStream @@ -212,7 +212,7 @@ public: virtual void flush(); - virtual void put(int ch); + virtual int put(gunichar ch); protected: @@ -238,8 +238,8 @@ public: void flush() { } - void put(int ch) - { putchar(ch); } + int put(gunichar ch) + {return putchar(ch); } }; diff --git a/src/io/stringstream.cpp b/src/io/stringstream.cpp index 44d11dd04..5a76e24a3 100644 --- a/src/io/stringstream.cpp +++ b/src/io/stringstream.cpp @@ -112,10 +112,10 @@ void StringOutputStream::flush() /** * Writes the specified byte to this output stream. */ -void StringOutputStream::put(int ch) +int StringOutputStream::put(gunichar ch) { - gunichar uch = (gunichar)ch; - buffer.push_back(uch); + buffer.push_back(ch); + return 1; } diff --git a/src/io/stringstream.h b/src/io/stringstream.h index 4a05d88a9..939a87455 100644 --- a/src/io/stringstream.h +++ b/src/io/stringstream.h @@ -67,7 +67,7 @@ public: virtual void flush(); - virtual void put(int ch); + virtual int put(gunichar ch); virtual Glib::ustring &getString() { return buffer; } diff --git a/src/io/uristream.cpp b/src/io/uristream.cpp index 19994bc82..37c13ada0 100644 --- a/src/io/uristream.cpp +++ b/src/io/uristream.cpp @@ -402,34 +402,30 @@ void UriOutputStream::flush() throw(StreamException) /** * Writes the specified byte to this output stream. */ -void UriOutputStream::put(int ch) throw(StreamException) +int UriOutputStream::put(gunichar ch) throw(StreamException) { if (closed) - return; + return -1; unsigned char uch; - gunichar gch; switch (scheme) { - case SCHEME_FILE: if (!outf) - return; + return -1; uch = (unsigned char)(ch & 0xff); if (fputc(uch, outf) == EOF) { Glib::ustring err = "ERROR writing to file "; throw StreamException(err); } - //fwrite(uch, 1, 1, outf); - break; + break; case SCHEME_DATA: - gch = (gunichar) ch; - data.push_back(gch); - break; + data.push_back(ch); + break; }//switch - + return 1; } @@ -474,8 +470,7 @@ void UriWriter::flush() throw(StreamException) */ void UriWriter::put(gunichar ch) throw(StreamException) { - int ich = (int)ch; - outputStream->put(ich); + outputStream->put(ch); } diff --git a/src/io/uristream.h b/src/io/uristream.h index 16b1b0894..3080519de 100644 --- a/src/io/uristream.h +++ b/src/io/uristream.h @@ -115,7 +115,7 @@ public: virtual void flush() throw(StreamException); - virtual void put(int ch) throw(StreamException); + virtual int put(gunichar ch) throw(StreamException); private: diff --git a/src/io/xsltstream.cpp b/src/io/xsltstream.cpp index 6b72627d3..7a6632233 100644 --- a/src/io/xsltstream.cpp +++ b/src/io/xsltstream.cpp @@ -230,10 +230,10 @@ void XsltOutputStream::flush() throw (StreamException) /** * Writes the specified byte to this output stream. */ -void XsltOutputStream::put(int ch) throw (StreamException) +int XsltOutputStream::put(gunichar ch) throw (StreamException) { - gunichar uch = (gunichar) ch; - outbuf.push_back(uch); + outbuf.push_back(ch); + return 1; } diff --git a/src/io/xsltstream.h b/src/io/xsltstream.h index cfe9e5124..31ee89e10 100644 --- a/src/io/xsltstream.h +++ b/src/io/xsltstream.h @@ -120,7 +120,7 @@ public: virtual void flush() throw (StreamException); - virtual void put(int ch) throw (StreamException); + virtual int put(gunichar ch) throw (StreamException); private: diff --git a/src/isinf.h b/src/isinf.h index 7799d2876..b4c56f79d 100644 --- a/src/isinf.h +++ b/src/isinf.h @@ -12,6 +12,9 @@ #elif defined(__APPLE__) && __GNUC__ == 3 #define isinf(x) __isinf(x) +#elif __cplusplus >= 201103L +# include <cmath> +# define isinf std::isinf #endif #endif /* __ISINF_H__ */ diff --git a/src/libnrtype/FontFactory.cpp b/src/libnrtype/FontFactory.cpp index a9220d867..a1a9ddc89 100644 --- a/src/libnrtype/FontFactory.cpp +++ b/src/libnrtype/FontFactory.cpp @@ -741,6 +741,11 @@ void font_factory::GetUIFamiliesAndStyles(FamilyToStylesMap *map) continue; } + // Disable synthesized (faux) font faces + if (pango_font_face_is_synthesized(faces[currentFace]) ) { + continue; + } + PangoFontDescription *faceDescr = pango_font_face_describe(faces[currentFace]); if (faceDescr) { Glib::ustring familyUIName = GetUIFamilyString(faceDescr); diff --git a/src/libnrtype/font-lister.cpp b/src/libnrtype/font-lister.cpp index 04859185c..1e3ba01e9 100644 --- a/src/libnrtype/font-lister.cpp +++ b/src/libnrtype/font-lister.cpp @@ -10,15 +10,19 @@ #include <glibmm.h> #include <gtkmm/treemodel.h> #include <gtkmm/liststore.h> - #include "font-lister.h" #include "FontFactory.h" +#include "desktop.h" +#include "desktop-style.h" +#include "document.h" +#include "inkscape.h" +#include "preferences.h" #include "sp-object.h" #include "sp-root.h" -#include "document.h" #include "xml/repr.h" -#include "preferences.h" + +//#define DEBUG_FONT namespace Inkscape { @@ -29,7 +33,7 @@ namespace Inkscape FamilyToStylesMap familyStyleMap; font_factory::Default()->GetUIFamiliesAndStyles(&familyStyleMap); - + // Grab the family names into a list and then sort them std::list<Glib::ustring> familyList; for (FamilyToStylesMap::iterator iter = familyStyleMap.begin(); @@ -47,7 +51,8 @@ namespace Inkscape if (!familyName.empty()) { Gtk::TreeModel::iterator treeModelIter = font_list_store->append(); - (*treeModelIter)[FontList.font] = reinterpret_cast<const char*>(g_strdup(familyName.c_str())); + //(*treeModelIter)[FontList.family] = reinterpret_cast<const char*>(g_strdup(familyName.c_str())); + (*treeModelIter)[FontList.family] = familyName; // Now go through the styles GList *styles = NULL; @@ -62,7 +67,21 @@ namespace Inkscape (*treeModelIter)[FontList.onSystem] = true; } } + current_family_row = 0; + current_family = "sans-serif"; + current_style = "Normal"; + current_fontspec = "sans-serif"; // Empty style -> Normal + current_fontspec_system = "Sans"; + + /* Create default styles for use when font-family is unknown on system. */ + default_styles = g_list_append( NULL, g_strdup("Normal") ); + default_styles = g_list_append( default_styles, g_strdup("Italic") ); + default_styles = g_list_append( default_styles, g_strdup("Bold") ); + default_styles = g_list_append( default_styles, g_strdup("Bold Italic") ); + font_list_store->thaw_notify(); + + style_list_store = Gtk::ListStore::create (FontStyleList); } // Example of how to use "foreach_iter" @@ -70,7 +89,7 @@ namespace Inkscape // FontLister::print_document_font( const Gtk::TreeModel::iterator &iter ) { // Gtk::TreeModel::Row row = *iter; // if( !row[FontList.onSystem] ) { - // std::cout << " Not on system: " << row[FontList.font] << std::endl; + // std::cout << " Not on system: " << row[FontList.family] << std::endl; // return false; // } // return true; @@ -87,28 +106,31 @@ namespace Inkscape font_list_store->freeze_notify(); + /* Find if current row is in document or system part of list */ + gboolean row_is_system = false; + if( current_family_row > -1 ) { + Gtk::TreePath path; + path.push_back( current_family_row ); + Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); + if( iter ) { + row_is_system = (*iter)[FontList.onSystem]; + // std::cout << " In: row: " << current_family_row << " " << (*iter)[FontList.family] << std::endl; + } + } + /* Clear all old document font-family entries */ Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); while( iter != font_list_store->children().end() ) { Gtk::TreeModel::Row row = *iter; if( !row[FontList.onSystem] ) { - // std::cout << " Not on system: " << row[FontList.font] << std::endl; + // std::cout << " Not on system: " << row[FontList.family] << std::endl; iter = font_list_store->erase( iter ); } else { - // std::cout << " First on system: " << row[FontList.font] << std::endl; + // std::cout << " First on system: " << row[FontList.family] << std::endl; break; } } - /* Create default styles for use when font-family is unknown on system. */ - static GList *default_styles = NULL; - if( default_styles == NULL ) { - default_styles = g_list_append( default_styles, g_strdup("Normal") ); - default_styles = g_list_append( default_styles, g_strdup("Italic") ); - default_styles = g_list_append( default_styles, g_strdup("Bold") ); - default_styles = g_list_append( default_styles, g_strdup("Bold Italic") ); - } - /* Get "font-family"s used in document. */ std::list<Glib::ustring> fontfamilies; update_font_list_recursive( r, &fontfamilies ); @@ -120,7 +142,7 @@ namespace Inkscape /* Insert separator */ if( !fontfamilies.empty() ) { Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); - (*treeModelIter)[FontList.font] = "#"; + (*treeModelIter)[FontList.family] = "#"; (*treeModelIter)[FontList.onSystem] = false; } @@ -137,7 +159,7 @@ namespace Inkscape Gtk::TreeModel::iterator iter2 = font_list_store->get_iter( "0" ); while( iter2 != font_list_store->children().end() ) { Gtk::TreeModel::Row row = *iter2; - if( row[FontList.onSystem] && tokens[0].compare( row[FontList.font] ) == 0 ) { + if( row[FontList.onSystem] && tokens[0].compare( row[FontList.family] ) == 0 ) { styles = row[FontList.styles]; break; } @@ -146,11 +168,37 @@ namespace Inkscape } Gtk::TreeModel::iterator treeModelIter = font_list_store->prepend(); - (*treeModelIter)[FontList.font] = reinterpret_cast<const char*>(g_strdup((*i).c_str())); + (*treeModelIter)[FontList.family] = reinterpret_cast<const char*>(g_strdup((*i).c_str())); (*treeModelIter)[FontList.styles] = styles; (*treeModelIter)[FontList.onSystem] = false; } + /* Now we do a song and dance to find the correct row as the row corresponding + * to the current_family may have changed. We can't simply search for the + * family name in the list since it can occur twice, once in the document + * font family part and once in the system font family part. Above we determined + * which part it is in. + */ + if( current_family_row > -1 ) { + int start = 0; + if( row_is_system ) start = fontfamilies.size(); + int length = font_list_store->children().size(); + for( int i = 0; i < length; ++i ) { + int row = i + start; + if( row >= length ) row -= length; + Gtk::TreePath path; + path.push_back( row ); + Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); + if( iter ) { + if( current_family.compare( (*iter)[FontList.family] ) == 0 ) { + current_family_row = row; + break; + } + } + } + } + // std::cout << " Out: row: " << current_family_row << " " << current_family << std::endl; + font_list_store->thaw_notify(); } @@ -191,7 +239,557 @@ namespace Inkscape } } - Gtk::TreePath + Glib::ustring + FontLister::canonize_fontspec( Glib::ustring fontspec ) { + + // Pass fontspec to and back from Pango to get a the fontspec in + // canonical form. -inkscape-font-specification relies on the + // Pango constructed fontspec not changing form. If it does, + // this is the place to fix it. + PangoFontDescription *descr = pango_font_description_from_string( fontspec.c_str() ); + gchar* canonized = pango_font_description_to_string ( descr ); + Glib::ustring Canonized = canonized; + g_free( canonized ); + pango_font_description_free( descr ); + + // Pango canonized strings remove space after comma between family names. Put it back. + size_t i = 0; + while( (i = Canonized.find(",", i)) != std::string::npos) { + Canonized.replace(i, 1, ", "); + i += 2; + } + + return Canonized; + } + + Glib::ustring + FontLister::system_fontspec( Glib::ustring fontspec ) { + + // Find what Pango thinks is the closest match. + Glib::ustring out = fontspec; + + PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); + font_instance *res = (font_factory::Default())->Face(descr); + if (res->pFont) { + PangoFontDescription *nFaceDesc = pango_font_describe(res->pFont); + out = sp_font_description_get_family(nFaceDesc); + } + pango_font_description_free(descr); + + return out; + } + + std::pair<Glib::ustring, Glib::ustring> + FontLister::ui_from_fontspec( Glib::ustring fontspec ) { + + PangoFontDescription *descr = pango_font_description_from_string(fontspec.c_str()); + const gchar* family = pango_font_description_get_family(descr); + Glib::ustring Family = family; + + // Pango canonized strings remove space after comma between family names. Put it back. + size_t i = 0; + while( (i = Family.find(",", i)) != std::string::npos) { + Family.replace(i, 1, ", "); + i += 2; + } + + pango_font_description_unset_fields(descr, PANGO_FONT_MASK_FAMILY); + gchar* style = pango_font_description_to_string( descr ); + Glib::ustring Style = style; + pango_font_description_free(descr); + g_free( style ); + + return std::make_pair( Family, Style ); + } + + std::pair<Glib::ustring, Glib::ustring> + FontLister::selection_update () { + +#ifdef DEBUG_FONT + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::selection_update: entrance" << std::endl; +#endif + // Get fontspec from a selection, preferences, or thin air. + Glib::ustring fontspec; + SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); + + // Directly from stored font specification. + int result = + sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); + + //std::cout << " Attempting selected style" << std::endl; + if( result != QUERY_STYLE_NOTHING && query->text->font_specification.set ) { + fontspec = query->text->font_specification.value; + //std::cout << " fontspec from query :" << fontspec << ":" << std::endl; + } + + // From style + if( fontspec.empty() ) { + //std::cout << " Attempting desktop style" << std::endl; + int rfamily = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); + int rstyle = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); + + // Must have text in selection + if( rfamily != QUERY_STYLE_NOTHING && rstyle != QUERY_STYLE_NOTHING ) { + fontspec = fontspec_from_style( query ); + } + //std::cout << " fontspec from style :" << fontspec << ":" << std::endl; + } + + // From preferences + if( fontspec.empty() ) { + //std::cout << " Attempting preferences" << std::endl; + sp_style_read_from_prefs(query, "/tools/text"); + fontspec = fontspec_from_style( query ); + //std::cout << " fontspec from prefs :" << fontspec << ":" << std::endl; + } + sp_style_unref(query); + + // From thin air + if( fontspec.empty() ) { + //std::cout << " Attempting thin air" << std::endl; + fontspec = current_family + ", " + current_style; + //std::cout << " fontspec from thin air :" << fontspec << ":" << std::endl; + } + + // Do we really need? Removes spaces between font-families. + //current_fontspec = canonize_fontspec( fontspec ); + current_fontspec = fontspec; // Ignore for now + + current_fontspec_system = system_fontspec( current_fontspec ); + + std::pair<Glib::ustring, Glib::ustring> ui = ui_from_fontspec( current_fontspec ); + set_font_family( ui.first ); + +#ifdef DEBUG_FONT + std::cout << " family_row: :" << current_family_row << ":" << std::endl; + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: :" << current_family << ":" << std::endl; + std::cout << " style: :" << current_style << ":" << std::endl; + std::cout << "FontLister::selection_update: exit" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return std::make_pair( current_family, current_style ); + } + + + // Set fontspec. If check is false, best style match will not be done. + void + FontLister::set_fontspec (Glib::ustring new_fontspec, gboolean check) { + + std::pair<Glib::ustring,Glib::ustring> ui = ui_from_fontspec( new_fontspec ); + Glib::ustring new_family = ui.first; + Glib::ustring new_style = ui.second; + +#ifdef DEBUG_FONT + std::cout << "FontLister::set_fontspec: family: " << new_family + << " style:" << new_style << std::endl; +#endif + + set_font_family( new_family, false ); + set_font_style( new_style ); + } + + + // TODO: use to determine font-selector best style + std::pair<Glib::ustring, Glib::ustring> + FontLister::new_font_family (Glib::ustring new_family, gboolean check_style ) { + +#ifdef DEBUG_FONT + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::new_font_family: " << new_family << std::endl; +#endif + + // No need to do anything if new family is same as old family. + if( new_family.compare( current_family ) == 0 ) { +#ifdef DEBUG_FONT + std::cout << "FontLister::new_font_family: exit: no change in family." << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return std::make_pair( current_family, current_style ); + } + + // We need to do two things: + // 1. Update style list for new family. + // 2. Select best valid style match to old style. + + // For finding style list, use list of first family in font-family list. + GList* styles = NULL; + Gtk::TreeModel::iterator iter = font_list_store->get_iter( "0" ); + while( iter != font_list_store->children().end() ) { + + Gtk::TreeModel::Row row = *iter; + + if( new_family.compare( row[FontList.family] ) == 0 ) { + styles = row[FontList.styles]; + break; + } + ++iter; + } + + // Newly typed in font-family may not yet be in list... use default list. + // TODO: if font-family is list, check if first family in list is on system + // and set style accordingly. + if( styles == NULL ) { + styles = default_styles; + } + + // Update style list. + style_list_store->freeze_notify(); + style_list_store->clear(); + + for (GList *l=styles; l; l = l->next) { + Gtk::TreeModel::iterator treeModelIter = style_list_store->append(); + (*treeModelIter)[FontStyleList.styles] = (char*)l->data; + } + + style_list_store->thaw_notify(); + + // Find best match to the style from the old font-family to the + // styles available with the new font. + // TODO: Maybe check if an exact match exists before using Pango. + Glib::ustring best_style = get_best_style_match( new_family, current_style ); + +#ifdef DEBUG_FONT + std::cout << "FontLister::new_font_family: exit: " << new_family << " " << best_style << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return std::make_pair( new_family, best_style ); + } + + std::pair<Glib::ustring, Glib::ustring> + FontLister::set_font_family (Glib::ustring new_family, gboolean check_style) { + +#ifdef DEBUG_FONT + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::set_font_family: " << new_family << std::endl; +#endif + + std::pair<Glib::ustring, Glib::ustring> ui = new_font_family( new_family, check_style ); + current_family = ui.first; + current_style = ui.second; + current_fontspec = canonize_fontspec( current_family + ", " + current_style ); + current_fontspec_system = system_fontspec( current_fontspec ); + +#ifdef DEBUG_FONT + std::cout << " family_row: :" << current_family_row << ":" << std::endl; + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: :" << current_family << ":" << std::endl; + std::cout << " style: :" << current_style << ":" << std::endl; + std::cout << "FontLister::set_font_family: end" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return ui; + } + + + std::pair<Glib::ustring, Glib::ustring> + FontLister::set_font_family (int row, gboolean check_style) { + +#ifdef DEBUG_FONT + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::set_font_family( row ): " << row << std::endl; +#endif + + current_family_row = row; + Gtk::TreePath path; + path.push_back( row ); + Glib::ustring new_family = current_family; + Gtk::TreeModel::iterator iter = font_list_store->get_iter( path ); + if( iter ) { + new_family = (*iter)[FontList.family]; + } + + std::pair<Glib::ustring, Glib::ustring> ui = set_font_family( new_family, check_style ); + +#ifdef DEBUG_FONT + std::cout << "FontLister::set_font_family( row ): end" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return ui; + } + + + void + FontLister::set_font_style (Glib::ustring new_style) { + + // TODO: Validate input using Pango. If Pango doesn't recognize a style it will + // attach the "invalid" style to the font-family. + +#ifdef DEBUG_FONT + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister:set_font_style: " << new_style << std::endl; +#endif + + current_style = new_style; + current_fontspec = canonize_fontspec( current_family + ", " + current_style ); + current_fontspec_system = system_fontspec( current_fontspec ); + +#ifdef DEBUG_FONT + std::cout << " canonized: :" << current_fontspec << ":" << std::endl; + std::cout << " system: :" << current_fontspec_system << ":" << std::endl; + std::cout << " family: " << current_family << std::endl; + std::cout << " style: " << current_style << std::endl; + std::cout << "FontLister::set_font_style: end" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + } + + + // We do this ourselves as we can't rely on FontFactory. + void + FontLister::fill_css( SPCSSAttr *css, Glib::ustring fontspec ) { + + if( fontspec.empty() ) { + fontspec = current_fontspec; + } + std::pair<Glib::ustring,Glib::ustring> ui = ui_from_fontspec( fontspec ); + + Glib::ustring family = ui.first; + + sp_repr_css_set_property (css, "-inkscape-font-specification", fontspec.c_str() ); + sp_repr_css_set_property (css, "font-family", family.c_str() ); //Canonized w/ spaces + + PangoFontDescription *desc = pango_font_description_from_string( fontspec.c_str() ); + PangoWeight weight = pango_font_description_get_weight( desc ); + switch ( weight ) { + case PANGO_WEIGHT_THIN: + sp_repr_css_set_property (css, "font-weight", "100" ); + break; + case PANGO_WEIGHT_ULTRALIGHT: + sp_repr_css_set_property (css, "font-weight", "200" ); + break; + case PANGO_WEIGHT_LIGHT: + sp_repr_css_set_property (css, "font-weight", "300" ); + break; + case PANGO_WEIGHT_BOOK: + sp_repr_css_set_property (css, "font-weight", "380" ); + break; + case PANGO_WEIGHT_NORMAL: + sp_repr_css_set_property (css, "font-weight", "normal" ); + break; + case PANGO_WEIGHT_MEDIUM: + sp_repr_css_set_property (css, "font-weight", "500" ); + break; + case PANGO_WEIGHT_SEMIBOLD: + sp_repr_css_set_property (css, "font-weight", "600" ); + break; + case PANGO_WEIGHT_BOLD: + sp_repr_css_set_property (css, "font-weight", "bold" ); + break; + case PANGO_WEIGHT_ULTRABOLD: + sp_repr_css_set_property (css, "font-weight", "800" ); + break; + case PANGO_WEIGHT_HEAVY: + sp_repr_css_set_property (css, "font-weight", "900" ); + break; + case PANGO_WEIGHT_ULTRAHEAVY: + sp_repr_css_set_property (css, "font-weight", "1000" ); + break; + } + + PangoStyle style = pango_font_description_get_style( desc ); + switch ( style ) { + case PANGO_STYLE_NORMAL: + sp_repr_css_set_property (css, "font-style", "normal" ); + break; + case PANGO_STYLE_OBLIQUE: + sp_repr_css_set_property (css, "font-style", "oblique" ); + break; + case PANGO_STYLE_ITALIC: + sp_repr_css_set_property (css, "font-style", "italic" ); + break; + } + + PangoStretch stretch = pango_font_description_get_stretch( desc ); + switch ( stretch ) { + case PANGO_STRETCH_ULTRA_CONDENSED: + sp_repr_css_set_property (css, "font-stretch", "ultra-condensed" ); + break; + case PANGO_STRETCH_EXTRA_CONDENSED: + sp_repr_css_set_property (css, "font-stretch", "extra-condensed" ); + break; + case PANGO_STRETCH_CONDENSED: + sp_repr_css_set_property (css, "font-stretch", "condensed" ); + break; + case PANGO_STRETCH_SEMI_CONDENSED: + sp_repr_css_set_property (css, "font-stretch", "semi-condensed" ); + break; + case PANGO_STRETCH_NORMAL: + sp_repr_css_set_property (css, "font-stretch", "normal" ); + break; + case PANGO_STRETCH_SEMI_EXPANDED: + sp_repr_css_set_property (css, "font-stretch", "semi-expanded" ); + break; + case PANGO_STRETCH_EXPANDED: + sp_repr_css_set_property (css, "font-stretch", "expanded" ); + break; + case PANGO_STRETCH_EXTRA_EXPANDED: + sp_repr_css_set_property (css, "font-stretch", "extra-expanded" ); + break; + case PANGO_STRETCH_ULTRA_EXPANDED: + sp_repr_css_set_property (css, "font-stretch", "ultra-expanded" ); + break; + } + + PangoVariant variant = pango_font_description_get_variant( desc ); + switch ( variant ) { + case PANGO_VARIANT_NORMAL: + sp_repr_css_set_property (css, "font-variant", "normal" ); + break; + case PANGO_VARIANT_SMALL_CAPS: + sp_repr_css_set_property (css, "font-variant", "small-caps" ); + break; + } + } + + // We do this ourselves as we can't rely on FontFactory. + Glib::ustring + FontLister::fontspec_from_style (SPStyle* style) { + + //std::cout << "FontLister:fontspec_from_style: " << std::endl; + + Glib::ustring fontspec; + if (style) { + + // First try to use the font specification if it is set + if (style->text->font_specification.set + && style->text->font_specification.value + && *style->text->font_specification.value) { + + fontspec = style->text->font_specification.value; + + } else { + + fontspec = style->text->font_family.value; + fontspec += ","; + + switch (style->font_weight.computed) { + + case SP_CSS_FONT_WEIGHT_100: + fontspec += " 100"; + break; + + case SP_CSS_FONT_WEIGHT_200: + fontspec += " 200"; + break; + + case SP_CSS_FONT_WEIGHT_300: + fontspec += " 300"; + break; + + case SP_CSS_FONT_WEIGHT_400: + case SP_CSS_FONT_WEIGHT_NORMAL: + //fontspec += " normal"; + break; + + case SP_CSS_FONT_WEIGHT_500: + fontspec += " 500"; + break; + + case SP_CSS_FONT_WEIGHT_600: + fontspec += " 600"; + break; + + case SP_CSS_FONT_WEIGHT_700: + case SP_CSS_FONT_WEIGHT_BOLD: + fontspec += " bold"; + break; + + case SP_CSS_FONT_WEIGHT_800: + fontspec += " 800"; + break; + + case SP_CSS_FONT_WEIGHT_900: + fontspec += " 900"; + break; + + case SP_CSS_FONT_WEIGHT_LIGHTER: + case SP_CSS_FONT_WEIGHT_BOLDER: + default: + g_warning("Unrecognized font_weight.computed value"); + break; + } + + switch (style->font_style.computed) { + case SP_CSS_FONT_STYLE_ITALIC: + fontspec += " italic"; + break; + + case SP_CSS_FONT_STYLE_OBLIQUE: + fontspec += " oblique"; + break; + + case SP_CSS_FONT_STYLE_NORMAL: + default: + //fontspec += " normal"; + break; + } + + switch (style->font_stretch.computed) { + + case SP_CSS_FONT_STRETCH_ULTRA_CONDENSED: + fontspec += " extra_condensed"; + break; + + case SP_CSS_FONT_STRETCH_EXTRA_CONDENSED: + fontspec += " extra_condensed"; + break; + + case SP_CSS_FONT_STRETCH_CONDENSED: + case SP_CSS_FONT_STRETCH_NARROWER: + fontspec += " condensed"; + break; + + case SP_CSS_FONT_STRETCH_SEMI_CONDENSED: + fontspec += " semi_condensed"; + break; + + case SP_CSS_FONT_STRETCH_NORMAL: + //fontspec += " normal"; + break; + + case SP_CSS_FONT_STRETCH_SEMI_EXPANDED: + fontspec += " semi_expanded"; + break; + + case SP_CSS_FONT_STRETCH_EXPANDED: + case SP_CSS_FONT_STRETCH_WIDER: + fontspec += " expanded"; + break; + + case SP_CSS_FONT_STRETCH_EXTRA_EXPANDED: + fontspec += " extra_expanded"; + break; + + case SP_CSS_FONT_STRETCH_ULTRA_EXPANDED: + fontspec += " ultra_expanded"; + break; + + default: + //fontspec += " normal"; + break; + } + + switch (style->font_variant.computed) { + + case SP_CSS_FONT_VARIANT_SMALL_CAPS: + fontspec += "small-caps"; + break; + + default: + //fontspec += "normal"; + break; + } + } + } + return canonize_fontspec( fontspec ); + } + + + Gtk::TreeModel::Row FontLister::get_row_for_font (Glib::ustring family) { Gtk::TreePath path; @@ -201,8 +799,8 @@ namespace Inkscape Gtk::TreeModel::Row row = *iter; - if( family.compare( row[FontList.font] ) == 0 ) { - return font_list_store->get_path( iter ); + if( family.compare( row[FontList.family] ) == 0 ) { + return row; } ++iter; @@ -211,6 +809,149 @@ namespace Inkscape throw FAMILY_NOT_FOUND; } + Gtk::TreePath + FontLister::get_path_for_font (Glib::ustring family) + { + return font_list_store->get_path( get_row_for_font ( family ) ); + } + + Gtk::TreeModel::Row + FontLister::get_row_for_style (Glib::ustring style) + { + Gtk::TreePath path; + + Gtk::TreeModel::iterator iter = style_list_store->get_iter( "0" ); + while( iter != style_list_store->children().end() ) { + + Gtk::TreeModel::Row row = *iter; + + if( style.compare( row[FontStyleList.styles] ) == 0 ) { + return row; + } + + ++iter; + } + + throw STYLE_NOT_FOUND; + } + + static gint + compute_distance (const PangoFontDescription *a, + const PangoFontDescription *b ) { + + // Weight: multiples of 100 + gint distance = abs( pango_font_description_get_weight( a ) - + pango_font_description_get_weight( b ) ); + + distance += 10000 * abs( pango_font_description_get_stretch( a ) - + pango_font_description_get_stretch( b ) ); + + PangoStyle style_a = pango_font_description_get_style( a ); + PangoStyle style_b = pango_font_description_get_style( b ); + if( style_a != style_b ) { + if( (style_a == PANGO_STYLE_OBLIQUE && style_b == PANGO_STYLE_ITALIC) || + (style_b == PANGO_STYLE_OBLIQUE && style_a == PANGO_STYLE_ITALIC) ) { + distance += 1000; // Oblique and italic are almost the same + } else { + distance += 100000; // Normal vs oblique/italic, not so similar + } + } + + // Normal vs small-caps + distance += 1000000 * abs( pango_font_description_get_variant( a ) - + pango_font_description_get_variant( b ) ); + return distance; + } + + // This is inspired by pango_font_description_better_match, but that routine + // always returns false if variant or stretch are different. This means, for + // example, that PT Sans Narrow with style Bold Condensed is never matched + // to another font-family with Bold style. + gboolean + font_description_better_match( PangoFontDescription* target, + PangoFontDescription* old_desc, + PangoFontDescription* new_desc ) { + + if( old_desc == NULL ) return true; + if( new_desc == NULL ) return false; + + int old_distance = compute_distance( target, old_desc ); + int new_distance = compute_distance( target, new_desc ); + //std::cout << "font_description_better_match: old: " << old_distance << std::endl; + //std::cout << " new: " << new_distance << std::endl; + + return (new_distance < old_distance ); + } + + // void + // font_description_dump( PangoFontDescription* target ) { + // std::cout << " Font: " << pango_font_description_to_string( target ) << std::endl; + // std::cout << " style: " << pango_font_description_get_style( target ) << std::endl; + // std::cout << " weight: " << pango_font_description_get_weight( target ) << std::endl; + // std::cout << " variant: " << pango_font_description_get_variant( target ) << std::endl; + // std::cout << " stretch: " << pango_font_description_get_stretch( target ) << std::endl; + // std::cout << " gravity: " << pango_font_description_get_gravity( target ) << std::endl; + // } + + /* Returns style string */ + // TODO: Remove or turn into function to be used by new_font_family. + Glib::ustring + FontLister::get_best_style_match (Glib::ustring family, Glib::ustring target_style) { + +#ifdef DEBUG_FONT + std::cout << "\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << std::endl; + std::cout << "FontLister::get_best_style_match: " << family << " : " << target_style << std::endl; +#endif + + Glib::ustring fontspec = family + ", " + target_style; + + Gtk::TreeModel::Row row; + try { + row = get_row_for_font( family ); + } catch (...) { + //std::cout << " ERROR: can't find family: " << family << std::endl; + return (target_style); + } + + PangoFontDescription* target = pango_font_description_from_string( fontspec.c_str() ); + PangoFontDescription* best = NULL; + + //font_description_dump( target ); + + GList* styles = row[FontList.styles]; + for (GList *l=styles; l; l = l->next) { + Glib::ustring fontspec = family + ", " + (char*)l->data; + PangoFontDescription* candidate = pango_font_description_from_string( fontspec.c_str() ); + //font_description_dump( candidate ); + //std::cout << " " << font_description_better_match( target, best, candidate ) << std::endl; + if( font_description_better_match( target, best, candidate ) ) { + pango_font_description_free( best ); + best = candidate; + //std::cout << " ... better: " << std::endl; + } else { + pango_font_description_free( candidate ); + //std::cout << " ... not better: " << std::endl; + } + } + + Glib::ustring best_style = target_style; + if( best ) { + pango_font_description_unset_fields( best, PANGO_FONT_MASK_FAMILY ); + best_style = pango_font_description_to_string( best ); + } + + if( target ) pango_font_description_free( target ); + if( best ) pango_font_description_free( best ); + + +#ifdef DEBUG_FONT + std::cout << " Returning: " << best_style << std::endl; + std::cout << "FontLister::get_best_style_match: exit" << std::endl; + std::cout << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n" << std::endl; +#endif + return best_style; + } + FontLister::~FontLister () { }; @@ -220,6 +961,12 @@ namespace Inkscape { return font_list_store; } + + const Glib::RefPtr<Gtk::ListStore> + FontLister::get_style_list () const + { + return style_list_store; + } } // Helper functions diff --git a/src/libnrtype/font-lister.h b/src/libnrtype/font-lister.h index 751350407..5c48bf7a8 100644 --- a/src/libnrtype/font-lister.h +++ b/src/libnrtype/font-lister.h @@ -25,12 +25,35 @@ class SPObject; class SPDocument; +class SPCSSAttr; +struct SPStyle; namespace Inkscape { /** * This class enumerates fonts using libnrtype into reusable data stores and - * allows for random access to the font list + * allows for random access to the font-family list and the font-style list. + * Setting the font-family updates the font-style list. "Style" in this case + * refers to everything but family and size (e.g. italic/oblique, weight). + * + * This class handles font-family lists and fonts that are not on the system, + * where there is not an entry in the fontInstanceMap. + * + * This class uses the idea of "font_spec". This is a plain text string as used by + * Pango. It is similar to the CSS font shorthand except that font-family comes + * first and in this class the font-size is not used. + * + * This class uses the FontFactory class to get a list of system fonts + * and to find best matches via Pango. The Pango interface is only setup + * to deal with fonts that are on the system so care must be taken. For + * example, best matches should only be done with the first font-family + * in a font-family list. If the first font-family is not on the system + * then a generic font-family should be used (sans-serif -> Sans). + * + * This class is used by the UI interface (text-toolbar, font-select, etc.). + * + * "Font" includes family and style. It should not be used when one + * means font-family. */ class FontLister { @@ -38,13 +61,14 @@ namespace Inkscape enum Exceptions { - FAMILY_NOT_FOUND + FAMILY_NOT_FOUND, + STYLE_NOT_FOUND }; virtual ~FontLister (); - /** GtkTreeModelColumnRecord for the font list Gtk::ListStore + /** GtkTreeModelColumnRecord for the font-family list Gtk::ListStore */ class FontListClass : public Gtk::TreeModelColumnRecord @@ -52,10 +76,9 @@ namespace Inkscape public: /** Column containing the family name */ - Gtk::TreeModelColumn<Glib::ustring> font; + Gtk::TreeModelColumn<Glib::ustring> family; - /** Column containing an std::vector<std::string> with style names - * for the corresponding family + /** Column containing the styles for each family name. */ Gtk::TreeModelColumn<GList*> styles; @@ -65,7 +88,7 @@ namespace Inkscape FontListClass () { - add (font); + add (family); add (styles); add (onSystem); } @@ -73,7 +96,23 @@ namespace Inkscape FontListClass FontList; - /** Returns the ListStore with the font names + class FontStyleListClass + : public Gtk::TreeModelColumnRecord + { + public: + /** Column containing the styles + */ + Gtk::TreeModelColumn<Glib::ustring> styles; + + FontStyleListClass () + { + add (styles); + } + }; + + FontStyleListClass FontStyleList; + + /** Returns the ListStore with the family names * * The return is const and the function is declared as const. * The ListStore is ready to be used after class instantiation @@ -82,6 +121,12 @@ namespace Inkscape const Glib::RefPtr<Gtk::ListStore> get_font_list () const; + /** Returns the ListStore with the styles + * + */ + const Glib::RefPtr<Gtk::ListStore> + get_style_list () const; + /** Updates font list to include fonts in document * */ @@ -96,13 +141,126 @@ namespace Inkscape static Inkscape::FontLister* get_instance () { - static Inkscape::FontLister* instance = new Inkscape::FontLister(); + static Inkscape::FontLister* instance = new Inkscape::FontLister(); return instance; } - Gtk::TreePath + /** Takes a hand written font spec and returns a Pango generated one in + * standard form. + */ + Glib::ustring canonize_fontspec( Glib::ustring fontspec ); + + /** Find closest system font to given font. + */ + Glib::ustring system_fontspec( Glib::ustring fontspec ); + + /** Gets font-family and style from fontspec. + * font-family and style returned. + */ + std::pair<Glib::ustring, Glib::ustring> + ui_from_fontspec (Glib::ustring fontspec); + + /** Sets font-family and style after a selection change. + * New font-family and style returned. + */ + std::pair<Glib::ustring, Glib::ustring> + selection_update (); + + /** Sets current_fontspec, etc. If check is false, won't + * try to find best style match (assumes style in fontspec + * valid for given font-family). + */ + void + set_fontspec (Glib::ustring fontspec, gboolean check=true); + + Glib::ustring + get_fontspec () + { + return current_fontspec; + } + + /** Changes font-family, updating style list and attempting to find + * closest style to current_style style (if check_style is true). + * New font-family and style returned. + * Does NOT update current_family and current_style. + * (For potential use in font-selector which doesn't update until + * "Apply" button clicked.) + */ + std::pair<Glib::ustring, Glib::ustring> + new_font_family (Glib::ustring family, gboolean check_style = true); + + /** Sets font-family, updating style list and attempting + * to find closest style to old current_style. + * New font-family and style returned. + * Updates current_family and current_style. + * Calls new_font_family(). + * (For use in text-toolbar where update is immediate.) + */ + std::pair<Glib::ustring, Glib::ustring> + set_font_family (Glib::ustring family, gboolean check_style = true); + + /** Sets font-family from row in list store. + * The row can be used to determine if we are in the + * document or system part of the font-family list. + * This is needed to handle scrolling through the + * font-family list correctly. + * Calls set_font_family(). + */ + std::pair<Glib::ustring, Glib::ustring> + set_font_family (int row, gboolean check_style = true); + + Glib::ustring + get_font_family () + { + return current_family; + } + + int + get_font_family_row () + { + return current_family_row; + } + + /** Sets style. Does not validate style for family. + */ + void + set_font_style (Glib::ustring style); + + Glib::ustring + get_font_style () + { + return current_style; + } + + Glib::ustring + fontspec_from_style (SPStyle* style); + + /** Fill css using current_fontspec. + */ + void + fill_css( SPCSSAttr *css, Glib::ustring fontspec = "" ); + + Gtk::TreeModel::Row get_row_for_font (Glib::ustring family); + Gtk::TreePath + get_path_for_font (Glib::ustring family); + + Gtk::TreeModel::Row + get_row_for_style (Glib::ustring style); + + Gtk::TreePath + get_path_for_style (Glib::ustring style); + + std::pair<Gtk::TreePath, Gtk::TreePath> + get_paths (Glib::ustring family, Glib::ustring style); + + /** Return best style match for new font given style for old font. + */ + Glib::ustring + get_best_style_match (Glib::ustring family, Glib::ustring style); + + /* Not Used */ const NRNameList get_name_list () const { @@ -116,7 +274,24 @@ namespace Inkscape NRNameList families; Glib::RefPtr<Gtk::ListStore> font_list_store; + Glib::RefPtr<Gtk::ListStore> style_list_store; + + /** Info for currently selected font (what is shown in the UI). + * May include font-family lists and fonts not on system. + */ + int current_family_row; + Glib::ustring current_family; + Glib::ustring current_style; + Glib::ustring current_fontspec; + + /** fontspec of system font closest to current_fontspec. + * (What the system will use to display current_fontspec.) + */ + Glib::ustring current_fontspec_system; + /** If a font-family is not on system, this list of styles is used. + */ + GList *default_styles; }; } @@ -125,7 +300,7 @@ namespace Inkscape static gboolean font_lister_separator_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer /*data*/) { gchar* text = 0; - gtk_tree_model_get(model, iter, 0, &text, -1 ); // Column 0: FontList.font + gtk_tree_model_get(model, iter, 0, &text, -1 ); // Column 0: FontList.family return (text && strcmp(text,"#") == 0); } diff --git a/src/livarot/PathCutting.cpp b/src/livarot/PathCutting.cpp index 9e6226ccc..848d8daa8 100644 --- a/src/livarot/PathCutting.cpp +++ b/src/livarot/PathCutting.cpp @@ -1126,6 +1126,8 @@ void Path::ConvertPositionsToForced(int nbPos, cut_position *poss) } } } + if (descr_cmd[0]->getType() == descr_moveto) + descr_flags |= descr_doing_subpath; // see LP Bug 166302 qsort(poss, nbPos, sizeof(cut_position), CmpPosition); diff --git a/src/menus-skeleton.h b/src/menus-skeleton.h index fa39dbd3a..868b606a4 100644 --- a/src/menus-skeleton.h +++ b/src/menus-skeleton.h @@ -282,11 +282,6 @@ static char const menus_skeleton[] = " <separator/>\n" " <effects-list/>\n" " </submenu>\n" -#ifdef WITH_INKBOARD -" <submenu name=\"" N_("Whiteboa_rd") "\">\n" -" <verb verb-id=\"DialogXmppClient\" />\n" -" </submenu>\n" -#endif " <submenu name=\"" N_("_Help") "\">\n" " <verb verb-id=\"org.inkscape.help.manual\" />\n" " <verb verb-id=\"org.inkscape.help.keys\" />\n" diff --git a/src/shortcuts.cpp b/src/shortcuts.cpp index 5af75a9a5..755269edb 100644 --- a/src/shortcuts.cpp +++ b/src/shortcuts.cpp @@ -52,10 +52,12 @@ using Inkscape::IO::Resource::SYSTEM; using Inkscape::IO::Resource::USER; using Inkscape::IO::Resource::KEYS; - static void try_shortcuts_file(char const *filename); static void read_shortcuts_file(char const *filename, bool const is_user_set=false); +unsigned int sp_shortcut_get_key(unsigned int const shortcut); +GdkModifierType sp_shortcut_get_modifiers(unsigned int const shortcut); + /* Returns true if action was performed */ bool @@ -430,7 +432,7 @@ void sp_shortcut_delete_from_file(char const * /*action*/, unsigned int const sh return; } - gchar *key = gdk_keyval_name (shortcut & (~SP_SHORTCUT_MODIFIER_MASK)); + gchar *key = gdk_keyval_name (sp_shortcut_get_key(shortcut)); std::string modifiers = sp_shortcut_to_label(shortcut & (SP_SHORTCUT_MODIFIER_MASK)); if (!key) { @@ -502,7 +504,7 @@ void sp_shortcut_add_to_file(char const *action, unsigned int const shortcut) { } } - gchar *key = gdk_keyval_name (shortcut & (~SP_SHORTCUT_MODIFIER_MASK)); + gchar *key = gdk_keyval_name (sp_shortcut_get_key(shortcut)); std::string modifiers = sp_shortcut_to_label(shortcut & (SP_SHORTCUT_MODIFIER_MASK)); if (!key) { @@ -639,6 +641,58 @@ sp_shortcut_unset(unsigned int const shortcut) } } + +GtkAccelGroup * +sp_shortcut_get_accel_group() +{ + static GtkAccelGroup *accel_group = NULL; + + if (!accel_group) { + accel_group = gtk_accel_group_new (); + } + + return accel_group; +} + +/** + * Adds a gtk accelerator to a widget + * Used to display the keyboard shortcuts in the main menu items + */ +void +sp_shortcut_add_accelerator(GtkWidget *item, unsigned int const shortcut) +{ + if (shortcut == GDK_KEY_VoidSymbol) { + return; + } + + unsigned int accel_key = sp_shortcut_get_key(shortcut); + if (accel_key > 0) { + gtk_widget_add_accelerator (item, + "activate", + sp_shortcut_get_accel_group(), + accel_key, + sp_shortcut_get_modifiers(shortcut), + GTK_ACCEL_VISIBLE); + } +} + + +unsigned int +sp_shortcut_get_key(unsigned int const shortcut) +{ + return (shortcut & (~SP_SHORTCUT_MODIFIER_MASK)); +} + +GdkModifierType +sp_shortcut_get_modifiers(unsigned int const shortcut) +{ + return static_cast<GdkModifierType>( + ((shortcut & SP_SHORTCUT_SHIFT_MASK) ? GDK_SHIFT_MASK : 0) | + ((shortcut & SP_SHORTCUT_CONTROL_MASK) ? GDK_CONTROL_MASK : 0) | + ((shortcut & SP_SHORTCUT_ALT_MASK) ? GDK_MOD1_MASK : 0) + ); +} + /** * Adds a keyboard shortcut for the given verb. * (Removes any existing binding for the given shortcut, including appropriately @@ -706,7 +760,6 @@ bool sp_shortcut_is_user_set(Inkscape::Verb *verb) return result; } - gchar *sp_shortcut_get_label(unsigned int shortcut) { // The comment below was copied from the function sp_ui_shortcut_string in interface.cpp (which was subsequently removed) @@ -721,11 +774,8 @@ gchar *sp_shortcut_get_label(unsigned int shortcut) gchar *result = 0; if (shortcut != GDK_KEY_VoidSymbol) { result = gtk_accelerator_get_label( - shortcut & (~SP_SHORTCUT_MODIFIER_MASK), static_cast<GdkModifierType>( - ((shortcut & SP_SHORTCUT_SHIFT_MASK) ? GDK_SHIFT_MASK : 0) | - ((shortcut & SP_SHORTCUT_CONTROL_MASK) ? GDK_CONTROL_MASK : 0) | - ((shortcut & SP_SHORTCUT_ALT_MASK) ? GDK_MOD1_MASK : 0) - )); + sp_shortcut_get_key(shortcut), + sp_shortcut_get_modifiers(shortcut)); } return result; } diff --git a/src/shortcuts.h b/src/shortcuts.h index 118909bd3..c2a6f6cde 100644 --- a/src/shortcuts.h +++ b/src/shortcuts.h @@ -28,13 +28,14 @@ namespace Inkscape { #define SP_SHORTCUT_ALT_MASK (1 << 26) #define SP_SHORTCUT_MODIFIER_MASK (SP_SHORTCUT_SHIFT_MASK|SP_SHORTCUT_CONTROL_MASK|SP_SHORTCUT_ALT_MASK) + /* Returns true if action was performed */ bool sp_shortcut_invoke (unsigned int shortcut, Inkscape::UI::View::View *view); void sp_shortcut_init(); Inkscape::Verb * sp_shortcut_get_verb (unsigned int shortcut); unsigned int sp_shortcut_get_primary (Inkscape::Verb * verb); // Returns GDK_VoidSymbol if no shortcut is found. -char* sp_shortcut_get_label (unsigned int shortcut); // Returns the human readable form of the shortcut (or NULL), for example Shift+Ctrl+F. Free the returned string with g_free. +gchar* sp_shortcut_get_label (unsigned int shortcut); // Returns the human readable form of the shortcut (or NULL), for example Shift+Ctrl+F. Free the returned string with g_free. void sp_shortcut_set(unsigned int const shortcut, Inkscape::Verb *const verb, bool const is_primary, bool const is_user_set=false); void sp_shortcut_unset(unsigned int const shortcut); void sp_shortcut_add_to_file(char const *action, unsigned int const shortcut); @@ -48,6 +49,8 @@ void sp_shortcut_file_export(); bool sp_shortcut_file_import(); void sp_shortcut_file_import_do(char const *importname); void sp_shortcut_file_export_do(char const *exportname); +GtkAccelGroup *sp_shortcut_get_accel_group(); +void sp_shortcut_add_accelerator(GtkWidget *item, unsigned int const shortcut); #endif diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp index 7445b0b75..48596cbc0 100644 --- a/src/sp-guide.cpp +++ b/src/sp-guide.cpp @@ -280,10 +280,10 @@ sp_guide_create_guides_around_page(SPDesktop *dt) { Geom::Point B(C[Geom::X], 0); Geom::Point D(0, C[Geom::Y]); - pts.push_back(std::make_pair<Geom::Point, Geom::Point>(A, B)); - pts.push_back(std::make_pair<Geom::Point, Geom::Point>(B, C)); - pts.push_back(std::make_pair<Geom::Point, Geom::Point>(C, D)); - pts.push_back(std::make_pair<Geom::Point, Geom::Point>(D, A)); + pts.push_back(std::pair<Geom::Point, Geom::Point>(A, B)); + pts.push_back(std::pair<Geom::Point, Geom::Point>(B, C)); + pts.push_back(std::pair<Geom::Point, Geom::Point>(C, D)); + pts.push_back(std::pair<Geom::Point, Geom::Point>(D, A)); sp_guide_pt_pairs_to_guides(doc, pts); diff --git a/src/splivarot.cpp b/src/splivarot.cpp index c3243930d..f9aaab898 100644 --- a/src/splivarot.cpp +++ b/src/splivarot.cpp @@ -460,10 +460,13 @@ sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb theShapeB->ConvertToShape(theShape, origWind[curOrig]); - // les elements arrivent en ordre inverse dans la liste - theShape->Booleen(theShapeB, theShapeA, bop); - - { + if (theShapeA->numberOfEdges() == 0) { + Shape *swap = theShapeB; + theShapeB = theShapeA; + theShapeA = swap; + } else if (theShapeB->numberOfEdges() > 0) { + // les elements arrivent en ordre inverse dans la liste + theShape->Booleen(theShapeB, theShapeA, bop); Shape *swap = theShape; theShape = theShapeA; theShapeA = swap; @@ -506,7 +509,10 @@ sp_selected_path_boolop(SPDesktop *desktop, bool_op bop, const unsigned int verb originaux[1]->ConvertWithBackData(1.0); - originaux[1]->Fill(theShape, 1,false,false,false); //do not closeIfNeeded + if ((originaux[1]->pts.size() == 2) && originaux[1]->pts[0].isMoveTo && !originaux[1]->pts[1].isMoveTo) + originaux[1]->Fill(theShape, 1,false,true,false); // see LP Bug 177956 + else + originaux[1]->Fill(theShape, 1,false,false,false); //do not closeIfNeeded theShapeB->ConvertToShape(theShape, fill_justDont); // fill_justDont doesn't computes winding numbers diff --git a/src/ui/CMakeLists.txt b/src/ui/CMakeLists.txt index 8fd8eb4e3..f3c3b8473 100644 --- a/src/ui/CMakeLists.txt +++ b/src/ui/CMakeLists.txt @@ -84,6 +84,7 @@ set(ui_SRC widget/entry.cpp widget/filter-effect-chooser.cpp widget/frame.cpp + widget/gimpcolorwheel.c widget/gimpspinscale.c widget/imageicon.cpp widget/imagetoggler.cpp @@ -212,6 +213,7 @@ set(ui_SRC widget/filter-effect-chooser.h widget/frame.h widget/gimpspinscale.h + widget/gimpcolorwheel.h widget/imageicon.h widget/imagetoggler.h widget/labelled.h diff --git a/src/ui/dialog/aboutbox.cpp b/src/ui/dialog/aboutbox.cpp index 0c0027c15..d4928d25d 100644 --- a/src/ui/dialog/aboutbox.cpp +++ b/src/ui/dialog/aboutbox.cpp @@ -97,7 +97,12 @@ AboutBox::AboutBox() : Gtk::Dialog(_("About Inkscape")) { tabs->append_page(*manage( make_scrolled_text(license_text)), _("_License"), true); +#if WITH_GTKMM_3_0 + get_content_area()->pack_end(*manage(tabs), true, true); +#else get_vbox()->pack_end(*manage(tabs), true, true); +#endif + tabs->show_all(); add_button(Gtk::Stock::CLOSE, Gtk::RESPONSE_CLOSE); @@ -114,7 +119,11 @@ AboutBox::AboutBox() : Gtk::Dialog(_("About Inkscape")) { label->set_selectable(true); label->show(); +#if WITH_GTKMM_3_0 + get_content_area()->pack_start(*manage(label), false, false); +#else get_vbox()->pack_start(*manage(label), false, false); +#endif Gtk::Requisition requisition; #if GTK_CHECK_VERSION(3,0,0) diff --git a/src/ui/dialog/calligraphic-profile-rename.cpp b/src/ui/dialog/calligraphic-profile-rename.cpp index 77a4f4f03..da43763c8 100644 --- a/src/ui/dialog/calligraphic-profile-rename.cpp +++ b/src/ui/dialog/calligraphic-profile-rename.cpp @@ -32,7 +32,12 @@ CalligraphicProfileRename::CalligraphicProfileRename() : { set_title(_("Edit profile")); +#if WITH_GTKMM_3_0 + Gtk::Box *mainVBox = get_content_area(); +#else Gtk::Box *mainVBox = get_vbox(); +#endif + _layout_table.set_spacings(4); _layout_table.resize (1, 2); diff --git a/src/ui/dialog/debug.cpp b/src/ui/dialog/debug.cpp index 429ed57bf..e61f8e389 100644 --- a/src/ui/dialog/debug.cpp +++ b/src/ui/dialog/debug.cpp @@ -69,7 +69,11 @@ DebugDialogImpl::DebugDialogImpl() set_title(_("Messages")); set_size_request(300, 400); +#if WITH_GTKMM_3_0 + Gtk::Box *mainVBox = get_content_area(); +#else Gtk::Box *mainVBox = get_vbox(); +#endif //## Add a menu for clear() Gtk::MenuItem* item = Gtk::manage(new Gtk::MenuItem(_("_File"), true)); diff --git a/src/ui/dialog/filter-effects-dialog.cpp b/src/ui/dialog/filter-effects-dialog.cpp index 50f30e8f4..fd368ed9f 100644 --- a/src/ui/dialog/filter-effects-dialog.cpp +++ b/src/ui/dialog/filter-effects-dialog.cpp @@ -20,6 +20,11 @@ #include "dialog-manager.h" #include <gtkmm/imagemenuitem.h> + +#if GTK_CHECK_VERSION(3,0,0) +# include <gdkmm/devicemanager.h> +#endif + #include "ui/widget/spinbutton.h" #include <glibmm/i18n.h> @@ -1201,7 +1206,6 @@ void FilterEffectsDialog::FilterModifier::on_change_selection() { Inkscape::Selection *selection = sp_desktop_selection (SP_ACTIVE_DESKTOP); update_selection(selection); - update_filters(); } void FilterEffectsDialog::FilterModifier::on_modified_selection( guint flags ) @@ -1785,7 +1789,15 @@ bool FilterEffectsDialog::PrimitiveList::on_draw_signal(const Cairo::RefPtr<Cair // Check mouse state int mx, my; Gdk::ModifierType mask; + +#if GTK_CHECK_VERSION(3,0,0) + Glib::RefPtr<Gdk::Display> display = get_bin_window()->get_display(); + Glib::RefPtr<Gdk::DeviceManager> dm = display->get_device_manager(); + Glib::RefPtr<const Gdk::Device> device = dm->get_client_pointer(); + get_bin_window()->get_device_position(device, mx, my, mask); +#else get_bin_window()->get_pointer(mx, my, mask); +#endif // Outline the bottom of the connection area const int outline_x = x + fheight * (row_count - row_index); @@ -2668,7 +2680,7 @@ void FilterEffectsDialog::update_primitive_infobox() break; case(NR_FILTER_SPECULARLIGHTING): _infobox_icon.set_from_icon_name("feSpecularLighting-icon", Gtk::ICON_SIZE_DIALOG); - _infobox_desc.set_markup(_("The feDiffuseLighting and <b>feSpecularLighting</b> filter primitives create \"embossed\" shadings. The input's alpha channel is used to provide depth information: higher opacity areas are raised toward the viewer and lower opacity areas recede away from the viewer.")); + _infobox_desc.set_markup(_("The <b>feDiffuseLighting</b> and <b>feSpecularLighting</b> filter primitives create \"embossed\" shadings. The input's alpha channel is used to provide depth information: higher opacity areas are raised toward the viewer and lower opacity areas recede away from the viewer.")); break; case(NR_FILTER_TILE): _infobox_icon.set_from_icon_name("feTile-icon", Gtk::ICON_SIZE_DIALOG); diff --git a/src/ui/dialog/floating-behavior.cpp b/src/ui/dialog/floating-behavior.cpp index ba81c6d47..d70c5f187 100644 --- a/src/ui/dialog/floating-behavior.cpp +++ b/src/ui/dialog/floating-behavior.cpp @@ -12,6 +12,7 @@ #include <gtkmm/dialog.h> #include <gtkmm/stock.h> +#include <glibmm/main.h> #include <gtk/gtk.h> #include "floating-behavior.h" @@ -134,7 +135,13 @@ FloatingBehavior::create(Dialog &dialog) inline FloatingBehavior::operator Gtk::Widget &() { return *_d; } inline GtkWidget *FloatingBehavior::gobj() { return GTK_WIDGET(_d->gobj()); } -inline Gtk::Box* FloatingBehavior::get_vbox() { return _d->get_vbox(); } +inline Gtk::Box* FloatingBehavior::get_vbox() { +#if WITH_GTKMM_3_0 + return _d->get_content_area(); +#else + return _d->get_vbox(); +#endif +} inline void FloatingBehavior::present() { _d->present(); } inline void FloatingBehavior::hide() { _d->hide(); } inline void FloatingBehavior::show() { _d->show(); } diff --git a/src/ui/dialog/font-substitution.cpp b/src/ui/dialog/font-substitution.cpp index 07e73cec8..f0112f1d8 100644 --- a/src/ui/dialog/font-substitution.cpp +++ b/src/ui/dialog/font-substitution.cpp @@ -37,6 +37,8 @@ #include "libnrtype/FontFactory.h" #include "libnrtype/font-instance.h" +#include <glibmm/regex.h> + namespace Inkscape { namespace UI { namespace Dialog { diff --git a/src/ui/dialog/glyphs.cpp b/src/ui/dialog/glyphs.cpp index eec904ee4..be44794d0 100644 --- a/src/ui/dialog/glyphs.cpp +++ b/src/ui/dialog/glyphs.cpp @@ -1,6 +1,7 @@ /* Authors: * Jon A. Cruz * Abhishek Sharma + * Tavmjong Bah * * Copyright (C) 2010 Jon A. Cruz * Released under GNU GPL, read the file 'COPYING' for more information @@ -343,7 +344,8 @@ GlyphsPanel::GlyphsPanel(gchar const *prefsPath) : GtkWidget *fontsel = sp_font_selector_new(); fsel = SP_FONT_SELECTOR(fontsel); - sp_font_selector_set_font(fsel, sp_font_selector_get_font(fsel), 12.0); + sp_font_selector_set_fontspec( fsel, sp_font_selector_get_fontspec(fsel), 12.0 ); + gtk_widget_set_size_request (fontsel, 0, 150); g_signal_connect( G_OBJECT(fontsel), "font_set", G_CALLBACK(fontChangeCB), this ); @@ -520,6 +522,7 @@ void GlyphsPanel::setTargetDesktop(SPDesktop *desktop) } } +// Append selected glyphs to selected text void GlyphsPanel::insertText() { SPItem *textItem = 0; @@ -611,7 +614,7 @@ void GlyphsPanel::glyphSelectionChanged() calcCanInsert(); } -void GlyphsPanel::fontChangeCB(SPFontSelector * /*fontsel*/, font_instance * /*font*/, GlyphsPanel *self) +void GlyphsPanel::fontChangeCB(SPFontSelector * /*fontsel*/, Glib::ustring /*fontspec*/, GlyphsPanel *self) { if (self) { self->rebuild(); @@ -667,7 +670,13 @@ void GlyphsPanel::readSelection( bool updateStyle, bool /*updateContent*/ ) void GlyphsPanel::rebuild() { - font_instance *font = fsel ? sp_font_selector_get_font(fsel) : 0; + Glib::ustring fontspec = fsel ? sp_font_selector_get_fontspec(fsel) : ""; + + font_instance* font = 0; + if( !fontspec.empty() ) { + font = font_factory::Default()->FaceFromFontSpecification( fontspec.c_str() ); + } + if (font) { //double sp_font_selector_get_size (SPFontSelector *fsel); diff --git a/src/ui/dialog/glyphs.h b/src/ui/dialog/glyphs.h index 162c7b296..6571af0a4 100644 --- a/src/ui/dialog/glyphs.h +++ b/src/ui/dialog/glyphs.h @@ -54,7 +54,7 @@ private: static GlyphColumns *getColumns(); - static void fontChangeCB(SPFontSelector *fontsel, font_instance *font, GlyphsPanel *self); + static void fontChangeCB(SPFontSelector *fontsel, Glib::ustring fontspec, GlyphsPanel *self); void rebuild(); diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp index d8bbb5539..06671393d 100644 --- a/src/ui/dialog/guides.cpp +++ b/src/ui/dialog/guides.cpp @@ -166,12 +166,12 @@ void GuidelinePropertiesDialog::_setup() { add_button(Gtk::Stock::DELETE, -12); add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); - Gtk::Box *mainVBox = get_vbox(); - #if WITH_GTKMM_3_0 + Gtk::Box *mainVBox = get_content_area(); _layout_table.set_row_spacing(4); _layout_table.set_column_spacing(4); #else + Gtk::Box *mainVBox = get_vbox(); _layout_table.set_spacings(4); _layout_table.resize (3, 4); #endif diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index 57f815730..c63b78c70 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -18,6 +18,7 @@ #endif #include <glibmm/i18n.h> +#include <glibmm/miscutils.h> #include "inkscape-preferences.h" #include <gtkmm/main.h> @@ -1288,7 +1289,7 @@ void InkscapePreferences::initPageBehavior() _page_mask.add_group_header( _("Before applying")); _mask_grouping_none.init( _("Do not group clipped/masked objects"), "/options/maskobject/grouping", PREFS_MASKOBJECT_GROUPING_NONE, true, 0); - _mask_grouping_separate.init( _("Enclose every clipped/masked object in its own group"), "/options/maskobject/grouping", PREFS_MASKOBJECT_GROUPING_SEPARATE, false, &_mask_grouping_none); + _mask_grouping_separate.init( _("Put every clipped/masked object in its own group"), "/options/maskobject/grouping", PREFS_MASKOBJECT_GROUPING_SEPARATE, false, &_mask_grouping_none); _mask_grouping_all.init( _("Put all clipped/masked objects into one group"), "/options/maskobject/grouping", PREFS_MASKOBJECT_GROUPING_ALL, false, &_mask_grouping_none); _page_mask.add_line(true, "", _mask_grouping_none, "", @@ -1476,7 +1477,15 @@ void InkscapePreferences::initKeyboardShortcuts(Gtk::TreeModel::iterator iter_ui scroller->add(_kb_tree); int row = 3; + +#if WITH_GTKMM_3_0 + scroller->set_hexpand(); + scroller->set_vexpand(); + _page_keyshortcuts.attach(*scroller, 0, row, 2, 1); +#else _page_keyshortcuts.attach(*scroller, 0, 2, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::EXPAND | Gtk::FILL); +#endif + row++; #if WITH_GTKMM_3_0 @@ -1487,7 +1496,13 @@ void InkscapePreferences::initKeyboardShortcuts(Gtk::TreeModel::iterator iter_ui box_buttons->set_layout(Gtk::BUTTONBOX_END); box_buttons->set_spacing(4); + +#if WITH_GTKMM_3_0 + box_buttons->set_hexpand(); + _page_keyshortcuts.attach(*box_buttons, 0, row, 3, 1); +#else _page_keyshortcuts.attach(*box_buttons, 0, 3, row, row+1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK); +#endif UI::Widget::Button *kb_reset = manage(new UI::Widget::Button(_("Reset"), _("Remove all your customized keyboard shortcuts, and revert to the shortcuts in the shortcut file listed above"))); box_buttons->pack_start(*kb_reset, true, true, 6); diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index b21ab0128..eaf1ffc3d 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -87,6 +87,14 @@ enum { }; +namespace Gtk { +#if WITH_GTKMM_3_0 +class Scale; +#else +class HScale; +#endif +} + namespace Inkscape { namespace UI { namespace Dialog { @@ -188,7 +196,12 @@ protected: UI::Widget::PrefCheckButton _scroll_space; UI::Widget::PrefCheckButton _wheel_zoom; +#if WITH_GTKMM_3_0 + Gtk::Scale *_slider_snapping_delay; +#else Gtk::HScale *_slider_snapping_delay; +#endif + UI::Widget::PrefCheckButton _snap_indicator; UI::Widget::PrefCheckButton _snap_closest_only; UI::Widget::PrefCheckButton _snap_mouse_pointer; diff --git a/src/ui/dialog/layer-properties.cpp b/src/ui/dialog/layer-properties.cpp index 6a1bc829e..3feed2afe 100644 --- a/src/ui/dialog/layer-properties.cpp +++ b/src/ui/dialog/layer-properties.cpp @@ -40,12 +40,12 @@ namespace Dialogs { LayerPropertiesDialog::LayerPropertiesDialog() : _strategy(NULL), _desktop(NULL), _layer(NULL), _position_visible(false) { - Gtk::Box *mainVBox = get_vbox(); - #if WITH_GTKMM_3_0 + Gtk::Box *mainVBox = get_content_area(); _layout_table.set_row_spacing(4); _layout_table.set_column_spacing(4); #else + Gtk::Box *mainVBox = get_vbox(); _layout_table.set_spacings(4); _layout_table.resize (1, 2); #endif diff --git a/src/ui/dialog/layers.cpp b/src/ui/dialog/layers.cpp index fdc33b2a6..dd147d00f 100644 --- a/src/ui/dialog/layers.cpp +++ b/src/ui/dialog/layers.cpp @@ -20,6 +20,7 @@ #include <gtkmm/separatormenuitem.h> #include <glibmm/i18n.h> +#include <glibmm/main.h> #include "desktop.h" #include "desktop-style.h" diff --git a/src/ui/dialog/livepatheffect-add.cpp b/src/ui/dialog/livepatheffect-add.cpp index e899dbcfc..b5f51d81d 100644 --- a/src/ui/dialog/livepatheffect-add.cpp +++ b/src/ui/dialog/livepatheffect-add.cpp @@ -73,7 +73,12 @@ LivePathEffectAdd::LivePathEffectAdd() : add_button.set_use_underline(true); add_button.set_can_default(); +#if WITH_GTKMM_3_0 + Gtk::Box *mainVBox = get_content_area(); +#else Gtk::Box *mainVBox = get_vbox(); +#endif + mainVBox->pack_start(scrolled_window, true, true); add_action_widget(close_button, Gtk::RESPONSE_CLOSE); add_action_widget(add_button, Gtk::RESPONSE_APPLY); diff --git a/src/ui/dialog/svg-fonts-dialog.cpp b/src/ui/dialog/svg-fonts-dialog.cpp index be69635e8..0da39dd73 100644 --- a/src/ui/dialog/svg-fonts-dialog.cpp +++ b/src/ui/dialog/svg-fonts-dialog.cpp @@ -22,6 +22,7 @@ #include "document-undo.h" #include <gtkmm/notebook.h> #include <gtkmm/imagemenuitem.h> +#include <gtkmm/scale.h> #include <gtkmm/stock.h> #include <glibmm/i18n.h> #include <message-stack.h> @@ -191,7 +192,7 @@ void SvgFontsDialog::on_kerning_value_changed(){ //slider values increase from right to left so that they match the kerning pair preview //XML Tree being directly used here while it shouldn't be. - this->kerning_pair->getRepr()->setAttribute("k", Glib::Ascii::dtostr(get_selected_spfont()->horiz_adv_x - kerning_slider.get_value()).c_str()); + this->kerning_pair->getRepr()->setAttribute("k", Glib::Ascii::dtostr(get_selected_spfont()->horiz_adv_x - kerning_slider->get_value()).c_str()); DocumentUndo::maybeDone(document, undokey.c_str(), SP_VERB_DIALOG_SVG_FONTS, _("Adjust kerning value")); //populate_kerning_pairs_box(); @@ -299,7 +300,7 @@ void SvgFontsDialog::on_kerning_pair_selection_changed(){ this->kerning_pair = kern; //slider values increase from right to left so that they match the kerning pair preview - kerning_slider.set_value(get_selected_spfont()->horiz_adv_x - kern->k); + kerning_slider->set_value(get_selected_spfont()->horiz_adv_x - kern->k); } void SvgFontsDialog::update_global_settings_tab(){ @@ -328,9 +329,9 @@ void SvgFontsDialog::on_font_selection_changed(){ double set_width = spfont->horiz_adv_x; setwidth_spin.set_value(set_width); - kerning_slider.set_range(0, set_width); - kerning_slider.set_draw_value(false); - kerning_slider.set_value(0); + kerning_slider->set_range(0, set_width); + kerning_slider->set_draw_value(false); + kerning_slider->set_value(0); update_global_settings_tab(); populate_glyphs_box(); @@ -779,7 +780,7 @@ Gtk::VBox* SvgFontsDialog::kerning_tab(){ add_kernpair_button.set_label(_("Add pair")); add_kernpair_button.signal_clicked().connect(sigc::mem_fun(*this, &SvgFontsDialog::add_kerning_pair)); _KerningPairsList.get_selection()->signal_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::on_kerning_pair_selection_changed)); - kerning_slider.signal_value_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::on_kerning_value_changed)); + kerning_slider->signal_value_changed().connect(sigc::mem_fun(*this, &SvgFontsDialog::on_kerning_value_changed)); kerning_vbox.pack_start(*kerning_selector, false,false); @@ -797,7 +798,7 @@ Gtk::VBox* SvgFontsDialog::kerning_tab(){ Gtk::HBox* kerning_amount_hbox = Gtk::manage(new Gtk::HBox()); kerning_vbox.pack_start(*kerning_amount_hbox, false,false); kerning_amount_hbox->add(*Gtk::manage(new Gtk::Label(_("Kerning value:")))); - kerning_amount_hbox->add(kerning_slider); + kerning_amount_hbox->add(*kerning_slider); kerning_preview.set_size(300 + 20, 150 + 20); _font_da.set_size(150 + 20, 50 + 20); @@ -884,6 +885,12 @@ void SvgFontsDialog::add_font(){ SvgFontsDialog::SvgFontsDialog() : UI::Widget::Panel("", "/dialogs/svgfonts", SP_VERB_DIALOG_SVG_FONTS), _add(Gtk::Stock::NEW) { +#if WITH_GTKMM_3_0 + kerning_slider = Gtk::manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL)); +#else + kerning_slider = Gtk::manage(new Gtk::HScale); +#endif + _add.signal_clicked().connect(sigc::mem_fun(*this, &SvgFontsDialog::add_font)); Gtk::HBox* hbox = Gtk::manage(new Gtk::HBox()); diff --git a/src/ui/dialog/svg-fonts-dialog.h b/src/ui/dialog/svg-fonts-dialog.h index 910f79d4c..9be984820 100644 --- a/src/ui/dialog/svg-fonts-dialog.h +++ b/src/ui/dialog/svg-fonts-dialog.h @@ -20,13 +20,20 @@ #include <gtkmm/drawingarea.h> #include <gtkmm/entry.h> #include <gtkmm/liststore.h> -#include <gtkmm/scale.h> #include <gtkmm/scrolledwindow.h> #include <gtkmm/treeview.h> #include "attributes.h" #include "xml/helper-observer.h" +namespace Gtk { +#if WITH_GTKMM_3_0 +class Scale; +#else +class HScale; +#endif +} + class SPGlyph; class SPGlyphKerning; class SvgFont; @@ -210,7 +217,12 @@ private: GlyphComboBox first_glyph, second_glyph; SPGlyphKerning* kerning_pair; Inkscape::UI::Widget::SpinButton setwidth_spin; - Gtk::HScale kerning_slider; + +#if WITH_GTKMM_3_0 + Gtk::Scale* kerning_slider; +#else + Gtk::HScale* kerning_slider; +#endif class EntryWidget : public Gtk::HBox { diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index 43b88e5c6..71fee342a 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -23,6 +23,7 @@ #include <glibmm/i18n.h> #include <glibmm/main.h> +#include <glibmm/timer.h> #include <gdkmm/pixbuf.h> #include "color-item.h" diff --git a/src/ui/dialog/text-edit.cpp b/src/ui/dialog/text-edit.cpp index 97cd28cdd..a71227861 100644 --- a/src/ui/dialog/text-edit.cpp +++ b/src/ui/dialog/text-edit.cpp @@ -8,8 +8,9 @@ * Johan Engelen <goejendaagh@zonnet.nl> * Abhishek Sharma * John Smith + * Tavmjong Bah * - * Copyright (C) 1999-2012 Authors + * Copyright (C) 1999-2013 Authors * Copyright (C) 2000-2001 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -32,6 +33,7 @@ extern "C" { #include <gtkmm/stock.h> #include <libnrtype/font-instance.h> #include <libnrtype/font-style-to-pos.h> +#include <libnrtype/font-lister.h> #include <xml/repr.h> #include "macros.h" @@ -305,18 +307,20 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) // FIXME: process result_family/style == QUERY_STYLE_MULTIPLE_DIFFERENT by showing "Many" in the lists - // Get a font_instance using the font-specification attribute stored in SPStyle if available - font_instance *font = font_factory::Default()->FaceFromStyle(query); + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - if (font) { + // This is done for us by text-toolbar. No need to do it twice. + // fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + // fontlister->selection_update(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); - sp_font_selector_set_font (fsel, font, sp_style_css_size_px_to_units(query->font_size.computed, unit) ); - setPreviewText(font, phrase); - font->Unref(); - font=NULL; - } + Glib::ustring fontspec = fontlister->get_fontspec(); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); + double size = sp_style_css_size_px_to_units(query->font_size.computed, unit); + sp_font_selector_set_fontspec(fsel, fontspec, size ); + + setPreviewText (fontspec, phrase); if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) { if (query->text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) { @@ -351,30 +355,31 @@ void TextEdit::onReadSelection ( gboolean dostyle, gboolean /*docontent*/ ) blocked = false; } -void TextEdit::setPreviewText (font_instance *font, Glib::ustring phrase) + +void TextEdit::setPreviewText (Glib::ustring font_spec, Glib::ustring phrase) { - if (!font) { + if (font_spec.empty()) { return; } - char *desc = pango_font_description_to_string(font->descr); + Glib::ustring phrase_escaped = Glib::Markup::escape_text( phrase ); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); double pt_size = sp_style_css_size_units_to_px(sp_font_selector_get_size(fsel), unit) * PT_PER_PX; - gchar *const phrase_escaped = g_markup_escape_text(phrase.c_str(), -1); - // Pango font size is in 1024ths of a point - gchar *markup = g_strdup_printf("<span font=\"%s\" size=\"%d\">%s</span>", - desc, (int) (pt_size * PANGO_SCALE ), phrase_escaped); + // C++11: Glib::ustring size = std::to_string( pt_size * PANGO_SCALE ); + std::ostringstream size_st; + size_st << pt_size * PANGO_SCALE; - preview_label.set_markup(markup); + Glib::ustring markup = "<span font=\"" + font_spec + + "\" size=\"" + size_st.str() + "\">" + phrase_escaped + "</span>"; - g_free(desc); - g_free(phrase_escaped); - g_free(markup); + preview_label.set_markup(markup.c_str()); } + SPItem *TextEdit::getSelectedTextItem (void) { if (!SP_ACTIVE_DESKTOP) @@ -430,34 +435,18 @@ void TextEdit::updateObjectText ( SPItem *text ) } } -SPCSSAttr *TextEdit::getTextStyle () +SPCSSAttr *TextEdit::fillTextStyle () { SPCSSAttr *css = sp_repr_css_attr_new (); - // font - font_instance *font = sp_font_selector_get_font (fsel); - - if ( font ) { - Glib::ustring fontName = font_factory::Default()->ConstructFontSpecification(font); - sp_repr_css_set_property (css, "-inkscape-font-specification", fontName.c_str()); - - gchar c[256]; - - font->Family(c, 256); - sp_repr_css_set_property (css, "font-family", c); - - font->Attribute( "weight", c, 256); - sp_repr_css_set_property (css, "font-weight", c); + Glib::ustring fontspec = sp_font_selector_get_fontspec (fsel); - font->Attribute("style", c, 256); - sp_repr_css_set_property (css, "font-style", c); + if( !fontspec.empty() ) { - font->Attribute("stretch", c, 256); - sp_repr_css_set_property (css, "font-stretch", c); - - font->Attribute("variant", c, 256); - sp_repr_css_set_property (css, "font-variant", c); + Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); + fontlister->fill_css( css, fontspec ); + // TODO, possibly move this to FontLister::set_css to be shared. Inkscape::CSSOStringStream os; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); @@ -467,9 +456,6 @@ SPCSSAttr *TextEdit::getTextStyle () os << sp_font_selector_get_size (fsel) << sp_style_get_css_unit_string(unit); } sp_repr_css_set_property (css, "font-size", os.str().c_str()); - - font->Unref(); - font=NULL; } // Layout @@ -505,7 +491,7 @@ SPCSSAttr *TextEdit::getTextStyle () void TextEdit::onSetDefault() { - SPCSSAttr *css = getTextStyle (); + SPCSSAttr *css = fillTextStyle (); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); blocked = true; @@ -525,7 +511,7 @@ void TextEdit::onApply() unsigned items = 0; const GSList *item_list = sp_desktop_selection(desktop)->itemList(); - SPCSSAttr *css = getTextStyle (); + SPCSSAttr *css = fillTextStyle (); sp_desktop_set_style(desktop, css, true); for (; item_list != NULL; item_list = item_list->next) { @@ -556,6 +542,13 @@ void TextEdit::onApply() } } + // Update FontLister + Glib::ustring fontspec = sp_font_selector_get_fontspec (fsel); + if( !fontspec.empty() ) { + Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); + fontlister->set_fontspec( fontspec, false ); + } + // complete the transaction DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, _("Set text style")); @@ -577,11 +570,11 @@ void TextEdit::onTextChange (GtkTextBuffer *text_buffer, TextEdit *self) GtkTextIter end; gtk_text_buffer_get_bounds (text_buffer, &start, &end); gchar *str = gtk_text_buffer_get_text(text_buffer, &start, &end, TRUE); - font_instance *font = sp_font_selector_get_font(self->fsel); + Glib::ustring fontspec = sp_font_selector_get_fontspec(self->fsel); - if (font) { + if( !fontspec.empty() ) { const gchar *phrase = str && *str ? str : self->samplephrase.c_str(); - self->setPreviewText(font, phrase); + self->setPreviewText(fontspec, phrase); } else { self->preview_label.set_markup(""); } @@ -594,7 +587,7 @@ void TextEdit::onTextChange (GtkTextBuffer *text_buffer, TextEdit *self) self->setasdefault_button.set_sensitive ( true); } -void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, font_instance * font, TextEdit *self) +void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, gchar* fontspec, TextEdit *self) { GtkTextIter start, end; gchar *str; @@ -607,9 +600,9 @@ void TextEdit::onFontChange(SPFontSelector * /*fontsel*/, font_instance * font, gtk_text_buffer_get_bounds (self->text_buffer, &start, &end); str = gtk_text_buffer_get_text (self->text_buffer, &start, &end, TRUE); - if (font) { + if (fontspec) { const gchar *phrase = str && *str ? str : self->samplephrase.c_str(); - self->setPreviewText(font, phrase); + self->setPreviewText(fontspec, phrase); } else { self->preview_label.set_markup(""); } diff --git a/src/ui/dialog/text-edit.h b/src/ui/dialog/text-edit.h index bca6cee90..3fdeea05d 100644 --- a/src/ui/dialog/text-edit.h +++ b/src/ui/dialog/text-edit.h @@ -7,8 +7,9 @@ * Johan Engelen <goejendaagh@zonnet.nl> * John Smith * Kris De Gussem <Kris.DeGussem@gmail.com> + * Tavmjong Bah * - * Copyright (C) 1999-2012 Authors + * Copyright (C) 1999-2013 Authors * Copyright (C) 2000-2001 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -100,10 +101,10 @@ protected: * onFontChange updates the dialog UI. The subfunction setPreviewText updates the preview label. * * @param fontsel pointer to SPFontSelector (currently not used). - * @param font pointer to the font instance for the text to be previewed + * @param fontspec for the text to be previewed. * @param self pointer to the current instance of the dialog. */ - static void onFontChange (SPFontSelector *fontsel, font_instance *font, TextEdit *self); + static void onFontChange (SPFontSelector *fontsel, gchar* fontspec, TextEdit *self); /** * Get the selected text off the main canvas. @@ -118,15 +119,15 @@ protected: unsigned getSelectedTextCount (void); /** - * Helper function to create markup from a font definition and display in the preview label. + * Helper function to create markup from a fontspec and display in the preview label. * - * @param font pointer to the font instance for the text to be previewed + * @param fontspec for the text to be previewed * @param phrase text to be shown */ - void setPreviewText (font_instance *font, Glib::ustring phrase); + void setPreviewText (Glib::ustring font_spec, Glib::ustring phrase); void updateObjectText ( SPItem *text ); - SPCSSAttr *getTextStyle (); + SPCSSAttr *fillTextStyle (); /** * Helper function to style radio buttons with icons, tooltips. diff --git a/src/ui/widget/color-picker.cpp b/src/ui/widget/color-picker.cpp index 31fb3096c..5585f2db4 100644 --- a/src/ui/widget/color-picker.cpp +++ b/src/ui/widget/color-picker.cpp @@ -56,8 +56,14 @@ void ColorPicker::setupDialog(const Glib::ustring &title) _colorSelectorDialog.set_title (title); _colorSelectorDialog.set_border_width (4); _colorSelector = SP_COLOR_SELECTOR(sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK)); + +#if WITH_GTKMM_3_0 + _colorSelectorDialog.get_content_area()->pack_start ( + *Glib::wrap(&_colorSelector->vbox), true, true, 0); +#else _colorSelectorDialog.get_vbox()->pack_start ( *Glib::wrap(&_colorSelector->vbox), true, true, 0); +#endif g_signal_connect(G_OBJECT(_colorSelector), "dragged", G_CALLBACK(sp_color_picker_color_mod), (void *)this); diff --git a/src/ui/widget/dock-item.cpp b/src/ui/widget/dock-item.cpp index b9cc50845..8d960ddc3 100644 --- a/src/ui/widget/dock-item.cpp +++ b/src/ui/widget/dock-item.cpp @@ -18,6 +18,7 @@ #include <gtkmm/icontheme.h> #include <gtkmm/stockitem.h> +#include <glibmm/exceptionhandler.h> namespace Inkscape { namespace UI { diff --git a/src/ui/widget/dock.cpp b/src/ui/widget/dock.cpp index a38a93fb1..2bfc7e0df 100644 --- a/src/ui/widget/dock.cpp +++ b/src/ui/widget/dock.cpp @@ -54,6 +54,17 @@ Dock::Dock(Gtk::Orientation orientation) { gdl_dock_bar_set_orientation(_gdl_dock_bar, static_cast<GtkOrientation>(orientation)); +#if WITH_GTKMM_3_0 + switch(orientation) { + case Gtk::ORIENTATION_VERTICAL: + _dock_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL)); + break; + case Gtk::ORIENTATION_HORIZONTAL: + _dock_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + } + + _paned = Gtk::manage(new Gtk::Paned(orientation)); +#else switch (orientation) { case Gtk::ORIENTATION_VERTICAL: _dock_box = Gtk::manage(new Gtk::HBox()); @@ -63,6 +74,7 @@ Dock::Dock(Gtk::Orientation orientation) _dock_box = Gtk::manage(new Gtk::VBox()); _paned = Gtk::manage(new Gtk::HPaned()); } +#endif _scrolled_window->add(*_dock_box); _scrolled_window->set_policy(Gtk::POLICY_NEVER, Gtk::POLICY_AUTOMATIC); diff --git a/src/ui/widget/preferences-widget.cpp b/src/ui/widget/preferences-widget.cpp index e5b062ec9..314bf75bf 100644 --- a/src/ui/widget/preferences-widget.cpp +++ b/src/ui/widget/preferences-widget.cpp @@ -21,7 +21,9 @@ #include <gtkmm/box.h> #include <gtkmm/frame.h> #include <gtkmm/alignment.h> +#include <gtkmm/scale.h> #include <gtkmm/stock.h> +#include <gtkmm/table.h> #include "preferences.h" #include "ui/widget/preferences-widget.h" @@ -49,90 +51,139 @@ namespace Widget { DialogPage::DialogPage() { - this->set_border_width(12); - this->set_col_spacings(12); - this->set_row_spacings(6); + set_border_width(12); + +#if WITH_GTKMM_3_0 + set_orientation(Gtk::ORIENTATION_VERTICAL); + set_column_spacing(12); + set_row_spacing(6); +#else + set_col_spacings(12); + set_row_spacings(6); +#endif } -void DialogPage::add_line(bool indent, Glib::ustring const &label, Gtk::Widget &widget, Glib::ustring const &suffix, const Glib::ustring &tip, bool expand_widget, Gtk::Widget *other_widget) +/** + * Add a widget to the bottom row of the dialog page + * + * \param[in] indent Whether the widget should be indented by one column + * \param[in] label The label text for the widget + * \param[in] widget The widget to add to the page + * \param[in] suffix Text for an optional label at the right of the widget + * \param[in] tip Tooltip text for the widget + * \param[in] expand_widget Whether to expand the widget horizontally + * \param[in] other_widget An optional additional widget to display at the right of the first one + */ +void DialogPage::add_line(bool indent, + Glib::ustring const &label, + Gtk::Widget &widget, + Glib::ustring const &suffix, + const Glib::ustring &tip, + bool expand_widget, + Gtk::Widget *other_widget) { - int start_col; - int row = this->property_n_rows(); - Gtk::Widget* w; - if (expand_widget) - { - w = &widget; - } - else - { - Gtk::HBox* hb = Gtk::manage(new Gtk::HBox()); - hb->set_spacing(12); - hb->pack_start(widget,false,false); - if (other_widget) { - hb->pack_start(*other_widget,false,false); - } - - w = (Gtk::Widget*) hb; - } + if (tip != "") + widget.set_tooltip_text (tip); + + Gtk::Alignment* label_alignment = Gtk::manage(new Gtk::Alignment()); + + Gtk::HBox* hb = Gtk::manage(new Gtk::HBox()); + hb->set_spacing(12); + hb->pack_start(widget, expand_widget, expand_widget); + + // Pack an additional widget into a box with the widget if desired + if (other_widget) + hb->pack_start(*other_widget, expand_widget, expand_widget); + + // Pack the widget into an alignment container so that it can + // be indented if desired + Gtk::Alignment* w_alignment = Gtk::manage(new Gtk::Alignment()); + w_alignment->add(*hb); + +#if WITH_GTKMM_3_0 + w_alignment->set_valign(Gtk::ALIGN_CENTER); +#else + guint row = property_n_rows(); +#endif + + // Add a label in the first column if provided if (label != "") { - Gtk::Label* label_widget; - label_widget = Gtk::manage(new Gtk::Label(label , Gtk::ALIGN_START , Gtk::ALIGN_CENTER, true)); + Gtk::Label* label_widget = Gtk::manage(new Gtk::Label(label, Gtk::ALIGN_START, + Gtk::ALIGN_CENTER, true)); label_widget->set_mnemonic_widget(widget); + + // Pack the label into an alignment container so that we can indent it + // if necessary + label_alignment->add(*label_widget); + if (indent) - { - Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment()); - alignment->set_padding(0, 0, 12, 0); - alignment->add(*label_widget); - this->attach(*alignment , 0, 1, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0); - } - else - this->attach(*label_widget , 0, 1, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0); - start_col = 1; + label_alignment->set_padding(0, 0, 12, 0); + +#if WITH_GTKMM_3_0 + label_alignment->set_valign(Gtk::ALIGN_CENTER); + add(*label_alignment); + attach_next_to(*w_alignment, *label_alignment, Gtk::POS_RIGHT, 1, 1); +#else + attach(*label_alignment, 0, 1, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0); +#endif } - else - start_col = 0; - if (start_col == 0 && indent) //indent this widget + // Now add the widget to the bottom of the dialog +#if WITH_GTKMM_3_0 + if (label == "") { - Gtk::Alignment* alignment = Gtk::manage(new Gtk::Alignment()); - alignment->set_padding(0, 0, 12, 0); - alignment->add(*w); - this->attach(*alignment, start_col, 2, row, row + 1, Gtk::FILL | Gtk::EXPAND, Gtk::AttachOptions(), 0, 0); - } - else - { - this->attach(*w, start_col, 2, row, row + 1, Gtk::FILL | Gtk::EXPAND, Gtk::AttachOptions(), 0, 0); - } + if (indent) + w_alignment->set_padding(0, 0, 12, 0); + + add(*w_alignment); + + GValue width = G_VALUE_INIT; + g_value_init(&width, G_TYPE_INT); + g_value_set_int(&width, 2); + gtk_container_child_set_property(GTK_CONTAINER(gobj()), GTK_WIDGET(w_alignment->gobj()), "width", &width); + } +#else + // The widget should span two columns if there is no label + int w_col_span = 1; + if (label == "") + w_col_span = 2; + + attach(*w_alignment, 2 - w_col_span, 2, row, row + 1, + Gtk::FILL | Gtk::EXPAND, + Gtk::AttachOptions(), + 0, 0); +#endif + // Add a label on the right of the widget if desired if (suffix != "") { Gtk::Label* suffix_widget = Gtk::manage(new Gtk::Label(suffix , Gtk::ALIGN_START , Gtk::ALIGN_CENTER, true)); - if (expand_widget) - this->attach(*suffix_widget, 2, 3, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0); - else - ((Gtk::HBox*)w)->pack_start(*suffix_widget,false,false); - } - - if (tip != "") - { - widget.set_tooltip_text (tip); + hb->pack_start(*suffix_widget,false,false); } } void DialogPage::add_group_header(Glib::ustring name) { - int row = this->property_n_rows(); if (name != "") { Gtk::Label* label_widget = Gtk::manage(new Gtk::Label(Glib::ustring(/*"<span size='large'>*/"<b>") + name + Glib::ustring("</b>"/*</span>"*/) , Gtk::ALIGN_START , Gtk::ALIGN_CENTER, true)); label_widget->set_use_markup(true); - this->attach(*label_widget , 0, 4, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0); + +#if WITH_GTKMM_3_0 + label_widget->set_valign(Gtk::ALIGN_CENTER); + add(*label_widget); +// if (row != 1) + // set_row_spacing(row - 1, 18); +#else + int row = property_n_rows(); + attach(*label_widget , 0, 4, row, row + 1, Gtk::FILL, Gtk::AttachOptions(), 0, 0); if (row != 1) - this->set_row_spacing(row - 1, 18); + set_row_spacing(row - 1, 18); +#endif } } @@ -444,8 +495,8 @@ ZoomCorrRulerSlider::on_slider_value_changed() { freeze = true; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/options/zoomcorrection/value", _slider.get_value() / 100.0); - _sb.set_value(_slider.get_value()); + prefs->setDouble("/options/zoomcorrection/value", _slider->get_value() / 100.0); + _sb.set_value(_slider->get_value()); _ruler.queue_draw(); freeze = false; } @@ -459,7 +510,7 @@ ZoomCorrRulerSlider::on_spinbutton_value_changed() freeze = true; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble("/options/zoomcorrection/value", _sb.get_value() / 100.0); - _slider.set_value(_sb.get_value()); + _slider->set_value(_sb.get_value()); _ruler.queue_draw(); freeze = false; } @@ -498,13 +549,19 @@ ZoomCorrRulerSlider::init(int ruler_width, int ruler_height, double lower, doubl _ruler.set_size(ruler_width, ruler_height); - _slider.set_size_request(_ruler.width(), -1); - _slider.set_range (lower, upper); - _slider.set_increments (step_increment, page_increment); - _slider.set_value (value); - _slider.set_digits(2); +#if WITH_GTKMM_3_0 + _slider = Gtk::manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL)); +#else + _slider = Gtk::manage(new Gtk::HScale()); +#endif + + _slider->set_size_request(_ruler.width(), -1); + _slider->set_range (lower, upper); + _slider->set_increments (step_increment, page_increment); + _slider->set_value (value); + _slider->set_digits(2); - _slider.signal_value_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_slider_value_changed)); + _slider->signal_value_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_slider_value_changed)); _sb.signal_value_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_spinbutton_value_changed)); _unit.signal_changed().connect(sigc::mem_fun(*this, &ZoomCorrRulerSlider::on_unit_changed)); @@ -518,18 +575,28 @@ ZoomCorrRulerSlider::init(int ruler_width, int ruler_height, double lower, doubl _unit.set_data("sensitive", GINT_TO_POINTER(1)); _unit.setUnit(prefs->getString("/options/zoomcorrection/unit")); - Gtk::Table *table = Gtk::manage(new Gtk::Table()); Gtk::Alignment *alignment1 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0)); Gtk::Alignment *alignment2 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0)); alignment1->add(_sb); alignment2->add(_unit); - table->attach(_slider, 0, 1, 0, 1); +#if WITH_GTKMM_3_0 + Gtk::Grid *table = Gtk::manage(new Gtk::Grid()); + table->attach(*_slider, 0, 0, 1, 1); + alignment1->set_halign(Gtk::ALIGN_CENTER); + table->attach(*alignment1, 1, 0, 1, 1); + table->attach(_ruler, 0, 1, 1, 1); + alignment2->set_halign(Gtk::ALIGN_CENTER); + table->attach(*alignment2, 1, 1, 1, 1); +#else + Gtk::Table *table = Gtk::manage(new Gtk::Table()); + table->attach(*_slider, 0, 1, 0, 1); table->attach(*alignment1, 1, 2, 0, 1, static_cast<Gtk::AttachOptions>(0)); table->attach(_ruler, 0, 1, 1, 2); table->attach(*alignment2, 1, 2, 1, 2, static_cast<Gtk::AttachOptions>(0)); +#endif - this->pack_start(*table, Gtk::PACK_EXPAND_WIDGET); + pack_start(*table, Gtk::PACK_SHRINK); } void @@ -539,8 +606,8 @@ PrefSlider::on_slider_value_changed() { freeze = true; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(_prefs_path, _slider.get_value()); - _sb.set_value(_slider.get_value()); + prefs->setDouble(_prefs_path, _slider->get_value()); + _sb.set_value(_slider->get_value()); freeze = false; } } @@ -553,7 +620,7 @@ PrefSlider::on_spinbutton_value_changed() freeze = true; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble(_prefs_path, _sb.get_value()); - _slider.set_value(_sb.get_value()); + _slider->set_value(_sb.get_value()); freeze = false; } } @@ -574,11 +641,17 @@ PrefSlider::init(Glib::ustring const &prefs_path, freeze = false; - _slider.set_range (lower, upper); - _slider.set_increments (step_increment, page_increment); - _slider.set_value (value); - _slider.set_digits(digits); - _slider.signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_slider_value_changed)); +#if WITH_GTKMM_3_0 + _slider = Gtk::manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL)); +#else + _slider = Gtk::manage(new Gtk::HScale()); +#endif + + _slider->set_range (lower, upper); + _slider->set_increments (step_increment, page_increment); + _slider->set_value (value); + _slider->set_digits(digits); + _slider->signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_slider_value_changed)); _sb.signal_value_changed().connect(sigc::mem_fun(*this, &PrefSlider::on_spinbutton_value_changed)); _sb.set_range (lower, upper); @@ -586,12 +659,20 @@ PrefSlider::init(Glib::ustring const &prefs_path, _sb.set_value (value); _sb.set_digits(digits); - Gtk::Table *table = Gtk::manage(new Gtk::Table()); Gtk::Alignment *alignment1 = Gtk::manage(new Gtk::Alignment(0.5,1,0,0)); alignment1->add(_sb); - table->attach(_slider, 0, 1, 0, 1); +#if WITH_GTKMM_3_0 + Gtk::Grid *table = Gtk::manage(new Gtk::Grid()); + _slider->set_hexpand(); + table->attach(*_slider, 0, 0, 1, 1); + alignment1->set_halign(Gtk::ALIGN_CENTER); + table->attach(*alignment1, 1, 0, 1, 1); +#else + Gtk::Table *table = Gtk::manage(new Gtk::Table()); + table->attach(*_slider, 0, 1, 0, 1); table->attach(*alignment1, 1, 2, 0, 1, static_cast<Gtk::AttachOptions>(0)); +#endif this->pack_start(*table, Gtk::PACK_EXPAND_WIDGET); } diff --git a/src/ui/widget/preferences-widget.h b/src/ui/widget/preferences-widget.h index 646a8b2fa..e3968045d 100644 --- a/src/ui/widget/preferences-widget.h +++ b/src/ui/widget/preferences-widget.h @@ -25,14 +25,26 @@ #include <gtkmm/radiobutton.h> #include <gtkmm/comboboxtext.h> #include <gtkmm/drawingarea.h> -#include <gtkmm/scale.h> + +#if WITH_GTKMM_3_0 +#include <gtkmm/grid.h> +#else #include <gtkmm/table.h> +#endif #include "ui/widget/color-picker.h" #include "ui/widget/unit-menu.h" #include "ui/widget/spinbutton.h" #include "ui/widget/scalar-unit.h" +namespace Gtk { +#if WITH_GTKMM_3_0 +class Scale; +#else +class HScale; +#endif +} + namespace Inkscape { namespace UI { namespace Widget { @@ -137,7 +149,11 @@ private: Inkscape::UI::Widget::SpinButton _sb; UnitMenu _unit; - Gtk::HScale _slider; +#if WITH_GTKMM_3_0 + Gtk::Scale* _slider; +#else + Gtk::HScale* _slider; +#endif ZoomCorrRuler _ruler; bool freeze; // used to block recursive updates of slider and spinbutton }; @@ -155,7 +171,13 @@ private: Glib::ustring _prefs_path; Inkscape::UI::Widget::SpinButton _sb; - Gtk::HScale _slider; + +#if WITH_GTKMM_3_0 + Gtk::Scale* _slider; +#else + Gtk::HScale* _slider; +#endif + bool freeze; // used to block recursive updates of slider and spinbutton }; @@ -251,7 +273,11 @@ protected: void on_changed(); }; +#if WITH_GTKMM_3_0 +class DialogPage : public Gtk::Grid +#else class DialogPage : public Gtk::Table +#endif { public: DialogPage(); diff --git a/src/ui/widget/scalar.cpp b/src/ui/widget/scalar.cpp index 9bbcc80f9..fca8a7974 100644 --- a/src/ui/widget/scalar.cpp +++ b/src/ui/widget/scalar.cpp @@ -142,7 +142,7 @@ void Scalar::update() void Scalar::addSlider() { #if WITH_GTKMM_3_0 - Gtk::HScale *scale = new Gtk::HScale(static_cast<SpinButton*>(_widget)->get_adjustment()); + Gtk::Scale *scale = new Gtk::Scale(static_cast<SpinButton*>(_widget)->get_adjustment()); #else Gtk::HScale *scale = new Gtk::HScale( * static_cast<SpinButton*>(_widget)->get_adjustment() ); #endif diff --git a/src/ui/widget/spin-slider.cpp b/src/ui/widget/spin-slider.cpp index 323b1209c..facbf704c 100644 --- a/src/ui/widget/spin-slider.cpp +++ b/src/ui/widget/spin-slider.cpp @@ -116,11 +116,20 @@ Gtk::Adjustment& SpinSlider::get_adjustment() return _adjustment; } +#if WITH_GTKMM_3_0 +const Gtk::Scale& SpinSlider::get_scale() const +#else const Gtk::HScale& SpinSlider::get_scale() const +#endif { return _scale; } + +#if WITH_GTKMM_3_0 +Gtk::Scale& SpinSlider::get_scale() +#else Gtk::HScale& SpinSlider::get_scale() +#endif { return _scale; } diff --git a/src/ui/widget/spin-slider.h b/src/ui/widget/spin-slider.h index f4a62107b..8a45299e5 100644 --- a/src/ui/widget/spin-slider.h +++ b/src/ui/widget/spin-slider.h @@ -41,13 +41,14 @@ public: #if WITH_GTKMM_3_0 const Glib::RefPtr<Gtk::Adjustment> get_adjustment() const; Glib::RefPtr<Gtk::Adjustment> get_adjustment(); + const Gtk::Scale& get_scale() const; + Gtk::Scale& get_scale(); #else const Gtk::Adjustment& get_adjustment() const; Gtk::Adjustment& get_adjustment(); -#endif - const Gtk::HScale& get_scale() const; Gtk::HScale& get_scale(); +#endif const Inkscape::UI::Widget::SpinButton& get_spin_button() const; Inkscape::UI::Widget::SpinButton& get_spin_button(); @@ -57,10 +58,11 @@ public: private: #if WITH_GTKMM_3_0 Glib::RefPtr<Gtk::Adjustment> _adjustment; + Gtk::Scale _scale; #else Gtk::Adjustment _adjustment; -#endif Gtk::HScale _scale; +#endif Inkscape::UI::Widget::SpinButton _spin; }; diff --git a/src/ui/widget/tolerance-slider.cpp b/src/ui/widget/tolerance-slider.cpp index 16558f0ee..f92a08d0a 100644 --- a/src/ui/widget/tolerance-slider.cpp +++ b/src/ui/widget/tolerance-slider.cpp @@ -73,8 +73,15 @@ void ToleranceSlider::init (const Glib::ustring& label1, const Glib::ustring& la theLabel1->set_use_underline(); theLabel1->set_alignment(0, 0.5); // align the label with the checkbox text above by indenting 22 px. - _hbox->pack_start(*theLabel1, Gtk::PACK_EXPAND_WIDGET, 22); + _hbox->pack_start(*theLabel1, Gtk::PACK_EXPAND_WIDGET, 22); + +#if WITH_GTKMM_3_0 + _hscale = manage(new Gtk::Scale(Gtk::ORIENTATION_HORIZONTAL)); + _hscale->set_range(1.0, 51.0); +#else _hscale = manage (new Gtk::HScale (1.0, 51, 1.0)); +#endif + theLabel1->set_mnemonic_widget (*_hscale); _hscale->set_draw_value (true); _hscale->set_value_pos (Gtk::POS_RIGHT); diff --git a/src/ui/widget/tolerance-slider.h b/src/ui/widget/tolerance-slider.h index d0b78e3c1..2184cd52b 100644 --- a/src/ui/widget/tolerance-slider.h +++ b/src/ui/widget/tolerance-slider.h @@ -13,7 +13,12 @@ #include <gtkmm/radiobuttongroup.h> namespace Gtk { - class RadioButton; +class RadioButton; +#if WITH_GTKMM_3_0 +class Scale; +#else +class HScale; +#endif } namespace Inkscape { @@ -55,7 +60,13 @@ protected: void on_toggled(); void update (double val); Gtk::HBox *_hbox; + +#if WITH_GTKMM_3_0 + Gtk::Scale *_hscale; +#else Gtk::HScale *_hscale; +#endif + Gtk::RadioButtonGroup _radio_button_group; Gtk::RadioButton *_button1; Gtk::RadioButton *_button2; diff --git a/src/verbs.cpp b/src/verbs.cpp index bbadb1a25..cdeeab99a 100644 --- a/src/verbs.cpp +++ b/src/verbs.cpp @@ -89,10 +89,6 @@ using Inkscape::DocumentUndo; using Inkscape::UI::Dialog::ActionAlign; -//#ifdef WITH_INKBOARD -//#include "jabber_whiteboard/session-manager.h" -//#endif - /** * Return the name without underscores and ellipsis, for use in dialog * titles, etc. Allocated memory must be freed by caller. @@ -1972,13 +1968,6 @@ void DialogVerb::perform(SPAction *action, void *data) //sp_item_dialog(); dt->_dlg_mgr->showDialog("ObjectProperties"); break; -/*#ifdef WITH_INKBOARD - case SP_VERB_XMPP_CLIENT: - { - Inkscape::Whiteboard::SessionManager::showClient(); - break; - } -#endif*/ case SP_VERB_DIALOG_INPUT: dt->_dlg_mgr->showDialog("InputDevices"); break; @@ -2796,10 +2785,6 @@ Verb *Verb::_base_verbs[] = { N_("Edit the object attributes..."), INKSCAPE_ICON("dialog-object-attributes")), new DialogVerb(SP_VERB_DIALOG_ITEM, "DialogObjectProperties", N_("_Object Properties..."), N_("Edit the ID, locked and visible status, and other object properties"), INKSCAPE_ICON("dialog-object-properties")), -/*#ifdef WITH_INKBOARD - new DialogVerb(SP_VERB_XMPP_CLIENT, "DialogXmppClient", - N_("_Instant Messaging..."), N_("Jabber Instant Messaging Client"), NULL), -#endif*/ new DialogVerb(SP_VERB_DIALOG_INPUT, "DialogInput", N_("_Input Devices..."), N_("Configure extended input devices, such as a graphics tablet"), INKSCAPE_ICON("dialog-input-devices")), new DialogVerb(SP_VERB_DIALOG_EXTENSIONEDITOR, "org.inkscape.dialogs.extensioneditor", N_("_Extensions..."), diff --git a/src/verbs.h b/src/verbs.h index c4a7b67e0..dab524d7a 100644 --- a/src/verbs.h +++ b/src/verbs.h @@ -282,9 +282,6 @@ enum { SP_VERB_DIALOG_CLONETILER, SP_VERB_DIALOG_ATTR, SP_VERB_DIALOG_ITEM, -/*#ifdef WITH_INKBOARD - SP_VERB_XMPP_CLIENT, -#endif*/ SP_VERB_DIALOG_INPUT, SP_VERB_DIALOG_EXTENSIONEDITOR, SP_VERB_DIALOG_LAYERS, diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 9e078cabb..b0d8d974e 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -82,11 +82,6 @@ using Inkscape::UI::UXManager; using Inkscape::UI::ToolboxFactory; using ege::AppearTimeTracker; -#ifdef WITH_INKBOARD -#endif - - - enum { ACTIVATE, DEACTIVATE, @@ -775,6 +770,10 @@ static void sp_desktop_widget_dispose(GObject *object) { SPDesktopWidget *dtw = SP_DESKTOP_WIDGET (object); + if (dtw == NULL) { + return; + } + UXManager::getInstance()->delTrack(dtw); if (dtw->desktop) { diff --git a/src/widgets/font-selector.cpp b/src/widgets/font-selector.cpp index 013ad9e94..453ef683f 100644 --- a/src/widgets/font-selector.cpp +++ b/src/widgets/font-selector.cpp @@ -8,10 +8,11 @@ * Lauris Kaplinski <lauris@kaplinski.com> * bulia byak <buliabyak@users.sf.net> * Johan Engelen <j.b.c.engelen@ewi.utwente.nl> + * Tavmjong Bah <tavmjong@free.fr> * * Copyright (C) 1999-2001 Ximian, Inc. * Copyright (C) 2002 Lauris Kaplinski - * Copyright (C) -2007 Authors + * Copyright (C) -2013 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -51,11 +52,9 @@ struct SPFontSelector NRNameList families; NRStyleList styles; - int familyidx; - int styleidx; gfloat fontsize; bool fontsize_dirty; - font_instance *font; + Glib::ustring *fontspec; }; @@ -63,7 +62,7 @@ struct SPFontSelectorClass { GtkHBoxClass parent_class; - void (* font_set) (SPFontSelector *fsel, font_instance *font); + void (* font_set) (SPFontSelector *fsel, gchar *fontspec); }; enum { @@ -138,6 +137,9 @@ static void sp_font_selector_set_size_tooltip(SPFontSelector *fsel) } +/* + * Create a widget with children for selecting font-family, font-style, and font-size. + */ static void sp_font_selector_init(SPFontSelector *fsel) { gtk_box_set_homogeneous(GTK_BOX(fsel), TRUE); @@ -155,8 +157,6 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw), GTK_SHADOW_IN); gtk_container_add(GTK_CONTAINER(f), sw); - Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - fsel->family_treeview = gtk_tree_view_new (); GtkTreeViewColumn *column = gtk_tree_view_column_new (); GtkCellRenderer *cell = gtk_cell_renderer_text_new (); @@ -177,6 +177,7 @@ static void sp_font_selector_init(SPFontSelector *fsel) "widget \"*font_selector_family\" style \"fontfamily-separator-style\""); + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); Glib::RefPtr<Gtk::ListStore> store = fontlister->get_font_list(); gtk_tree_view_set_model (GTK_TREE_VIEW(fsel->family_treeview), GTK_TREE_MODEL (Glib::unwrap (store))); gtk_container_add(GTK_CONTAINER(sw), fsel->family_treeview); @@ -231,6 +232,7 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_widget_show(hb); gtk_box_pack_start(GTK_BOX(vb), hb, FALSE, FALSE, 0); + // Font-size fsel->size = gtk_combo_box_text_new_with_entry (); sp_font_selector_set_size_tooltip(fsel); @@ -246,20 +248,20 @@ static void sp_font_selector_init(SPFontSelector *fsel) gtk_widget_show_all (fsel->size); - fsel->familyidx = 0; - fsel->styleidx = 0; - fsel->fontsize = 10.0; + // Set default size... next two lines must match + gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(fsel->size))), "18.0"); + fsel->fontsize = 18.0; fsel->fontsize_dirty = false; - fsel->font = NULL; + + fsel->fontspec = new Glib::ustring; } static void sp_font_selector_dispose(GObject *object) { SPFontSelector *fsel = SP_FONT_SELECTOR (object); - if (fsel->font) { - fsel->font->Unref(); - fsel->font = NULL; + if (fsel->fontspec) { + delete fsel->fontspec; } if (fsel->families.length > 0) { @@ -277,49 +279,62 @@ static void sp_font_selector_dispose(GObject *object) } } +// Callback when family changed, updates style list for new family. static void sp_font_selector_family_select_row(GtkTreeSelection *selection, SPFontSelector *fsel) { - GtkTreeIter iter; - GtkTreeModel *model; - GtkListStore *store; - GtkTreePath *path; - GList *list=0; + // We need our own copy of the style list store since the font-family + // may not be the same in the font-selector as stored in the font-lister + // TODO: use font-lister class for this by modifying new_font_family to accept an optional style list + // TODO: add store to SPFontSelector struct and reuse. + + // Start by getting iterator to selected font + GtkTreeModel *model; + GtkTreeIter iter; if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; - path = gtk_tree_model_get_path (model, &iter); - gtk_tree_model_get (model, &iter, 1, &list, -1); - fsel->familyidx = gtk_tree_path_get_indices (path)[0]; - fsel->styleidx = 0; + // Next get family name with its style list + gchar *family; + GList *list=0; + gtk_tree_model_get (model, &iter, 0, &family, 1, &list, -1); - store = gtk_list_store_new (1, G_TYPE_STRING); + // Find best style match for selected family with current style (e.g. of selected text). + Inkscape::FontLister *fontlister = Inkscape::FontLister::get_instance(); + Glib::ustring style = fontlister->get_font_style(); + Glib::ustring best = fontlister->get_best_style_match (family, style); + // Create our own store of styles for selected font-family and find index of best style match + int path_index = 0; + int index = 0; + GtkListStore *store = gtk_list_store_new (1, G_TYPE_STRING); // Where is this deleted? for ( ; list ; list = list->next ) { gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, static_cast<char*>(list->data), -1); + gtk_list_store_set (store, &iter, 0, (char*)list->data, -1); + + if( best.compare( (char*)list->data ) == 0 ) { + path_index = index; + } + ++index; } + // Attach store to tree view. Can trigger style changed signal (but not FONT_SET): gtk_tree_view_set_model (GTK_TREE_VIEW (fsel->style_treeview), GTK_TREE_MODEL (store)); - path = gtk_tree_path_new (); - gtk_tree_path_append_index (path, 0); + + // Get path to best style + GtkTreePath *path = gtk_tree_path_new (); + gtk_tree_path_append_index (path, path_index); + + // Highlight best style. Triggers style changed signal: gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path); gtk_tree_path_free (path); } +// Callback when row changed static void sp_font_selector_style_select_row (GtkTreeSelection *selection, SPFontSelector *fsel) { - GtkTreeModel *model; - GtkTreePath *path; - GtkTreeIter iter; - - if (!gtk_tree_selection_get_selected (selection, &model, &iter)) return; - - path = gtk_tree_model_get_path (model, &iter); - fsel->styleidx = gtk_tree_path_get_indices (path)[0]; - if (!fsel->block_emit) { sp_font_selector_emit_set (fsel); @@ -329,6 +344,7 @@ static void sp_font_selector_style_select_row (GtkTreeSelection *selection, /* * Set the default list of font sizes, scaled to the users preferred unit + * TODO: This routine occurs both here and in text-toolbar. Move to font-lister? */ static void sp_font_selector_set_sizes( SPFontSelector *fsel ) { @@ -355,6 +371,7 @@ static void sp_font_selector_set_sizes( SPFontSelector *fsel ) } +// Callback when size changed static void sp_font_selector_size_changed( GtkComboBox */*cbox*/, SPFontSelector *fsel ) { char *text = NULL; @@ -388,9 +405,13 @@ static void sp_font_selector_size_changed( GtkComboBox */*cbox*/, SPFontSelector sp_font_selector_emit_set (fsel); } + +// Called from sp_font_selector_style_select_row +// Called from sp_font_selector_size_changed +// Called indirectly for sp_font_selector_family_select_row (since style changes). +// Emits FONT_SET signal (handled by TextEdit::onFontChange, GlyphsPanel::fontChangeCB). static void sp_font_selector_emit_set (SPFontSelector *fsel) { - font_instance *font; GtkTreeSelection *selection_family; GtkTreeSelection *selection_style; @@ -405,41 +426,27 @@ static void sp_font_selector_emit_set (SPFontSelector *fsel) model_family = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->family_treeview)); if (!model_family) return; - model_style = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->style_treeview)); - if (!model_style) return; + model_style = gtk_tree_view_get_model (GTK_TREE_VIEW (fsel->style_treeview)); + if (!model_style ) return; selection_family = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->family_treeview)); - selection_style = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)); + selection_style = gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview )); if (!gtk_tree_selection_get_selected (selection_family, NULL, &iter_family)) return; - if (!gtk_tree_selection_get_selected (selection_style, NULL, &iter_style)) return; + if (!gtk_tree_selection_get_selected (selection_style, NULL, &iter_style )) return; gtk_tree_model_get (model_family, &iter_family, 0, &family, -1); - gtk_tree_model_get (model_style, &iter_style, 0, &style, -1); + gtk_tree_model_get (model_style, &iter_style, 0, &style, -1); if ((!family) || (!style)) return; - font = (font_factory::Default())->FaceFromUIStrings (family, style); + Glib::ustring fontspec = family; + fontspec += ", "; + fontspec += style; - // FIXME: when a text object uses non-available font, font==NULL and we can't set size - // (and the size shown in the widget is invalid). To fix, here we must always get some - // default font, exactly the same as sptext uses for on-canvas display, so that - // font!=NULL ever. - if (font != fsel->font || ( font && fsel->fontsize_dirty ) ) { - if ( font ) { - font->Ref(); - } - if ( fsel->font ) { - fsel->font->Unref(); - } - fsel->font = font; - g_signal_emit(fsel, fs_signals[FONT_SET], 0, fsel->font); - } - fsel->fontsize_dirty = false; - if (font) { - font->Unref(); - } - font = NULL; + *(fsel->fontspec) = fontspec; + + g_signal_emit(fsel, fs_signals[FONT_SET], 0, fontspec.c_str()); } GtkWidget *sp_font_selector_new() @@ -449,116 +456,53 @@ GtkWidget *sp_font_selector_new() return GTK_WIDGET(fsel); } + /* - * Returns the index of the fonts closest style match from the provided list of styles - * Used in both the Text dialog and the Text toolbar to set the style combo on selection change + * Sets the values displayed in the font-selector from a fontspec. + * It is only called from TextEdit with a new selection and from GlyphsPanel */ -unsigned int sp_font_selector_get_best_style (font_instance *font, GList *list) +void sp_font_selector_set_fontspec (SPFontSelector *fsel, Glib::ustring fontspec, double size) { - if ( !font || !list) { - return 0; - } - - font_instance *tempFont = NULL; - unsigned int currentStyleNumber = 0; - unsigned int bestStyleNumber = 0; - - Glib::ustring family = font_factory::Default()->GetUIFamilyString(font->descr); - - PangoFontDescription *incomingFont = pango_font_description_copy(font->descr); - pango_font_description_unset_fields(incomingFont, PANGO_FONT_MASK_SIZE); - - char *incomingFontString = pango_font_description_to_string(incomingFont); - - tempFont = (font_factory::Default())->FaceFromUIStrings(family.c_str(), static_cast<char*>(list->data)); - - PangoFontDescription *bestMatchForFont = NULL; - if (tempFont) { - bestMatchForFont = pango_font_description_copy(tempFont->descr); - tempFont->Unref(); - tempFont = NULL; - } - - if( bestMatchForFont != NULL ) { - pango_font_description_unset_fields(bestMatchForFont, PANGO_FONT_MASK_SIZE); - } - - list = list->next; - - while (list) { - currentStyleNumber++; - - tempFont = font_factory::Default()->FaceFromUIStrings(family.c_str(), static_cast<char*>(list->data)); - - PangoFontDescription *currentMatchForFont = NULL; - if (tempFont) { - currentMatchForFont = pango_font_description_copy(tempFont->descr); - tempFont->Unref(); - tempFont = NULL; - } - - if (currentMatchForFont) { - pango_font_description_unset_fields(currentMatchForFont, PANGO_FONT_MASK_SIZE); - - char *currentMatchString = pango_font_description_to_string(currentMatchForFont); - - if (!strcmp(incomingFontString, currentMatchString) - || pango_font_description_better_match(incomingFont, bestMatchForFont, currentMatchForFont)) { - // Found a better match for the font we are looking for - pango_font_description_free(bestMatchForFont); - bestMatchForFont = pango_font_description_copy(currentMatchForFont); - bestStyleNumber = currentStyleNumber; - } - - g_free(currentMatchString); - - pango_font_description_free(currentMatchForFont); - } - - list = list->next; - } - - if (bestMatchForFont) - pango_font_description_free(bestMatchForFont); - if (incomingFont) - pango_font_description_free(incomingFont); - g_free(incomingFontString); + if (!fontspec.empty()) + { - return bestStyleNumber; -} + Inkscape::FontLister *font_lister = Inkscape::FontLister::get_instance(); + std::pair<Glib::ustring, Glib::ustring> ui = font_lister->ui_from_fontspec( fontspec ); + Glib::ustring family = ui.first; + Glib::ustring style = ui.second; -void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, double size) -{ - if (font) - { Gtk::TreePath path; - - Glib::ustring family = font_factory::Default()->GetUIFamilyString(font->descr); - try { - path = Inkscape::FontLister::get_instance()->get_row_for_font (family); + path = font_lister->get_row_for_font (family); } catch (...) { + g_warning( "Couldn't find row for font-family: %s", family.c_str() ); return; } + // High light selected family and scroll so it is in view. fsel->block_emit = TRUE; gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->family_treeview)), path.gobj()); gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->family_treeview), path.gobj(), NULL, TRUE, 0.5, 0.5); - fsel->block_emit = FALSE; + fsel->block_emit = FALSE; // TODO: Should this be moved to the end? - GList *list = 0; - GtkTreeIter iter; - GtkTreeModel *model = gtk_tree_view_get_model (GTK_TREE_VIEW(fsel->family_treeview)); - gtk_tree_model_get_iter (model, &iter, path.gobj()); - gtk_tree_model_get (model, &iter, 1, &list, -1); - unsigned int bestStyleNumber = sp_font_selector_get_best_style(font, list); + // We don't need to get best style since this is only called on a new + // selection where we already know the "best" style. + // Glib::ustring bestStyle = font_lister->get_best_style_match (family, style); + // std::cout << "Best: " << bestStyle << std::endl; + + // The "trial" style list and the regular list are the same in this case. + Gtk::TreePath path_c; + try { + path_c = font_lister->get_row_for_style( style ); + } catch (...) { + g_warning( "Couldn't find row for style: %s (%s)", style.c_str(), family.c_str() ); + return; + } + + gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path_c.gobj()); + gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->style_treeview), path_c.gobj(), NULL, TRUE, 0.5, 0.5); - GtkTreePath *path_c = gtk_tree_path_new (); - gtk_tree_path_append_index (path_c, bestStyleNumber); - gtk_tree_selection_select_path (gtk_tree_view_get_selection (GTK_TREE_VIEW (fsel->style_treeview)), path_c); - gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (fsel->style_treeview), path_c, NULL, TRUE, 0.5, 0.5); - if (size != fsel->fontsize) { gchar s[8]; @@ -572,13 +516,9 @@ void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, doubl } -font_instance* sp_font_selector_get_font(SPFontSelector *fsel) +Glib::ustring sp_font_selector_get_fontspec(SPFontSelector *fsel) { - if (fsel->font) { - fsel->font->Ref(); - } - - return fsel->font; + return *(fsel->fontspec); } /* diff --git a/src/widgets/font-selector.h b/src/widgets/font-selector.h index 80e8b1e4d..66715f048 100644 --- a/src/widgets/font-selector.h +++ b/src/widgets/font-selector.h @@ -7,9 +7,11 @@ * Authors: * Chris Lahey <clahey@ximian.com> * Lauris Kaplinski <lauris@kaplinski.com> + * Tavmjong Bah <tavmjong@free.fr> * * Copyright (C) 1999-2001 Ximian, Inc. * Copyright (C) 2002 Lauris Kaplinski + * Copyright (C) 1999-2013 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -22,7 +24,24 @@ struct SPFontSelector; #define SP_FONT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), SP_TYPE_FONT_SELECTOR, SPFontSelector)) #define SP_IS_FONT_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), SP_TYPE_FONT_SELECTOR)) -class font_instance; +/* + * The routines here create and manage a font selector widget with three parts, + * one each for font-family, font-style, and font-size. + * + * It is used by the TextEdit and Glyphs panel dialogs. The FontLister class is used + * to access the list of font-families and their associated styles for fonts either + * on the system or in the document. The FontLister class is also used by the Text + * toolbar. Fonts are kept track of by their "fontspecs" which are the same as the + * strings that Pango generates. + * + * The main functions are: + * Create the font-seletor widget. + * Update the lists when a new text selection is made. + * Update the Style list when a new font-family is selected, highlighting the + * best match to the original font style (as not all fonts have the same style options). + * Emit a signal when any change is made so that the Text Preview can be updated. + * Provide the currently selected values. + */ /* SPFontSelector */ @@ -30,13 +49,11 @@ GType sp_font_selector_get_type (void); GtkWidget *sp_font_selector_new (void); -void sp_font_selector_set_font (SPFontSelector *fsel, font_instance *font, double size); +void sp_font_selector_set_fontspec (SPFontSelector *fsel, Glib::ustring fontspec, double size); +Glib::ustring sp_font_selector_get_fontspec (SPFontSelector *fsel); -font_instance *sp_font_selector_get_font (SPFontSelector *fsel); double sp_font_selector_get_size (SPFontSelector *fsel); -unsigned int sp_font_selector_get_best_style (font_instance *font, GList *list); - #endif // SP_FONT_SELECTOR_H /* diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index 8470e93db..7580d9602 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -24,6 +24,7 @@ #include <gtkmm/image.h> #include <gdkmm/pixbuf.h> #include <glibmm/fileutils.h> +#include <glibmm/miscutils.h> #include <2geom/transforms.h> #include "path-prefix.h" diff --git a/src/widgets/text-toolbar.cpp b/src/widgets/text-toolbar.cpp index a01f950a6..ef7d31d76 100644 --- a/src/widgets/text-toolbar.cpp +++ b/src/widgets/text-toolbar.cpp @@ -18,8 +18,8 @@ * * Copyright (C) 2004 David Turner * Copyright (C) 2003 MenTaLguY - * Copyright (C) 1999-2013 authors * Copyright (C) 2001-2002 Ximian, Inc. + * Copyright (C) 1999-2013 authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -133,115 +133,7 @@ static void sp_print_fontstyle( SPStyle *query ) { } #endif -/* - * Fill the font style combobox with the available font styles for the selected font family - * Set the selected style to that in font - */ -static void sp_text_fontstyle_populate(GObject *tbl, font_instance *font=NULL) -{ - - Ink_ComboBoxEntry_Action* act = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); - GtkTreeModel *model = ink_comboboxentry_action_get_model( act ); - gchar *current_font = ink_comboboxentry_action_get_active_text( act ); - if (!current_font) { - return; - } - - // If font list, take only first font in list - gchar** tokens = g_strsplit( current_font, ",", 0 ); - g_strstrip( tokens[0] ); - current_font = tokens[0]; - - // Get an iter to the selected font from the model data - // We cant get it from the combo, cause it might not have been created yet - gboolean found = false; - GtkTreeIter iter; - gboolean valid = gtk_tree_model_get_iter_first( model, &iter ); - while ( valid ) { - - // Get text from list entry - gchar* text = NULL; - gtk_tree_model_get( model, &iter, 0, &text, -1 ); // Column 0 - - // Check for match - if ( text && (strcmp( current_font, text ) == 0) ) { - found = true; - break; - } - valid = gtk_tree_model_iter_next( model, &iter ); - } - - g_strfreev( tokens ); - - Ink_ComboBoxEntry_Action* fontStyleAction = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); - - gchar *current_style = ink_comboboxentry_action_get_active_text( fontStyleAction ); - - GtkListStore *store = GTK_LIST_STORE( ink_comboboxentry_action_get_model( fontStyleAction ) ); - gtk_list_store_clear ( store ); - - // Get the list of styles from the selected font. - GList *list = NULL; - - if (found) { - - // Use precompiled list if font-family on system. - gtk_tree_model_get (model, &iter, 1, &list, -1); - - } else { - - // Use generic list if font-family not on system. - static GList *glist = NULL; - if( glist == NULL ) { - glist = g_list_append (glist, (void*)"Normal"); - glist = g_list_append (glist, (void*)"Italic"); - glist = g_list_append (glist, (void*)"Bold"); - glist = g_list_append (glist, (void*)"Bold Italic"); - } - list = glist; - } - - for (GList *l=list; l; l = l->next) - { - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, (char*)l->data, -1); - } - - // Select the style in the combo that best matches font - if (font && list) { - - unsigned int index = sp_font_selector_get_best_style(font, list); - - Ink_ComboBoxEntry_Action* fontStyleAction = - INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); - model = ink_comboboxentry_action_get_model( fontStyleAction ); - GtkTreePath *path_c = gtk_tree_path_new (); - gtk_tree_path_append_index (path_c, index); - gtk_tree_model_get_iter(model, &iter, path_c); - gchar *name; - gtk_tree_model_get (model, &iter, 0, &name, -1); - ink_comboboxentry_action_set_active_text( fontStyleAction, name ); - - } else if (current_style) { - ink_comboboxentry_action_set_active_text( fontStyleAction, current_style ); - } -} - // Font family -// -// In most cases we should just be able to set the new family name -// but there may be cases where a font family doesn't follow the -// standard naming pattern. To handle those cases, we do a song and -// dance to use Pango to find the best match. To do that we start -// with the old "fontSpec" (which is the returned string from -// pango_font_description_to_string() with the size unset). This -// has the form "[family-list] [style-options]" where the -// family-list is a comma separated list of font-family names -// (optionally terminated by a comma). An example would be -// "DejaVu Sans, Sans Bold". Only a "fontSpec" containing a -// single font-family will work with Pango's best match routine. -// If we can't obtain a good "fontSpec", we then resort to blindly -// changing the font-family. static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) { #ifdef DEBUG_TEXT @@ -252,156 +144,45 @@ static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GOb // quit if run by the _changed callbacks if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gchar *family = ink_comboboxentry_action_get_active_text( act ); #ifdef DEBUG_TEXT - std::cout << " New family: " << family << std::endl; -#endif - - // First try to get the old font spec from the stored value - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); - - Glib::ustring fontSpec = query->text->font_specification.set ? query->text->font_specification.value : ""; -#ifdef DEBUG_TEXT - std::cout << " fontSpec from query :" << fontSpec << ":" << std::endl; -#endif - - // If that didn't work, try to get font spec from style - if (fontSpec.empty()) { - - // Must query all to fill font-family, font-style, font-weight, font-specification - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - - // Construct a new font specification if it does not yet exist - font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query); - if( fontFromStyle ) { - fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle); - fontFromStyle->Unref(); - } - -#ifdef DEBUG_TEXT - std::cout << " fontSpec empty, try from style" << std::endl; - std::cout << " from style :" << fontSpec << ":" << std::endl; - sp_print_font( query ); -#endif - - } - - // And if that didn't work use default. DO WE REALLY WANT TO DO THIS? - if ( fontSpec.empty() ) { - - sp_style_read_from_prefs(query, "/tools/text"); - - // Construct a new font specification if it does not yet exist - font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query); - if ( fontFromStyle ) { - fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle); - fontFromStyle->Unref(); - } - -#ifdef DEBUG_TEXT - std::cout << " fontSpec empty, trying from prefs" << std::endl; - std::cout << " from prefs :" << fontSpec << ":" << std::endl; - sp_print_font( query ); + std::cout << "sp_text_fontfamily_value_changed: frozen... return" << std::endl; + std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM\n" << std::endl; #endif + return; } + g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - // Now we have a font specification, replace family. - Glib::ustring newFontSpec = ""; - SPCSSAttr *css = sp_repr_css_attr_new (); - - if (!fontSpec.empty()) newFontSpec = font_factory::Default()->ReplaceFontSpecificationFamily(fontSpec, family); - -#ifdef DEBUG_TEXT - std::cout << " New FontSpec from ReplaceFontSpecificationFamily :" << newFontSpec << ":" << std::endl; -#endif - - if (!fontSpec.empty() && !newFontSpec.empty() ) { - - if (fontSpec != newFontSpec) { - - font_instance *font = font_factory::Default()->FaceFromFontSpecification(newFontSpec.c_str()); - - if (font) { - sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str()); - - // Set all the these just in case they were altered when finding the best - // match for the new family and old style... Unnecessary? - - gchar c[256]; - - font->Family(c, 256); - - sp_repr_css_set_property (css, "font-family", c); - - font->Attribute( "weight", c, 256); - sp_repr_css_set_property (css, "font-weight", c); - - font->Attribute("style", c, 256); - sp_repr_css_set_property (css, "font-style", c); - - font->Attribute("stretch", c, 256); - sp_repr_css_set_property (css, "font-stretch", c); - - font->Attribute("variant", c, 256); - sp_repr_css_set_property (css, "font-variant", c); - - font->Unref(); - - // Set the list of font styles - sp_text_fontstyle_populate(tbl); - - } else { - g_warning(_("Failed to find font matching: %s\n"), newFontSpec.c_str()); - } - } - } else { - - // Either old font does not exist on system or ReplaceFontSpecificationFamily() failed. - // Blindly fall back to setting the family to text in the font-family chooser. + Glib::ustring new_family = ink_comboboxentry_action_get_active_text( act ); + // TODO: Think about how to handle handle multiple selections. While + // the font-family may be the same for all, the styles might be different. + // See: TextEdit::onApply() for example of looping over selected items. + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); #ifdef DEBUG_TEXT - std::cout << " Failed to find new font, blindly setting family: " << family << std::endl; + std::cout << " Old family: " << fontlister->get_font_family() << std::endl; + std::cout << " New family: " << new_family << std::endl; + std::cout << " Old active: " << fontlister->get_font_family_row() << std::endl; + std::cout << " New active: " << act->active << std::endl; #endif - sp_repr_css_set_property (css, "-inkscape-font-specification", family); - sp_repr_css_set_property (css, "font-family", family); - } + if( new_family.compare( fontlister->get_font_family() ) != 0 ) { - // If querying returned nothing, update default style. - if (result_fontspec == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - //sp_text_edit_dialog_default_set_insensitive (); //FIXME: Replace through a verb - } - else - { - sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); - } + std::pair<Glib::ustring,Glib::ustring> ui = fontlister->set_font_family( act->active ); + // active text set in sp_text_toolbox_selection_changed() - sp_style_unref(query); + SPCSSAttr *css = sp_repr_css_attr_new (); + fontlister->fill_css( css ); - g_free (family); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css, true, true); // Results in selection change called twice. + sp_repr_css_attr_unref (css); - // Save for undo - if (result_fontspec != QUERY_STYLE_NOTHING) { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, _("Text: Change font family")); } - sp_repr_css_attr_unref (css); // unfreeze g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - // focus to canvas (not useful if you want to choose font for your text) - //gtk_widget_grab_focus (GTK_WIDGET((SP_ACTIVE_DESKTOP)->canvas)); - #ifdef DEBUG_TEXT std::cout << "sp_text_toolbox_fontfamily_changes: exit" << std::endl; std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" << std::endl; @@ -473,7 +254,6 @@ static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObje /* * Font style */ -//static void sp_text_fontstyle_value_changed( EgeSelectOneAction *act, GObject *tbl ) static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) { // quit if run by the _changed callbacks @@ -482,95 +262,26 @@ static void sp_text_fontstyle_value_changed( Ink_ComboBoxEntry_Action *act, GObj } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - // First query font-specification, this is the most complete font face description. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); + Glib::ustring new_style = ink_comboboxentry_action_get_active_text( act ); - // font_specification will not be set unless defined explicitily on a tspan. - // This should be fixed! - Glib::ustring fontSpec = query->text->font_specification.set ? query->text->font_specification.value : ""; + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - if (fontSpec.empty()) { - // Construct a new font specification if it does not yet exist - // Must query font-family, font-style, font-weight, to find correct font face. - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); + if( new_style.compare( fontlister->get_font_style() ) != 0 ) { - font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query); - if ( fontFromStyle ) { - fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle); - fontFromStyle->Unref(); - } - } - - SPCSSAttr *css = sp_repr_css_attr_new (); + fontlister->set_font_style( new_style ); + // active text set in sp_text_toolbox_seletion_changed() - Glib::ustring current_style = ink_comboboxentry_action_get_active_text( act ); - Glib::ustring fontFamily = ""; - - if (query->text->font_family.set) { - fontFamily = query->text->font_family.value; - } else { - // if the font_family is not set, get it from the font family combo instead - Ink_ComboBoxEntry_Action* act = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); - fontFamily = ink_comboboxentry_action_get_active_text( act ); - } - - font_instance *font = (font_factory::Default())->FaceFromUIStrings (fontFamily.c_str(), current_style.c_str()); - - if (font) { - - gchar c[256]; - - font->Attribute( "weight", c, 256); - sp_repr_css_set_property (css, "font-weight", c); - - font->Attribute("style", c, 256); - sp_repr_css_set_property (css, "font-style", c); - - font->Attribute("stretch", c, 256); - sp_repr_css_set_property (css, "font-stretch", c); - - font->Attribute("variant", c, 256); - sp_repr_css_set_property (css, "font-variant", c); - - font->Unref(); - font = NULL; - - } else { - - // Font not found on system, blindly update style - // Options match choices in sp_text_fontstyle_populate - sp_repr_css_set_property (css, "font-weight", "normal"); - sp_repr_css_set_property (css, "font-style", "normal" ); - if( current_style.find("Bold") != Glib::ustring::npos ) { - sp_repr_css_set_property (css, "font-weight", "bold"); - } - if( current_style.find("Italic") != Glib::ustring::npos ) { - sp_repr_css_set_property (css, "font-style", "italic"); - } - } - - // If querying returned nothing, update default style. - if (result_fontspec == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } + SPCSSAttr *css = sp_repr_css_attr_new (); + fontlister->fill_css( css ); - sp_style_unref(query); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + sp_desktop_set_style (desktop, css, true, true); + sp_repr_css_attr_unref (css); - // Do we need to update other CSS values? - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, true); - if (result_fontspec != QUERY_STYLE_NOTHING) { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, - _("Text: Change font style")); + DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_TEXT, + _("Text: Change font style")); } - sp_repr_css_attr_unref (css); - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } @@ -1145,6 +856,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ if (g_object_get_data(G_OBJECT(tbl), "freeze")) { #ifdef DEBUG_TEXT std::cout << " Frozen, returning" << std::endl; + std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; std::cout << std::endl; #endif @@ -1152,15 +864,21 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - // Update font list, but only if widget already created. Ink_ComboBoxEntry_Action* fontFamilyAction = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); + Ink_ComboBoxEntry_Action* fontStyleAction = + INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontStyleAction" ) ); + + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); + fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + fontlister->selection_update(); + + // Update font list, but only if widget already created. if( fontFamilyAction->combobox != NULL ) { - Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); - fontlister->update_font_list( sp_desktop_document( SP_ACTIVE_DESKTOP )); + ink_comboboxentry_action_set_active_text( fontFamilyAction, fontlister->get_font_family().c_str(), fontlister->get_font_family_row() ); + ink_comboboxentry_action_set_active_text( fontStyleAction, fontlister->get_font_style().c_str() ); } - // Only flowed text can be justified, only normal text can be kerned... // Find out if we have flowed text now so we can use it several places gboolean isFlow = false; @@ -1207,6 +925,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); #ifdef DEBUG_TEXT std::cout << " text_style_from_prefs: toolbar already set" << std:: endl; + std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; std::cout << std::endl; #endif @@ -1225,15 +944,6 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // If we have valid query data for text (font-family, font-specification) set toolbar accordingly. if (query->text) { - // Font family - if( query->text->font_family.value ) { - gchar *fontFamily = query->text->font_family.value; - - Ink_ComboBoxEntry_Action* fontFamilyAction = - INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); - ink_comboboxentry_action_set_active_text( fontFamilyAction, fontFamily ); - } - // Size (average of text selected) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT); @@ -1247,16 +957,17 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ Ink_ComboBoxEntry_Action* fontSizeAction = INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontSizeAction" ) ); + + // Freeze to ignore callbacks. + //g_object_freeze_notify( G_OBJECT( fontSizeAction->combobox ) ); sp_text_set_sizes(GTK_LIST_STORE(ink_comboboxentry_action_get_model(fontSizeAction)), unit); + //g_object_thaw_notify( G_OBJECT( fontSizeAction->combobox ) ); + ink_comboboxentry_action_set_active_text( fontSizeAction, os.str().c_str() ); Glib::ustring tooltip = Glib::ustring::format(_("Font size"), " (", sp_style_get_css_unit_string(unit), ")"); ink_comboboxentry_action_set_tooltip ( fontSizeAction, tooltip.c_str()); - // Font styles - font_instance *font = font_factory::Default()->FaceFromStyle(query); - sp_text_fontstyle_populate(tbl, font); - // Superscript gboolean superscriptSet = ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && @@ -1438,6 +1149,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ } #ifdef DEBUG_TEXT + std::cout << "sp_text_toolbox_selection_changed: exit " << count << std::endl; std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; std::cout << std::endl; #endif @@ -1457,41 +1169,47 @@ sp_text_toolbox_subselection_changed (gpointer /*tc*/, GObject *tbl) sp_text_toolbox_selection_changed (NULL, tbl); } +// TODO: possibly share with font-selector by moving most code to font-lister (passing family name) +static void sp_text_toolbox_select_cb( GtkEntry* entry, GtkEntryIconPosition /*position*/, GdkEvent /*event*/, gpointer /*data*/ ) { -/* Recursively extract all "font-family" attributes from a document. */ -void -sp_text_toolbox_get_font_list_in_doc_recursive (SPObject *r, std::list<Glib::ustring> *l) -{ - if (!r) { - return; - } + Glib::ustring family = gtk_entry_get_text ( entry ); + //std::cout << "text_toolbox_missing_font_cb: selecting: " << family << std::endl; - const gchar *style = r->getRepr()->attribute("style"); - if( style != NULL ) { - //std::cout << style << std::endl; - std::vector<Glib::ustring> tokens = Glib::Regex::split_simple(";", style ); - for( size_t i=0; i < tokens.size(); ++i ) { - Glib::ustring token = tokens[i]; - size_t found = token.find("font-family:"); - if( found != Glib::ustring::npos ) { - // Remove "font-family:" - token.erase(found,12); - // Remove any leading single or double quote - if( token[0] == '\'' || token[0] == '"' ) { - token.erase(0,1); - } - // Remove any trailing single or double quote - if( token[token.length()-1] == '\'' || token[token.length()-1] == '"' ) { - token.erase(token.length()-1); - } - l->push_back( token ); - } - } - } + // Get all items with matching font-family set (not inherited!). + GSList *selectList = NULL; + + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *document = sp_desktop_document( desktop ); + GSList *allList = get_all_items(NULL, document->getRoot(), desktop, false, false, true, NULL); + for (GSList *i = allList; i != NULL; i = i->next) { + + SPItem *item = SP_ITEM(i->data); + SPStyle *style = item->style; + + if (style && style->text) { + + Glib::ustring family_style; + if (style->text->font_family.set) { + family_style = style->text->font_family.value; + //std::cout << " family style from font_family: " << family_style << std::endl; + } + else if (style->text->font_specification.set) { + family_style = style->text->font_specification.value; + //std::cout << " family style from font_spec: " << family_style << std::endl; + } - for (SPObject *child = r->firstChild(); child; child = child->getNext()) { - sp_text_toolbox_get_font_list_in_doc_recursive( child, l ); + if (family_style.compare( family ) == 0 ) { + //std::cout << " found: " << item->getId() << std::endl; + selectList = g_slist_prepend (selectList, item); + } } + } + + // Update selection + Inkscape::Selection *selection = sp_desktop_selection (desktop ); + selection->clear(); + //std::cout << " list length: " << g_slist_length ( selectList ) << std::endl; + selection->setList(selectList); } @@ -1526,8 +1244,16 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje (gpointer)font_lister_separator_func, GTK_WIDGET(desktop->canvas)); // Focus widget ink_comboboxentry_action_popup_enable( act ); // Enable entry completion + + gchar *const info = _("Select all text with this font-family"); + ink_comboboxentry_action_set_info( act, info ); // Show selection icon + ink_comboboxentry_action_set_info_cb( act, (gpointer)sp_text_toolbox_select_cb ); + gchar *const warning = _("Font not found on system"); - ink_comboboxentry_action_set_warning( act, warning ); // Show icon with tooltip if missing font + ink_comboboxentry_action_set_warning( act, warning ); // Show icon w/ tooltip if font missing + ink_comboboxentry_action_set_warning_cb( act, (gpointer)sp_text_toolbox_select_cb ); + + //ink_comboboxentry_action_set_warning_callback( act, sp_text_fontfamily_select_all ); ink_comboboxentry_action_set_altx_name( act, "altx-text" ); // Set Alt-X keyboard shortcut g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontfamily_value_changed), holder ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); @@ -1577,18 +1303,20 @@ void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObje /* Font styles */ { - GtkListStore* model_style = gtk_list_store_new( 1, G_TYPE_STRING ); + Inkscape::FontLister* fontlister = Inkscape::FontLister::get_instance(); + Glib::RefPtr<Gtk::ListStore> store = fontlister->get_style_list(); + GtkListStore* model_style = store->gobj(); - Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontStyleAction", + Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontStyleAction", _("Font Style"), _("Font style"), NULL, GTK_TREE_MODEL(model_style), 12, // Width in characters - 0, // Extra list width - NULL, // Cell layout - NULL, // Separator - GTK_WIDGET(desktop->canvas)); // Focus widget + 0, // Extra list width + NULL, // Cell layout + NULL, // Separator + GTK_WIDGET(desktop->canvas)); // Focus widget g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontstyle_value_changed), holder ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); |
