Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / widgets / gradient-toolbar.cpp
index da84eafca659ad5161ed310e53588293adcbd6c4..e7596ead42e5c99c2057b43e263b24ff616a877f 100644 (file)
@@ -3,7 +3,10 @@
  *
  * Authors:
  *   bulia byak <bulia@dr.com>
+ *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
+ *   Abhishek Sharma
  *
+ * Copyright (C) 2007 Johan Engelen
  * Copyright (C) 2005 authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
@@ -24,7 +27,7 @@
 #include "widgets/gradient-image.h"
 #include "style.h"
 
-#include "prefs-utils.h"
+#include "preferences.h"
 #include "document-private.h"
 #include "desktop.h"
 #include "desktop-handles.h"
 #include "sp-radial-gradient.h"
 #include "gradient-chemistry.h"
 #include "selection.h"
+#include "ui/icon-names.h"
 
 #include "toolbox.h"
 
+using Inkscape::DocumentUndo;
 
 //########################
 //##       Gradient     ##
 //########################
 
 static void gr_toggle_type (GtkWidget *button, gpointer data) {
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     GtkWidget *linear = (GtkWidget *) g_object_get_data (G_OBJECT(data), "linear");
     GtkWidget *radial = (GtkWidget *) g_object_get_data (G_OBJECT(data), "radial");
     if (button == linear && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (linear))) {
-        prefs_set_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR);
+        prefs->setInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR);
         if (radial) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radial), FALSE);
     } else if (button == radial && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radial))) {
-        prefs_set_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_RADIAL);
+        prefs->setInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_RADIAL);
         if (linear) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (linear), FALSE);
     }
 }
 
 static void gr_toggle_fillstroke (GtkWidget *button, gpointer data) {
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     GtkWidget *fill = (GtkWidget *) g_object_get_data (G_OBJECT(data), "fill");
     GtkWidget *stroke = (GtkWidget *) g_object_get_data (G_OBJECT(data), "stroke");
     if (button == fill && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (fill))) {
-        prefs_set_int_attribute ("tools.gradient", "newfillorstroke", 1);
+        prefs->setBool("/tools/gradient/newfillorstroke", true);
         if (stroke) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (stroke), FALSE);
     } else if (button == stroke && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (stroke))) {
-        prefs_set_int_attribute ("tools.gradient", "newfillorstroke", 0);
+        prefs->setBool("/tools/gradient/newfillorstroke", false);
         if (fill) gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fill), FALSE);
     }
 }
 
-void
-gr_apply_gradient_to_item (SPItem *item, SPGradient *gr, SPGradientType new_type, guint new_fill, bool do_fill, bool do_stroke)
+void gr_apply_gradient_to_item( SPItem *item, SPGradient *gr, SPGradientType new_type, guint new_fill, bool do_fill, bool do_stroke )
 {
-    SPStyle *style = SP_OBJECT_STYLE (item);
+    SPStyle *style = item->style;
 
     if (do_fill) {
-        if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER) && 
-            SP_IS_GRADIENT (SP_OBJECT_STYLE_FILL_SERVER (item))) {
-            SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
-            if (SP_IS_LINEARGRADIENT (server)) {
+        if (style && (style->fill.isPaintserver()) &&
+            SP_IS_GRADIENT( item->style->getFillPaintServer() )) {
+            SPPaintServer *server = item->style->getFillPaintServer();
+            if ( SP_IS_LINEARGRADIENT(server) ) {
                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, true);
-            } else if (SP_IS_RADIALGRADIENT (server)) {
+            } else if ( SP_IS_RADIALGRADIENT(server) ) {
                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, true);
-            } 
+            }
         } else if (new_fill) {
             sp_item_set_gradient(item, gr, new_type, true);
         }
