diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-04-07 23:42:04 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2011-04-07 23:42:04 +0000 |
| commit | 945ce419c806c73d70203dec33ececafbe108a92 (patch) | |
| tree | cfcdb59bf47e9db7f9e01f7eebb59924bdeaea94 /src/widgets | |
| parent | Merge from trunk (again) (diff) | |
| parent | Extensions. SVG+media fix (see Bug #400356). (diff) | |
| download | inkscape-945ce419c806c73d70203dec33ececafbe108a92.tar.gz inkscape-945ce419c806c73d70203dec33ececafbe108a92.zip | |
Merge from trunk
(bzr r9508.1.73)
Diffstat (limited to 'src/widgets')
| -rw-r--r-- | src/widgets/desktop-widget.cpp | 56 | ||||
| -rw-r--r-- | src/widgets/desktop-widget.h | 3 | ||||
| -rw-r--r-- | src/widgets/gradient-image.h | 1 | ||||
| -rw-r--r-- | src/widgets/gradient-selector.cpp | 12 | ||||
| -rw-r--r-- | src/widgets/gradient-vector.cpp | 76 | ||||
| -rw-r--r-- | src/widgets/gradient-vector.h | 1 | ||||
| -rw-r--r-- | src/widgets/icon.cpp | 644 | ||||
| -rw-r--r-- | src/widgets/icon.h | 26 | ||||
| -rw-r--r-- | src/widgets/paint-selector.cpp | 12 | ||||
| -rw-r--r-- | src/widgets/select-toolbar.cpp | 2 | ||||
| -rw-r--r-- | src/widgets/sp-attribute-widget.cpp | 20 | ||||
| -rw-r--r-- | src/widgets/sp-attribute-widget.h | 1 | ||||
| -rw-r--r-- | src/widgets/sp-color-notebook.cpp | 1 | ||||
| -rw-r--r-- | src/widgets/spw-utilities.cpp | 14 | ||||
| -rw-r--r-- | src/widgets/spw-utilities.h | 3 | ||||
| -rw-r--r-- | src/widgets/stroke-style.cpp | 84 | ||||
| -rw-r--r-- | src/widgets/swatch-selector.cpp | 6 | ||||
| -rw-r--r-- | src/widgets/toolbox.cpp | 308 |
18 files changed, 797 insertions, 473 deletions
diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp index 7a3e337de..63fdc5930 100644 --- a/src/widgets/desktop-widget.cpp +++ b/src/widgets/desktop-widget.cpp @@ -33,6 +33,7 @@ #include "desktop-events.h" #include "desktop-handles.h" #include "desktop-widget.h" +#include "display/sp-canvas.h" #include "display/canvas-arena.h" #include "display/nr-arena.h" #include "document.h" @@ -56,6 +57,7 @@ #include "ui/widget/layer-selector.h" #include "ui/widget/selected-style.h" #include "ui/uxmanager.h" +#include "util/ege-appear-time-tracker.h" // We're in the "widgets" directory, so no need to explicitly prefix these: #include "button.h" @@ -73,6 +75,7 @@ using Inkscape::round; using Inkscape::UnitTracker; using Inkscape::UI::UXManager; using Inkscape::UI::ToolboxFactory; +using ege::AppearTimeTracker; #ifdef WITH_INKBOARD #endif @@ -243,6 +246,8 @@ SPDesktopWidget::window_get_pointer() return Geom::Point(x,y); } +static GTimer *overallTimer = 0; + /** * Registers SPDesktopWidget class and returns its type number. */ @@ -263,6 +268,8 @@ GType SPDesktopWidget::getType(void) 0 // value_table }; type = g_type_register_static(SP_TYPE_VIEW_WIDGET, "SPDesktopWidget", &info, static_cast<GTypeFlags>(0)); + // Begin a timer to watch for the first desktop to appear on-screen + overallTimer = g_timer_new(); } return type; } @@ -564,6 +571,18 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw ) gtk_widget_show_all (dtw->vbox); gtk_widget_grab_focus (GTK_WIDGET(dtw->canvas)); + + // If this is the first desktop created, report the time it takes to show up + if ( overallTimer ) { + if ( prefs->getBool("/dialogs/debug/trackAppear", false) ) { + // Time tracker takes ownership of the timer. + AppearTimeTracker *tracker = new AppearTimeTracker(overallTimer, GTK_WIDGET(dtw), "first SPDesktopWidget"); + tracker->setAutodelete(true); + } else { + g_timer_destroy(overallTimer); + } + overallTimer = 0; + } } /** @@ -619,25 +638,37 @@ SPDesktopWidget::updateTitle(gchar const* uri) ? uri : g_basename(uri) ); GString *name = g_string_new (""); + + gchar const *grayscalename = "(grayscale) "; + gchar const *grayscalenamecomma = ", grayscale"; + gchar const *printcolorsname = "(print colors preview) "; + gchar const *printcolorsnamecomma = ", print colors preview"; + gchar const *colormodename = ""; + gchar const *colormodenamecomma = ""; + + if (this->desktop->getColorMode() == Inkscape::COLORRENDERMODE_GRAYSCALE) { + colormodename = grayscalename; + colormodenamecomma = grayscalenamecomma; + } else if (this->desktop->getColorMode() == Inkscape::COLORRENDERMODE_PRINT_COLORS_PREVIEW) { + colormodename = printcolorsname; + colormodenamecomma = printcolorsnamecomma; + } + if (this->desktop->number > 1) { if (this->desktop->getMode() == Inkscape::RENDERMODE_OUTLINE) { - g_string_printf (name, _("%s: %d (outline) - Inkscape"), fname, this->desktop->number); + g_string_printf (name, _("%s: %d (outline%s) - Inkscape"), fname, this->desktop->number, colormodenamecomma); } else if (this->desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) { - g_string_printf (name, _("%s: %d (no filters) - Inkscape"), fname, this->desktop->number); - } else if (this->desktop->getMode() == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW) { - g_string_printf (name, _("%s: %d (print colors preview) - Inkscape"), fname, this->desktop->number); + g_string_printf (name, _("%s: %d (no filters%s) - Inkscape"), fname, this->desktop->number, colormodenamecomma); } else { - g_string_printf (name, _("%s: %d - Inkscape"), fname, this->desktop->number); + g_string_printf (name, _("%s: %d %s- Inkscape"), fname, this->desktop->number, colormodename); } } else { if (this->desktop->getMode() == Inkscape::RENDERMODE_OUTLINE) { - g_string_printf (name, _("%s (outline) - Inkscape"), fname); + g_string_printf (name, _("%s (outline%s) - Inkscape"), fname, colormodenamecomma); } else if (this->desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) { - g_string_printf (name, _("%s (no filters) - Inkscape"), fname); - } else if (this->desktop->getMode() == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW) { - g_string_printf (name, _("%s (print colors preview) - Inkscape"), fname); + g_string_printf (name, _("%s (no filters%s) - Inkscape"), fname, colormodenamecomma); } else { - g_string_printf (name, _("%s - Inkscape"), fname); + g_string_printf (name, _("%s %s- Inkscape"), fname, colormodename); } } window->set_title (name->str); @@ -912,10 +943,9 @@ SPDesktopWidget::shutdown() GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_NONE, - _("<span weight=\"bold\" size=\"larger\">The file \"%s\" was saved with a format (%s) that may cause data loss!</span>\n\n" + _("<span weight=\"bold\" size=\"larger\">The file \"%s\" was saved with a format that may cause data loss!</span>\n\n" "Do you want to save this file as Inkscape SVG?"), - doc->getName() ? doc->getName() : "Unnamed", - SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE); + doc->getName() ? doc->getName() : "Unnamed"); // fix for bug 1767940: GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(GTK_MESSAGE_DIALOG(dialog)->label), GTK_CAN_FOCUS); diff --git a/src/widgets/desktop-widget.h b/src/widgets/desktop-widget.h index 4edd434af..0102897e5 100644 --- a/src/widgets/desktop-widget.h +++ b/src/widgets/desktop-widget.h @@ -15,7 +15,6 @@ #include <gtk/gtktooltips.h> #include <gtk/gtkwindow.h> -#include "display/display-forward.h" #include "libnr/nr-point.h" #include "forward.h" #include "sp-object.h" @@ -23,10 +22,12 @@ #include "ui/view/view-widget.h" #include "ui/view/edit-widget-interface.h" +#include <stddef.h> #include <sigc++/connection.h> // forward declaration typedef struct _EgeColorProfTracker EgeColorProfTracker; +struct SPCanvas; #define SP_TYPE_DESKTOP_WIDGET SPDesktopWidget::getType() diff --git a/src/widgets/gradient-image.h b/src/widgets/gradient-image.h index 3ddd14e35..e098beab4 100644 --- a/src/widgets/gradient-image.h +++ b/src/widgets/gradient-image.h @@ -18,6 +18,7 @@ class SPGradient; #include <glib.h> +#include <stddef.h> #include <sigc++/connection.h> #define SP_TYPE_GRADIENT_IMAGE (sp_gradient_image_get_type ()) diff --git a/src/widgets/gradient-selector.cpp b/src/widgets/gradient-selector.cpp index 49549de1c..f7a981c9f 100644 --- a/src/widgets/gradient-selector.cpp +++ b/src/widgets/gradient-selector.cpp @@ -259,7 +259,7 @@ SPGradientSpread SPGradientSelector::getSpread() void SPGradientSelector::setVector(SPDocument *doc, SPGradient *vector) { g_return_if_fail(!vector || SP_IS_GRADIENT(vector)); - g_return_if_fail(!vector || (SP_OBJECT_DOCUMENT(vector) == doc)); + g_return_if_fail(!vector || (vector->document == doc)); if (vector && !vector->hasStops()) { return; @@ -312,7 +312,7 @@ sp_gradient_selector_vector_set (SPGradientVectorSelector */*gvs*/, SPGradient * if (!blocked) { blocked = TRUE; gr = sp_gradient_ensure_vector_normalized (gr); - sel->setVector((gr) ? SP_OBJECT_DOCUMENT (gr) : 0, gr); + sel->setVector((gr) ? gr->document : 0, gr); g_signal_emit (G_OBJECT (sel), signals[CHANGED], 0, gr); blocked = FALSE; } @@ -344,9 +344,9 @@ sp_gradient_selector_add_vector_clicked (GtkWidget */*w*/, SPGradientSelector *s Inkscape::XML::Node *repr = NULL; - if (gr) - repr = SP_OBJECT_REPR (gr)->duplicate(xml_doc); - else { + if (gr) { + repr = gr->getRepr()->duplicate(xml_doc); + } else { repr = xml_doc->createElement("svg:linearGradient"); Inkscape::XML::Node *stop = xml_doc->createElement("svg:stop"); stop->setAttribute("offset", "0"); @@ -360,7 +360,7 @@ sp_gradient_selector_add_vector_clicked (GtkWidget */*w*/, SPGradientSelector *s Inkscape::GC::release(stop); } - SP_OBJECT_REPR (SP_DOCUMENT_DEFS (doc))->addChild(repr, NULL); + SP_DOCUMENT_DEFS(doc)->getRepr()->addChild(repr, NULL); gr = (SPGradient *) doc->getObjectByRepr(repr); sp_gradient_vector_selector_set_gradient( diff --git a/src/widgets/gradient-vector.cpp b/src/widgets/gradient-vector.cpp index dbb934fb1..737b3d7bb 100644 --- a/src/widgets/gradient-vector.cpp +++ b/src/widgets/gradient-vector.cpp @@ -162,7 +162,7 @@ GtkWidget *sp_gradient_vector_selector_new(SPDocument *doc, SPGradient *gr) GtkWidget *gvs; g_return_val_if_fail(!gr || SP_IS_GRADIENT(gr), NULL); - g_return_val_if_fail(!gr || (SP_OBJECT_DOCUMENT(gr) == doc), NULL); + g_return_val_if_fail(!gr || (gr->document == doc), NULL); gvs = static_cast<GtkWidget*>(gtk_type_new(SP_TYPE_GRADIENT_VECTOR_SELECTOR)); @@ -187,7 +187,7 @@ void sp_gradient_vector_selector_set_gradient(SPGradientVectorSelector *gvs, SPD g_return_if_fail(SP_IS_GRADIENT_VECTOR_SELECTOR(gvs)); g_return_if_fail(!gr || (doc != NULL)); g_return_if_fail(!gr || SP_IS_GRADIENT(gr)); - g_return_if_fail(!gr || (SP_OBJECT_DOCUMENT(gr) == doc)); + g_return_if_fail(!gr || (gr->document == doc)); g_return_if_fail(!gr || gr->hasStops()); if (doc != gvs->doc) { @@ -256,7 +256,7 @@ static void sp_gvs_rebuild_gui_full(SPGradientVectorSelector *gvs) /* Pick up all gradients with vectors */ GSList *gl = NULL; if (gvs->gr) { - const GSList *gradients = SP_OBJECT_DOCUMENT(gvs->gr)->getResourceList("gradient"); + const GSList *gradients = gvs->gr->document->getResourceList("gradient"); for (const GSList *curr = gradients; curr; curr = curr->next) { SPGradient* grad = SP_GRADIENT(curr->data); if ( grad->hasStops() && (grad->isSwatch() == gvs->swatched) ) { @@ -371,7 +371,7 @@ static void sp_gvs_gradient_activate(GtkMenuItem *mi, SPGradientVectorSelector * /* We do extra undo push here */ /* If handler has already done it, it is just NOP */ // FIXME: looks like this is never a valid undo step, consider removing this - DocumentUndo::done(SP_OBJECT_DOCUMENT(norm), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(norm->document, SP_VERB_CONTEXT_GRADIENT, /* TODO: annotate */ "gradient-vector.cpp:350"); } } @@ -479,7 +479,7 @@ static void verify_grad(SPGradient *gradient) } Inkscape::XML::Document *xml_doc; - xml_doc = SP_OBJECT_REPR(gradient)->document(); + xml_doc = gradient->getRepr()->document(); if (i < 1) { Inkscape::CSSOStringStream os; @@ -490,20 +490,20 @@ static void verify_grad(SPGradient *gradient) child = xml_doc->createElement("svg:stop"); sp_repr_set_css_double(child, "offset", 0.0); child->setAttribute("style", os.str().c_str()); - SP_OBJECT_REPR(gradient)->addChild(child, NULL); + gradient->getRepr()->addChild(child, NULL); Inkscape::GC::release(child); child = xml_doc->createElement("svg:stop"); sp_repr_set_css_double(child, "offset", 1.0); child->setAttribute("style", os.str().c_str()); - SP_OBJECT_REPR(gradient)->addChild(child, NULL); + gradient->getRepr()->addChild(child, NULL); Inkscape::GC::release(child); } if (i < 2) { - sp_repr_set_css_double(SP_OBJECT_REPR(stop), "offset", 0.0); - Inkscape::XML::Node *child = SP_OBJECT_REPR(stop)->duplicate(SP_OBJECT_REPR(gradient)->document()); + sp_repr_set_css_double(stop->getRepr(), "offset", 0.0); + Inkscape::XML::Node *child = stop->getRepr()->duplicate(gradient->getRepr()->document()); sp_repr_set_css_double(child, "offset", 1.0); - SP_OBJECT_REPR(gradient)->addChild(child, SP_OBJECT_REPR(stop)); + gradient->getRepr()->addChild(child, stop->getRepr()); Inkscape::GC::release(child); } } @@ -513,7 +513,7 @@ static void select_stop_in_list( GtkWidget *mnu, SPGradient *gradient, SPStop *n int i = 0; for ( SPObject *ochild = gradient->firstChild() ; ochild ; ochild = ochild->getNext() ) { if (SP_IS_STOP(ochild)) { - if (SP_OBJECT(ochild) == SP_OBJECT(new_stop)) { + if (ochild == new_stop) { gtk_option_menu_set_history(GTK_OPTION_MENU(mnu), i); break; } @@ -566,7 +566,7 @@ static void update_stop_list( GtkWidget *mnu, SPGradient *gradient, SPStop *new_ gtk_widget_show(cpv); gtk_container_add( GTK_CONTAINER(hb), cpv ); g_object_set_data( G_OBJECT(i), "preview", cpv ); - Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) sl->data); + Inkscape::XML::Node *repr = reinterpret_cast<SPItem *>(sl->data)->getRepr(); GtkWidget *l = gtk_label_new(repr->attribute("id")); gtk_widget_show(l); gtk_misc_set_alignment(GTK_MISC(l), 1.0, 0.5); @@ -660,9 +660,9 @@ static void offadjustmentChanged( GtkAdjustment *adjustment, GtkWidget *vb) SPStop *stop = SP_STOP(g_object_get_data(G_OBJECT(gtk_menu_get_active(GTK_MENU(gtk_option_menu_get_menu(mnu)))), "stop")); stop->offset = adjustment->value; - sp_repr_set_css_double(SP_OBJECT_REPR(stop), "offset", stop->offset); + sp_repr_set_css_double(stop->getRepr(), "offset", stop->offset); - DocumentUndo::maybeDone(SP_OBJECT_DOCUMENT(stop), "gradient:stop:offset", SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::maybeDone(stop->document, "gradient:stop:offset", SP_VERB_CONTEXT_GRADIENT, _("Change gradient stop offset")); blocked = FALSE; @@ -706,15 +706,15 @@ static void sp_grd_ed_add_stop(GtkWidget */*widget*/, GtkWidget *vb) } if (next != NULL) { - new_stop_repr = SP_OBJECT_REPR(stop)->duplicate(SP_OBJECT_REPR(gradient)->document()); - SP_OBJECT_REPR(gradient)->addChild(new_stop_repr, SP_OBJECT_REPR(stop)); + new_stop_repr = stop->getRepr()->duplicate(gradient->getRepr()->document()); + gradient->getRepr()->addChild(new_stop_repr, stop->getRepr()); } else { next = stop; - new_stop_repr = SP_OBJECT_REPR(stop->getPrevStop())->duplicate(SP_OBJECT_REPR(gradient)->document()); - SP_OBJECT_REPR(gradient)->addChild(new_stop_repr, SP_OBJECT_REPR(stop->getPrevStop())); + new_stop_repr = stop->getPrevStop()->getRepr()->duplicate(gradient->getRepr()->document()); + gradient->getRepr()->addChild(new_stop_repr, stop->getPrevStop()->getRepr()); } - SPStop *newstop = (SPStop *) SP_OBJECT_DOCUMENT(gradient)->getObjectByRepr(new_stop_repr); + SPStop *newstop = reinterpret_cast<SPStop *>(gradient->document->getObjectByRepr(new_stop_repr)); newstop->offset = (stop->offset + next->offset) * 0.5 ; @@ -727,8 +727,8 @@ static void sp_grd_ed_add_stop(GtkWidget */*widget*/, GtkWidget *vb) sp_svg_write_color(c, sizeof(c), cnew); gdouble opacity = static_cast<gdouble>(SP_RGBA32_A_F(cnew)); os << "stop-color:" << c << ";stop-opacity:" << opacity <<";"; - SP_OBJECT_REPR (newstop)->setAttribute("style", os.str().c_str()); - sp_repr_set_css_double( SP_OBJECT_REPR(newstop), "offset", (double)newstop->offset); + newstop->getRepr()->setAttribute("style", os.str().c_str()); + sp_repr_set_css_double( newstop->getRepr(), "offset", (double)newstop->offset); sp_gradient_vector_widget_load_gradient(vb, gradient); Inkscape::GC::release(new_stop_repr); @@ -737,7 +737,7 @@ static void sp_grd_ed_add_stop(GtkWidget */*widget*/, GtkWidget *vb) GtkWidget *offslide =GTK_WIDGET(g_object_get_data(G_OBJECT(vb), "offslide")); gtk_widget_set_sensitive(offslide, TRUE); gtk_widget_set_sensitive(GTK_WIDGET(offspin), TRUE); - DocumentUndo::done(SP_OBJECT_DOCUMENT(gradient), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(gradient->document, SP_VERB_CONTEXT_GRADIENT, _("Add gradient stop")); } @@ -755,20 +755,20 @@ static void sp_grd_ed_del_stop(GtkWidget */*widget*/, GtkWidget *vb) SPStop *next = stop->getNextStop(); if (next) { next->offset = 0; - sp_repr_set_css_double(SP_OBJECT_REPR(next), "offset", 0); + sp_repr_set_css_double(next->getRepr(), "offset", 0); } } else if (stop->offset == 1) { SPStop *prev = stop->getPrevStop(); if (prev) { prev->offset = 1; - sp_repr_set_css_double(SP_OBJECT_REPR(prev), "offset", 1); + sp_repr_set_css_double(prev->getRepr(), "offset", 1); } } - SP_OBJECT_REPR(gradient)->removeChild(SP_OBJECT_REPR(stop)); + gradient->getRepr()->removeChild(stop->getRepr()); sp_gradient_vector_widget_load_gradient(vb, gradient); update_stop_list(GTK_WIDGET(mnu), gradient, NULL); - DocumentUndo::done(SP_OBJECT_DOCUMENT(gradient), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(gradient->document, SP_VERB_CONTEXT_GRADIENT, _("Delete gradient stop")); } @@ -788,7 +788,7 @@ static GtkWidget * sp_gradient_vector_widget_new(SPGradient *gradient, SPStop *s gtk_widget_show(w); gtk_box_pack_start(GTK_BOX(vb), w, TRUE, TRUE, PAD); - sp_repr_add_listener(SP_OBJECT_REPR(gradient), &grad_edit_dia_repr_events, vb); + sp_repr_add_listener(gradient->getRepr(), &grad_edit_dia_repr_events, vb); GtkTooltips *tt = gtk_tooltips_new(); /* Stop list */ @@ -1032,11 +1032,11 @@ static void sp_gradient_vector_widget_load_gradient(GtkWidget *widget, SPGradien update_stop_list(GTK_WIDGET(mnu), gradient, NULL); // Once the user edits a gradient, it stops being auto-collectable - if (SP_OBJECT_REPR(gradient)->attribute("inkscape:collect")) { - SPDocument *document = SP_OBJECT_DOCUMENT(gradient); + if (gradient->getRepr()->attribute("inkscape:collect")) { + SPDocument *document = gradient->document; bool saved = DocumentUndo::getUndoSensitive(document); DocumentUndo::setUndoSensitive(document, false); - SP_OBJECT_REPR(gradient)->setAttribute("inkscape:collect", NULL); + gradient->getRepr()->setAttribute("inkscape:collect", NULL); DocumentUndo::setUndoSensitive(document, saved); } } else { // no gradient, disable everything @@ -1078,9 +1078,7 @@ static gboolean sp_gradient_vector_dialog_delete(GtkWidget */*widget*/, GdkEvent static void sp_gradient_vector_widget_destroy(GtkObject *object, gpointer /*data*/) { - GObject *gradient; - - gradient = (GObject*)g_object_get_data(G_OBJECT(object), "gradient"); + SPObject *gradient = reinterpret_cast<SPObject*>(g_object_get_data(G_OBJECT(object), "gradient")); sigc::connection *release_connection = (sigc::connection *)g_object_get_data(G_OBJECT(object), "gradient_release_connection"); sigc::connection *modified_connection = (sigc::connection *)g_object_get_data(G_OBJECT(object), "gradient_modified_connection"); @@ -1093,8 +1091,8 @@ static void sp_gradient_vector_widget_destroy(GtkObject *object, gpointer /*data sp_signal_disconnect_by_data(gradient, object); } - if (gradient && SP_OBJECT_REPR(gradient)) { - sp_repr_remove_listener_by_data(SP_OBJECT_REPR(gradient), object); + if (gradient && gradient->getRepr()) { + sp_repr_remove_listener_by_data(gradient->getRepr(), object); } } @@ -1179,14 +1177,14 @@ static void sp_gradient_vector_color_changed(SPColorSelector *csel, GtkObject *o float alpha = 0; csel->base->getColorAlpha( color, alpha ); - sp_repr_set_css_double(SP_OBJECT_REPR(stop), "offset", stop->offset); + sp_repr_set_css_double(stop->getRepr(), "offset", stop->offset); Inkscape::CSSOStringStream os; os << "stop-color:" << color.toString() << ";stop-opacity:" << static_cast<gdouble>(alpha) <<";"; - SP_OBJECT_REPR(stop)->setAttribute("style", os.str().c_str()); + stop->getRepr()->setAttribute("style", os.str().c_str()); // g_snprintf(c, 256, "stop-color:#%06x;stop-opacity:%g;", rgb >> 8, static_cast<gdouble>(alpha)); - //SP_OBJECT_REPR(stop)->setAttribute("style", c); + //stop->getRepr()->setAttribute("style", c); - DocumentUndo::done(SP_OBJECT_DOCUMENT(ngr), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(ngr->document, SP_VERB_CONTEXT_GRADIENT, _("Change gradient stop color")); blocked = FALSE; diff --git a/src/widgets/gradient-vector.h b/src/widgets/gradient-vector.h index 9147f9cc1..012d4e9a3 100644 --- a/src/widgets/gradient-vector.h +++ b/src/widgets/gradient-vector.h @@ -17,6 +17,7 @@ #include <glib.h> +#include <stddef.h> #include <sigc++/connection.h> #include <gtk/gtkvbox.h> diff --git a/src/widgets/icon.cpp b/src/widgets/icon.cpp index 1b6878c32..88cf43588 100644 --- a/src/widgets/icon.cpp +++ b/src/widgets/icon.cpp @@ -18,8 +18,11 @@ #include <cstring> #include <glib/gmem.h> +#include <glib/gstdio.h> #include <gtk/gtk.h> #include <gtkmm.h> +#include <gdkmm/pixbuf.h> +#include <glibmm/fileutils.h> #include "path-prefix.h" #include "preferences.h" @@ -33,36 +36,76 @@ #include "icon.h" -static gboolean icon_prerender_task(gpointer data); +// Bring in work-around for Glib versions missing GStatBuf +#if !GLIB_CHECK_VERSION(2,25,0) +#if defined (_MSC_VER) && !defined(_WIN64) +typedef struct _stat32 GStatBuf; +#else //defined (_MSC_VER) && !defined(_WIN64) +typedef struct stat GStatBuf; +#endif //defined (_MSC_VER) && !defined(_WIN64) +#endif //!GLIB_CHECK_VERSION(2,25,0) -static void addPreRender( GtkIconSize lsize, gchar const *name ); +struct IconImpl { + static void classInit(SPIconClass *klass); + static void init(SPIcon *icon); -static void sp_icon_class_init(SPIconClass *klass); -static void sp_icon_init(SPIcon *icon); -static void sp_icon_dispose(GObject *object); + static GtkWidget *newFull( Inkscape::IconSize lsize, gchar const *name ); -static void sp_icon_reset(SPIcon *icon); -static void sp_icon_clear(SPIcon *icon); + static void dispose(GObject *object); -static void sp_icon_size_request(GtkWidget *widget, GtkRequisition *requisition); -static void sp_icon_size_allocate(GtkWidget *widget, GtkAllocation *allocation); -static int sp_icon_expose(GtkWidget *widget, GdkEventExpose *event); + static void reset(SPIcon *icon); + static void clear(SPIcon *icon); -static void sp_icon_paint(SPIcon *icon, GdkRectangle const *area); + static void sizeRequest(GtkWidget *widget, GtkRequisition *requisition); + static void sizeAllocate(GtkWidget *widget, GtkAllocation *allocation); + static int expose(GtkWidget *widget, GdkEventExpose *event); -static void sp_icon_screen_changed( GtkWidget *widget, GdkScreen *previous_screen ); -static void sp_icon_style_set( GtkWidget *widget, GtkStyle *previous_style ); -static void sp_icon_theme_changed( SPIcon *icon ); + static void paint(SPIcon *icon, GdkRectangle const *area); -static GdkPixbuf *sp_icon_image_load_pixmap(gchar const *name, unsigned lsize, unsigned psize); -static GdkPixbuf *sp_icon_image_load_svg(gchar const *name, GtkIconSize lsize, unsigned psize); + static void screenChanged( GtkWidget *widget, GdkScreen *previous_screen ); + static void styleSet( GtkWidget *widget, GtkStyle *previous_style ); + static void themeChanged( SPIcon *icon ); -static void sp_icon_overlay_pixels( guchar *px, int width, int height, int stride, - unsigned r, unsigned g, unsigned b ); + static int getPhysSize(int size); + static void fetchPixbuf( SPIcon *icon ); -static void injectCustomSize(); + static gboolean prerenderTask(gpointer data); + static void addPreRender( GtkIconSize lsize, gchar const *name ); + static GdkPixbuf* renderup( gchar const* name, Inkscape::IconSize lsize, unsigned psize ); + + + static GdkPixbuf *loadPixmap(gchar const *name, unsigned lsize, unsigned psize); + static GdkPixbuf *loadSvg(std::list<Glib::ustring> const &names, GtkIconSize lsize, unsigned psize); + + static void overlayPixels( guchar *px, int width, int height, int stride, + unsigned r, unsigned g, unsigned b ); + + static void injectCustomSize(); + + static void imageMapCB(GtkWidget* widget, gpointer user_data); + static void imageMapNamedCB(GtkWidget* widget, gpointer user_data); + static bool prerenderIcon(gchar const *name, GtkIconSize lsize, unsigned psize); + + + static std::list<gchar*> &icons_svg_paths(); + static guchar *load_svg_pixels(std::list<Glib::ustring> const &names, + unsigned psize, unsigned &stride); + + static std::string fileEscape( std::string const & str ); + + static void validateCache(); + static void setupLegacyNaming(); + +private: + static const std::string magicNumber; + static GtkWidgetClass *parent_class; + static std::map<Glib::ustring, Glib::ustring> legacyNames; +}; + +const std::string IconImpl::magicNumber = "1.0"; +GtkWidgetClass *IconImpl::parent_class = 0; +std::map<Glib::ustring, Glib::ustring> IconImpl::legacyNames; -static GtkWidgetClass *parent_class; static bool sizeDirty = true; @@ -78,8 +121,6 @@ static GtkIconSize iconSizeLookup[] = { GTK_ICON_SIZE_MENU, // for Inkscape::ICON_SIZE_DECORATION }; -static std::map<Glib::ustring, Glib::ustring> legacyNames; - class IconCacheItem { public: @@ -94,8 +135,7 @@ public: static std::map<Glib::ustring, std::vector<IconCacheItem> > iconSetCache; static std::set<Glib::ustring> internalNames; -GType -sp_icon_get_type() +GType SPIcon::getType() { static GType type = 0; if (!type) { @@ -103,12 +143,12 @@ sp_icon_get_type() sizeof(SPIconClass), NULL, NULL, - (GClassInitFunc) sp_icon_class_init, + reinterpret_cast<GClassInitFunc>(IconImpl::classInit), NULL, NULL, sizeof(SPIcon), 0, - (GInstanceInitFunc) sp_icon_init, + reinterpret_cast<GInstanceInitFunc>(IconImpl::init), NULL }; type = g_type_register_static(GTK_TYPE_WIDGET, "SPIcon", &info, (GTypeFlags)0); @@ -116,8 +156,7 @@ sp_icon_get_type() return type; } -static void -sp_icon_class_init(SPIconClass *klass) +void IconImpl::classInit(SPIconClass *klass) { GObjectClass *object_class; GtkWidgetClass *widget_class; @@ -127,18 +166,16 @@ sp_icon_class_init(SPIconClass *klass) parent_class = (GtkWidgetClass*)g_type_class_peek_parent(klass); - object_class->dispose = sp_icon_dispose; + object_class->dispose = IconImpl::dispose; - widget_class->size_request = sp_icon_size_request; - widget_class->size_allocate = sp_icon_size_allocate; - widget_class->expose_event = sp_icon_expose; - widget_class->screen_changed = sp_icon_screen_changed; - widget_class->style_set = sp_icon_style_set; + widget_class->size_request = IconImpl::sizeRequest; + widget_class->size_allocate = IconImpl::sizeAllocate; + widget_class->expose_event = IconImpl::expose; + widget_class->screen_changed = IconImpl::screenChanged; + widget_class->style_set = IconImpl::styleSet; } - -static void -sp_icon_init(SPIcon *icon) +void IconImpl::init(SPIcon *icon) { GTK_WIDGET_FLAGS(icon) |= GTK_NO_WINDOW; icon->lsize = Inkscape::ICON_SIZE_BUTTON; @@ -147,11 +184,10 @@ sp_icon_init(SPIcon *icon) icon->pb = 0; } -static void -sp_icon_dispose(GObject *object) +void IconImpl::dispose(GObject *object) { SPIcon *icon = SP_ICON(object); - sp_icon_clear(icon); + clear(icon); if ( icon->name ) { g_free( icon->name ); icon->name = 0; @@ -160,32 +196,32 @@ sp_icon_dispose(GObject *object) ((GObjectClass *) (parent_class))->dispose(object); } -static void sp_icon_reset( SPIcon *icon ) { +void IconImpl::reset( SPIcon *icon ) +{ icon->psize = 0; - sp_icon_clear(icon); + clear(icon); } -static void sp_icon_clear( SPIcon *icon ) { +void IconImpl::clear( SPIcon *icon ) +{ if (icon->pb) { g_object_unref(G_OBJECT(icon->pb)); icon->pb = NULL; } } -static void -sp_icon_size_request(GtkWidget *widget, GtkRequisition *requisition) +void IconImpl::sizeRequest(GtkWidget *widget, GtkRequisition *requisition) { SPIcon const *icon = SP_ICON(widget); int const size = ( icon->psize ? icon->psize - : sp_icon_get_phys_size(icon->lsize) ); + : getPhysSize(icon->lsize) ); requisition->width = size; requisition->height = size; } -static void -sp_icon_size_allocate(GtkWidget *widget, GtkAllocation *allocation) +void IconImpl::sizeAllocate(GtkWidget *widget, GtkAllocation *allocation) { widget->allocation = *allocation; @@ -194,34 +230,37 @@ sp_icon_size_allocate(GtkWidget *widget, GtkAllocation *allocation) } } -static int sp_icon_expose(GtkWidget *widget, GdkEventExpose *event) +int IconImpl::expose(GtkWidget *widget, GdkEventExpose *event) { if ( GTK_WIDGET_DRAWABLE(widget) ) { SPIcon *icon = SP_ICON(widget); if ( !icon->pb ) { - sp_icon_fetch_pixbuf( icon ); + fetchPixbuf( icon ); } - sp_icon_paint(SP_ICON(widget), &event->area); + paint(icon, &event->area); } return TRUE; } -static GdkPixbuf* renderup( gchar const* name, Inkscape::IconSize lsize, unsigned psize ); - // PUBLIC CALL: void sp_icon_fetch_pixbuf( SPIcon *icon ) { + return IconImpl::fetchPixbuf(icon); +} + +void IconImpl::fetchPixbuf( SPIcon *icon ) +{ if ( icon ) { if ( !icon->pb ) { - icon->psize = sp_icon_get_phys_size(icon->lsize); + icon->psize = getPhysSize(icon->lsize); icon->pb = renderup(icon->name, icon->lsize, icon->psize); } } } -GdkPixbuf* renderup( gchar const* name, Inkscape::IconSize lsize, unsigned psize ) { +GdkPixbuf* IconImpl::renderup( gchar const* name, Inkscape::IconSize lsize, unsigned psize ) { GtkIconTheme *theme = gtk_icon_theme_get_default(); GdkPixbuf *pb = 0; @@ -229,21 +268,24 @@ GdkPixbuf* renderup( gchar const* name, Inkscape::IconSize lsize, unsigned psize pb = gtk_icon_theme_load_icon(theme, name, psize, (GtkIconLookupFlags) 0, NULL); } if (!pb) { - pb = sp_icon_image_load_svg( name, Inkscape::getRegisteredIconSize(lsize), psize ); - if (!pb && (legacyNames.find(name) != legacyNames.end())) { + std::list<Glib::ustring> names; + names.push_back(name); + if ( legacyNames.find(name) != legacyNames.end() ) { if ( Inkscape::Preferences::get()->getBool("/debug/icons/dumpSvg") ) { g_message("Checking fallback [%s]->[%s]", name, legacyNames[name].c_str()); } - pb = sp_icon_image_load_svg( legacyNames[name].c_str(), Inkscape::getRegisteredIconSize(lsize), psize ); + names.push_back(legacyNames[name]); } + pb = loadSvg( names, Inkscape::getRegisteredIconSize(lsize), psize ); + // if this was loaded from SVG, add it as a builtin icon if (pb) { gtk_icon_theme_add_builtin_icon(name, psize, pb); } } if (!pb) { - pb = sp_icon_image_load_pixmap( name, lsize, psize ); + pb = loadPixmap( name, lsize, psize ); } if ( !pb ) { // TODO: We should do something more useful if we can't load the image. @@ -252,43 +294,176 @@ GdkPixbuf* renderup( gchar const* name, Inkscape::IconSize lsize, unsigned psize return pb; } -static void sp_icon_screen_changed( GtkWidget *widget, GdkScreen *previous_screen ) +void IconImpl::screenChanged( GtkWidget *widget, GdkScreen *previous_screen ) { if ( GTK_WIDGET_CLASS( parent_class )->screen_changed ) { GTK_WIDGET_CLASS( parent_class )->screen_changed( widget, previous_screen ); } SPIcon *icon = SP_ICON(widget); - sp_icon_theme_changed(icon); + themeChanged(icon); } -static void sp_icon_style_set( GtkWidget *widget, GtkStyle *previous_style ) +void IconImpl::styleSet( GtkWidget *widget, GtkStyle *previous_style ) { if ( GTK_WIDGET_CLASS( parent_class )->style_set ) { GTK_WIDGET_CLASS( parent_class )->style_set( widget, previous_style ); } SPIcon *icon = SP_ICON(widget); - sp_icon_theme_changed(icon); + themeChanged(icon); } -static void sp_icon_theme_changed( SPIcon *icon ) +void IconImpl::themeChanged( SPIcon *icon ) { bool const dump = Inkscape::Preferences::get()->getBool("/debug/icons/dumpSvg"); if ( dump ) { g_message("Got a change bump for this icon"); } sizeDirty = true; - sp_icon_reset(icon); + reset(icon); gtk_widget_queue_draw( GTK_WIDGET(icon) ); } +std::string IconImpl::fileEscape( std::string const & str ) +{ + std::string result; + result.reserve(str.size()); + for ( size_t i = 0; i < str.size(); ++i ) { + char ch = str[i]; + if ( (0x20 <= ch) && !(0x80 & ch) ) { + result += ch; + } else { + result += "\\x"; + gchar *tmp = g_strdup_printf("%02X", (0x0ff & ch)); + result += tmp; + g_free(tmp); + } + } + return result; +} -static void imageMapCB(GtkWidget* widget, gpointer user_data); -static void imageMapNamedCB(GtkWidget* widget, gpointer user_data); -static bool prerender_icon(gchar const *name, GtkIconSize lsize, unsigned psize); -static Glib::ustring icon_cache_key(gchar const *name, unsigned psize); +static bool isSizedSubdir( std::string const &name ) +{ + bool isSized = false; + if ( (name.size() > 2) && (name.size() & 1) ) { // needs to be an odd length 3 or more + size_t mid = (name.size() - 1) / 2; + if ( (name[mid] == 'x') && (name.substr(0, mid) == name.substr(mid + 1)) ) { + isSized = true; + for ( size_t i = 0; (i < mid) && isSized; ++i ) { + isSized &= g_ascii_isdigit(name[i]); + } + } + } + return isSized; +} + +void IconImpl::validateCache() +{ + std::list<gchar *> &sources = icons_svg_paths(); + std::string iconCacheDir = Glib::build_filename(Glib::build_filename(Glib::get_user_cache_dir(), "inkscape"), "icons"); + std::string iconCacheFile = Glib::build_filename( iconCacheDir, "cache.info" ); + + std::vector<std::string> filesFound; + + for (std::list<gchar*>::iterator i = sources.begin(); i != sources.end(); ++i) { + gchar const* potentialFile = *i; + if ( Glib::file_test(potentialFile, Glib::FILE_TEST_EXISTS) && Glib::file_test(potentialFile, Glib::FILE_TEST_IS_REGULAR) ) { + filesFound.push_back(*i); + } + } + + unsigned long lastSeen = 0; + std::ostringstream out; + out << "Inkscape cache v" << std::hex << magicNumber << std::dec << std::endl; + out << "Sourcefiles: " << filesFound.size() << std::endl; + for ( std::vector<std::string>::iterator it = filesFound.begin(); it != filesFound.end(); ++it ) { + GStatBuf st; + memset(&st, 0, sizeof(st)); + if ( !g_stat(it->c_str(), &st) ) { + unsigned long when = st.st_mtime; + lastSeen = std::max(lastSeen, when); + out << std::hex << when << std::dec << " " << fileEscape(*it) << std::endl; + } else { + out << "0 " << fileEscape(*it) << std::endl; + } + } + std::string wanted = out.str(); + + std::string present; + { + gchar *contents = 0; + if ( g_file_get_contents(iconCacheFile.c_str(), &contents, 0, 0) ) { + if ( contents ) { + present = contents; + } + g_free(contents); + contents = 0; + } + } + bool cacheValid = (present == wanted); + + if ( cacheValid ) { + // Check if any cached rasters are out of date + Glib::Dir dir(iconCacheDir); + for ( Glib::DirIterator it = dir.begin(); cacheValid && (it != dir.end()); ++it ) { + if ( isSizedSubdir(*it) ) { + std::string subdirName = Glib::build_filename( iconCacheDir, *it ); + if ( Glib::file_test(subdirName, Glib::FILE_TEST_IS_DIR) ) { + Glib::Dir subdir(subdirName); + for ( Glib::DirIterator subit = subdir.begin(); cacheValid && (subit != subdir.end()); ++subit ) { + std::string fullpath = Glib::build_filename( subdirName, *subit ); + if ( Glib::file_test(fullpath, Glib::FILE_TEST_EXISTS) && !Glib::file_test(fullpath, Glib::FILE_TEST_IS_DIR) ) { + GStatBuf st; + memset(&st, 0, sizeof(st)); + if ( !g_stat(fullpath.c_str(), &st) ) { + unsigned long when = st.st_mtime; + if ( when < lastSeen ) { + cacheValid = false; + } + } + } + } + } + } + } + } + + if ( !cacheValid ) { + if ( Glib::file_test(iconCacheDir, Glib::FILE_TEST_EXISTS) ) { + // Purge existing icons, but not possible future sub-directories. + if ( Glib::file_test(iconCacheDir, Glib::FILE_TEST_IS_DIR) ) { + Glib::Dir dir(iconCacheDir); + for ( Glib::DirIterator it = dir.begin(); it != dir.end(); ++it ) { + if ( isSizedSubdir(*it) ) { + std::string subdirName = Glib::build_filename( iconCacheDir, *it ); + if ( Glib::file_test(subdirName, Glib::FILE_TEST_IS_DIR) ) { + Glib::Dir subdir(subdirName); + for ( Glib::DirIterator subit = subdir.begin(); subit != subdir.end(); ++subit ) { + std::string fullpath = Glib::build_filename( subdirName, *subit ); + if ( Glib::file_test(fullpath, Glib::FILE_TEST_EXISTS) && !Glib::file_test(fullpath, Glib::FILE_TEST_IS_DIR) ) { + g_remove(fullpath.c_str()); + } + } + g_rmdir( subdirName.c_str() ); + } + } + } + } + } else { + g_mkdir_with_parents( iconCacheDir.c_str(), 0x1ED ); + } + + if ( g_file_set_contents(iconCacheFile.c_str(), wanted.c_str(), wanted.size(), 0) ) { + // Caching may proceed + } else { + g_warning("Unable to write cache info file."); + } + } +} + +static Glib::ustring icon_cache_key(Glib::ustring const &name, unsigned psize); static GdkPixbuf *get_cached_pixbuf(Glib::ustring const &key); -static void setupLegacyNaming() { +void IconImpl::setupLegacyNaming() { legacyNames["document-import"] ="file_import"; legacyNames["document-export"] ="file_export"; legacyNames["document-import-ocal"] ="ocal_import"; @@ -543,8 +718,7 @@ static void setupLegacyNaming() { legacyNames["zoom"] ="sticky_zoom"; } -static GtkWidget * -sp_icon_new_full( Inkscape::IconSize lsize, gchar const *name ) +GtkWidget *IconImpl::newFull( Inkscape::IconSize lsize, gchar const *name ) { static bool dump = Inkscape::Preferences::get()->getBool("/debug/icons/dumpGtk"); @@ -600,8 +774,8 @@ sp_icon_new_full( Inkscape::IconSize lsize, gchar const *name ) g_signal_connect( G_OBJECT(widget), "map", G_CALLBACK(imageMapNamedCB), GINT_TO_POINTER(0) ); if ( Inkscape::Preferences::get()->getBool("/options/iconrender/named_nodelay") ) { - int psize = sp_icon_get_phys_size(lsize); - prerender_icon(name, mappedSize, psize); + int psize = getPhysSize(lsize); + prerenderIcon(name, mappedSize, psize); } else { addPreRender( mappedSize, name ); } @@ -619,7 +793,7 @@ sp_icon_new_full( Inkscape::IconSize lsize, gchar const *name ) SPIcon *icon = (SPIcon *)g_object_new(SP_TYPE_ICON, NULL); icon->lsize = lsize; icon->name = g_strdup(name); - icon->psize = sp_icon_get_phys_size(lsize); + icon->psize = getPhysSize(lsize); widget = GTK_WIDGET(icon); } @@ -627,17 +801,17 @@ sp_icon_new_full( Inkscape::IconSize lsize, gchar const *name ) return widget; } -GtkWidget * -sp_icon_new( Inkscape::IconSize lsize, gchar const *name ) +// PUBLIC CALL: +GtkWidget *sp_icon_new( Inkscape::IconSize lsize, gchar const *name ) { - return sp_icon_new_full( lsize, name ); + return IconImpl::newFull( lsize, name ); } // PUBLIC CALL: Gtk::Widget *sp_icon_get_icon( Glib::ustring const &oid, Inkscape::IconSize size ) { Gtk::Widget *result = 0; - GtkWidget *widget = sp_icon_new_full( static_cast<Inkscape::IconSize>(Inkscape::getRegisteredIconSize(size)), oid.c_str() ); + GtkWidget *widget = IconImpl::newFull( static_cast<Inkscape::IconSize>(Inkscape::getRegisteredIconSize(size)), oid.c_str() ); if ( widget ) { if ( GTK_IS_IMAGE(widget) ) { @@ -651,22 +825,7 @@ Gtk::Widget *sp_icon_get_icon( Glib::ustring const &oid, Inkscape::IconSize size return result; } -GtkIconSize -sp_icon_get_gtk_size(int size) -{ - static GtkIconSize sizemap[64] = {(GtkIconSize)0}; - size = CLAMP(size, 4, 63); - if (!sizemap[size]) { - static int count = 0; - char c[64]; - g_snprintf(c, 64, "InkscapeIcon%d", count++); - sizemap[size] = gtk_icon_size_register(c, size, size); - } - return sizemap[size]; -} - - -static void injectCustomSize() +void IconImpl::injectCustomSize() { // TODO - still need to handle the case of theme changes and resize, especially as we can't re-register a string. if ( !sizeMapDone ) @@ -697,7 +856,7 @@ static void injectCustomSize() GtkIconSize Inkscape::getRegisteredIconSize( Inkscape::IconSize size ) { GtkIconSize other = GTK_ICON_SIZE_MENU; - injectCustomSize(); + IconImpl::injectCustomSize(); size = CLAMP( size, Inkscape::ICON_SIZE_MENU, Inkscape::ICON_SIZE_DECORATION ); if ( size == Inkscape::ICON_SIZE_DECORATION ) { other = gtk_icon_size_from_name("inkscape-decoration"); @@ -712,6 +871,11 @@ GtkIconSize Inkscape::getRegisteredIconSize( Inkscape::IconSize size ) // PUBLIC CALL: int sp_icon_get_phys_size(int size) { + return IconImpl::getPhysSize(size); +} + +int IconImpl::getPhysSize(int size) +{ static bool init = false; static int lastSys[Inkscape::ICON_SIZE_DECORATION + 1]; static int vals[Inkscape::ICON_SIZE_DECORATION + 1]; @@ -825,7 +989,7 @@ int sp_icon_get_phys_size(int size) return vals[size]; } -static void sp_icon_paint(SPIcon *icon, GdkRectangle const */*area*/) +void IconImpl::paint(SPIcon *icon, GdkRectangle const */*area*/) { GtkWidget &widget = *GTK_WIDGET(icon); GdkPixbuf *image = icon->pb; @@ -861,7 +1025,7 @@ static void sp_icon_paint(SPIcon *icon, GdkRectangle const */*area*/) } } -GdkPixbuf *sp_icon_image_load_pixmap(gchar const *name, unsigned /*lsize*/, unsigned psize) +GdkPixbuf *IconImpl::loadPixmap(gchar const *name, unsigned /*lsize*/, unsigned psize) { gchar *path = (gchar *) g_strdup_printf("%s/%s.png", INKSCAPE_PIXMAPDIR, name); // TODO: bulia, please look over @@ -921,10 +1085,10 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, SPObject *object = doc->getObjectById(name); if (object && SP_IS_ITEM(object)) { /* Find bbox in document */ - Geom::Matrix const i2doc(SP_ITEM(object)->i2doc_affine()); + Geom::Affine const i2doc(SP_ITEM(object)->i2doc_affine()); Geom::OptRect dbox = SP_ITEM(object)->getBounds(i2doc); - if ( SP_OBJECT_PARENT(object) == NULL ) + if ( object->parent == NULL ) { dbox = Geom::Rect(Geom::Point(0, 0), Geom::Point(doc->getWidth(), doc->getHeight())); @@ -935,7 +1099,7 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, NRGC gc(NULL); /* Update to renderable state */ double sf = 1.0; - nr_arena_item_set_transform(root, (Geom::Matrix)Geom::Scale(sf, sf)); + nr_arena_item_set_transform(root, (Geom::Affine)Geom::Scale(sf, sf)); gc.transform.setIdentity(); nr_arena_item_invoke_update( root, NULL, &gc, NR_ARENA_ITEM_STATE_ALL, @@ -967,7 +1131,7 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, } sf = (double)psize / (double)block; - nr_arena_item_set_transform(root, (Geom::Matrix)Geom::Scale(sf, sf)); + nr_arena_item_set_transform(root, (Geom::Affine)Geom::Scale(sf, sf)); gc.transform.setIdentity(); nr_arena_item_invoke_update( root, NULL, &gc, NR_ARENA_ITEM_STATE_ALL, @@ -1035,7 +1199,7 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, convert_pixels_argb32_to_pixbuf(px, psize, psize, stride); if ( Inkscape::Preferences::get()->getBool("/debug/icons/overlaySvg") ) { - sp_icon_overlay_pixels( px, psize, psize, stride, 0x00, 0x00, 0xff ); + IconImpl::overlayPixels( px, psize, psize, stride, 0x00, 0x00, 0xff ); } } } @@ -1046,18 +1210,20 @@ sp_icon_doc_icon( SPDocument *doc, NRArenaItem *root, -struct svg_doc_cache_t +class SVGDocCache { +public: + SVGDocCache( SPDocument *doc, NRArenaItem *root ) : doc(doc), root(root) {} SPDocument *doc; NRArenaItem *root; }; -static std::map<Glib::ustring, svg_doc_cache_t *> doc_cache; +static std::map<Glib::ustring, SVGDocCache *> doc_cache; static std::map<Glib::ustring, GdkPixbuf *> pb_cache; -Glib::ustring icon_cache_key(gchar const *name, unsigned psize) +Glib::ustring icon_cache_key(Glib::ustring const & name, unsigned psize) { - Glib::ustring key=name; + Glib::ustring key = name; key += ":"; key += psize; return key; @@ -1072,7 +1238,7 @@ GdkPixbuf *get_cached_pixbuf(Glib::ustring const &key) { return pb; } -static std::list<gchar*> &icons_svg_paths() +std::list<gchar*> &IconImpl::icons_svg_paths() { static std::list<gchar *> sources; static bool initialized = false; @@ -1088,91 +1254,59 @@ static std::list<gchar*> &icons_svg_paths() } // this function renders icons from icons.svg and returns the pixels. -static guchar *load_svg_pixels(gchar const *name, unsigned psize, unsigned &stride) +guchar *IconImpl::load_svg_pixels(std::list<Glib::ustring> const &names, + unsigned psize, unsigned &stride) { - SPDocument *doc = NULL; - NRArenaItem *root = NULL; - svg_doc_cache_t *info = NULL; - + bool const dump = Inkscape::Preferences::get()->getBool("/debug/icons/dumpSvg"); std::list<gchar *> &sources = icons_svg_paths(); // Try each document in turn until we successfully load the icon from one - guchar *px=NULL; - for (std::list<gchar*>::iterator i = sources.begin(); i != sources.end() && !px; ++i) { + guchar *px = NULL; + for (std::list<gchar*>::iterator i = sources.begin(); (i != sources.end()) && !px; ++i) { gchar *doc_filename = *i; + SVGDocCache *info = 0; // Did we already load this doc? Glib::ustring key(doc_filename); - info = 0; { - std::map<Glib::ustring, svg_doc_cache_t *>::iterator i = doc_cache.find(key); + std::map<Glib::ustring, SVGDocCache *>::iterator i = doc_cache.find(key); if ( i != doc_cache.end() ) { info = i->second; } } - /* Try to load from document. */ - if (!info && - Inkscape::IO::file_test( doc_filename, G_FILE_TEST_IS_REGULAR ) && - (doc = SPDocument::createNewDoc( doc_filename, FALSE )) ) { - - //g_message("Loaded icon file %s", doc_filename); - // prep the document - doc->ensureUpToDate(); - /* Create new arena */ - NRArena *arena = NRArena::create(); - /* Create ArenaItem and set transform */ - unsigned visionkey = SPItem::display_key_new(1); - /* fixme: Memory manage root if needed (Lauris) */ - // This needs to be fixed indeed; this leads to a memory leak of a few megabytes these days - // because shapes are being rendered which are not being freed - // Valgrind output: - /*==7014== 1,548,344 bytes in 599 blocks are possibly lost in loss record 20,361 of 20,362 - ==7014== at 0x4A05974: operator new(unsigned long) (vg_replace_malloc.c:220) - ==7014== by 0x4F1015: __gnu_cxx::new_allocator<Shape::point_data>::allocate(unsigned long, void const*) (new_allocator.h:89) - ==7014== by 0x4F02AC: std::_Vector_base<Shape::point_data, std::allocator<Shape::point_data> >::_M_allocate(unsigned long) (stl_vector.h:140) - ==7014== by 0xCF62D7: std::vector<Shape::point_data, std::allocator<Shape::point_data> >::_M_fill_insert(__gnu_cxx::__normal_iterator<Shape::point_data*, std::vector<Shape::point_data, std::allocator<Shape::point_data> > >, unsigned long, Shape::point_data const&) (vector.tcc:414) - ==7014== by 0xCF4D45: std::vector<Shape::point_data, std::allocator<Shape::point_data> >::insert(__gnu_cxx::__normal_iterator<Shape::point_data*, std::vector<Shape::point_data, std::allocator<Shape::point_data> > >, unsigned long, Shape::point_data const&) (stl_vector.h:851) - ==7014== by 0xCF3DCD: std::vector<Shape::point_data, std::allocator<Shape::point_data> >::resize(unsigned long, Shape::point_data) (stl_vector.h:557) - ==7014== by 0xCEA771: Shape::AddPoint(Geom::Point) (Shape.cpp:326) - ==7014== by 0xD0F413: Shape::ConvertToShape(Shape*, fill_typ, bool) (ShapeSweep.cpp:257) - ==7014== by 0x5ECD4F: nr_arena_shape_update_stroke(NRArenaShape*, NRGC*, NRRectL*) (nr-arena-shape.cpp:651) - ==7014== by 0x5EE0DA: nr_arena_shape_render(_cairo*, NRArenaItem*, NRRectL*, NRPixBlock*, unsigned int) (nr-arena-shape.cpp:862) - ==7014== by 0x5E72FB: nr_arena_item_invoke_render(_cairo*, NRArenaItem*, NRRectL const*, NRPixBlock*, unsigned int) (nr-arena-item.cpp:578) - ==7014== by 0x5E9DDE: nr_arena_group_render(_cairo*, NRArenaItem*, NRRectL*, NRPixBlock*, unsigned int) (nr-arena-group.cpp:228) - ==7014== by 0x5E72FB: nr_arena_item_invoke_render(_cairo*, NRArenaItem*, NRRectL const*, NRPixBlock*, unsigned int) (nr-arena-item.cpp:578) - ==7014== by 0x5E9DDE: nr_arena_group_render(_cairo*, NRArenaItem*, NRRectL*, NRPixBlock*, unsigned int) (nr-arena-group.cpp:228) - ==7014== by 0x5E72FB: nr_arena_item_invoke_render(_cairo*, NRArenaItem*, NRRectL const*, NRPixBlock*, unsigned int) (nr-arena-item.cpp:578) - */ - root = SP_ITEM(doc->getRoot())->invoke_show(arena, visionkey, SP_ITEM_SHOW_DISPLAY ); - - // store into the cache - info = new svg_doc_cache_t; - g_assert(info); - - info->doc=doc; - info->root=root; - doc_cache[key]=info; + // Try to load from document. + if (!info && Inkscape::IO::file_test( doc_filename, G_FILE_TEST_IS_REGULAR ) ) { + SPDocument *doc = SPDocument::createNewDoc( doc_filename, FALSE ); + if ( doc ) { + if ( dump ) { + g_message("Loaded icon file %s", doc_filename); + } + // prep the document + doc->ensureUpToDate(); + + // Create new arena + NRArena *arena = NRArena::create(); + + // Create ArenaItem and set transform + unsigned visionkey = SPItem::display_key_new(1); + // fixme: Memory manage root if needed (Lauris) + // This needs to be fixed indeed; this leads to a memory leak of a few megabytes these days + // because shapes are being rendered which are not being freed + NRArenaItem *root = SP_ITEM(doc->getRoot())->invoke_show( arena, visionkey, SP_ITEM_SHOW_DISPLAY ); + + // store into the cache + info = new SVGDocCache(doc, root); + doc_cache[key] = info; + } } if (info) { - doc=info->doc; - root=info->root; - } - - // move on to the next document if we couldn't get anything - if (!info && !doc) { - continue; + for (std::list<Glib::ustring>::const_iterator it = names.begin(); !px && (it != names.end()); ++it ) { + px = sp_icon_doc_icon( info->doc, info->root, it->c_str(), psize, stride ); + } } - - px = sp_icon_doc_icon( doc, root, name, psize, stride); -// if (px) { -// g_message("Found icon %s in %s", name, doc_filename); -// } } -// if (!px) { -// g_message("Not found icon %s", name); -// } return px; } @@ -1196,76 +1330,152 @@ void Inkscape::queueIconPrerender( Glib::ustring const &name, Inkscape::IconSize if (!stockFound && !themedFound ) { gint trySize = CLAMP( static_cast<gint>(lsize), 0, static_cast<gint>(G_N_ELEMENTS(iconSizeLookup) - 1) ); if ( !sizeMapDone ) { - injectCustomSize(); + IconImpl::injectCustomSize(); } GtkIconSize mappedSize = iconSizeLookup[trySize]; - int psize = sp_icon_get_phys_size(lsize); + int psize = IconImpl::getPhysSize(lsize); // TODO place in a queue that is triggered by other map events - prerender_icon(name.c_str(), mappedSize, psize); + IconImpl::prerenderIcon(name.c_str(), mappedSize, psize); + } +} + +static std::map<unsigned, Glib::ustring> sizePaths; + +static std::string getDestDir( unsigned psize ) +{ + if ( sizePaths.find(psize) == sizePaths.end() ) { + gchar *tmp = g_strdup_printf("%dx%d", psize, psize); + sizePaths[psize] = tmp; + g_free(tmp); } + + return sizePaths[psize]; } // returns true if icon needed preloading, false if nothing was done -bool prerender_icon(gchar const *name, GtkIconSize lsize, unsigned psize) +bool IconImpl::prerenderIcon(gchar const *name, GtkIconSize lsize, unsigned psize) { bool loadNeeded = false; static bool dump = Inkscape::Preferences::get()->getBool("/debug/icons/dumpGtk"); + static bool useCache = Inkscape::Preferences::get()->getBool("/debug/icons/useCache", true); + static bool cacheValidated = false; + if (!cacheValidated) { + cacheValidated = true; + if ( useCache ) { + validateCache(); + } + } Glib::ustring key = icon_cache_key(name, psize); if ( !get_cached_pixbuf(key) ) { if ((internalNames.find(name) != internalNames.end()) || (!gtk_icon_theme_has_icon(gtk_icon_theme_get_default(), name))) { if (dump) { - g_message("prerender_icon [%s] %d:%d", name, lsize, psize); + g_message("prerenderIcon [%s] %d:%d", name, lsize, psize); } - unsigned stride; - guchar* px = load_svg_pixels(name, psize, stride); - if ( !px ) { - // check for a fallback name + + std::string potentialFile; + bool dataLoaded = false; + if ( useCache ) { + // In file encoding: + std::string iconCacheDir = Glib::build_filename(Glib::build_filename(Glib::get_user_cache_dir(), "inkscape"), "icons"); + std::string subpart = getDestDir(psize); + std::string subdir = Glib::build_filename( iconCacheDir, subpart ); + if ( !Glib::file_test(subdir, Glib::FILE_TEST_EXISTS) ) { + g_mkdir_with_parents( subdir.c_str(), 0x1ED ); + } + potentialFile = Glib::build_filename( subdir, name ); + potentialFile += ".png"; + + if ( Glib::file_test(potentialFile, Glib::FILE_TEST_EXISTS) && Glib::file_test(potentialFile, Glib::FILE_TEST_IS_REGULAR) ) { + bool badFile = false; + try { + Glib::RefPtr<Gdk::Pixbuf> pb = Gdk::Pixbuf::create_from_file(potentialFile); + if (pb) { + dataLoaded = true; + GdkPixbuf *obj = pb->gobj(); + g_object_ref(obj); + pb_cache[key] = obj; + addToIconSet(obj, name, lsize, psize); + loadNeeded = true; + if (internalNames.find(name) == internalNames.end()) { + internalNames.insert(name); + } + } + } catch ( Glib::FileError &ex ) { + //g_warning("FileError [%s]", ex.what().c_str()); + badFile = true; + } catch ( Gdk::PixbufError &ex ) { + //g_warning("PixbufError [%s]", ex.what().c_str()); + // Invalid contents. Remove cached item + badFile = true; + } + if ( badFile ) { + g_remove(potentialFile.c_str()); + } + } + } + + if (!dataLoaded) { + std::list<Glib::ustring> names; + names.push_back(name); if ( legacyNames.find(name) != legacyNames.end() ) { + names.push_back(legacyNames[name]); if ( dump ) { - g_message("load_svg_pixels([%s]=%s, %d, %d)", name, legacyNames[name].c_str(), lsize, psize); + g_message("load_svg_pixels([%s] = %s, %d, %d)", name, legacyNames[name].c_str(), lsize, psize); } - px = load_svg_pixels(legacyNames[name].c_str(), psize, stride); } - } - if (px) { - GdkPixbuf* pb = gdk_pixbuf_new_from_data( px, GDK_COLORSPACE_RGB, TRUE, 8, - psize, psize, stride, - reinterpret_cast<GdkPixbufDestroyNotify>(g_free), NULL ); - pb_cache[key] = pb; - addToIconSet(pb, name, lsize, psize); - loadNeeded = true; - if (internalNames.find(name) == internalNames.end()) { - internalNames.insert(name); + unsigned stride; + guchar* px = load_svg_pixels(names, psize, stride); + if (px) { + GdkPixbuf* pb = gdk_pixbuf_new_from_data( px, GDK_COLORSPACE_RGB, TRUE, 8, + psize, psize, stride, + reinterpret_cast<GdkPixbufDestroyNotify>(g_free), NULL ); + pb_cache[key] = pb; + addToIconSet(pb, name, lsize, psize); + loadNeeded = true; + if (internalNames.find(name) == internalNames.end()) { + internalNames.insert(name); + } + if (useCache) { + g_object_ref(pb); + Glib::RefPtr<Gdk::Pixbuf> ppp = Glib::wrap(pb); + try { + ppp->save( potentialFile, "png" ); + } catch ( Glib::FileError &ex ) { + //g_warning("FileError [%s]", ex.what().c_str()); + } catch ( Gdk::PixbufError &ex ) { + //g_warning("PixbufError [%s]", ex.what().c_str()); + } + } + } else if (dump) { + g_message("XXXXXXXXXXXXXXXXXXXXXXXXXXXXX error!!! pixels not found for '%s'", name); } - } else if (dump) { - g_message("XXXXXXXXXXXXXXXXXXXXXXXXXXXXX error!!! pixels not found for '%s'", name); } } else if (dump) { - g_message("prerender_icon [%s] %d NOT!!!!!!", name, psize); + g_message("prerenderIcon [%s] %d NOT!!!!!!", name, psize); } } return loadNeeded; } -static GdkPixbuf *sp_icon_image_load_svg(gchar const *name, GtkIconSize lsize, unsigned psize) +GdkPixbuf *IconImpl::loadSvg(std::list<Glib::ustring> const &names, GtkIconSize lsize, unsigned psize) { - Glib::ustring key = icon_cache_key(name, psize); + Glib::ustring key = icon_cache_key(*names.begin(), psize); // did we already load this icon at this scale/size? GdkPixbuf* pb = get_cached_pixbuf(key); if (!pb) { unsigned stride; - guchar *px = load_svg_pixels(name, psize, stride); + guchar *px = load_svg_pixels(names, psize, stride); if (px) { pb = gdk_pixbuf_new_from_data(px, GDK_COLORSPACE_RGB, TRUE, 8, psize, psize, stride, (GdkPixbufDestroyNotify)g_free, NULL); pb_cache[key] = pb; - addToIconSet(pb, name, lsize, psize); + addToIconSet(pb, names.begin()->c_str(), lsize, psize); } } @@ -1276,7 +1486,7 @@ static GdkPixbuf *sp_icon_image_load_svg(gchar const *name, GtkIconSize lsize, u return pb; } -void sp_icon_overlay_pixels(guchar *px, int width, int height, int stride, +void IconImpl::overlayPixels(guchar *px, int width, int height, int stride, unsigned r, unsigned g, unsigned b) { int bytesPerPixel = 4; @@ -1348,18 +1558,18 @@ public: static std::vector<preRenderItem> pendingRenders; static bool callbackHooked = false; -static void addPreRender( GtkIconSize lsize, gchar const *name ) +void IconImpl::addPreRender( GtkIconSize lsize, gchar const *name ) { if ( !callbackHooked ) { callbackHooked = true; - g_idle_add_full( G_PRIORITY_LOW, &icon_prerender_task, NULL, NULL ); + g_idle_add_full( G_PRIORITY_LOW, &prerenderTask, NULL, NULL ); } pendingRenders.push_back(preRenderItem(lsize, name)); } -gboolean icon_prerender_task(gpointer /*data*/) { +gboolean IconImpl::prerenderTask(gpointer /*data*/) { if ( inkscapeIsCrashing() ) { // stop } else if (!pendingRenders.empty()) { @@ -1367,8 +1577,8 @@ gboolean icon_prerender_task(gpointer /*data*/) { do { preRenderItem single = pendingRenders.front(); pendingRenders.erase(pendingRenders.begin()); - int psize = sp_icon_get_phys_size(single._lsize); - workDone = prerender_icon(single._name.c_str(), single._lsize, psize); + int psize = getPhysSize(single._lsize); + workDone = prerenderIcon(single._name.c_str(), single._lsize, psize); } while (!pendingRenders.empty() && !workDone); } @@ -1381,22 +1591,23 @@ gboolean icon_prerender_task(gpointer /*data*/) { } -void imageMapCB(GtkWidget* widget, gpointer user_data) { +void IconImpl::imageMapCB(GtkWidget* widget, gpointer user_data) +{ gchar* id = 0; GtkIconSize size = GTK_ICON_SIZE_INVALID; gtk_image_get_stock(GTK_IMAGE(widget), &id, &size); GtkIconSize lsize = static_cast<GtkIconSize>(GPOINTER_TO_INT(user_data)); if ( id ) { - int psize = sp_icon_get_phys_size(lsize); + int psize = getPhysSize(lsize); g_message("imageMapCB(%p) for [%s]:%d:%d", widget, id, lsize, psize); for ( std::vector<preRenderItem>::iterator it = pendingRenders.begin(); it != pendingRenders.end(); ++it ) { if ( (it->_name == id) && (it->_lsize == lsize) ) { - prerender_icon(id, lsize, psize); + prerenderIcon(id, lsize, psize); pendingRenders.erase(it); g_message(" prerender for %s:%d:%d", id, lsize, psize); if (lsize != size) { - int psize = sp_icon_get_phys_size(size); - prerender_icon(id, size, psize); + int psize = getPhysSize(size); + prerenderIcon(id, size, psize); } break; } @@ -1406,7 +1617,8 @@ void imageMapCB(GtkWidget* widget, gpointer user_data) { g_signal_handlers_disconnect_by_func(widget, (gpointer)imageMapCB, user_data); } -static void imageMapNamedCB(GtkWidget* widget, gpointer user_data) { +void IconImpl::imageMapNamedCB(GtkWidget* widget, gpointer user_data) +{ GtkImage* img = GTK_IMAGE(widget); gchar const* iconName = 0; GtkIconSize size = GTK_ICON_SIZE_INVALID; @@ -1426,8 +1638,8 @@ static void imageMapNamedCB(GtkWidget* widget, gpointer user_data) { for ( std::vector<preRenderItem>::iterator it = pendingRenders.begin(); it != pendingRenders.end(); ++it ) { if ( (it->_name == iconName) && (it->_lsize == size) ) { - int psize = sp_icon_get_phys_size(size); - prerender_icon(iconName, size, psize); + int psize = getPhysSize(size); + prerenderIcon(iconName, size, psize); pendingRenders.erase(it); break; } diff --git a/src/widgets/icon.h b/src/widgets/icon.h index f70423702..a20fad73a 100644 --- a/src/widgets/icon.h +++ b/src/widgets/icon.h @@ -6,8 +6,10 @@ * * Author: * Lauris Kaplinski <lauris@kaplinski.com> + * Jon A. Cruz <jon@joncruz.org> * * Copyright (C) 2002 Lauris Kaplinski + * Copyright (C) 2010 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -16,12 +18,16 @@ #include "icon-size.h" -#define SP_TYPE_ICON (sp_icon_get_type ()) +#define SP_TYPE_ICON SPIcon::getType() #define SP_ICON(o) (GTK_CHECK_CAST ((o), SP_TYPE_ICON, SPIcon)) #define SP_IS_ICON(o) (GTK_CHECK_TYPE ((o), SP_TYPE_ICON)) #include <gtk/gtkwidget.h> +struct SPIconClass { + GtkWidgetClass parent_class; +}; + struct SPIcon { GtkWidget widget; @@ -30,13 +36,12 @@ struct SPIcon { gchar *name; GdkPixbuf *pb; -}; -struct SPIconClass { - GtkWidgetClass parent_class; + static GType getType(void); + + friend class SPIconImpl; }; -GType sp_icon_get_type (void); GtkWidget *sp_icon_new( Inkscape::IconSize size, const gchar *name ); @@ -54,3 +59,14 @@ namespace Inkscape { } #endif // SEEN_SP_ICON_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : diff --git a/src/widgets/paint-selector.cpp b/src/widgets/paint-selector.cpp index 1d8acb40a..f0b55cf13 100644 --- a/src/widgets/paint-selector.cpp +++ b/src/widgets/paint-selector.cpp @@ -457,7 +457,7 @@ void SPPaintSelector::setSwatch(SPGradient *vector ) SwatchSelector *swatchsel = static_cast<SwatchSelector*>(g_object_get_data(G_OBJECT(selector), "swatch-selector")); if (swatchsel) { - swatchsel->setVector( (vector) ? SP_OBJECT_DOCUMENT(vector) : 0, vector ); + swatchsel->setVector( (vector) ? vector->document : 0, vector ); } } @@ -471,7 +471,7 @@ void SPPaintSelector::setGradientLinear(SPGradient *vector) SPGradientSelector *gsel = getGradientFromData(this); gsel->setMode(SPGradientSelector::MODE_LINEAR); - gsel->setVector((vector) ? SP_OBJECT_DOCUMENT(vector) : 0, vector); + gsel->setVector((vector) ? vector->document : 0, vector); } void SPPaintSelector::setGradientRadial(SPGradient *vector) @@ -485,7 +485,7 @@ void SPPaintSelector::setGradientRadial(SPGradient *vector) gsel->setMode(SPGradientSelector::MODE_RADIAL); - gsel->setVector((vector) ? SP_OBJECT_DOCUMENT(vector) : 0, vector); + gsel->setVector((vector) ? vector->document : 0, vector); } void SPPaintSelector::setGradientProperties( SPGradientUnits units, SPGradientSpread spread ) @@ -541,7 +541,7 @@ void SPPaintSelector::pushAttrsToGradient( SPGradient *gr ) const getGradientProperties( units, spread ); gr->setUnits(units); gr->setSpread(spread); - SP_OBJECT(gr)->updateRepr(); + gr->updateRepr(); } static void @@ -804,7 +804,7 @@ sp_pattern_menu_build (GtkWidget *m, GSList *pattern_list, SPDocument */*source* { for (; pattern_list != NULL; pattern_list = pattern_list->next) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) pattern_list->data); + Inkscape::XML::Node *repr = reinterpret_cast<SPItem *>(pattern_list->data)->getRepr(); GtkWidget *i = gtk_menu_item_new(); gtk_widget_show(i); @@ -950,7 +950,7 @@ void SPPaintSelector::updatePatternList( SPPattern *pattern ) gtk_object_set_data(GTK_OBJECT(mnu), "update", GINT_TO_POINTER(TRUE)); - gchar *patname = (gchar *) SP_OBJECT_REPR(pattern)->attribute("id"); + gchar const *patname = pattern->getRepr()->attribute("id"); GtkMenu *m = GTK_MENU(gtk_option_menu_get_menu(GTK_OPTION_MENU(mnu))); diff --git a/src/widgets/select-toolbar.cpp b/src/widgets/select-toolbar.cpp index a0ec248ca..89253983b 100644 --- a/src/widgets/select-toolbar.cpp +++ b/src/widgets/select-toolbar.cpp @@ -242,7 +242,7 @@ sp_object_layout_any_value_changed(GtkAdjustment *adj, SPWidget *spw) gdouble strokewidth = stroke_average_width (selection->itemList()); int transform_stroke = prefs->getBool("/options/transform/stroke", true) ? 1 : 0; - Geom::Matrix scaler = get_scale_transform_with_stroke (*bbox, strokewidth, transform_stroke, x0, y0, x1, y1); + Geom::Affine scaler = get_scale_transform_with_stroke (*bbox, strokewidth, transform_stroke, x0, y0, x1, y1); sp_selection_apply_affine(selection, scaler); DocumentUndo::maybeDone(document, actionkey, SP_VERB_CONTEXT_SELECT, diff --git a/src/widgets/sp-attribute-widget.cpp b/src/widgets/sp-attribute-widget.cpp index 0c31c2f74..a64a03f4e 100644 --- a/src/widgets/sp-attribute-widget.cpp +++ b/src/widgets/sp-attribute-widget.cpp @@ -154,14 +154,12 @@ sp_attribute_widget_changed (GtkEditable *editable) if (!*text) text = NULL; - if (spaw->hasobj && spaw->src.object) { - - SP_OBJECT_REPR (spaw->src.object)->setAttribute(spaw->attribute, text, false); - DocumentUndo::done(SP_OBJECT_DOCUMENT (spaw->src.object), SP_VERB_NONE, + if (spaw->hasobj && spaw->src.object) { + spaw->src.object->getRepr()->setAttribute(spaw->attribute, text, false); + DocumentUndo::done(spaw->src.object->document, SP_VERB_NONE, _("Set attribute")); } else if (spaw->src.repr) { - spaw->src.repr->setAttribute(spaw->attribute, text, false); /* TODO: Warning! Undo will not be flushed in given case */ } @@ -248,7 +246,7 @@ sp_attribute_widget_set_object ( SPAttributeWidget *spaw, spaw->attribute = g_strdup (attribute); - val = SP_OBJECT_REPR (object)->attribute(attribute); + val = object->getRepr()->attribute(attribute); gtk_entry_set_text (GTK_ENTRY (spaw), val ? val : (const gchar *) ""); spaw->blocked = FALSE; } @@ -317,7 +315,7 @@ sp_attribute_widget_object_modified ( SPObject */*object*/, if (flags && SP_OBJECT_MODIFIED_FLAG) { const gchar *val, *text; - val = SP_OBJECT_REPR (spaw->src.object)->attribute(spaw->attribute); + val = spaw->src.object->getRepr()->attribute(spaw->attribute); text = gtk_entry_get_text (GTK_ENTRY (spaw)); if (val || text) { @@ -588,7 +586,7 @@ sp_attribute_table_set_object ( SPAttributeTable *spat, XPAD, YPAD ); w = gtk_entry_new (); gtk_widget_show (w); - val = SP_OBJECT_REPR (object)->attribute(attributes[i]); + val = object->getRepr()->attribute(attributes[i]); gtk_entry_set_text (GTK_ENTRY (w), val ? val : (const gchar *) ""); gtk_table_attach ( GTK_TABLE (spat->table), w, 1, 2, i, i + 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), @@ -719,7 +717,7 @@ sp_attribute_table_object_modified ( SPObject */*object*/, gint i; for (i = 0; i < spat->num_attr; i++) { const gchar *val, *text; - val = SP_OBJECT_REPR (spat->src.object)->attribute(spat->attributes[i]); + val = spat->src.object->getRepr()->attribute(spat->attributes[i]); text = gtk_entry_get_text (GTK_ENTRY (spat->entries[i])); if (val || text) { if (!val || !text || strcmp (val, text)) { @@ -763,8 +761,8 @@ sp_attribute_table_entry_changed ( GtkEditable *editable, text = NULL; if (spat->hasobj && spat->src.object) { - SP_OBJECT_REPR (spat->src.object)->setAttribute(spat->attributes[i], text, false); - DocumentUndo::done(SP_OBJECT_DOCUMENT (spat->src.object), SP_VERB_NONE, + spat->src.object->getRepr()->setAttribute(spat->attributes[i], text, false); + DocumentUndo::done(spat->src.object->document, SP_VERB_NONE, _("Set attribute")); } else if (spat->src.repr) { diff --git a/src/widgets/sp-attribute-widget.h b/src/widgets/sp-attribute-widget.h index 2703bd98a..617c5b012 100644 --- a/src/widgets/sp-attribute-widget.h +++ b/src/widgets/sp-attribute-widget.h @@ -14,6 +14,7 @@ #define SEEN_DIALOGS_SP_ATTRIBUTE_WIDGET_H #include <glib.h> +#include <stddef.h> #include <sigc++/connection.h> #define SP_TYPE_ATTRIBUTE_WIDGET (sp_attribute_widget_get_type ()) diff --git a/src/widgets/sp-color-notebook.cpp b/src/widgets/sp-color-notebook.cpp index 8429434a6..174971555 100644 --- a/src/widgets/sp-color-notebook.cpp +++ b/src/widgets/sp-color-notebook.cpp @@ -22,6 +22,7 @@ #include <cstring> #include <string> #include <cstdlib> +#include <cstddef> #include <gtk/gtk.h> #include <glibmm/i18n.h> diff --git a/src/widgets/spw-utilities.cpp b/src/widgets/spw-utilities.cpp index 7c2956c65..49e3a7495 100644 --- a/src/widgets/spw-utilities.cpp +++ b/src/widgets/spw-utilities.cpp @@ -34,11 +34,19 @@ * position in the table. */ Gtk::Label * -spw_label(Gtk::Table *table, const gchar *label_text, int col, int row) +spw_label(Gtk::Table *table, const gchar *label_text, int col, int row, Gtk::Widget* target) { - Gtk::Label *label_widget = new Gtk::Label(label_text); + Gtk::Label *label_widget = new Gtk::Label(); g_assert(label_widget != NULL); - + if (target != NULL) + { + label_widget->set_text_with_mnemonic(label_text); + label_widget->set_mnemonic_widget(*target); + } + else + { + label_widget->set_text(label_text); + } label_widget->set_alignment(1.0, 0.5); label_widget->show(); table->attach(*label_widget, col, col+1, row, row+1, (Gtk::EXPAND | Gtk::FILL), static_cast<Gtk::AttachOptions>(0), 4, 0); diff --git a/src/widgets/spw-utilities.h b/src/widgets/spw-utilities.h index d17762811..9a387454f 100644 --- a/src/widgets/spw-utilities.h +++ b/src/widgets/spw-utilities.h @@ -20,6 +20,7 @@ #include <glib/gtypes.h> #include <gtk/gtkstyle.h> /* GtkWidget */ +#include <gtkmm/widget.h> namespace Gtk { class Label; @@ -28,7 +29,7 @@ namespace Gtk { } Gtk::Label * -spw_label(Gtk::Table *table, gchar const *label_text, int col, int row); +spw_label(Gtk::Table *table, gchar const *label_text, int col, int row, Gtk::Widget *target); GtkWidget * spw_label_old(GtkWidget *table, gchar const *label_text, int col, int row); diff --git a/src/widgets/stroke-style.cpp b/src/widgets/stroke-style.cpp index 7226b970e..5288b5102 100644 --- a/src/widgets/stroke-style.cpp +++ b/src/widgets/stroke-style.cpp @@ -161,11 +161,11 @@ sp_marker_prev_new(unsigned psize, gchar const *mname, // Create a copy repr of the marker with id="sample" Inkscape::XML::Document *xml_doc = sandbox->getReprDoc(); - Inkscape::XML::Node *mrepr = SP_OBJECT_REPR (marker)->duplicate(xml_doc); + Inkscape::XML::Node *mrepr = marker->getRepr()->duplicate(xml_doc); mrepr->setAttribute("id", "sample"); // Replace the old sample in the sandbox by the new one - Inkscape::XML::Node *defsrepr = SP_OBJECT_REPR (sandbox->getObjectById("defs")); + Inkscape::XML::Node *defsrepr = sandbox->getObjectById("defs")->getRepr(); SPObject *oldmarker = sandbox->getObjectById("sample"); if (oldmarker) oldmarker->deleteObject(false); @@ -186,7 +186,7 @@ sp_marker_prev_new(unsigned psize, gchar const *mname, return NULL; // sandbox broken? // Find object's bbox in document - Geom::Matrix const i2doc(SP_ITEM(object)->i2doc_affine()); + Geom::Affine const i2doc(SP_ITEM(object)->i2doc_affine()); Geom::OptRect dbox = SP_ITEM(object)->getBounds(i2doc); if (!dbox) { @@ -225,7 +225,7 @@ ink_marker_list_get (SPDocument *source) GSList *ml = NULL; SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS (source); - for ( SPObject *child = SP_OBJECT(defs)->firstChild(); child; child = child->getNext() ) + for ( SPObject *child = defs->firstChild(); child; child = child->getNext() ) { if (SP_IS_MARKER(child)) { ml = g_slist_prepend (ml, child); @@ -248,14 +248,15 @@ sp_marker_menu_build (Gtk::Menu *m, GSList *marker_list, SPDocument *source, SPD NRArenaItem *root = SP_ITEM(sandbox->getRoot())->invoke_show((NRArena *) arena, visionkey, SP_ITEM_SHOW_DISPLAY); for (; marker_list != NULL; marker_list = marker_list->next) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) marker_list->data); + Inkscape::XML::Node *repr = reinterpret_cast<SPItem *>(marker_list->data)->getRepr(); Gtk::MenuItem *i = new Gtk::MenuItem(); i->show(); - if (repr->attribute("inkscape:stockid")) + if (repr->attribute("inkscape:stockid")) { i->set_data("stockid", (void *) "true"); - else + } else { i->set_data("stockid", (void *) "false"); + } gchar const *markid = repr->attribute("id"); i->set_data("marker", (void *) markid); @@ -468,7 +469,7 @@ sp_marker_select(Gtk::OptionMenu *mnu, Gtk::Container *spw, SPMarkerLoc const wh if (!strcmp(stockid,"true")) markurn = g_strconcat("urn:inkscape:marker:",markid,NULL); SPObject *mark = get_stock_item(markurn); if (mark) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR(mark); + Inkscape::XML::Node *repr = mark->getRepr(); marker = g_strconcat("url(#", repr->attribute("id"), ")", NULL); } } else { @@ -486,16 +487,17 @@ sp_marker_select(Gtk::OptionMenu *mnu, Gtk::Container *spw, SPMarkerLoc const wh Inkscape::Selection *selection = sp_desktop_selection(desktop); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { - SPItem *item = (SPItem *) items->data; - if (!SP_IS_SHAPE(item) || SP_IS_RECT(item)) // can't set marker to rect, until it's converted to using <path> - continue; - Inkscape::XML::Node *selrepr = SP_OBJECT_REPR((SPItem *) items->data); - if (selrepr) { - sp_repr_css_change_recursive(selrepr, css, "style"); - } - SP_OBJECT(items->data)->requestModified(SP_OBJECT_MODIFIED_FLAG); - SP_OBJECT(items->data)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); - } + SPItem *item = reinterpret_cast<SPItem *>(items->data); + if (!SP_IS_SHAPE(item) || SP_IS_RECT(item)) { // can't set marker to rect, until it's converted to using <path> + continue; + } + Inkscape::XML::Node *selrepr = item->getRepr(); + if (selrepr) { + sp_repr_css_change_recursive(selrepr, css, "style"); + } + item->requestModified(SP_OBJECT_MODIFIED_FLAG); + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG); + } sp_repr_css_attr_unref(css); css = 0; @@ -673,7 +675,7 @@ sp_stroke_style_line_widget_new(void) gint i = 0; - spw_label(t, C_("Stroke width", "Width:"), 0, i); + //spw_label(t, C_("Stroke width", "_Width:"), 0, i); hb = spw_hbox(t, 3, 1, i); @@ -689,6 +691,7 @@ sp_stroke_style_line_widget_new(void) sb = new Gtk::SpinButton(*a, 0.1, 3); tt->set_tip(*sb, _("Stroke width")); sb->show(); + spw_label(t, C_("Stroke width", "_Width:"), 0, i, sb); sp_dialog_defocus_on_enter_cpp(sb); @@ -711,7 +714,7 @@ sp_stroke_style_line_widget_new(void) /* Join type */ // TRANSLATORS: The line join style specifies the shape to be used at the // corners of paths. It can be "miter", "round" or "bevel". - spw_label(t, _("Join:"), 0, i); + spw_label(t, _("Join:"), 0, i, NULL); hb = spw_hbox(t, 3, 1, i); @@ -755,7 +758,7 @@ sp_stroke_style_line_widget_new(void) // spike that extends well beyond the connection point. The purpose of the // miter limit is to cut off such spikes (i.e. convert them into bevels) // when they become too long. - spw_label(t, _("Miter limit:"), 0, i); + //spw_label(t, _("Miter _limit:"), 0, i); hb = spw_hbox(t, 3, 1, i); @@ -765,6 +768,7 @@ sp_stroke_style_line_widget_new(void) sb = new Gtk::SpinButton(*a, 0.1, 2); tt->set_tip(*sb, _("Maximum length of the miter (in units of stroke width)")); sb->show(); + spw_label(t, _("Miter _limit:"), 0, i, sb); spw->set_data("miterlimit_sb", sb); sp_dialog_defocus_on_enter_cpp(sb); @@ -775,7 +779,8 @@ sp_stroke_style_line_widget_new(void) /* Cap type */ // TRANSLATORS: cap type specifies the shape for the ends of lines - spw_label(t, _("Cap:"), 0, i); + //spw_label(t, _("_Cap:"), 0, i); + spw_label(t, _("Cap:"), 0, i, NULL); hb = spw_hbox(t, 3, 1, i); @@ -809,7 +814,11 @@ sp_stroke_style_line_widget_new(void) /* Dash */ - spw_label(t, _("Dashes:"), 0, i); + spw_label(t, _("Dashes:"), 0, i, NULL); //no mnemonic for now + //decide what to do: + // implement a set_mnemonic_source function in the + // SPDashSelector class, so that we do not have to + // expose any of the underlying widgets? ds = manage(new SPDashSelector); ds->show(); @@ -826,8 +835,9 @@ sp_stroke_style_line_widget_new(void) // TRANSLATORS: Path markers are an SVG feature that allows you to attach arbitrary shapes // (arrowheads, bullets, faces, whatever) to the start, end, or middle nodes of a path. - spw_label(t, _("Start Markers:"), 0, i); + //spw_label(t, _("_Start Markers:"), 0, i); marker_start_menu = ink_marker_menu(spw ,"marker-start", sandbox); + spw_label(t, _("_Start Markers:"), 0, i, marker_start_menu); tt->set_tip(*marker_start_menu, _("Start Markers are drawn on the first node of a path or shape")); marker_start_menu_connection = marker_start_menu->signal_changed().connect( sigc::bind<Gtk::OptionMenu *, Gtk::Container *, SPMarkerLoc>( @@ -837,8 +847,9 @@ sp_stroke_style_line_widget_new(void) spw->set_data("start_mark_menu", marker_start_menu); i++; - spw_label(t, _("Mid Markers:"), 0, i); + //spw_label(t, _("_Mid Markers:"), 0, i); marker_mid_menu = ink_marker_menu(spw ,"marker-mid", sandbox); + spw_label(t, _("_Mid Markers:"), 0, i, marker_mid_menu); tt->set_tip(*marker_mid_menu, _("Mid Markers are drawn on every node of a path or shape except the first and last nodes")); marker_mid_menu_connection = marker_mid_menu->signal_changed().connect( sigc::bind<Gtk::OptionMenu *, Gtk::Container *, SPMarkerLoc>( @@ -848,8 +859,9 @@ sp_stroke_style_line_widget_new(void) spw->set_data("mid_mark_menu", marker_mid_menu); i++; - spw_label(t, _("End Markers:"), 0, i); + //spw_label(t, _("_End Markers:"), 0, i); marker_end_menu = ink_marker_menu(spw ,"marker-end", sandbox); + spw_label(t, _("_End Markers:"), 0, i, marker_end_menu); tt->set_tip(*marker_end_menu, _("End Markers are drawn on the last node of a path or shape")); marker_end_menu_connection = marker_end_menu->signal_changed().connect( sigc::bind<Gtk::OptionMenu *, Gtk::Container *, SPMarkerLoc>( @@ -1081,7 +1093,7 @@ sp_stroke_style_line_update(Gtk::Container *spw, Inkscape::Selection *sel) GSList const *objects = sel->itemList(); SPObject * const object = SP_OBJECT(objects->data); - SPStyle * const style = SP_OBJECT_STYLE(object); + SPStyle * const style = object->style; /* Markers */ sp_stroke_style_update_marker_menus(spw, objects); // FIXME: make this desktop query too @@ -1164,7 +1176,7 @@ sp_stroke_style_scale_line(Gtk::Container *spw) if (unit->base == SP_UNIT_ABSOLUTE || unit->base == SP_UNIT_DEVICE) { width = sp_units_get_pixels (width_typed, *unit); } else { // percentage - gdouble old_w = SP_OBJECT_STYLE (i->data)->stroke_width.computed; + gdouble old_w = SP_OBJECT(i->data)->style->stroke_width.computed; width = old_w * width_typed / 100; } @@ -1352,14 +1364,16 @@ ink_marker_menu_set_current(SPObject *marker, Gtk::OptionMenu *mnu) Gtk::Menu *m = mnu->get_menu(); if (marker != NULL) { bool mark_is_stock = false; - if (SP_OBJECT_REPR(marker)->attribute("inkscape:stockid")) + if (marker->getRepr()->attribute("inkscape:stockid")) { mark_is_stock = true; + } - gchar *markname; - if (mark_is_stock) - markname = g_strdup(SP_OBJECT_REPR(marker)->attribute("inkscape:stockid")); - else - markname = g_strdup(SP_OBJECT_REPR(marker)->attribute("id")); + gchar *markname = 0; + if (mark_is_stock) { + markname = g_strdup(marker->getRepr()->attribute("inkscape:stockid")); + } else { + markname = g_strdup(marker->getRepr()->attribute("id")); + } int markpos = ink_marker_menu_get_pos(m, markname); mnu->set_history(markpos); @@ -1417,7 +1431,7 @@ sp_stroke_style_update_marker_menus(Gtk::Container *spw, GSList const *objects) // If the object has this type of markers, // Extract the name of the marker that the object uses - SPObject *marker = ink_extract_marker_name(object->style->marker[keyloc[i].loc].value, SP_OBJECT_DOCUMENT(object)); + SPObject *marker = ink_extract_marker_name(object->style->marker[keyloc[i].loc].value, object->document); // Scroll the menu to that marker ink_marker_menu_set_current(marker, mnu); diff --git a/src/widgets/swatch-selector.cpp b/src/widgets/swatch-selector.cpp index 935282a3a..cd624630b 100644 --- a/src/widgets/swatch-selector.cpp +++ b/src/widgets/swatch-selector.cpp @@ -133,9 +133,9 @@ void SwatchSelector::_changedCb(SPColorSelector */*csel*/, void *data) gchar c[64]; sp_svg_write_color(c, sizeof(c), rgb); os << "stop-color:" << c << ";stop-opacity:" << static_cast<gdouble>(alpha) <<";"; - SP_OBJECT_REPR(stop)->setAttribute("style", os.str().c_str()); + stop->getRepr()->setAttribute("style", os.str().c_str()); - DocumentUndo::done(SP_OBJECT_DOCUMENT(ngr), SP_VERB_CONTEXT_GRADIENT, + DocumentUndo::done(ngr->document, SP_VERB_CONTEXT_GRADIENT, _("Change swatch color")); } } @@ -169,7 +169,7 @@ void SwatchSelector::connectchangedHandler( GCallback handler, void *data ) void SwatchSelector::setVector(SPDocument */*doc*/, SPGradient *vector) { //GtkVBox * box = gobj(); - _gsel->setVector((vector) ? SP_OBJECT_DOCUMENT(vector) : 0, vector); + _gsel->setVector((vector) ? vector->document : 0, vector); if ( vector && vector->isSolid() ) { SPStop* stop = vector->getFirstStop(); diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 28b4c9fb2..db86ff8a0 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -332,7 +332,6 @@ static gchar const * ui_descr = " <toolbar name='SprayToolbar'>" " <toolitem action='SprayModeAction' />" " <separator />" - " <separator />" " <toolitem action='SprayWidthAction' />" " <toolitem action='SprayPressureAction' />" " <toolitem action='SprayPopulationAction' />" @@ -469,9 +468,9 @@ static gchar const * ui_descr = " </toolbar>" " <toolbar name='EraserToolbar'>" - " <toolitem action='EraserWidthAction' />" - " <separator />" " <toolitem action='EraserModeAction' />" + " <separator />" + " <toolitem action='EraserWidthAction' />" " </toolbar>" " <toolbar name='TextToolbar'>" @@ -2041,14 +2040,14 @@ static void toggle_snap_callback(GtkToggleAction *act, gpointer data) //data poi SPDesktop *dt = reinterpret_cast<SPDesktop*>(ptr); SPNamedView *nv = sp_desktop_namedview(dt); - SPDocument *doc = SP_OBJECT_DOCUMENT(nv); + SPDocument *doc = nv->document; if (dt == NULL || nv == NULL) { g_warning("No desktop or namedview specified (in toggle_snap_callback)!"); return; } - Inkscape::XML::Node *repr = SP_OBJECT_REPR(nv); + Inkscape::XML::Node *repr = nv->getRepr(); if (repr == NULL) { g_warning("This namedview doesn't have a xml representation attached!"); @@ -2520,13 +2519,14 @@ static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKlu Inkscape::Selection *selection = sp_desktop_selection(desktop); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { - if (SP_IS_STAR((SPItem *) items->data)) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data); + SPItem *item = reinterpret_cast<SPItem*>(items->data); + if (SP_IS_STAR(item)) { + Inkscape::XML::Node *repr = item->getRepr(); sp_repr_set_int(repr,"sodipodi:sides",(gint)adj->value); sp_repr_set_svg_double(repr, "sodipodi:arg2", (sp_repr_get_double_attribute(repr, "sodipodi:arg1", 0.5) + M_PI / (gint)adj->value)); - SP_OBJECT((SPItem *) items->data)->updateRepr(); + item->updateRepr(); modmade = true; } } @@ -2561,8 +2561,9 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl Inkscape::Selection *selection = sp_desktop_selection(desktop); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { - if (SP_IS_STAR((SPItem *) items->data)) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data); + SPItem *item = reinterpret_cast<SPItem *>(items->data); + if (SP_IS_STAR(item)) { + Inkscape::XML::Node *repr = item->getRepr(); gdouble r1 = sp_repr_get_double_attribute(repr, "sodipodi:r1", 1.0); gdouble r2 = sp_repr_get_double_attribute(repr, "sodipodi:r2", 1.0); @@ -2572,7 +2573,7 @@ static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKl sp_repr_set_svg_double(repr, "sodipodi:r1", r2*adj->value); } - SP_OBJECT((SPItem *) items->data)->updateRepr(); + item->updateRepr(); modmade = true; } } @@ -2613,10 +2614,11 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d } for (; items != NULL; items = items->next) { - if (SP_IS_STAR((SPItem *) items->data)) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data); + SPItem *item = reinterpret_cast<SPItem *>(items->data); + if (SP_IS_STAR(item)) { + Inkscape::XML::Node *repr = item->getRepr(); repr->setAttribute("inkscape:flatsided", flat ? "true" : "false" ); - SP_OBJECT((SPItem *) items->data)->updateRepr(); + item->updateRepr(); modmade = true; } } @@ -2651,10 +2653,11 @@ static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludg Inkscape::Selection *selection = sp_desktop_selection(desktop); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { - if (SP_IS_STAR((SPItem *) items->data)) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data); + SPItem *item = reinterpret_cast<SPItem*>(items->data); + if (SP_IS_STAR(item)) { + Inkscape::XML::Node *repr = item->getRepr(); sp_repr_set_svg_double(repr, "inkscape:rounded", (gdouble) adj->value); - SP_OBJECT(items->data)->updateRepr(); + item->updateRepr(); modmade = true; } } @@ -2688,10 +2691,11 @@ static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKl Inkscape::Selection *selection = sp_desktop_selection(desktop); GSList const *items = selection->itemList(); for (; items != NULL; items = items->next) { - if (SP_IS_STAR((SPItem *) items->data)) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data); + SPItem *item = reinterpret_cast<SPItem *>(items->data); + if (SP_IS_STAR(item)) { + Inkscape::XML::Node *repr = item->getRepr(); sp_repr_set_svg_double(repr, "inkscape:randomized", (gdouble) adj->value); - SP_OBJECT(items->data)->updateRepr(); + item->updateRepr(); modmade = true; } } @@ -2783,9 +2787,10 @@ sp_star_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) items != NULL; items = items->next) { - if (SP_IS_STAR((SPItem *) items->data)) { + SPItem* item = reinterpret_cast<SPItem *>(items->data); + if (SP_IS_STAR(item)) { n_selected++; - repr = SP_OBJECT_REPR((SPItem *) items->data); + repr = item->getRepr(); } } @@ -3055,7 +3060,7 @@ static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const * if (adj->value != 0) { setter(SP_RECT(items->data), sp_units_get_pixels(adj->value, *unit)); } else { - SP_OBJECT_REPR(items->data)->setAttribute(value_name, NULL); + SP_OBJECT(items->data)->getRepr()->setAttribute(value_name, NULL); } modmade = true; } @@ -3184,10 +3189,10 @@ static void sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GO for (GSList const *items = selection->itemList(); items != NULL; items = items->next) { - if (SP_IS_RECT((SPItem *) items->data)) { + if (SP_IS_RECT(reinterpret_cast<SPItem *>(items->data))) { n_selected++; - item = (SPItem *) items->data; - repr = SP_OBJECT_REPR(item); + item = reinterpret_cast<SPItem *>(items->data); + repr = item->getRepr(); } } @@ -3474,7 +3479,7 @@ static void box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObj // FIXME: Also deal with multiple selected boxes SPBox3D *box = SP_BOX3D(item); Persp3D *persp = box3d_get_perspective(box); - persp_repr = SP_OBJECT_REPR(persp); + persp_repr = persp->getRepr(); if (persp_repr) { g_object_set_data(tbl, "repr", persp_repr); Inkscape::GC::anchor(persp_repr); @@ -3513,7 +3518,7 @@ static void box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, P Persp3D *persp = sel_persps.front(); persp->perspective_impl->tmat.set_infinite_direction (axis, adj->value); - SP_OBJECT(persp)->updateRepr(); + persp->updateRepr(); // TODO: use the correct axis here, too DocumentUndo::maybeDone(document, "perspangle", SP_VERB_CONTEXT_3DBOX, _("3D Box: Change perspective (angle of infinite axis)")); @@ -3731,10 +3736,11 @@ static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustr items != NULL; items = items->next) { - if (SP_IS_SPIRAL((SPItem *) items->data)) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data); + SPItem *item = reinterpret_cast<SPItem*>(items->data); + if (SP_IS_SPIRAL(item)) { + Inkscape::XML::Node *repr = item->getRepr(); sp_repr_set_svg_double( repr, namespaced_name, adj->value ); - SP_OBJECT((SPItem *) items->data)->updateRepr(); + item->updateRepr(); modmade = true; } } @@ -3841,9 +3847,10 @@ static void sp_spiral_toolbox_selection_changed(Inkscape::Selection *selection, items != NULL; items = items->next) { - if (SP_IS_SPIRAL((SPItem *) items->data)) { + SPItem *item = reinterpret_cast<SPItem*>(items->data); + if (SP_IS_SPIRAL(item)) { n_selected++; - repr = SP_OBJECT_REPR((SPItem *) items->data); + repr = item->getRepr(); } } @@ -4601,10 +4608,10 @@ static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction { /* Mean */ - gchar const* labels[] = {_("(minimum mean)"), 0, 0, _("(default)"), 0, 0, 0, _("(maximum mean)")}; - gdouble values[] = {1, 5, 10, 20, 30, 50, 70, 100}; + gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(maximum mean)")}; + gdouble values[] = {0, 5, 10, 20, 30, 50, 70, 100}; EgeAdjustmentAction *eact = create_adjustment_action( "SprayMeanAction", - _("Focus"), _("Focus:"), _("0 to spray a spot. Increase to enlarge the ring radius."), + _("Focus"), _("Focus:"), _("0 to spray a spot; increase to enlarge the ring radius"), "/tools/spray/mean", 0, GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-mean", 0, 100, 1.0, 10.0, @@ -4617,13 +4624,10 @@ static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction { /* Standard_deviation */ - gchar const* labels[] = {_("(minimum scatter)"), 0, 0, _("(default)"), 0, 0, 0, _("(maximum scatter)")}; + gchar const* labels[] = {_("(minimum scatter)"), 0, 0, 0, 0, 0, _("(default)"), _("(maximum scatter)")}; gdouble values[] = {1, 5, 10, 20, 30, 50, 70, 100}; - - //TRANSLATORS: only translate "string" in "context|string". - // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS EgeAdjustmentAction *eact = create_adjustment_action( "SprayStandard_deviationAction", - Q_("Toolbox|Scatter"), Q_("Toolbox|Scatter:"), _("Increase to scatter sprayed objects."), + C_("Spray tool", "Scatter"), C_("Spray tool", "Scatter:"), _("Increase to scatter sprayed objects"), "/tools/spray/standard_deviation", 70, GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-standard_deviation", 1, 100, 1.0, 10.0, @@ -4680,11 +4684,11 @@ static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction } { /* Population */ - gchar const* labels[] = {_("(low population)"), 0, 0, _("(default)"), 0, 0, _("(high population)")}; - gdouble values[] = {10, 25, 35, 50, 60, 80, 100}; + gchar const* labels[] = {_("(low population)"), 0, 0, 0, _("(default)"), 0, _("(high population)")}; + gdouble values[] = {5, 20, 35, 50, 70, 85, 100}; EgeAdjustmentAction *eact = create_adjustment_action( "SprayPopulationAction", _("Amount"), _("Amount:"), - _("Adjusts the number of items sprayed per clic."), + _("Adjusts the number of items sprayed per clic"), "/tools/spray/population", 70, GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-population", 1, 100, 1.0, 10.0, @@ -4700,21 +4704,22 @@ static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction { InkToggleAction* act = ink_toggle_action_new( "SprayPressureAction", _("Pressure"), - _("Use the pressure of the input device to alter the amount of sprayed objects."), + _("Use the pressure of the input device to alter the amount of sprayed objects"), "use_pressure", Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_spray_pressure_state_changed), NULL); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/spray/usepressure", true) ); + gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); + PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressure"); + g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); + } { /* Rotation */ - gchar const* labels[] = {_("(low rotation variation)"), 0, 0, _("(default)"), 0, 0, _("(high rotation variation)")}; - gdouble values[] = {10, 25, 35, 50, 60, 80, 100}; + gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(high rotation variation)")}; + gdouble values[] = {0, 10, 25, 35, 50, 60, 80, 100}; EgeAdjustmentAction *eact = create_adjustment_action( "SprayRotationAction", _("Rotation"), _("Rotation:"), // xgettext:no-c-format - _("Variation of the rotation of the sprayed objects. 0% for the same rotation than the original object."), + _("Variation of the rotation of the sprayed objects; 0% for the same rotation than the original object"), "/tools/spray/rotation_variation", 0, GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-rotation", 0, 100, 1.0, 10.0, @@ -4727,15 +4732,12 @@ static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction } { /* Scale */ - gchar const* labels[] = {_("(low scale variation)"), 0, 0, _("(default)"), 0, 0, _("(high scale variation)")}; - gdouble values[] = {10, 25, 35, 50, 60, 80, 100}; - - //TRANSLATORS: only translate "string" in "context|string". - // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS + gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(high scale variation)")}; + gdouble values[] = {0, 10, 25, 35, 50, 60, 80, 100}; EgeAdjustmentAction *eact = create_adjustment_action( "SprayScaleAction", - Q_("Toolbox|Scale"), Q_("Toolbox|Scale:"), + C_("Spray tool", "Scale"), C_("Spray tool", "Scale:"), // xgettext:no-c-format - _("Variation in the scale of the sprayed objects. 0% for the same scale than the original object."), + _("Variation in the scale of the sprayed objects; 0% for the same scale than the original object"), "/tools/spray/scale_variation", 0, GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-scale", 0, 100, 1.0, 10.0, @@ -5395,10 +5397,11 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) items != NULL; items = items->next) { - if (SP_IS_ARC((SPItem *) items->data)) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data); + SPItem *item = reinterpret_cast<SPItem*>(items->data); + if (SP_IS_ARC(item)) { + Inkscape::XML::Node *repr = item->getRepr(); repr->setAttribute("sodipodi:open", "true"); - SP_OBJECT((SPItem *) items->data)->updateRepr(); + item->updateRepr(); modmade = true; } } @@ -5407,10 +5410,11 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) items != NULL; items = items->next) { - if (SP_IS_ARC((SPItem *) items->data)) { - Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data); + SPItem *item = reinterpret_cast<SPItem *>(items->data); + if (SP_IS_ARC(item)) { + Inkscape::XML::Node *repr = item->getRepr(); repr->setAttribute("sodipodi:open", NULL); - SP_OBJECT((SPItem *) items->data)->updateRepr(); + item->updateRepr(); modmade = true; } } @@ -5496,9 +5500,10 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb items != NULL; items = items->next) { - if (SP_IS_ARC((SPItem *) items->data)) { + SPItem *item = reinterpret_cast<SPItem *>(items->data); + if (SP_IS_ARC(item)) { n_selected++; - repr = SP_OBJECT_REPR((SPItem *) items->data); + repr = item->getRepr(); } } @@ -6107,23 +6112,6 @@ static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) static void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) { { - /* Width */ - gchar const* labels[] = {_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")}; - gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "EraserWidthAction", - _("Pen Width"), _("Width:"), - _("The width of the eraser pen (relative to the visible canvas area)"), - "/tools/eraser/width", 15, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-eraser", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_erc_width_value_changed, 1, 0); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); GtkTreeIter iter; @@ -6142,9 +6130,10 @@ static void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio -1 ); EgeSelectOneAction* act = ege_select_one_action_new( "EraserModeAction", (""), (""), NULL, GTK_TREE_MODEL(model) ); + g_object_set( act, "short_label", _("Mode:"), NULL ); gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); g_object_set_data( holder, "eraser_mode_action", act ); - + ege_select_one_action_set_appearance( act, "full" ); ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); @@ -6158,6 +6147,23 @@ static void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_erasertb_mode_changed), holder ); } + { + /* Width */ + gchar const* labels[] = {_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")}; + gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; + EgeAdjustmentAction *eact = create_adjustment_action( "EraserWidthAction", + _("Pen Width"), _("Width:"), + _("The width of the eraser pen (relative to the visible canvas area)"), + "/tools/eraser/width", 15, + GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-eraser", + 1, 100, 1.0, 10.0, + labels, values, G_N_ELEMENTS(labels), + sp_erc_width_value_changed, 1, 0); + ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + } + } //######################## @@ -6185,7 +6191,7 @@ static void sp_print_font( SPStyle *query ) { << (query->text->font_specification.value ? query->text->font_specification.value : "No value") << std::endl; } - + static void sp_print_fontweight( SPStyle *query ) { const gchar* names[] = {"100", "200", "300", "400", "500", "600", "700", "800", "900", "NORMAL", "BOLD", "LIGHTER", "BOLDER", "Out of range"}; @@ -6385,8 +6391,10 @@ static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GOb g_free (family); // Save for undo - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + if (result_fontspec != QUERY_STYLE_NOTHING) { + DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, _("Text: Change font family")); + } sp_repr_css_attr_unref (css); // unfreeze @@ -6431,10 +6439,6 @@ static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObje SPDesktop *desktop = SP_ACTIVE_DESKTOP; sp_desktop_set_style (desktop, css, true, true); - // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:size", SP_VERB_NONE, - _("Text: Change font size")); - // If no selected objects, set default. SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); int result_numbers = @@ -6443,7 +6447,12 @@ static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObje { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->mergeStyle("/tools/text/style", css); + } else { + // Save for undo + DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:size", SP_VERB_NONE, + _("Text: Change font size")); } + sp_style_unref(query); sp_repr_css_attr_unref (css); @@ -6578,8 +6587,10 @@ static void sp_text_style_changed( InkToggleAction* act, GObject *tbl ) // Do we need to update other CSS values? SPDesktop *desktop = SP_ACTIVE_DESKTOP; sp_desktop_set_style (desktop, css, true, true); - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + if (result_fontspec != QUERY_STYLE_NOTHING) { + DocumentUndo::done(sp_desktop_document(SP_ACTIVE_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) ); @@ -6655,9 +6666,10 @@ static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) sp_desktop_set_style (desktop, css, true, false); // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:script", SP_VERB_NONE, + if(result_baseline != QUERY_STYLE_NOTHING) { + DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:script", SP_VERB_NONE, _("Text: Change superscript or subscript")); - + } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } @@ -6682,7 +6694,7 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) if (SP_IS_TEXT((SPItem *) items->data)) { SPItem *item = SP_ITEM(items->data); - unsigned writing_mode = SP_OBJECT_STYLE(item)->writing_mode.value; + unsigned writing_mode = item->style->writing_mode.value; // below, variable names suggest horizontal move, but we check the writing direction // and move in the corresponding axis int axis; @@ -6702,7 +6714,7 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) // frame (currently unused) double left_slack = 0; double right_slack = 0; - unsigned old_align = SP_OBJECT_STYLE(item)->text_align.value; + unsigned old_align = item->style->text_align.value; double move = 0; if (old_align == SP_CSS_TEXT_ALIGN_START || old_align == SP_CSS_TEXT_ALIGN_LEFT) { switch (mode) { @@ -6748,8 +6760,8 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) XY = XY + Geom::Point (0, move); } SP_TEXT(item)->attributes.setFirstXY(XY); - SP_OBJECT(item)->updateRepr(); - SP_OBJECT(item)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + item->updateRepr(); + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } @@ -6799,8 +6811,11 @@ static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) sp_style_unref(query); sp_desktop_set_style (desktop, css, true, true); - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + if (result_numbers != QUERY_STYLE_NOTHING) + { + DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, _("Text: Change alignment")); + } sp_repr_css_attr_unref (css); gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas)); @@ -6831,15 +6846,19 @@ static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) // Until deprecated sodipodi:linespacing purged: Inkscape::Selection *selection = sp_desktop_selection(desktop); GSList const *items = selection->itemList(); + bool modmade = false; for (; items != NULL; items = items->next) { if (SP_IS_TEXT (items->data)) { - SP_OBJECT_REPR(items->data)->setAttribute("sodipodi:linespacing", sp_repr_css_property (css, "line-height", NULL)); + SP_OBJECT(items->data)->getRepr()->setAttribute("sodipodi:linespacing", sp_repr_css_property (css, "line-height", NULL)); + modmade = true; } } // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:line-height", SP_VERB_NONE, + if(modmade) { + DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:line-height", SP_VERB_NONE, _("Text: Change line-height")); + } // If no selected objects, set default. SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); @@ -6876,10 +6895,6 @@ static void sp_text_wordspacing_value_changed( GtkAdjustment *adj, GObject *tbl SPDesktop *desktop = SP_ACTIVE_DESKTOP; sp_desktop_set_style (desktop, css, true, false); - // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:word-spacing", SP_VERB_NONE, - _("Text: Change word-spacing")); - // If no selected objects, set default. SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); int result_numbers = @@ -6888,6 +6903,10 @@ static void sp_text_wordspacing_value_changed( GtkAdjustment *adj, GObject *tbl { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->mergeStyle("/tools/text/style", css); + } else { + // Save for undo + DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:word-spacing", SP_VERB_NONE, + _("Text: Change word-spacing")); } sp_style_unref(query); @@ -6915,9 +6934,6 @@ static void sp_text_letterspacing_value_changed( GtkAdjustment *adj, GObject *tb SPDesktop *desktop = SP_ACTIVE_DESKTOP; sp_desktop_set_style (desktop, css, true, false); - // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:letter-spacing", SP_VERB_NONE, - _("Text: Change letter-spacing")); // If no selected objects, set default. SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); @@ -6928,8 +6944,16 @@ static void sp_text_letterspacing_value_changed( GtkAdjustment *adj, GObject *tb Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->mergeStyle("/tools/text/style", css); } + else + { + // Save for undo + DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:letter-spacing", SP_VERB_NONE, + _("Text: Change letter-spacing")); + } + sp_style_unref(query); + sp_repr_css_attr_unref (css); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -6945,6 +6969,7 @@ static void sp_text_dx_value_changed( GtkAdjustment *adj, GObject *tbl ) g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); gdouble new_dx = adj->value; + bool modmade = false; if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); @@ -6956,14 +6981,16 @@ static void sp_text_dx_value_changed( GtkAdjustment *adj, GObject *tbl ) double old_dx = attributes->getDx( char_index ); double delta_dx = new_dx - old_dx; sp_te_adjust_dx( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_dx ); + modmade = true; } } } - // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:dx", SP_VERB_NONE, + if(modmade) { + // Save for undo + DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:dx", SP_VERB_NONE, _("Text: Change dx (kern)")); - + } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } @@ -6976,6 +7003,7 @@ static void sp_text_dy_value_changed( GtkAdjustment *adj, GObject *tbl ) g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); gdouble new_dy = adj->value; + bool modmade = false; if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); @@ -6987,13 +7015,16 @@ static void sp_text_dy_value_changed( GtkAdjustment *adj, GObject *tbl ) double old_dy = attributes->getDy( char_index ); double delta_dy = new_dy - old_dy; sp_te_adjust_dy( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_dy ); + modmade = true; } } } - // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:dy", SP_VERB_NONE, + if(modmade) { + // Save for undo + DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:dy", SP_VERB_NONE, _("Text: Change dy")); + } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } @@ -7008,6 +7039,7 @@ static void sp_text_rotation_value_changed( GtkAdjustment *adj, GObject *tbl ) gdouble new_degrees = adj->value; + bool modmade = false; if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); if( tc ) { @@ -7018,13 +7050,16 @@ static void sp_text_rotation_value_changed( GtkAdjustment *adj, GObject *tbl ) double old_degrees = attributes->getRotate( char_index ); double delta_deg = new_degrees - old_degrees; sp_te_adjust_rotation( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_deg ); - } + modmade = true; + } } } // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:rotate", SP_VERB_NONE, + if(modmade) { + DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:rotate", SP_VERB_NONE, _("Text: Change rotate")); + } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } @@ -7068,8 +7103,11 @@ static void sp_text_orientation_mode_changed( EgeSelectOneAction *act, GObject * } sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, + if(result_numbers != QUERY_STYLE_NOTHING) + { + DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, _("Text: Change orientation")); + } sp_repr_css_attr_unref (css); g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); @@ -7217,7 +7255,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Superscript gboolean superscriptSet = - ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && + ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && query->baseline_shift.set && query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); @@ -7228,7 +7266,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ // Subscript gboolean subscriptSet = - ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && + ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && query->baseline_shift.set && query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); @@ -7302,7 +7340,7 @@ static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/ double letterSpacing; if (query->letter_spacing.normal) letterSpacing = 0.0; else letterSpacing = query->letter_spacing.computed; // Assume no units (change in desktop-style.cpp) - + GtkAction* letterSpacingAction = GTK_ACTION( g_object_get_data( tbl, "TextLetterSpacingAction" ) ); GtkAdjustment *letterSpacingAdjustment = ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( letterSpacingAction )); @@ -7639,7 +7677,7 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions /* Line height */ { // Drop down menu - gchar const* labels[] = {_("Smaller spacing"), 0, 0, 0, 0, _("Normal"), 0, 0, 0, 0, 0, _("Larger spacing")}; + gchar const* labels[] = {_("Smaller spacing"), 0, 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, _("Larger spacing")}; gdouble values[] = { 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1,2, 1.3, 1.4, 1.5, 2.0}; EgeAdjustmentAction *eact = create_adjustment_action( @@ -7670,7 +7708,7 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions /* Word spacing */ { // Drop down menu - gchar const* labels[] = {_("Negative spacing"), 0, 0, 0, _("Normal"), 0, 0, 0, 0, 0, 0, 0, _("Positive spacing")}; + gchar const* labels[] = {_("Negative spacing"), 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, 0, 0, _("Positive spacing")}; gdouble values[] = {-2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0}; EgeAdjustmentAction *eact = create_adjustment_action( @@ -7701,7 +7739,7 @@ static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions /* Letter spacing */ { // Drop down menu - gchar const* labels[] = {_("Negative spacing"), 0, 0, 0, _("Normal"), 0, 0, 0, 0, 0, 0, 0, _("Positive spacing")}; + gchar const* labels[] = {_("Negative spacing"), 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, 0, 0, _("Positive spacing")}; gdouble values[] = {-2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0}; EgeAdjustmentAction *eact = create_adjustment_action( @@ -7913,10 +7951,11 @@ static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl if (!modmade) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setBool("/tools/connector/orthogonal", is_orthog); - } + } else { - DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, + DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, is_orthog ? _("Set connector type: orthogonal"): _("Set connector type: polyline")); + } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } @@ -7962,9 +8001,10 @@ static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) Inkscape::Preferences *prefs = Inkscape::Preferences::get(); prefs->setDouble(Glib::ustring("/tools/connector/curvature"), newValue); } - - DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, + else { + DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, _("Change connector curvature")); + } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } @@ -7979,7 +8019,7 @@ static void connector_spacing_changed(GtkAdjustment *adj, GObject* tbl) return; } - Inkscape::XML::Node *repr = SP_OBJECT_REPR(desktop->namedview); + Inkscape::XML::Node *repr = desktop->namedview->getRepr(); if ( !repr->attribute("inkscape:connector-spacing") && ( adj->value == defaultConnSpacing )) { @@ -7998,22 +8038,24 @@ static void connector_spacing_changed(GtkAdjustment *adj, GObject* tbl) g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); sp_repr_set_css_double(repr, "inkscape:connector-spacing", adj->value); - SP_OBJECT(desktop->namedview)->updateRepr(); + desktop->namedview->updateRepr(); + bool modmade = false; GSList *items = get_avoided_items(NULL, desktop->currentRoot(), desktop); for ( GSList const *iter = items ; iter != NULL ; iter = iter->next ) { SPItem *item = reinterpret_cast<SPItem *>(iter->data); - Geom::Matrix m = Geom::identity(); + Geom::Affine m = Geom::identity(); avoid_item_move(&m, item); + modmade = true; } if (items) { g_slist_free(items); } - - DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, + if(modmade) { + DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, _("Change connector spacing")); - + } g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); } @@ -8278,7 +8320,7 @@ static void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainA // Code to watch for changes to the connector-spacing attribute in // the XML. - Inkscape::XML::Node *repr = SP_OBJECT_REPR(desktop->namedview); + Inkscape::XML::Node *repr = desktop->namedview->getRepr(); g_assert(repr != NULL); purge_repr_listener( holder, holder ); @@ -8411,7 +8453,7 @@ static void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main _("Grow/shrink by"), _("Grow/shrink by:"), _("The amount to grow (positive) or shrink (negative) the created fill path"), "/tools/paintbucket/offset", 0, GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, TRUE, - "inkscape:paintbucket-offset", -1e6, 1e6, 0.1, 0.5, + "inkscape:paintbucket-offset", -1e4, 1e4, 0.1, 0.5, 0, 0, 0, paintbucket_offset_changed, 1, 2); tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); |