-    } 
+    }
 
     if (do_stroke) {
-        if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER) && 
-            SP_IS_GRADIENT (SP_OBJECT_STYLE_STROKE_SERVER (item))) {
-            SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
-            if (SP_IS_LINEARGRADIENT (server)) {
+        if (style && (style->stroke.isPaintserver()) &&
+            SP_IS_GRADIENT( item->style->getStrokePaintServer() )) {
+            SPPaintServer *server = item->style->getStrokePaintServer();
+            if ( SP_IS_LINEARGRADIENT(server) ) {
                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_LINEAR, false);
-            } else if (SP_IS_RADIALGRADIENT (server)) {
+            } else if ( SP_IS_RADIALGRADIENT(server) ) {
                 sp_item_set_gradient(item, gr, SP_GRADIENT_TYPE_RADIAL, false);
-            } 
+            }
         } else if (!new_fill) {
             sp_item_set_gradient(item, gr, new_type, false);
         }
@@ -111,12 +117,16 @@ gradient.
 void
 gr_apply_gradient (Inkscape::Selection *selection, GrDrag *drag, SPGradient *gr)
 {
-    SPGradientType new_type = (SPGradientType) prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR);
-    guint new_fill = prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1);
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    SPGradientType new_type = (SPGradientType) prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR);
+    guint new_fill = prefs->getBool("/tools/gradient/newfillorstroke", true);
+
+
+    // GRADIENTFIXME: make this work for multiple selected draggers.
 
     // First try selected dragger
     if (drag && drag->selected) {
-        GrDragger *dragger = drag->selected;
+        GrDragger *dragger = (GrDragger*) drag->selected->data;
         for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
             GrDraggable *draggable = (GrDraggable *) i->data;
             gr_apply_gradient_to_item (draggable->item, gr, new_type, new_fill, draggable->fill_or_stroke, !draggable->fill_or_stroke);
@@ -126,7 +136,7 @@ gr_apply_gradient (Inkscape::Selection *selection, GrDrag *drag, SPGradient *gr)
 
    // If no drag or no dragger selected, act on selection
    for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
-       gr_apply_gradient_to_item (SP_ITEM(i->data), gr, new_type, new_fill, true, true);
+       gr_apply_gradient_to_item (SP_ITEM(i->data), gr, new_type, new_fill, new_fill, !new_fill);
    }
 }
 
@@ -142,21 +152,20 @@ gr_item_activate (GtkMenuItem *menuitem, gpointer data)
 
     gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr);
 
-    sp_document_done (sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT,
-                      /* TODO: annotate */ "gradient-toolbar.cpp:146");
+    DocumentUndo::done(sp_desktop_document (desktop), SP_VERB_CONTEXT_GRADIENT,
+                      _("Assign gradient to object"));
 }
 
 gchar *
 gr_prepare_label (SPObject *obj)
 {
     const gchar *id = obj->defaultLabel();
-    if (strlen(id) > 15 && (!strncmp (id, "#linearGradient", 15) || !strncmp (id, "#radialGradient", 15))) 
+    if (strlen(id) > 15 && (!strncmp (id, "#linearGradient", 15) || !strncmp (id, "#radialGradient", 15)))
         return g_strdup_printf ("<small>#%s</small>", id+15);
     return g_strdup_printf ("<small>%s</small>", id);
 }
 
-GtkWidget *
-gr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
+GtkWidget *gr_vector_list(SPDesktop *desktop, bool selection_empty, SPGradient *gr_selected, bool gr_multi)
 {
     SPDocument *document = sp_desktop_document (desktop);
 
@@ -164,18 +173,20 @@ gr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selecte
     GtkWidget *m = gtk_menu_new ();
 
     GSList *gl = NULL;
-    const GSList *gradients = sp_document_get_resource_list (document, "gradient");
-               for (const GSList *i = gradients; i != NULL; i = i->next) {
-        if (SP_GRADIENT_HAS_STOPS (i->data)) {
+    const GSList *gradients = document->getResourceList("gradient");
+    for (const GSList *i = gradients; i != NULL; i = i->next) {
+        SPGradient *grad = SP_GRADIENT(i->data);
+        if ( grad->hasStops() && !grad->isSolid() ) {
             gl = g_slist_prepend (gl, i->data);
         }
-               }
+    }
     gl = g_slist_reverse (gl);
 
     guint pos = 0;
     guint idx = 0;
 
     if (!gl) {
+        // The document has no gradients
         GtkWidget *l = gtk_label_new("");
         gtk_label_set_markup (GTK_LABEL(l), _("<small>No gradients</small>"));
         GtkWidget *i = gtk_menu_item_new ();
@@ -185,6 +196,7 @@ gr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selecte
         gtk_menu_append (GTK_MENU (m), i);
         gtk_widget_set_sensitive (om, FALSE);
     } else if (selection_empty) {
+        // Document has gradients, but nothing is currently selected.
         GtkWidget *l = gtk_label_new("");
         gtk_label_set_markup (GTK_LABEL(l), _("<small>Nothing selected</small>"));
         GtkWidget *i = gtk_menu_item_new ();
@@ -227,7 +239,7 @@ gr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selecte
 
             GtkWidget *hb = gtk_hbox_new (FALSE, 4);
             GtkWidget *l = gtk_label_new ("");
-            gchar *label = gr_prepare_label (SP_OBJECT(gradient));
+            gchar *label = gr_prepare_label(gradient);
             gtk_label_set_markup (GTK_LABEL(l), label);
             g_free (label);
             gtk_misc_set_alignment (GTK_MISC (l), 1.0, 0.5);
@@ -252,84 +264,103 @@ gr_vector_list (SPDesktop *desktop, bool selection_empty, SPGradient *gr_selecte
     /* Select the current gradient, or the Multi/Nothing line */
     if (gr_multi || gr_selected == NULL)
         gtk_option_menu_set_history (GTK_OPTION_MENU (om), 0);
-    else 
+    else
         gtk_option_menu_set_history (GTK_OPTION_MENU (om), pos);
 
     return om;
 }
 
 
-void
-gr_read_selection (Inkscape::Selection *selection, GrDrag *drag, SPGradient **gr_selected, bool *gr_multi, SPGradientSpread *spr_selected, bool *spr_multi) 
+void gr_read_selection( Inkscape::Selection *selection,
+                        GrDrag *drag,
+                        SPGradient *&gr_selected,
+                        bool &gr_multi,
+                        SPGradientSpread &spr_selected,
+                        bool &spr_multi )
 {
     if (drag && drag->selected) {
-        GrDragger *dragger = drag->selected;
-        for (GSList const* i = dragger->draggables; i != NULL; i = i->next) { // for all draggables of dragger
-            GrDraggable *draggable = (GrDraggable *) i->data;
-            SPGradient *gradient = sp_item_gradient_get_vector (draggable->item, draggable->fill_or_stroke);
-            SPGradientSpread spread = sp_item_gradient_get_spread (draggable->item, draggable->fill_or_stroke);
+        // GRADIENTFIXME: make this work for more than one selected dragger?
+        GrDragger *dragger = static_cast<GrDragger*>(drag->selected->data);
+        for (GSList const* i = dragger->draggables; i; i = i->next) { // for all draggables of dragger
+            GrDraggable *draggable = static_cast<GrDraggable *>(i->data);
+            SPGradient *gradient = sp_item_gradient_get_vector(draggable->item, draggable->fill_or_stroke);
+            SPGradientSpread spread = sp_item_gradient_get_spread(draggable->item, draggable->fill_or_stroke);
+
+            if (gradient && gradient->isSolid()) {
+                gradient = 0;
+            }
 
-            if (gradient != *gr_selected) {
-                if (*gr_selected != NULL) {
-                    *gr_multi = true;
+            if (gradient && (gradient != gr_selected)) {
+                if (gr_selected) {
+                    gr_multi = true;
                 } else {
-                    *gr_selected = gradient;
+                    gr_selected = gradient;
                 }
             }
-            if (spread != *spr_selected) {
-                if (*spr_selected != INT_MAX) {
-                    *spr_multi = true;
+            if (spread != spr_selected) {
+                if (spr_selected != INT_MAX) {
+                    spr_multi = true;
                 } else {
-                    *spr_selected = spread;
+                    spr_selected = spread;
                 }
             }
          }
         return;
-    } 
+    }
 
    // If no selected dragger, read desktop selection
-   for (GSList const* i = selection->itemList(); i != NULL; i = i->next) {
+   for (GSList const* i = selection->itemList(); i; i = i->next) {
         SPItem *item = SP_ITEM(i->data);
-        SPStyle *style = SP_OBJECT_STYLE (item);
-
-        if (style && (style->fill.type == SP_PAINT_TYPE_PAINTSERVER)) { 
-            SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (item);
-            if (SP_IS_GRADIENT (server)) {
-                SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
-                SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
-                if (gradient != *gr_selected) {
-                    if (*gr_selected != NULL) {
-                        *gr_multi = true;
+        SPStyle *style = item->style;
+
+        if (style && (style->fill.isPaintserver())) {
+            SPPaintServer *server = item->style->getFillPaintServer();
+            if ( SP_IS_GRADIENT(server) ) {
+                SPGradient *gradient = SP_GRADIENT(server)->getVector();
+                SPGradientSpread spread = SP_GRADIENT(server)->fetchSpread();
+
+                if (gradient && gradient->isSolid()) {
+                    gradient = 0;
+                }
+
+                if (gradient && (gradient != gr_selected)) {
+                    if (gr_selected) {
+                        gr_multi = true;
                     } else {
-                        *gr_selected = gradient;
+                        gr_selected = gradient;
                     }
                 }
-                if (spread != *spr_selected) {
-                    if (*spr_selected != INT_MAX) {
-                        *spr_multi = true;
+                if (spread != spr_selected) {
+                    if (spr_selected != INT_MAX) {
+                        spr_multi = true;
                     } else {
-                        *spr_selected = spread;
+                        spr_selected = spread;
                     }
                 }
             }
         }
-        if (style && (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER)) { 
-            SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (item);
-            if (SP_IS_GRADIENT (server)) {
-                SPGradient *gradient = sp_gradient_get_vector (SP_GRADIENT (server), false);
-                SPGradientSpread spread = sp_gradient_get_spread (SP_GRADIENT (server));
-                if (gradient != *gr_selected) {
-                    if (*gr_selected != NULL) {
-                        *gr_multi = true;
+        if (style && (style->stroke.isPaintserver())) {
+            SPPaintServer *server = item->style->getStrokePaintServer();
+            if ( SP_IS_GRADIENT(server) ) {
+                SPGradient *gradient = SP_GRADIENT(server)->getVector();
+                SPGradientSpread spread = SP_GRADIENT(server)->fetchSpread();
+
+                if (gradient && gradient->isSolid()) {
+                    gradient = 0;
+                }
+
+                if (gradient && (gradient != gr_selected)) {
+                    if (gr_selected) {
+                        gr_multi = true;
                     } else {
-                        *gr_selected = gradient;
+                        gr_selected = gradient;
                     }
                 }
-                if (spread != *spr_selected) {
-                    if (*spr_selected != INT_MAX) {
-                        *spr_multi = true;
+                if (spread != spr_selected) {
+                    if (spr_selected != INT_MAX) {
+                        spr_multi = true;
                     } else {
-                        *spr_selected = spread;
+                        spr_selected = spread;
                     }
                 }
             }
@@ -337,106 +368,74 @@ gr_read_selection (Inkscape::Selection *selection, GrDrag *drag, SPGradient **gr
     }
  }
 
-static void 
-gr_tb_selection_changed (Inkscape::Selection *, gpointer data)
+static void gr_tb_selection_changed(Inkscape::Selection * /*selection*/, gpointer data)
 {
-    GtkWidget *widget = (GtkWidget *) data;
+    GtkWidget *widget = GTK_WIDGET(data);
+
+    SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(G_OBJECT(widget), "desktop"));
+    if (desktop) {
+        Inkscape::Selection *selection = sp_desktop_selection(desktop); // take from desktop, not from args
+        if (selection) {
+            SPEventContext *ev = sp_desktop_event_context(desktop);
+
+            GtkWidget *om = (GtkWidget *) g_object_get_data(G_OBJECT(widget), "menu");
+            if (om) {
+                gtk_widget_destroy(om);
+                om = 0;
+            }
 
-    SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
-    if (!desktop)
-        return;
+            SPGradient *gr_selected = 0;
+            bool gr_multi = false;
 
-    Inkscape::Selection *selection = sp_desktop_selection (desktop); // take from desktop, not from args
-    if (!selection) 
-        return;
-    
-    SPEventContext *ev = sp_desktop_event_context (desktop);
+            SPGradientSpread spr_selected = static_cast<SPGradientSpread>(INT_MAX); // meaning undefined
+            bool spr_multi = false;
 
-    GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT (widget), "menu");
-    if (om) gtk_widget_destroy (om);
+            gr_read_selection(selection, ev ? ev->get_drag() : 0, gr_selected, gr_multi, spr_selected, spr_multi);
 
-    SPGradient *gr_selected = NULL;
-    bool gr_multi = false;
+            om = gr_vector_list(desktop, selection->isEmpty(), gr_selected, gr_multi);
+            g_object_set_data(G_OBJECT(widget), "menu", om);
 
-    SPGradientSpread spr_selected = (SPGradientSpread) INT_MAX; // meaning undefined
-    bool spr_multi = false;
-
-    gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
-
-    om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
-    g_object_set_data (G_OBJECT (widget), "menu", om);
+            GtkWidget *buttons = (GtkWidget *) g_object_get_data(G_OBJECT(widget), "buttons");
+            gtk_widget_set_sensitive(buttons, (gr_selected && !gr_multi));
 
-    GtkWidget *buttons = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "buttons");
-    gtk_widget_set_sensitive (buttons, (gr_selected && !gr_multi));
-  
-    gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
+            gtk_box_pack_start(GTK_BOX(widget), om, TRUE, TRUE, 0);
 
-    gtk_widget_show_all (widget);
+            gtk_widget_show_all(widget);
+        }
+    }
 }
 
 static void
-gr_tb_selection_modified (Inkscape::Selection *selection, guint flags, gpointer data)
+gr_tb_selection_modified (Inkscape::Selection *selection, guint /*flags*/, gpointer data)
 {
     gr_tb_selection_changed (selection, data);
 }
 
 static void
-gr_drag_selection_changed (gpointer dragger, gpointer data)
+gr_drag_selection_changed (gpointer /*dragger*/, gpointer data)
 {
     gr_tb_selection_changed (NULL, data);
 }
 
 static void
-gr_defs_release (SPObject *defs, GtkWidget *widget)
+gr_defs_release (SPObject */*defs*/, GtkWidget *widget)
 {
     gr_tb_selection_changed (NULL, (gpointer) widget);
 }
 
 static void
-gr_defs_modified (SPObject *defs, guint flags, GtkWidget *widget)
+gr_defs_modified (SPObject */*defs*/, guint /*flags*/, GtkWidget *widget)
 {
     gr_tb_selection_changed (NULL, (gpointer) widget);
 }
 
-static void
-gr_fork (GtkWidget *button, GtkWidget *widget)
-{
-    SPDesktop *desktop = (SPDesktop *) g_object_get_data (G_OBJECT(widget), "desktop");
-    SPDocument *document = sp_desktop_document (desktop);
-    Inkscape::Selection *selection = sp_desktop_selection (desktop);
-    SPEventContext *ev = sp_desktop_event_context (desktop);
-    GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
-
-    if (om && document) {
-        GtkWidget *i = gtk_menu_get_active (GTK_MENU (gtk_option_menu_get_menu (GTK_OPTION_MENU (om))));
-        SPGradient *gr = (SPGradient *) g_object_get_data (G_OBJECT(i), "gradient");
-
-        if (gr) {
-            SPGradient *gr_new = sp_gradient_fork_vector_if_necessary (gr);
-            if (gr_new != gr) {
-                gr_apply_gradient (selection, ev? ev->get_drag() : NULL, gr_new);
-                sp_document_done (document, SP_VERB_CONTEXT_GRADIENT,
-                                  /* TODO: annotate */ "gradient-toolbar.cpp:419");
-            }
-        }
-    }
-
-    spinbutton_defocus(GTK_OBJECT(widget));
-}
-
-static void gr_disconnect_sigc (GObject *obj, sigc::connection *connection) {
+static void gr_disconnect_sigc (GObject */*obj*/, sigc::connection *connection) {
     connection->disconnect();
     delete connection;
 }
 
-static void gr_disconnect_gsignal (GObject *widget, gpointer defs) {
-    if (defs && G_IS_OBJECT(defs))
-        sp_signal_disconnect_by_data (defs, widget);
-}
-
-
 static void
-gr_edit (GtkWidget *button, GtkWidget *widget)
+gr_edit (GtkWidget */*button*/, GtkWidget *widget)
 {
     GtkWidget *om = (GtkWidget *) g_object_get_data (G_OBJECT(widget), "menu");
 
@@ -453,8 +452,7 @@ gr_edit (GtkWidget *button, GtkWidget *widget)
     }
 }
 
-GtkWidget *
-gr_change_widget (SPDesktop *desktop)
+GtkWidget * gr_change_widget(SPDesktop *desktop)
 {
     Inkscape::Selection *selection = sp_desktop_selection (desktop);
     SPDocument *document = sp_desktop_document (desktop);
@@ -468,31 +466,20 @@ gr_change_widget (SPDesktop *desktop)
 
     GtkTooltips *tt = gtk_tooltips_new();
 
-    gr_read_selection (selection, ev? ev->get_drag() : NULL, &gr_selected, &gr_multi, &spr_selected, &spr_multi);
+    gr_read_selection (selection, ev? ev->get_drag() : 0, gr_selected, gr_multi, spr_selected, spr_multi);
+
     GtkWidget *widget = gtk_hbox_new(FALSE, FALSE);
     gtk_object_set_data(GTK_OBJECT(widget), "dtw", desktop->canvas);
     g_object_set_data (G_OBJECT (widget), "desktop", desktop);
 
     GtkWidget *om = gr_vector_list (desktop, selection->isEmpty(), gr_selected, gr_multi);
     g_object_set_data (G_OBJECT (widget), "menu", om);
-  
+
     gtk_box_pack_start (GTK_BOX (widget), om, TRUE, TRUE, 0);
 
     {
     GtkWidget *buttons = gtk_hbox_new(FALSE, 1);
 
-    /* Fork */
-    {
-        GtkWidget *hb = gtk_hbox_new(FALSE, 1);
-        GtkWidget *b = gtk_button_new_with_label(_("Duplicate"));
-        gtk_tooltips_set_tip(tt, b, _("If the gradient is used by more than one object, create a copy of it for the selected object(s)"), NULL);
-        gtk_widget_show(b);
-        gtk_container_add(GTK_CONTAINER(hb), b);
-        gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(gr_fork), widget);
-        gtk_box_pack_start (GTK_BOX(buttons), hb, FALSE, FALSE, 0);
-    }
-
     /* Edit... */
     {
         GtkWidget *hb = gtk_hbox_new(FALSE, 1);
@@ -533,12 +520,14 @@ gr_change_widget (SPDesktop *desktop)
     g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), conn3);
 
     // connect to release and modified signals of the defs (i.e. when someone changes gradient)
-    g_signal_connect (G_OBJECT (SP_DOCUMENT_DEFS (document)), "release", G_CALLBACK (gr_defs_release), widget);
-    g_signal_connect (G_OBJECT (SP_DOCUMENT_DEFS (document)), "modified", G_CALLBACK (gr_defs_modified), widget);
+    sigc::connection *release_connection = new sigc::connection();
+    *release_connection = SP_DOCUMENT_DEFS(document)->connectRelease(sigc::bind<1>(sigc::ptr_fun(&gr_defs_release), widget));
+    sigc::connection *modified_connection = new sigc::connection();
+    *modified_connection = SP_DOCUMENT_DEFS(document)->connectModified(sigc::bind<2>(sigc::ptr_fun(&gr_defs_modified), widget));
 
     // when widget is destroyed, disconnect
-    g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_gsignal), G_OBJECT (SP_DOCUMENT_DEFS (document)));
-    g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_gsignal), G_OBJECT (SP_DOCUMENT_DEFS (document)));
+    g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), release_connection);
+    g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(gr_disconnect_sigc), modified_connection);
 
     gtk_widget_show_all (widget);
     return widget;
@@ -547,7 +536,8 @@ gr_change_widget (SPDesktop *desktop)
 GtkWidget *
 sp_gradient_toolbox_new(SPDesktop *desktop)
 {
-    GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    GtkWidget *tbl = gtk_toolbar_new();
 
     gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
     gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
@@ -556,7 +546,7 @@ sp_gradient_toolbox_new(SPDesktop *desktop)
 
     sp_toolbox_add_label(tbl, _("<b>New:</b>"));
 
-    aux_toolbox_space(tbl, AUX_SPACING);
+    // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
 
     {
     GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
@@ -566,13 +556,13 @@ sp_gradient_toolbox_new(SPDesktop *desktop)
     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
                                               SP_BUTTON_TYPE_TOGGLE,
                                               NULL,
-                                              "fill_gradient",
+                                              INKSCAPE_ICON_PAINT_GRADIENT_LINEAR,
                                               _("Create linear gradient"),
                                               tt);
     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
     g_object_set_data(G_OBJECT(tbl), "linear", button);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
-              prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+              prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_LINEAR);
     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
     }
 
@@ -580,25 +570,25 @@ sp_gradient_toolbox_new(SPDesktop *desktop)
     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
                                               SP_BUTTON_TYPE_TOGGLE,
                                               NULL,
-                                              "fill_radial",
+                                              INKSCAPE_ICON_PAINT_GRADIENT_RADIAL,
                                               _("Create radial (elliptic or circular) gradient"),
                                               tt);
     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_type), tbl);
     g_object_set_data(G_OBJECT(tbl), "radial", button);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
-              prefs_get_int_attribute ("tools.gradient", "newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+              prefs->getInt("/tools/gradient/newgradient", SP_GRADIENT_TYPE_LINEAR) == SP_GRADIENT_TYPE_RADIAL);
     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
     }
 
     gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
+    gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), cvbox, "", "" );
     }
 
-    aux_toolbox_space(tbl, AUX_SPACING);
+    // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
 
     sp_toolbox_add_label(tbl, _("on"), false);
 
-    aux_toolbox_space(tbl, AUX_SPACING);
+    // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
 
     {
         GtkWidget *cvbox = gtk_vbox_new (FALSE, 0);
@@ -608,13 +598,13 @@ sp_gradient_toolbox_new(SPDesktop *desktop)
     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
                                               SP_BUTTON_TYPE_TOGGLE,
                                               NULL,
-                                              "controls_fill",
+                                              INKSCAPE_ICON_OBJECT_FILL,
                                               _("Create gradient in the fill"),
                                               tt);
     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
     g_object_set_data(G_OBJECT(tbl), "fill", button);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
-                                  prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 1);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+                                  prefs->getBool("/tools/gradient/newfillorstroke", true));
     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
     }
 
@@ -622,28 +612,28 @@ sp_gradient_toolbox_new(SPDesktop *desktop)
     GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION,
                                               SP_BUTTON_TYPE_TOGGLE,
                                               NULL,
-                                              "controls_stroke",
+                                              INKSCAPE_ICON_OBJECT_STROKE,
                                               _("Create gradient in the stroke"),
                                               tt);
     g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (gr_toggle_fillstroke), tbl);
     g_object_set_data(G_OBJECT(tbl), "stroke", button);
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), 
-                                  prefs_get_int_attribute ("tools.gradient", "newfillorstroke", 1) == 0);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button),
+                                  !prefs->getBool("/tools/gradient/newfillorstroke", true));
     gtk_box_pack_start(GTK_BOX(cbox), button, FALSE, FALSE, 0);
     }
 
     gtk_box_pack_start(GTK_BOX(cvbox), cbox, TRUE, TRUE, 3);
-    gtk_box_pack_start(GTK_BOX(tbl), cvbox, FALSE, FALSE, 0);
+    gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), cvbox, "", "" );
     }
 
 
     sp_toolbox_add_label(tbl, _("<b>Change:</b>"));
 
-    aux_toolbox_space(tbl, AUX_SPACING);
+    // TODO replace aux_toolbox_space(tbl, AUX_SPACING);
 
     {
         GtkWidget *vectors = gr_change_widget (desktop);
-        gtk_box_pack_start (GTK_BOX (tbl), vectors, FALSE, FALSE, 0);
+        gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), vectors, "", "" );
     }
 
     gtk_widget_show_all(tbl);