Code

Rename LPE: mirror reflect --> mirror symmetry
[inkscape.git] / src / widgets / toolbox.cpp
index a4d24203f95bfae6fe2ab1f8adba82ba69379c5b..8f3c570c54d30af33c65b77abf17af574a48fa13 100644 (file)
@@ -27,6 +27,9 @@
 # include "config.h"
 #endif
 
+#include <cstring>
+#include <string>
+
 #include <gtkmm.h>
 #include <gtk/gtk.h>
 #include <iostream>
@@ -37,6 +40,7 @@
 #include "widgets/spw-utilities.h"
 #include "widgets/spinbutton-events.h"
 #include "dialogs/text-edit.h"
+#include "dialogs/dialog-events.h"
 
 #include "ui/widget/style-swatch.h"
 
@@ -50,6 +54,7 @@
 #include <glibmm/i18n.h>
 #include "helper/unit-menu.h"
 #include "helper/units.h"
+#include "live_effects/effect.h"
 
 #include "inkscape.h"
 #include "conn-avoid-ref.h"
@@ -60,6 +65,7 @@
 
 #include "connector-context.h"
 #include "node-context.h"
+#include "draw-context.h"
 #include "shape-editor.h"
 #include "tweak-context.h"
 #include "sp-rect.h"
 #include "sp-ellipse.h"
 #include "sp-text.h"
 #include "sp-flowtext.h"
+#include "sp-clippath.h"
+#include "sp-mask.h"
 #include "style.h"
 #include "selection.h"
+#include "selection-chemistry.h"
 #include "document-private.h"
 #include "desktop-style.h"
 #include "../libnrtype/font-lister.h"
+#include "../libnrtype/font-instance.h"
 #include "../connection-pool.h"
 #include "../prefs-utils.h"
 #include "../inkscape-stock.h"
 #include "icon.h"
 #include "graphlayout/graphlayout.h"
+#include "interface.h"
+#include "shortcuts.h"
 
 #include "mod360.h"
 
 #include "ege-select-one-action.h"
 #include "helper/unit-tracker.h"
 
+#include "svg/css-ostringstream.h"
+
+#include "widgets/calligraphic-profile-rename.h"
+
 using Inkscape::UnitTracker;
 
 typedef void (*SetupFunction)(GtkWidget *toolbox, SPDesktop *desktop);
@@ -104,7 +120,7 @@ static void       sp_zoom_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainA
 static void       sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 static void       sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 static void       sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
-static void       sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
+static void       box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 static void       sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 static void       sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 static void       sp_pen_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
@@ -113,10 +129,21 @@ static void       sp_dropper_toolbox_prep(SPDesktop *desktop, GtkActionGroup* ma
 static GtkWidget *sp_empty_toolbox_new(SPDesktop *desktop);
 static void       sp_connector_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 static void       sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
+static void       sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder);
 
 namespace { GtkWidget *sp_text_toolbox_new (SPDesktop *desktop); }
 
 
+Inkscape::IconSize prefToSize( gchar const *path, gchar const *attr, int base ) {
+    static Inkscape::IconSize sizeChoices[] = {
+        Inkscape::ICON_SIZE_LARGE_TOOLBAR,
+        Inkscape::ICON_SIZE_SMALL_TOOLBAR,
+        Inkscape::ICON_SIZE_MENU
+    };
+    int index = prefs_get_int_attribute_limited( path, attr, base, 0, G_N_ELEMENTS(sizeChoices) );
+    return sizeChoices[index];
+}
+
 static struct {
     gchar const *type_name;
     gchar const *data_name;
@@ -128,13 +155,14 @@ static struct {
     { "SPTweakContext",    "tweak_tool",     SP_VERB_CONTEXT_TWEAK, SP_VERB_CONTEXT_TWEAK_PREFS },
     { "SPZoomContext",     "zoom_tool",      SP_VERB_CONTEXT_ZOOM, SP_VERB_CONTEXT_ZOOM_PREFS },
     { "SPRectContext",     "rect_tool",      SP_VERB_CONTEXT_RECT, SP_VERB_CONTEXT_RECT_PREFS },
-//    { "SP3DBoxContext",    "3dbox_tool",     SP_VERB_CONTEXT_3DBOX, SP_VERB_CONTEXT_3DBOX_PREFS },
+    { "Box3DContext",      "3dbox_tool",     SP_VERB_CONTEXT_3DBOX, SP_VERB_CONTEXT_3DBOX_PREFS },
     { "SPArcContext",      "arc_tool",       SP_VERB_CONTEXT_ARC, SP_VERB_CONTEXT_ARC_PREFS },
     { "SPStarContext",     "star_tool",      SP_VERB_CONTEXT_STAR, SP_VERB_CONTEXT_STAR_PREFS },
     { "SPSpiralContext",   "spiral_tool",    SP_VERB_CONTEXT_SPIRAL, SP_VERB_CONTEXT_SPIRAL_PREFS },
     { "SPPencilContext",   "pencil_tool",    SP_VERB_CONTEXT_PENCIL, SP_VERB_CONTEXT_PENCIL_PREFS },
     { "SPPenContext",      "pen_tool",       SP_VERB_CONTEXT_PEN, SP_VERB_CONTEXT_PEN_PREFS },
     { "SPDynaDrawContext", "dyna_draw_tool", SP_VERB_CONTEXT_CALLIGRAPHIC, SP_VERB_CONTEXT_CALLIGRAPHIC_PREFS },
+    { "SPEraserContext",   "eraser_tool",    SP_VERB_CONTEXT_ERASER, SP_VERB_CONTEXT_ERASER_PREFS },
     { "SPFloodContext",    "paintbucket_tool",     SP_VERB_CONTEXT_PAINTBUCKET, SP_VERB_CONTEXT_PAINTBUCKET_PREFS },
     { "SPTextContext",     "text_tool",      SP_VERB_CONTEXT_TEXT, SP_VERB_CONTEXT_TEXT_PREFS },
     { "SPConnectorContext","connector_tool", SP_VERB_CONTEXT_CONNECTOR, SP_VERB_CONTEXT_CONNECTOR_PREFS },
@@ -158,25 +186,27 @@ static struct {
     { "SPNodeContext",   "node_toolbox",   0, sp_node_toolbox_prep,              "NodeToolbar",
       SP_VERB_INVALID, 0, 0},
     { "SPTweakContext",   "tweak_toolbox",   0, sp_tweak_toolbox_prep,              "TweakToolbar",
-      SP_VERB_CONTEXT_TWEAK_PREFS, "tools.tweak", _("Color/opacity used for color tweaking")},
+      SP_VERB_CONTEXT_TWEAK_PREFS, "tools.tweak", N_("Color/opacity used for color tweaking")},
     { "SPZoomContext",   "zoom_toolbox",   0, sp_zoom_toolbox_prep,              "ZoomToolbar",
       SP_VERB_INVALID, 0, 0},
     { "SPStarContext",   "star_toolbox",   0, sp_star_toolbox_prep,              "StarToolbar",
-      SP_VERB_CONTEXT_STAR_PREFS,   "tools.shapes.star",     _("Style of new stars")},
+      SP_VERB_CONTEXT_STAR_PREFS,   "tools.shapes.star",     N_("Style of new stars")},
     { "SPRectContext",   "rect_toolbox",   0, sp_rect_toolbox_prep,              "RectToolbar",
-      SP_VERB_CONTEXT_RECT_PREFS,   "tools.shapes.rect",     _("Style of new rectangles")},
-    { "SP3DBoxContext",  "3dbox_toolbox",  0, sp_3dbox_toolbox_prep,             "3DBoxToolbar",
-      SP_VERB_CONTEXT_3DBOX_PREFS,  "tools.shapes.3dbox",    _("Style of new 3D boxes")},
+      SP_VERB_CONTEXT_RECT_PREFS,   "tools.shapes.rect",     N_("Style of new rectangles")},
+    { "Box3DContext",  "3dbox_toolbox",  0, box3d_toolbox_prep,             "3DBoxToolbar",
+      SP_VERB_CONTEXT_3DBOX_PREFS,  "tools.shapes.3dbox",    N_("Style of new 3D boxes")},
     { "SPArcContext",    "arc_toolbox",    0, sp_arc_toolbox_prep,               "ArcToolbar",
-      SP_VERB_CONTEXT_ARC_PREFS,    "tools.shapes.arc",      _("Style of new ellipses")},
+      SP_VERB_CONTEXT_ARC_PREFS,    "tools.shapes.arc",      N_("Style of new ellipses")},
     { "SPSpiralContext", "spiral_toolbox", 0, sp_spiral_toolbox_prep,            "SpiralToolbar",
-      SP_VERB_CONTEXT_SPIRAL_PREFS, "tools.shapes.spiral",   _("Style of new spirals")},
+      SP_VERB_CONTEXT_SPIRAL_PREFS, "tools.shapes.spiral",   N_("Style of new spirals")},
     { "SPPencilContext", "pencil_toolbox", 0, sp_pencil_toolbox_prep,            "PencilToolbar",
-      SP_VERB_CONTEXT_PENCIL_PREFS, "tools.freehand.pencil", _("Style of new paths created by Pencil")},
+      SP_VERB_CONTEXT_PENCIL_PREFS, "tools.freehand.pencil", N_("Style of new paths created by Pencil")},
     { "SPPenContext", "pen_toolbox", 0, sp_pen_toolbox_prep,                     "PenToolbar",
-      SP_VERB_CONTEXT_PEN_PREFS,    "tools.freehand.pen",    _("Style of new paths created by Pen")},
+      SP_VERB_CONTEXT_PEN_PREFS,    "tools.freehand.pen",    N_("Style of new paths created by Pen")},
     { "SPDynaDrawContext", "calligraphy_toolbox", 0, sp_calligraphy_toolbox_prep,"CalligraphyToolbar",
-      SP_VERB_CONTEXT_CALLIGRAPHIC_PREFS, "tools.calligraphic", _("Style of new calligraphic strokes")},
+      SP_VERB_CONTEXT_CALLIGRAPHIC_PREFS, "tools.calligraphic", N_("Style of new calligraphic strokes")},
+    { "SPEraserContext", "eraser_toolbox", 0, sp_eraser_toolbox_prep,"EraserToolbar",
+      SP_VERB_CONTEXT_ERASER_PREFS, "tools.eraser", _("TBD")},
     { "SPTextContext",   "text_toolbox",   sp_text_toolbox_new, 0,               0,
       SP_VERB_INVALID, 0, 0},
     { "SPDropperContext", "dropper_toolbox", 0, sp_dropper_toolbox_prep,         "DropperToolbar",
@@ -186,10 +216,11 @@ static struct {
     { "SPConnectorContext", "connector_toolbox", 0, sp_connector_toolbox_prep,   "ConnectorToolbar",
       SP_VERB_INVALID, 0, 0},
     { "SPFloodContext",  "paintbucket_toolbox",  0, sp_paintbucket_toolbox_prep, "PaintbucketToolbar",
-      SP_VERB_CONTEXT_PAINTBUCKET_PREFS, "tools.paintbucket", _("Style of Paint Bucket fill objects")},
+      SP_VERB_CONTEXT_PAINTBUCKET_PREFS, "tools.paintbucket", N_("Style of Paint Bucket fill objects")},
     { NULL, NULL, NULL, NULL, NULL, SP_VERB_INVALID, NULL, NULL }
 };
 
+#define TOOLBAR_SLIDER_HINT "full"
 
 static gchar const * ui_descr =
         "<ui>"
@@ -227,9 +258,10 @@ static gchar const * ui_descr =
         "    <toolitem action='NodeDeleteAction' />"
         "    <separator />"
         "    <toolitem action='NodeJoinAction' />"
+        "    <toolitem action='NodeBreakAction' />"
+        "    <separator />"
         "    <toolitem action='NodeJoinSegmentAction' />"
         "    <toolitem action='NodeDeleteSegmentAction' />"
-        "    <toolitem action='NodeBreakAction' />"
         "    <separator />"
         "    <toolitem action='NodeCuspAction' />"
         "    <toolitem action='NodeSmoothAction' />"
@@ -241,10 +273,16 @@ static gchar const * ui_descr =
         "    <toolitem action='ObjectToPath' />"
         "    <toolitem action='StrokeToPath' />"
         "    <separator />"
-        "    <toolitem action='NodesShowHandlesAction' />"
-        "    <separator />"
         "    <toolitem action='NodeXAction' />"
         "    <toolitem action='NodeYAction' />"
+        "    <toolitem action='NodeUnitsAction' />"
+        "    <separator />"
+        "    <toolitem action='ObjectEditClipPathAction' />"
+        "    <toolitem action='ObjectEditMaskPathAction' />"
+        "    <toolitem action='EditNextLPEParameterAction' />"
+        "    <separator />"
+        "    <toolitem action='NodesShowHandlesAction' />"
+        "    <toolitem action='NodesShowHelperpath' />"
         "  </toolbar>"
 
         "  <toolbar name='TweakToolbar'>"
@@ -307,15 +345,14 @@ static gchar const * ui_descr =
         "  </toolbar>"
 
         "  <toolbar name='3DBoxToolbar'>"
-        "    <toolitem action='3DBoxPosAngleXAction' />"
-        "    <toolitem action='3DBoxVPXAction' />"
+        "    <toolitem action='3DBoxAngleXAction' />"
+        "    <toolitem action='3DBoxVPXStateAction' />"
         "    <separator />"
-        "    <toolitem action='3DBoxPosAngleYAction' />"
-        "    <toolitem action='3DBoxVPYAction' />"
-        "    <separator />"
-        "    <toolitem action='3DBoxPosAngleZAction' />"
-        "    <toolitem action='3DBoxVPZAction' />"
+        "    <toolitem action='3DBoxAngleYAction' />"
+        "    <toolitem action='3DBoxVPYStateAction' />"
         "    <separator />"
+        "    <toolitem action='3DBoxAngleZAction' />"
+        "    <toolitem action='3DBoxVPZStateAction' />"
         "  </toolbar>"
 
         "  <toolbar name='SpiralToolbar'>"
@@ -328,13 +365,28 @@ static gchar const * ui_descr =
         "  </toolbar>"
 
         "  <toolbar name='PenToolbar'>"
+        "    <toolitem action='FreehandModeActionPenTemp' />"
+        "    <toolitem action='FreehandModeActionPen' />"
+        "    <separator />"
+        "    <toolitem action='SetPenShapeAction'/>"
         "  </toolbar>"
 
         "  <toolbar name='PencilToolbar'>"
+        "    <toolitem action='FreehandModeActionPencilTemp' />"
+        "    <toolitem action='FreehandModeActionPencil' />"
+        "    <separator />"
+        "    <toolitem action='PencilToleranceAction' />"
+        "    <separator />"
+        "    <toolitem action='PencilResetAction' />"
+        "    <separator />"
+        "    <toolitem action='SetPencilShapeAction'/>"
         "  </toolbar>"
 
         "  <toolbar name='CalligraphyToolbar'>"
         "    <separator />"
+        "    <toolitem action='SetProfileAction'/>"
+        "    <toolitem action='SaveDeleteProfileAction'/>"
+        "    <separator />"
         "    <toolitem action='CalligraphyWidthAction' />"
         "    <toolitem action='PressureAction' />"
         "    <toolitem action='TraceAction' />"
@@ -350,7 +402,6 @@ static gchar const * ui_descr =
         "    <toolitem action='WiggleAction' />"
         "    <toolitem action='MassAction' />"
         "    <separator />"
-        "    <toolitem action='CalligraphyResetAction' />"
         "  </toolbar>"
 
         "  <toolbar name='ArcToolbar'>"
@@ -378,7 +429,14 @@ static gchar const * ui_descr =
         "    <toolitem action='PaintbucketResetAction' />"
         "  </toolbar>"
 
+        "  <toolbar name='EraserToolbar'>"
+        "    <toolitem action='EraserWidthAction' />"
+        "    <separator />"
+        "    <toolitem action='EraserModeAction' />"
+        "  </toolbar>"
+
         "  <toolbar name='DropperToolbar'>"
+        "    <toolitem action='DropperOpacityAction' />"
         "    <toolitem action='DropperPickAlphaAction' />"
         "    <toolitem action='DropperSetAlphaAction' />"
         "  </toolbar>"
@@ -396,7 +454,7 @@ static gchar const * ui_descr =
         "</ui>"
 ;
 
-static GtkActionGroup* create_or_fetch_actions( SPDesktop* desktop );
+static Glib::RefPtr<Gtk::ActionGroup> create_or_fetch_actions( SPDesktop* desktop );
 
 static void toolbox_set_desktop (GtkWidget *toolbox, SPDesktop *desktop, SetupFunction setup_func, UpdateFunction update_func, sigc::connection*);
 
@@ -409,6 +467,138 @@ static void update_aux_toolbox (SPDesktop *desktop, SPEventContext *eventcontext
 static void setup_commands_toolbox (GtkWidget *toolbox, SPDesktop *desktop);
 static void update_commands_toolbox (SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget *toolbox);
 
+
+GtkWidget * sp_toolbox_button_new_from_verb_with_doubleclick( GtkWidget *t, Inkscape::IconSize size, SPButtonType type,
+                                                              Inkscape::Verb *verb, Inkscape::Verb *doubleclick_verb,
+                                                              Inkscape::UI::View::View *view, GtkTooltips *tt);
+
+class VerbAction : public Gtk::Action {
+public:
+    static Glib::RefPtr<VerbAction> create(Inkscape::Verb* verb, Inkscape::Verb* verb2, Inkscape::UI::View::View *view, GtkTooltips *tooltips);
+
+    virtual ~VerbAction();
+    virtual void set_active(bool active = true);
+
+protected:
+    virtual Gtk::Widget* create_menu_item_vfunc();
+    virtual Gtk::Widget* create_tool_item_vfunc();
+
+    virtual void connect_proxy_vfunc(Gtk::Widget* proxy);
+    virtual void disconnect_proxy_vfunc(Gtk::Widget* proxy);
+
+    virtual void on_activate();
+
+private:
+    Inkscape::Verb* verb;
+    Inkscape::Verb* verb2;
+    Inkscape::UI::View::View *view;
+    GtkTooltips *tooltips;
+    bool active;
+
+    VerbAction(Inkscape::Verb* verb, Inkscape::Verb* verb2, Inkscape::UI::View::View *view, GtkTooltips *tooltips);
+};
+
+
+Glib::RefPtr<VerbAction> VerbAction::create(Inkscape::Verb* verb, Inkscape::Verb* verb2, Inkscape::UI::View::View *view, GtkTooltips *tooltips)
+{
+    Glib::RefPtr<VerbAction> result;
+    SPAction *action = verb->get_action(view);
+    if ( action ) {
+        //SPAction* action2 = verb2 ? verb2->get_action(view) : 0;
+        result = Glib::RefPtr<VerbAction>(new VerbAction(verb, verb2, view, tooltips));
+    }
+
+    return result;
+}
+
+VerbAction::VerbAction(Inkscape::Verb* verb, Inkscape::Verb* verb2, Inkscape::UI::View::View *view, GtkTooltips *tooltips) :
+    Gtk::Action(Glib::ustring(verb->get_id()), Gtk::StockID(verb->get_image()), Glib::ustring(_(verb->get_name())), Glib::ustring(_(verb->get_tip()))),
+    verb(verb),
+    verb2(verb2),
+    view(view),
+    tooltips(tooltips),
+    active(false)
+{
+}
+
+VerbAction::~VerbAction()
+{
+}
+
+Gtk::Widget* VerbAction::create_menu_item_vfunc()
+{
+// First call in to get the icon rendered if present in SVG
+    Gtk::Widget *widget = sp_icon_get_icon( property_stock_id().get_value().get_string(), Inkscape::ICON_SIZE_MENU );
+    delete widget;
+    widget = 0;
+
+    Gtk::Widget* widg = Gtk::Action::create_menu_item_vfunc();
+//     g_message("create_menu_item_vfunc() = %p  for '%s'", widg, verb->get_id());
+    return widg;
+}
+
+Gtk::Widget* VerbAction::create_tool_item_vfunc()
+{
+//     Gtk::Widget* widg = Gtk::Action::create_tool_item_vfunc();
+    Inkscape::IconSize toolboxSize = prefToSize("toolbox.tools", "small");
+    GtkWidget* toolbox = 0;
+    GtkWidget *button = sp_toolbox_button_new_from_verb_with_doubleclick( toolbox, toolboxSize,
+                                                                          SP_BUTTON_TYPE_TOGGLE,
+                                                                          verb,
+                                                                          verb2,
+                                                                          view,
+                                                                          tooltips );
+    if ( active ) {
+        sp_button_toggle_set_down( SP_BUTTON(button), active);
+    }
+    gtk_widget_show_all( button );
+    Gtk::Widget* wrapped = Glib::wrap(button);
+    Gtk::ToolItem* holder = Gtk::manage(new Gtk::ToolItem());
+    holder->add(*wrapped);
+
+//     g_message("create_tool_item_vfunc() = %p  for '%s'", holder, verb->get_id());
+    return holder;
+}
+
+void VerbAction::connect_proxy_vfunc(Gtk::Widget* proxy)
+{
+//     g_message("connect_proxy_vfunc(%p)  for '%s'", proxy, verb->get_id());
+    Gtk::Action::connect_proxy_vfunc(proxy);
+}
+
+void VerbAction::disconnect_proxy_vfunc(Gtk::Widget* proxy)
+{
+//     g_message("disconnect_proxy_vfunc(%p)  for '%s'", proxy, verb->get_id());
+    Gtk::Action::disconnect_proxy_vfunc(proxy);
+}
+
+void VerbAction::set_active(bool active)
+{
+    this->active = active;
+    Glib::SListHandle<Gtk::Widget*> proxies = get_proxies();
+    for ( Glib::SListHandle<Gtk::Widget*>::iterator it = proxies.begin(); it != proxies.end(); ++it ) {
+        Gtk::ToolItem* ti = dynamic_cast<Gtk::ToolItem*>(*it);
+        if (ti) {
+            // *should* have one child that is the SPButton
+            Gtk::Widget* child = ti->get_child();
+            if ( child && SP_IS_BUTTON(child->gobj()) ) {
+                SPButton* button = SP_BUTTON(child->gobj());
+                sp_button_toggle_set_down( button, active );
+            }
+        }
+    }
+}
+
+void VerbAction::on_activate()
+{
+    if ( verb ) {
+        SPAction *action = verb->get_action(view);
+        if ( action ) {
+            sp_action_perform(action, 0);
+        }
+    }
+}
+
 /* Global text entry widgets necessary for update */
 /* GtkWidget *dropper_rgb_entry,
           *dropper_opacity_entry ; */
@@ -449,21 +639,24 @@ sp_toolbox_button_new_from_verb_with_doubleclick(GtkWidget *t, Inkscape::IconSiz
     /* fixme: Implement sp_button_new_from_action */
     GtkWidget *b = sp_button_new(size, type, action, doubleclick_action, tt);
     gtk_widget_show(b);
-    gtk_box_pack_start(GTK_BOX(t), b, FALSE, FALSE, 0);
 
-    return b;
-}
 
-GtkWidget *sp_toolbox_button_new_from_verb(GtkWidget *t, Inkscape::IconSize size, SPButtonType type, Inkscape::Verb *verb,
-                                           Inkscape::UI::View::View *view, GtkTooltips *tt)
-{
-    return sp_toolbox_button_new_from_verb_with_doubleclick(t, size, type, verb, NULL, view, tt);
-}
+    unsigned int shortcut = sp_shortcut_get_primary(verb);
+    if (shortcut) {
+        gchar key[256];
+        sp_ui_shortcut_string(shortcut, key);
+        gchar *tip = g_strdup_printf ("%s (%s)", action->tip, key);
+        if ( t ) {
+            gtk_toolbar_append_widget( GTK_TOOLBAR(t), b, tip, 0 );
+        }
+        g_free(tip);
+    } else {
+        if ( t ) {
+            gtk_toolbar_append_widget( GTK_TOOLBAR(t), b, action->tip, 0 );
+        }
+    }
 
-GtkWidget * sp_toolbox_button_normal_new_from_verb(GtkWidget *t, Inkscape::IconSize size, Inkscape::Verb *verb,
-                                                   Inkscape::UI::View::View *view, GtkTooltips *tt)
-{
-    return sp_toolbox_button_new_from_verb(t, size, SP_BUTTON_TYPE_NORMAL, verb, view, tt);
+    return b;
 }
 
 
@@ -497,7 +690,7 @@ static GtkAction* create_action_for_verb( Inkscape::Verb* verb, Inkscape::UI::Vi
     GtkAction* act = 0;
 
     SPAction* targetAction = verb->get_action(view);
-    InkAction* inky = ink_action_new( verb->get_id(), verb->get_name(), verb->get_tip(), verb->get_image(), size  );
+    InkAction* inky = ink_action_new( verb->get_id(), _(verb->get_name()), verb->get_tip(), verb->get_image(), size  );
     act = GTK_ACTION(inky);
     gtk_action_set_sensitive( act, targetAction->sensitive );
 
@@ -509,7 +702,7 @@ static GtkAction* create_action_for_verb( Inkscape::Verb* verb, Inkscape::UI::Vi
     return act;
 }
 
-GtkActionGroup* create_or_fetch_actions( SPDesktop* desktop )
+Glib::RefPtr<Gtk::ActionGroup> create_or_fetch_actions( SPDesktop* desktop )
 {
     Inkscape::UI::View::View *view = desktop;
     gint verbsToUse[] = {
@@ -554,39 +747,68 @@ GtkActionGroup* create_or_fetch_actions( SPDesktop* desktop )
         SP_VERB_ZOOM_SELECTION,
     };
 
-    gint shrinkTop = prefs_get_int_attribute_limited( "toolbox", "small", 1, 0, 1 );
-    Inkscape::IconSize toolboxSize = shrinkTop ? Inkscape::ICON_SIZE_SMALL_TOOLBAR : Inkscape::ICON_SIZE_LARGE_TOOLBAR;
+    Inkscape::IconSize toolboxSize = prefToSize("toolbox", "small");
 
-    static std::map<SPDesktop*, GtkActionGroup*> groups;
-    GtkActionGroup* mainActions = 0;
+    static std::map<SPDesktop*, Glib::RefPtr<Gtk::ActionGroup> > groups;
+    Glib::RefPtr<Gtk::ActionGroup> mainActions;
     if ( groups.find(desktop) != groups.end() ) {
         mainActions = groups[desktop];
     }
 
     if ( !mainActions ) {
-        mainActions = gtk_action_group_new("main");
+        mainActions = Gtk::ActionGroup::create("main");
         groups[desktop] = mainActions;
     }
 
     for ( guint i = 0; i < G_N_ELEMENTS(verbsToUse); i++ ) {
         Inkscape::Verb* verb = Inkscape::Verb::get(verbsToUse[i]);
         if ( verb ) {
-            if ( !gtk_action_group_get_action( mainActions, verb->get_id() ) ) {
+            if (!mainActions->get_action(verb->get_id())) {
                 GtkAction* act = create_action_for_verb( verb, view, toolboxSize );
-                gtk_action_group_add_action( mainActions, act );
+                mainActions->add(Glib::wrap(act));
+            }
+        }
+    }
+
+    if ( !mainActions->get_action("ToolZoom") ) {
+        GtkTooltips *tt = gtk_tooltips_new();
+        for ( guint i = 0; i < G_N_ELEMENTS(tools) && tools[i].type_name; i++ ) {
+            Glib::RefPtr<VerbAction> va = VerbAction::create(Inkscape::Verb::get(tools[i].verb), Inkscape::Verb::get(tools[i].doubleclick_verb), view, tt);
+            if ( va ) {
+                mainActions->add(va);
+                if ( i == 0 ) {
+                    va->set_active(true);
+                }
             }
         }
     }
 
+
     return mainActions;
 }
 
 
+void handlebox_detached(GtkHandleBox* /*handlebox*/, GtkWidget* widget, gpointer /*userData*/)
+{
+    gtk_widget_set_size_request( widget,
+                                 widget->allocation.width,
+                                 widget->allocation.height );
+}
+
+void handlebox_attached(GtkHandleBox* /*handlebox*/, GtkWidget* widget, gpointer /*userData*/)
+{
+    gtk_widget_set_size_request( widget, -1, -1 );
+}
+
+
+
 GtkWidget *
 sp_tool_toolbox_new()
 {
     GtkTooltips *tt = gtk_tooltips_new();
-    GtkWidget *tb = gtk_vbox_new(FALSE, 0);
+    GtkWidget* tb = gtk_toolbar_new();
+    gtk_toolbar_set_orientation(GTK_TOOLBAR(tb), GTK_ORIENTATION_VERTICAL);
+    gtk_toolbar_set_show_arrow(GTK_TOOLBAR(tb), TRUE);
 
     g_object_set_data(G_OBJECT(tb), "desktop", NULL);
     g_object_set_data(G_OBJECT(tb), "tooltips", tt);
@@ -604,21 +826,10 @@ sp_tool_toolbox_new()
     sigc::connection* conn = new sigc::connection;
     g_object_set_data(G_OBJECT(hb), "event_context_connection", conn);
 
-    return hb;
-}
-
-static void
-aux_toolbox_attached(GtkHandleBox */*toolbox*/, GtkWidget *child)
-{
-    g_object_set_data(G_OBJECT(child), "is_detached", GINT_TO_POINTER(FALSE));
-    gtk_widget_queue_resize(child);
-}
+    g_signal_connect(G_OBJECT(hb), "child_detached", G_CALLBACK(handlebox_detached), static_cast<gpointer>(0));
+    g_signal_connect(G_OBJECT(hb), "child_attached", G_CALLBACK(handlebox_attached), static_cast<gpointer>(0));
 
-static void
-aux_toolbox_detached(GtkHandleBox */*toolbox*/, GtkWidget *child)
-{
-    g_object_set_data(G_OBJECT(child), "is_detached", GINT_TO_POINTER(TRUE));
-    gtk_widget_queue_resize(child);
+    return hb;
 }
 
 GtkWidget *
@@ -626,14 +837,9 @@ sp_aux_toolbox_new()
 {
     GtkWidget *tb = gtk_vbox_new(FALSE, 0);
 
-    GtkWidget *tb_s = gtk_vbox_new(FALSE, 0);
-    GtkWidget *tb_e = gtk_vbox_new(FALSE, 0);
     gtk_box_set_spacing(GTK_BOX(tb), AUX_SPACING);
-    gtk_box_pack_start(GTK_BOX(tb), GTK_WIDGET(tb_s), FALSE, FALSE, 0);
-    gtk_box_pack_end(GTK_BOX(tb), GTK_WIDGET(tb_e), FALSE, FALSE, 0);
 
     g_object_set_data(G_OBJECT(tb), "desktop", NULL);
-    g_object_set_data(G_OBJECT(tb), "top_spacer", tb_s);
 
     gtk_widget_set_sensitive(tb, FALSE);
 
@@ -642,15 +848,15 @@ sp_aux_toolbox_new()
     gtk_handle_box_set_shadow_type(GTK_HANDLE_BOX(hb), GTK_SHADOW_OUT);
     gtk_handle_box_set_snap_edge(GTK_HANDLE_BOX(hb), GTK_POS_LEFT);
 
-    g_signal_connect(G_OBJECT(hb), "child_attached", G_CALLBACK(aux_toolbox_attached), (gpointer)tb);
-    g_signal_connect(G_OBJECT(hb), "child_detached", G_CALLBACK(aux_toolbox_detached), (gpointer)tb);
-
     gtk_container_add(GTK_CONTAINER(hb), tb);
     gtk_widget_show(GTK_WIDGET(tb));
 
     sigc::connection* conn = new sigc::connection;
     g_object_set_data(G_OBJECT(hb), "event_context_connection", conn);
 
+    g_signal_connect(G_OBJECT(hb), "child_detached", G_CALLBACK(handlebox_detached), static_cast<gpointer>(0));
+    g_signal_connect(G_OBJECT(hb), "child_attached", G_CALLBACK(handlebox_attached), static_cast<gpointer>(0));
+
     return hb;
 }
 
@@ -661,13 +867,7 @@ sp_aux_toolbox_new()
 GtkWidget *
 sp_commands_toolbox_new()
 {
-    GtkWidget *tb = gtk_vbox_new(FALSE, 0);
-
-    GtkWidget *tb_s = gtk_vbox_new(FALSE, 0);
-    GtkWidget *tb_e = gtk_vbox_new(FALSE, 0);
-    gtk_box_set_spacing(GTK_BOX(tb), AUX_SPACING);
-    gtk_box_pack_start(GTK_BOX(tb), GTK_WIDGET(tb_s), FALSE, FALSE, 0);
-    gtk_box_pack_end(GTK_BOX(tb), GTK_WIDGET(tb_e), FALSE, FALSE, 0);
+    GtkWidget *tb = gtk_toolbar_new();
 
     g_object_set_data(G_OBJECT(tb), "desktop", NULL);
     gtk_widget_set_sensitive(tb, FALSE);
@@ -677,18 +877,19 @@ sp_commands_toolbox_new()
     gtk_handle_box_set_shadow_type(GTK_HANDLE_BOX(hb), GTK_SHADOW_OUT);
     gtk_handle_box_set_snap_edge(GTK_HANDLE_BOX(hb), GTK_POS_LEFT);
 
-    g_signal_connect(G_OBJECT(hb), "child_attached", G_CALLBACK(aux_toolbox_attached), (gpointer)tb);
-    g_signal_connect(G_OBJECT(hb), "child_detached", G_CALLBACK(aux_toolbox_detached), (gpointer)tb);
-
     gtk_container_add(GTK_CONTAINER(hb), tb);
     gtk_widget_show(GTK_WIDGET(tb));
 
     sigc::connection* conn = new sigc::connection;
     g_object_set_data(G_OBJECT(hb), "event_context_connection", conn);
 
+    g_signal_connect(G_OBJECT(hb), "child_detached", G_CALLBACK(handlebox_detached), static_cast<gpointer>(0));
+    g_signal_connect(G_OBJECT(hb), "child_attached", G_CALLBACK(handlebox_attached), static_cast<gpointer>(0));
+
     return hb;
 }
 
+
 static EgeAdjustmentAction * create_adjustment_action( gchar const *name,
                                                        gchar const *label, gchar const *shortLabel, gchar const *tooltip,
                                                        gchar const *path, gchar const *data, gdouble def,
@@ -771,7 +972,7 @@ void
 sp_node_path_edit_delete(void)
 {
     ShapeEditor *shape_editor = get_current_shape_editor();
-    if (shape_editor) shape_editor->delete_nodes();
+    if (shape_editor) shape_editor->delete_nodes_preserving_shape();
 }
 
 void
@@ -844,6 +1045,25 @@ static void toggle_show_handles (GtkToggleAction *act, gpointer /*data*/) {
     if (shape_editor) shape_editor->show_handles(show);
 }
 
+static void toggle_show_helperpath (GtkToggleAction *act, gpointer /*data*/) {
+    bool show = gtk_toggle_action_get_active( act );
+    prefs_set_int_attribute ("tools.nodes", "show_helperpath",  show ? 1 : 0);
+    ShapeEditor *shape_editor = get_current_shape_editor();
+    if (shape_editor) shape_editor->show_helperpath(show);
+}
+
+void sp_node_path_edit_nextLPEparam (GtkAction */*act*/, gpointer data) {
+    sp_selection_next_patheffect_param( reinterpret_cast<SPDesktop*>(data) );
+}
+
+void sp_node_path_edit_clippath (GtkAction */*act*/, gpointer data) {
+    sp_selection_edit_clip_or_mask( reinterpret_cast<SPDesktop*>(data), true);
+}
+
+void sp_node_path_edit_maskpath (GtkAction */*act*/, gpointer data) {
+    sp_selection_edit_clip_or_mask( reinterpret_cast<SPDesktop*>(data), false);
+}
+
 /* is called when the node selection is modified */
 static void
 sp_node_toolbox_coord_changed(gpointer /*shape_editor*/, GObject *tbl)
@@ -861,6 +1081,9 @@ sp_node_toolbox_coord_changed(gpointer /*shape_editor*/, GObject *tbl)
     // in turn, prevent listener from responding
     g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE));
 
+    UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) );
+    SPUnit const *unit = tracker->getActiveUnit();
+
     ShapeEditor *shape_editor = get_current_shape_editor();
     if (shape_editor && shape_editor->has_nodepath()) {
         Inkscape::NodePath::Path *nodepath = shape_editor->get_nodepath();
@@ -875,14 +1098,14 @@ sp_node_toolbox_coord_changed(gpointer /*shape_editor*/, GObject *tbl)
         } else {
             gtk_action_set_sensitive(xact, TRUE);
             gtk_action_set_sensitive(yact, TRUE);
-            NR::Coord oldx = gtk_adjustment_get_value(xadj);
-            NR::Coord oldy = gtk_adjustment_get_value(xadj);
+            NR::Coord oldx = sp_units_get_pixels(gtk_adjustment_get_value(xadj), *unit);
+            NR::Coord oldy = sp_units_get_pixels(gtk_adjustment_get_value(xadj), *unit);
 
             if (n_selected == 1) {
                 NR::Point sel_node = nodepath->singleSelectedCoords();
                 if (oldx != sel_node[NR::X] || oldy != sel_node[NR::Y]) {
-                    gtk_adjustment_set_value(xadj, sel_node[NR::X]);
-                    gtk_adjustment_set_value(yadj, sel_node[NR::Y]);
+                    gtk_adjustment_set_value(xadj, sp_pixels_get_units(sel_node[NR::X], *unit));
+                    gtk_adjustment_set_value(yadj, sp_pixels_get_units(sel_node[NR::Y], *unit));
                 }
             } else {
                 NR::Maybe<NR::Coord> x = sp_node_selected_common_coord(nodepath, NR::X);
@@ -891,11 +1114,17 @@ sp_node_toolbox_coord_changed(gpointer /*shape_editor*/, GObject *tbl)
                     /* Note: Currently x and y will always have a value, even if the coordinates of the
                        selected nodes don't coincide (in this case we use the coordinates of the center
                        of the bounding box). So the entries are never set to zero. */
-                    gtk_adjustment_set_value(xadj, x ? (*x) : 0.0); // FIXME: Maybe we should clear the entry
-                    gtk_adjustment_set_value(yadj, y ? (*y) : 0.0); //        fields, not set them to zero.
+                    // FIXME: Maybe we should clear the entry if several nodes are selected
+                    //        instead of providing a kind of average value
+                    gtk_adjustment_set_value(xadj, sp_pixels_get_units(x ? (*x) : 0.0, *unit));
+                    gtk_adjustment_set_value(yadj, sp_pixels_get_units(y ? (*y) : 0.0, *unit));
                 }
             }
         }
+    } else {
+        // no shape-editor or nodepath yet (when we just switched to the tool); coord entries must be inactive
+        gtk_action_set_sensitive(xact, FALSE);
+        gtk_action_set_sensitive(yact, FALSE);
     }
 
     g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
@@ -904,6 +1133,15 @@ sp_node_toolbox_coord_changed(gpointer /*shape_editor*/, GObject *tbl)
 static void
 sp_node_path_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name)
 {
+    SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
+
+    UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" ));
+    SPUnit const *unit = tracker->getActiveUnit();
+
+    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
+        prefs_set_double_attribute("tools.nodes", value_name, sp_units_get_pixels(adj->value, *unit));
+    }
+
     // quit if run by the attr_changed listener
     if (g_object_get_data( tbl, "freeze" )) {
         return;
@@ -914,11 +1152,12 @@ sp_node_path_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_
 
     ShapeEditor *shape_editor = get_current_shape_editor();
     if (shape_editor && shape_editor->has_nodepath()) {
+        double val = sp_units_get_pixels(gtk_adjustment_get_value(adj), *unit);
         if (!strcmp(value_name, "x")) {
-            sp_node_selected_move_absolute(shape_editor->get_nodepath(), gtk_adjustment_get_value(adj), NR::X);
+            sp_node_selected_move_absolute(shape_editor->get_nodepath(), val, NR::X);
         }
         if (!strcmp(value_name, "y")) {
-            sp_node_selected_move_absolute(shape_editor->get_nodepath(), gtk_adjustment_get_value(adj), NR::Y);
+            sp_node_selected_move_absolute(shape_editor->get_nodepath(), val, NR::Y);
         }
     }
 
@@ -937,18 +1176,70 @@ sp_node_path_y_value_changed(GtkAdjustment *adj, GObject *tbl)
     sp_node_path_value_changed(adj, tbl, "y");
 }
 
+void
+sp_node_toolbox_sel_changed (Inkscape::Selection *selection, GObject *tbl)
+{
+    {
+    GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "nodes_lpeedit" ) );
+    SPItem *item = selection->singleItem();
+    if (item && SP_IS_LPE_ITEM(item)) {
+       if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(item))) {
+           gtk_action_set_sensitive(w, TRUE);
+       } else {
+           gtk_action_set_sensitive(w, FALSE);
+       }
+    } else {
+       gtk_action_set_sensitive(w, FALSE);
+    }
+    }
+
+    {
+    GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "nodes_clippathedit" ) );
+    SPItem *item = selection->singleItem();
+    if (item && item->clip_ref && item->clip_ref->getObject()) {
+       gtk_action_set_sensitive(w, TRUE);
+    } else {
+       gtk_action_set_sensitive(w, FALSE);
+    }
+    }
+
+    {
+    GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "nodes_maskedit" ) );
+    SPItem *item = selection->singleItem();
+    if (item && item->mask_ref && item->mask_ref->getObject()) {
+       gtk_action_set_sensitive(w, TRUE);
+    } else {
+       gtk_action_set_sensitive(w, FALSE);
+    }
+    }
+}
+
+void
+sp_node_toolbox_sel_modified (Inkscape::Selection *selection, guint /*flags*/, GObject *tbl)
+{
+    sp_node_toolbox_sel_changed (selection, tbl);
+}
+
+
+
 //################################
 //##    Node Editing Toolbox    ##
 //################################
 
 static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 {
+    UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE );
+    tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units );
+    g_object_set_data( holder, "tracker", tracker );
+
+    Inkscape::IconSize secondarySize = prefToSize("toolbox", "secondary", 1);
+
     {
         InkAction* inky = ink_action_new( "NodeInsertAction",
                                           _("Insert node"),
                                           _("Insert new nodes into selected segments"),
                                           "node_insert",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_object_set( inky, "short_label", _("Insert"), NULL );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add), 0 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
@@ -959,7 +1250,7 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
                                           _("Delete node"),
                                           _("Delete selected nodes"),
                                           "node_delete",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_object_set( inky, "short_label", _("Delete"), NULL );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_delete), 0 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
@@ -970,48 +1261,49 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
                                           _("Join endnodes"),
                                           _("Join selected endnodes"),
                                           "node_join",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_object_set( inky, "short_label", _("Join"), NULL );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_join), 0 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
     }
 
+    {
+        InkAction* inky = ink_action_new( "NodeBreakAction",
+                                          _("Break nodes"),
+                                          _("Break path at selected nodes"),
+                                          "node_break",
+                                          secondarySize );
+        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_break), 0 );
+        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
+    }
+
+
     {
         InkAction* inky = ink_action_new( "NodeJoinSegmentAction",
-                                          _("Join Segment"),
+                                          _("Join with segment"),
                                           _("Join selected endnodes with a new segment"),
                                           "node_join_segment",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_join_segment), 0 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
     }
 
     {
         InkAction* inky = ink_action_new( "NodeDeleteSegmentAction",
-                                          _("Delete Segment"),
-                                          _("Split path between two non-endpoint nodes"),
+                                          _("Delete segment"),
+                                          _("Delete segment between two non-endpoint nodes"),
                                           "node_delete_segment",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_delete_segment), 0 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
     }
 
-    {
-        InkAction* inky = ink_action_new( "NodeBreakAction",
-                                          _("Node Break"),
-                                          _("Break path at selected nodes"),
-                                          "node_break",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
-        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_break), 0 );
-        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
-    }
-
     {
         InkAction* inky = ink_action_new( "NodeCuspAction",
                                           _("Node Cusp"),
                                           _("Make selected nodes corner"),
                                           "node_cusp",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_cusp), 0 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
     }
@@ -1021,7 +1313,7 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
                                           _("Node Smooth"),
                                           _("Make selected nodes smooth"),
                                           "node_smooth",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_smooth), 0 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
     }
@@ -1031,7 +1323,7 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
                                           _("Node Symmetric"),
                                           _("Make selected nodes symmetric"),
                                           "node_symmetric",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_symmetrical), 0 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
     }
@@ -1041,7 +1333,7 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
                                           _("Node Line"),
                                           _("Make selected segments lines"),
                                           "node_line",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_toline), 0 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
     }
@@ -1051,7 +1343,7 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
                                           _("Node Curve"),
                                           _("Make selected segments curves"),
                                           "node_curve",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_tocurve), 0 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
     }
@@ -1067,6 +1359,50 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
         gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.nodes", "show_handles", 1 ) );
     }
 
+    {
+        InkToggleAction* act = ink_toggle_action_new( "NodesShowHelperpath",
+                                                      _("Show Outline"),
+                                                      _("Show the outline of the path"),
+                                                      "nodes_show_helperpath",
+                                                      Inkscape::ICON_SIZE_DECORATION );
+        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_show_helperpath), desktop );
+        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.nodes", "show_helperpath", 0 ) );
+    }
+
+    {
+        InkAction* inky = ink_action_new( "EditNextLPEParameterAction",
+                                          _("Next path effect parameter"),
+                                          _("Show next path effect parameter for editing"),
+                                          "edit_next_parameter",
+                                          Inkscape::ICON_SIZE_DECORATION );
+        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_nextLPEparam), desktop );
+        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
+        g_object_set_data( holder, "nodes_lpeedit", inky);
+    }
+
+    {
+        InkAction* inky = ink_action_new( "ObjectEditClipPathAction",
+                                          _("Edit clipping path"),
+                                          _("Edit the clipping path of the object"),
+                                          "nodeedit-clippath",
+                                          Inkscape::ICON_SIZE_DECORATION );
+        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_clippath), desktop );
+        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
+        g_object_set_data( holder, "nodes_clippathedit", inky);
+    }
+
+    {
+        InkAction* inky = ink_action_new( "ObjectEditMaskPathAction",
+                                          _("Edit mask path"),
+                                          _("Edit the mask of the object"),
+                                          "nodeedit-mask",
+                                          Inkscape::ICON_SIZE_DECORATION );
+        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_maskpath), desktop );
+        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
+        g_object_set_data( holder, "nodes_maskedit", inky);
+    }
+
     /* X coord of selected node(s) */
     {
         EgeAdjustmentAction* eact = 0;
@@ -1079,6 +1415,7 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
                                          -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
                                          labels, values, G_N_ELEMENTS(labels),
                                          sp_node_path_x_value_changed );
+        tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
         g_object_set_data( holder, "nodes_x_action", eact );
         gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
         gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
@@ -1096,16 +1433,41 @@ static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
                                          -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
                                          labels, values, G_N_ELEMENTS(labels),
                                          sp_node_path_y_value_changed );
+        tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
         g_object_set_data( holder, "nodes_y_action", eact );
         gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
         gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
     }
 
-    sigc::connection *connection = new sigc::connection (
-        desktop->connectToolSubselectionChanged(sigc::bind (sigc::ptr_fun(sp_node_toolbox_coord_changed), (GObject *)holder))
-        );
+    // add the units menu
+    {
+        GtkAction* act = tracker->createAction( "NodeUnitsAction", _("Units"), ("") );
+        gtk_action_group_add_action( mainActions, act );
+    }
+
+
+    sp_node_toolbox_sel_changed(sp_desktop_selection(desktop), holder);
+
+    //watch selection
+    Inkscape::ConnectionPool* pool = Inkscape::ConnectionPool::new_connection_pool ("ISNodeToolbox");
+
+    sigc::connection *c_selection_changed =
+        new sigc::connection (sp_desktop_selection (desktop)->connectChanged
+                              (sigc::bind (sigc::ptr_fun (sp_node_toolbox_sel_changed), (GObject*)holder)));
+    pool->add_connection ("selection-changed", c_selection_changed);
+
+    sigc::connection *c_selection_modified =
+        new sigc::connection (sp_desktop_selection (desktop)->connectModified
+                              (sigc::bind (sigc::ptr_fun (sp_node_toolbox_sel_modified), (GObject*)holder)));
+    pool->add_connection ("selection-modified", c_selection_modified);
+
+    sigc::connection *c_subselection_changed =
+        new sigc::connection (desktop->connectToolSubselectionChanged
+                              (sigc::bind (sigc::ptr_fun (sp_node_toolbox_coord_changed), (GObject*)holder)));
+    pool->add_connection ("tool-subselection-changed", c_subselection_changed);
+
+    Inkscape::ConnectionPool::connect_destroy (G_OBJECT (holder), pool);
 
-    g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection );
     g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
 } // end of sp_node_toolbox_prep()
 
@@ -1122,20 +1484,35 @@ static void sp_zoom_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* /*mainA
 void
 sp_tool_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop)
 {
-    toolbox_set_desktop(gtk_bin_get_child(GTK_BIN(toolbox)), desktop, setup_tool_toolbox, update_tool_toolbox, static_cast<sigc::connection*>(g_object_get_data(G_OBJECT(toolbox), "event_context_connection")));
+    toolbox_set_desktop(toolbox,
+                        desktop,
+                        setup_tool_toolbox,
+                        update_tool_toolbox,
+                        static_cast<sigc::connection*>(g_object_get_data(G_OBJECT(toolbox),
+                                                                         "event_context_connection")));
 }
 
 
 void
 sp_aux_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop)
 {
-    toolbox_set_desktop(gtk_bin_get_child(GTK_BIN(toolbox)), desktop, setup_aux_toolbox, update_aux_toolbox, static_cast<sigc::connection*>(g_object_get_data(G_OBJECT(toolbox), "event_context_connection")));
+    toolbox_set_desktop(gtk_bin_get_child(GTK_BIN(toolbox)),
+                        desktop,
+                        setup_aux_toolbox,
+                        update_aux_toolbox,
+                        static_cast<sigc::connection*>(g_object_get_data(G_OBJECT(toolbox),
+                                                                         "event_context_connection")));
 }
 
 void
 sp_commands_toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop)
 {
-    toolbox_set_desktop(gtk_bin_get_child(GTK_BIN(toolbox)), desktop, setup_commands_toolbox, update_commands_toolbox, static_cast<sigc::connection*>(g_object_get_data(G_OBJECT(toolbox), "event_context_connection")));
+    toolbox_set_desktop(toolbox,
+                        desktop,
+                        setup_commands_toolbox,
+                        update_commands_toolbox,
+                        static_cast<sigc::connection*>(g_object_get_data(G_OBJECT(toolbox),
+                                                                         "event_context_connection")));
 }
 
 static void
@@ -1172,41 +1549,75 @@ toolbox_set_desktop(GtkWidget *toolbox, SPDesktop *desktop, SetupFunction setup_
 static void
 setup_tool_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
 {
-    GtkTooltips *tooltips=GTK_TOOLTIPS(g_object_get_data(G_OBJECT(toolbox), "tooltips"));
-    gint shrinkLeft = prefs_get_int_attribute_limited( "toolbox.tools", "small", 0, 0, 1 );
-    if ( (shrinkLeft == 0) && (prefs_get_int_attribute_limited( "toolbox.tools", "small", 1, 0, 1 ) == 1) ) {
-        // "toolbox.tools" was not set. Fallback to older value
-        shrinkLeft = prefs_get_int_attribute_limited( "toolbox.left", "small", 0, 0, 1 );
+    gchar const * descr =
+        "<ui>"
+        "  <toolbar name='ToolToolbar'>"
+        "    <toolitem action='ToolSelector' />"
+        "    <toolitem action='ToolNode' />"
+        "    <toolitem action='ToolTweak' />"
+        "    <toolitem action='ToolZoom' />"
+        "    <toolitem action='ToolRect' />"
+        "    <toolitem action='Tool3DBox' />"
+        "    <toolitem action='ToolArc' />"
+        "    <toolitem action='ToolStar' />"
+        "    <toolitem action='ToolSpiral' />"
+        "    <toolitem action='ToolPencil' />"
+        "    <toolitem action='ToolPen' />"
+        "    <toolitem action='ToolCalligraphic' />"
+        "    <toolitem action='ToolEraser' />"
+        "    <toolitem action='ToolPaintBucket' />"
+        "    <toolitem action='ToolText' />"
+        "    <toolitem action='ToolConnector' />"
+        "    <toolitem action='ToolGradient' />"
+        "    <toolitem action='ToolDropper' />"
+        "  </toolbar>"
+        "</ui>";
+    Glib::RefPtr<Gtk::ActionGroup> mainActions = create_or_fetch_actions( desktop );
+    GtkUIManager* mgr = gtk_ui_manager_new();
+    GError* errVal = 0;
 
-        // Copy the setting forwards
-        prefs_set_int_attribute( "toolbox.tools", "small", shrinkLeft );
+    gtk_ui_manager_insert_action_group( mgr, mainActions->gobj(), 0 );
+    gtk_ui_manager_add_ui_from_string( mgr, descr, -1, &errVal );
+
+    GtkWidget* toolBar = gtk_ui_manager_get_widget( mgr, "/ui/ToolToolbar" );
+    if ( prefs_get_int_attribute_limited( "toolbox", "icononly", 1, 0, 1 ) ) {
+        gtk_toolbar_set_style( GTK_TOOLBAR(toolBar), GTK_TOOLBAR_ICONS );
     }
-    Inkscape::IconSize toolboxSize = shrinkLeft ? Inkscape::ICON_SIZE_SMALL_TOOLBAR : Inkscape::ICON_SIZE_LARGE_TOOLBAR;
+    Inkscape::IconSize toolboxSize = prefToSize("toolbox.tools", "small");
+    gtk_toolbar_set_icon_size( GTK_TOOLBAR(toolBar), (GtkIconSize)toolboxSize );
 
-    for (int i = 0 ; tools[i].type_name ; i++ ) {
-        GtkWidget *button =
-            sp_toolbox_button_new_from_verb_with_doubleclick( toolbox, toolboxSize,
-                                                              SP_BUTTON_TYPE_TOGGLE,
-                                                              Inkscape::Verb::get(tools[i].verb),
-                                                              Inkscape::Verb::get(tools[i].doubleclick_verb),
-                                                              desktop,
-                                                              tooltips );
+    gtk_toolbar_set_orientation(GTK_TOOLBAR(toolBar), GTK_ORIENTATION_VERTICAL);
+    gtk_toolbar_set_show_arrow(GTK_TOOLBAR(toolBar), TRUE);
 
-        g_object_set_data( G_OBJECT(toolbox), tools[i].data_name,
-                           (gpointer)button );
+    g_object_set_data(G_OBJECT(toolBar), "desktop", NULL);
+
+    GtkWidget* child = gtk_bin_get_child(GTK_BIN(toolbox));
+    if ( child ) {
+        gtk_container_remove( GTK_CONTAINER(toolbox), child );
     }
+
+    gtk_container_add( GTK_CONTAINER(toolbox), toolBar );
+//     Inkscape::IconSize toolboxSize = prefToSize("toolbox.tools", "small");
 }
 
 
 static void
-update_tool_toolbox( SPDesktop */*desktop*/, SPEventContext *eventcontext, GtkWidget *toolbox )
+update_tool_toolbox( SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget */*toolbox*/ )
 {
     gchar const *const tname = ( eventcontext
                                  ? gtk_type_name(GTK_OBJECT_TYPE(eventcontext))
                                  : NULL );
+    Glib::RefPtr<Gtk::ActionGroup> mainActions = create_or_fetch_actions( desktop );
+
     for (int i = 0 ; tools[i].type_name ; i++ ) {
-        SPButton *button = SP_BUTTON(g_object_get_data(G_OBJECT(toolbox), tools[i].data_name));
-        sp_button_toggle_set_down(button, tname && !strcmp(tname, tools[i].type_name));
+        Glib::RefPtr<Gtk::Action> act = mainActions->get_action( Inkscape::Verb::get(tools[i].verb)->get_id() );
+        if ( act ) {
+            bool setActive = tname && !strcmp(tname, tools[i].type_name);
+            Glib::RefPtr<VerbAction> verbAct = Glib::RefPtr<VerbAction>::cast_dynamic(act);
+            if ( verbAct ) {
+                verbAct->set_active(setActive);
+            }
+        }
     }
 }
 
@@ -1214,10 +1625,10 @@ static void
 setup_aux_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
 {
     GtkSizeGroup* grouper = gtk_size_group_new( GTK_SIZE_GROUP_BOTH );
-    GtkActionGroup* mainActions = create_or_fetch_actions( desktop );
+    Glib::RefPtr<Gtk::ActionGroup> mainActions = create_or_fetch_actions( desktop );
     GtkUIManager* mgr = gtk_ui_manager_new();
     GError* errVal = 0;
-    gtk_ui_manager_insert_action_group( mgr, mainActions, 0 );
+    gtk_ui_manager_insert_action_group( mgr, mainActions->gobj(), 0 );
     gtk_ui_manager_add_ui_from_string( mgr, ui_descr, -1, &errVal );
 
     std::map<std::string, GtkWidget*> dataHolders;
@@ -1226,11 +1637,11 @@ setup_aux_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
         if ( aux_toolboxes[i].prep_func ) {
             // converted to GtkActions and UIManager
 
-            GtkWidget* kludge = gtk_hbox_new( FALSE, 0 );
+            GtkWidget* kludge = gtk_toolbar_new();
             g_object_set_data( G_OBJECT(kludge), "dtw", desktop->canvas);
             g_object_set_data( G_OBJECT(kludge), "desktop", desktop);
             dataHolders[aux_toolboxes[i].type_name] = kludge;
-            aux_toolboxes[i].prep_func( desktop, mainActions, G_OBJECT(kludge) );
+            aux_toolboxes[i].prep_func( desktop, mainActions->gobj(), G_OBJECT(kludge) );
         } else {
 
             GtkWidget *sub_toolbox = 0;
@@ -1263,8 +1674,7 @@ setup_aux_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
             g_free( tmp );
             tmp = 0;
 
-            gint shrinkTop = prefs_get_int_attribute_limited( "toolbox", "small", 1, 0, 1 );
-            Inkscape::IconSize toolboxSize = shrinkTop ? Inkscape::ICON_SIZE_SMALL_TOOLBAR : Inkscape::ICON_SIZE_LARGE_TOOLBAR;
+            Inkscape::IconSize toolboxSize = prefToSize("toolbox", "small");
             if ( prefs_get_int_attribute_limited( "toolbox", "icononly", 1, 0, 1 ) ) {
                 gtk_toolbar_set_style( GTK_TOOLBAR(toolBar), GTK_TOOLBAR_ICONS );
             }
@@ -1274,7 +1684,7 @@ setup_aux_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
             gtk_table_attach( GTK_TABLE(holder), toolBar, 0, 1, 0, 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0 );
 
             if ( aux_toolboxes[i].swatch_verb_id != SP_VERB_INVALID ) {
-                Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch( NULL, aux_toolboxes[i].swatch_tip );
+                Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch( NULL, _(aux_toolboxes[i].swatch_tip) );
                 swatch->setDesktop( desktop );
                 swatch->setClickVerb( aux_toolboxes[i].swatch_verb_id );
                 swatch->setWatchedTool( aux_toolboxes[i].swatch_tool, true );
@@ -1353,23 +1763,33 @@ setup_commands_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
         "    <toolitem action='DialogDocumentProperties' />"
         "  </toolbar>"
         "</ui>";
-    GtkActionGroup* mainActions = create_or_fetch_actions( desktop );
+    Glib::RefPtr<Gtk::ActionGroup> mainActions = create_or_fetch_actions( desktop );
 
 
     GtkUIManager* mgr = gtk_ui_manager_new();
     GError* errVal = 0;
 
-    gtk_ui_manager_insert_action_group( mgr, mainActions, 0 );
+    gtk_ui_manager_insert_action_group( mgr, mainActions->gobj(), 0 );
     gtk_ui_manager_add_ui_from_string( mgr, descr, -1, &errVal );
 
     GtkWidget* toolBar = gtk_ui_manager_get_widget( mgr, "/ui/CommandsToolbar" );
     if ( prefs_get_int_attribute_limited( "toolbox", "icononly", 1, 0, 1 ) ) {
         gtk_toolbar_set_style( GTK_TOOLBAR(toolBar), GTK_TOOLBAR_ICONS );
     }
-    gint shrinkTop = prefs_get_int_attribute_limited( "toolbox", "small", 1, 0, 1 );
-    Inkscape::IconSize toolboxSize = shrinkTop ? Inkscape::ICON_SIZE_SMALL_TOOLBAR : Inkscape::ICON_SIZE_LARGE_TOOLBAR;
+
+    Inkscape::IconSize toolboxSize = prefToSize("toolbox", "small");
     gtk_toolbar_set_icon_size( GTK_TOOLBAR(toolBar), (GtkIconSize)toolboxSize );
 
+    gtk_toolbar_set_orientation(GTK_TOOLBAR(toolBar), GTK_ORIENTATION_HORIZONTAL);
+    gtk_toolbar_set_show_arrow(GTK_TOOLBAR(toolBar), TRUE);
+
+
+    g_object_set_data(G_OBJECT(toolBar), "desktop", NULL);
+
+    GtkWidget* child = gtk_bin_get_child(GTK_BIN(toolbox));
+    if ( child ) {
+        gtk_container_remove( GTK_CONTAINER(toolbox), child );
+    }
 
     gtk_container_add( GTK_CONTAINER(toolbox), toolBar );
 }
@@ -1390,23 +1810,13 @@ void show_aux_toolbox(GtkWidget *toolbox_toplevel)
     }
     gtk_widget_show(toolbox);
 
-    // need to show the spacer, or the padding will be off
-    GtkWidget *spacer = GTK_WIDGET(g_object_get_data(G_OBJECT(toolbox), "top_spacer"));
-    gtk_widget_show(spacer);
-
     gtk_widget_show_all(shown_toolbox);
 }
 
-void
-aux_toolbox_space(GtkWidget *tb, gint space)
-{
-    gtk_box_pack_start(GTK_BOX(tb), gtk_hbox_new(FALSE, 0), FALSE, FALSE, space);
-}
-
 static GtkWidget *
 sp_empty_toolbox_new(SPDesktop *desktop)
 {
-    GtkWidget *tbl = gtk_hbox_new(FALSE, 0);
+    GtkWidget *tbl = gtk_toolbar_new();
     gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
     gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
 
@@ -1416,50 +1826,6 @@ sp_empty_toolbox_new(SPDesktop *desktop)
     return tbl;
 }
 
-// helper UI functions
-
-GtkWidget *
-sp_tb_spinbutton(
-    gchar *label, gchar const *tooltip,
-    gchar const *path, gchar const *data, gdouble def,
-    GtkWidget *us,
-    GtkWidget *tbl,
-    gboolean altx, gchar const *altx_mark,
-    gdouble lower, gdouble upper, gdouble step, gdouble page,
-    void (*callback)(GtkAdjustment *, GtkWidget *),
-    gdouble climb = 0.1, guint digits = 3, double factor = 1.0)
-{
-    GtkTooltips *tt = gtk_tooltips_new();
-
-    GtkWidget *hb = gtk_hbox_new(FALSE, 1);
-
-    GtkWidget *l = gtk_label_new(label);
-    gtk_widget_show(l);
-    gtk_misc_set_alignment(GTK_MISC(l), 1.0, 0.5);
-    gtk_container_add(GTK_CONTAINER(hb), l);
-
-    GtkObject *a = gtk_adjustment_new(prefs_get_double_attribute(path, data, def) * factor,
-                                      lower, upper, step, page, page);
-    gtk_object_set_data(GTK_OBJECT(tbl), data, a);
-    if (us)
-        sp_unit_selector_add_adjustment(SP_UNIT_SELECTOR(us), GTK_ADJUSTMENT(a));
-
-    GtkWidget *sb = gtk_spin_button_new(GTK_ADJUSTMENT(a), climb, digits);
-    gtk_tooltips_set_tip(tt, sb, tooltip, NULL);
-    if (altx)
-        gtk_object_set_data(GTK_OBJECT(sb), altx_mark, sb);
-    gtk_widget_set_size_request(sb,
-                                (upper <= 1.0 || digits == 0)? AUX_SPINBUTTON_WIDTH_SMALL - 10: AUX_SPINBUTTON_WIDTH_SMALL,
-                                AUX_SPINBUTTON_HEIGHT);
-    gtk_widget_show(sb);
-    gtk_signal_connect(GTK_OBJECT(sb), "focus-in-event", GTK_SIGNAL_FUNC(spinbutton_focus_in), tbl);
-    gtk_signal_connect(GTK_OBJECT(sb), "key-press-event", GTK_SIGNAL_FUNC(spinbutton_keypress), tbl);
-    gtk_container_add(GTK_CONTAINER(hb), sb);
-    gtk_signal_connect(GTK_OBJECT(a), "value_changed", GTK_SIGNAL_FUNC(callback), tbl);
-
-    return hb;
-}
-
 #define MODE_LABEL_WIDTH 70
 
 //########################
@@ -1495,7 +1861,7 @@ static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKlu
             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(repr, SP_OBJECT_WRITE_EXT);
+            SP_OBJECT((SPItem *) items->data)->updateRepr();
             modmade = true;
         }
     }
@@ -1536,7 +1902,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(repr, SP_OBJECT_WRITE_EXT);
+            SP_OBJECT((SPItem *) items->data)->updateRepr();
             modmade = true;
         }
     }
@@ -1578,7 +1944,7 @@ static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *d
         if (SP_IS_STAR((SPItem *) items->data)) {
             Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data);
             repr->setAttribute("inkscape:flatsided", flat ? "true" : "false" );
-            SP_OBJECT((SPItem *) items->data)->updateRepr(repr, SP_OBJECT_WRITE_EXT);
+            SP_OBJECT((SPItem *) items->data)->updateRepr();
             modmade = true;
         }
     }
@@ -1615,7 +1981,7 @@ static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludg
         if (SP_IS_STAR((SPItem *) items->data)) {
             Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data);
             sp_repr_set_svg_double(repr, "inkscape:rounded", (gdouble) adj->value);
-            SP_OBJECT(items->data)->updateRepr(repr, SP_OBJECT_WRITE_EXT);
+            SP_OBJECT(items->data)->updateRepr();
             modmade = true;
         }
     }
@@ -1649,7 +2015,7 @@ static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKl
         if (SP_IS_STAR((SPItem *) items->data)) {
             Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data);
             sp_repr_set_svg_double(repr, "inkscape:randomized", (gdouble) adj->value);
-            SP_OBJECT(items->data)->updateRepr(repr, SP_OBJECT_WRITE_EXT);
+            SP_OBJECT(items->data)->updateRepr();
             modmade = true;
         }
     }
@@ -1676,6 +2042,9 @@ static void star_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *n
 
     GtkAdjustment *adj = 0;
 
+    gchar const *flatsidedstr = prefs_get_string_attribute( "tools.shapes.star", "isflatsided" );
+    bool isFlatSided = flatsidedstr ? (strcmp(flatsidedstr, "false") != 0) : true;
+
     if (!strcmp(name, "inkscape:randomized")) {
         adj = GTK_ADJUSTMENT( gtk_object_get_data(GTK_OBJECT(tbl), "randomized") );
         gtk_adjustment_set_value(adj, sp_repr_get_double_attribute(repr, "inkscape:randomized", 0.0));
@@ -1693,7 +2062,7 @@ static void star_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *n
             ege_select_one_action_set_active( flat_action, 0 );
             gtk_action_set_sensitive( prop_action, FALSE );
         }
-    } else if (!strcmp(name, "sodipodi:r1") || !strcmp(name, "sodipodi:r2")) {
+    } else if ((!strcmp(name, "sodipodi:r1") || !strcmp(name, "sodipodi:r2")) && (!isFlatSided) ) {
         adj = (GtkAdjustment*)gtk_object_get_data(GTK_OBJECT(tbl), "proportion");
         gdouble r1 = sp_repr_get_double_attribute(repr, "sodipodi:r1", 1.0);
         gdouble r2 = sp_repr_get_double_attribute(repr, "sodipodi:r2", 1.0);
@@ -1809,13 +2178,19 @@ sp_toolbox_add_label(GtkWidget *tbl, gchar const *title, bool wide)
     GtkWidget *l = gtk_label_new(NULL);
     gtk_label_set_markup(GTK_LABEL(l), title);
     gtk_box_pack_end(GTK_BOX(boxl), l, FALSE, FALSE, 0);
-    gtk_box_pack_start(GTK_BOX(tbl), boxl, FALSE, FALSE, 0);
+    if ( GTK_IS_TOOLBAR(tbl) ) {
+        gtk_toolbar_append_widget( GTK_TOOLBAR(tbl), boxl, "", "" );
+    } else {
+        gtk_box_pack_start(GTK_BOX(tbl), boxl, FALSE, FALSE, 0);
+    }
     gtk_object_set_data(GTK_OBJECT(tbl), "mode_label", l);
 }
 
 
 static void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 {
+    Inkscape::IconSize secondarySize = prefToSize("toolbox", "secondary", 1);
+
     {
         EgeOutputAction* act = ege_output_action_new( "StarStateAction", _("<b>New:</b>"), "", 0 );
         ege_output_action_set_use_markup( act, TRUE );
@@ -1824,7 +2199,6 @@ static void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
     }
 
     {
-        //EgeAdjustmentAction* calligraphy_angle = 0;
         EgeAdjustmentAction* eact = 0;
         gchar const *flatsidedstr = prefs_get_string_attribute( "tools.shapes.star", "isflatsided" );
         bool isFlatSided = flatsidedstr ? (strcmp(flatsidedstr, "false") != 0) : true;
@@ -1856,6 +2230,7 @@ static void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
             ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE );
             g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL );
             ege_select_one_action_set_icon_column( act, 2 );
+            ege_select_one_action_set_icon_size( act, secondarySize );
             ege_select_one_action_set_tooltip_column( act, 1  );
 
             ege_select_one_action_set_active( act, isFlatSided ? 0 : 1 );
@@ -2182,6 +2557,7 @@ sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
 static void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 {
     EgeAdjustmentAction* eact = 0;
+    Inkscape::IconSize secondarySize = prefToSize("toolbox", "secondary", 1);
 
     {
         EgeOutputAction* act = ege_output_action_new( "RectStateAction", _("<b>New:</b>"), "", 0 );
@@ -2273,7 +2649,7 @@ static void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
                                           _("Not rounded"),
                                           _("Make corners sharp"),
                                           "squared_corner",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_rtb_defaults), holder );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
         gtk_action_set_sensitive( GTK_ACTION(inky), TRUE );
@@ -2294,277 +2670,356 @@ static void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
 //##       3D Box       ##
 //########################
 
-static void sp_3dbox_toggle_vp_changed (GtkToggleAction */*act*/, GObject *dataKludge, Box3D::Axis axis)
-{
-    SPDesktop *desktop = (SPDesktop *) g_object_get_data (dataKludge, "desktop");
-    SPDocument *document = sp_desktop_document (desktop);
-    Box3D::Perspective3D *persp = document->current_perspective;
+// normalize angle so that it lies in the interval [0,360]
+static double box3d_normalize_angle (double a) {
+    double angle = a + ((int) (a/360.0))*360;
+    if (angle < 0) {
+        angle += 360.0;
+    }
+    return angle;
+}
 
-    g_return_if_fail (is_single_axis_direction (axis));
-    g_return_if_fail (persp);
+static void
+box3d_set_button_and_adjustment(Persp3D *persp, Proj::Axis axis,
+                                GtkAdjustment *adj, GtkAction *act, GtkToggleAction *tact) {
+    // TODO: Take all selected perspectives into account but don't touch the state button if not all of them
+    //       have the same state (otherwise a call to box3d_vp_z_state_changed() is triggered and the states
+    //       are reset).
+    bool is_infinite = !persp3d_VP_is_finite(persp, axis);
+
+    if (is_infinite) {
+        gtk_toggle_action_set_active(tact, TRUE);
+        gtk_action_set_sensitive(act, TRUE);
+
+        double angle = persp3d_get_infinite_angle(persp, axis);
+        if (angle != NR_HUGE) { // FIXME: We should catch this error earlier (don't show the spinbutton at all)
+            gtk_adjustment_set_value(adj, box3d_normalize_angle(angle));
+        }
+    } else {
+        gtk_toggle_action_set_active(tact, FALSE);
+        gtk_action_set_sensitive(act, FALSE);
+    }
+}
 
-    persp->toggle_boxes (axis);
+static void
+box3d_resync_toolbar(Inkscape::XML::Node *persp_repr, GObject *data) {
+    if (!persp_repr) {
+        g_print ("No perspective given to box3d_resync_toolbar().\n");
+        return;
+    }
 
-    gchar *str;
-    switch (axis) {
-        case Box3D::X:
-            str = g_strdup ("box3d_angle_x_action");
-            break;
-        case Box3D::Y:
-            str = g_strdup ("box3d_angle_y_action");
-            break;
-        case Box3D::Z:
-            str = g_strdup ("box3d_angle_z_action");
-            break;
-        default:
-            return;
+    GtkWidget *tbl = GTK_WIDGET(data);
+    GtkAdjustment *adj = 0;
+    GtkAction *act = 0;
+    GtkToggleAction *tact = 0;
+    Persp3D *persp = persp3d_get_from_repr(persp_repr);
+    {
+        adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_x"));
+        act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_x_action"));
+        tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_x_state_action"))->action;
+
+        box3d_set_button_and_adjustment(persp, Proj::X, adj, act, tact);
     }
-    GtkAction* angle_action = GTK_ACTION (g_object_get_data (dataKludge, str));
-    if (angle_action) {
-        gtk_action_set_sensitive (angle_action, !persp->get_vanishing_point (axis)->is_finite() );
+    {
+        adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_y"));
+        act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_y_action"));
+        tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_y_state_action"))->action;
+
+        box3d_set_button_and_adjustment(persp, Proj::Y, adj, act, tact);
     }
+    {
+        adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "box3d_angle_z"));
+        act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_z_action"));
+        tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_z_state_action"))->action;
 
-    // FIXME: Given how it is realized in the other tools, this is probably not the right way to do it,
-    //        but without the if construct, we get continuous segfaults. Needs further investigation.
-    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
-        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
-                         _("3D Box: Change perspective"));
+        box3d_set_button_and_adjustment(persp, Proj::Z, adj, act, tact);
     }
 }
 
-static void sp_3dbox_toggle_vp_x_changed(GtkToggleAction *act, GObject *dataKludge)
+static void box3d_persp_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const */*name*/,
+                                                  gchar const */*old_value*/, gchar const */*new_value*/,
+                                                  bool /*is_interactive*/, gpointer data)
 {
-    sp_3dbox_toggle_vp_changed (act, dataKludge, Box3D::X);
-}
+    GtkWidget *tbl = GTK_WIDGET(data);
 
-static void sp_3dbox_toggle_vp_y_changed(GtkToggleAction *act, GObject *dataKludge)
-{
-    sp_3dbox_toggle_vp_changed (act, dataKludge, Box3D::Y);
+    // quit if run by the attr_changed listener
+    // note: it used to work without the differently called freeze_ attributes (here and in
+    //       box3d_angle_value_changed()) but I now it doesn't so I'm leaving them in for now
+    if (g_object_get_data(G_OBJECT(tbl), "freeze_angle")) {
+        return;
+    }
+
+    // set freeze so that it can be caught in box3d_angle_z_value_changed() (to avoid calling
+    // sp_document_maybe_done() when the document is undo insensitive)
+    g_object_set_data(G_OBJECT(tbl), "freeze_attr", GINT_TO_POINTER(TRUE));
+
+    // TODO: Only update the appropriate part of the toolbar
+//    if (!strcmp(name, "inkscape:vp_z")) {
+        box3d_resync_toolbar(repr, G_OBJECT(tbl));
+//    }
+
+    Persp3D *persp = persp3d_get_from_repr(repr);
+    persp3d_update_box_reprs(persp);
+
+    g_object_set_data(G_OBJECT(tbl), "freeze_attr", GINT_TO_POINTER(FALSE));
 }
 
-static void sp_3dbox_toggle_vp_z_changed(GtkToggleAction *act, GObject *dataKludge)
+static Inkscape::XML::NodeEventVector box3d_persp_tb_repr_events =
 {
-    sp_3dbox_toggle_vp_changed (act, dataKludge, Box3D::Z);
-}
+    NULL, /* child_added */
+    NULL, /* child_removed */
+    box3d_persp_tb_event_attr_changed,
+    NULL, /* content_changed */
+    NULL  /* order_changed */
+};
 
-static void sp_3dbox_vp_angle_changed(GtkAdjustment *adj, GObject *dataKludge, Box3D::Axis axis )
+/**
+ *  \param selection Should not be NULL.
+ */
+// FIXME: This should rather be put into persp3d-reference.cpp or something similar so that it reacts upon each
+//        Change of the perspective, and not of the current selection (but how to refer to the toolbar then?)
+static void
+box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
 {
-    SPDesktop *desktop = (SPDesktop *) g_object_get_data(dataKludge, "desktop");
-    Box3D::Perspective3D *persp = sp_desktop_document (desktop)->current_perspective;
+    // Here the following should be done: If all selected boxes have finite VPs in a certain direction,
+    // disable the angle entry fields for this direction (otherwise entering a value in them should only
+    // update the perspectives with infinite VPs and leave the other ones untouched).
 
-    if (persp) {
-        double angle = adj->value * M_PI/180;
-        persp->set_infinite_direction (axis, NR::Point (cos (angle), sin (angle)));
+    Inkscape::XML::Node *persp_repr = NULL;
+    purge_repr_listener(tbl, tbl);
 
-        // FIXME: See comment above; without the if construct we get segfaults during undo.
-        if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
-            sp_document_maybe_done(sp_desktop_document(desktop), "perspectiveangle", SP_VERB_CONTEXT_3DBOX,
-                             _("3D Box: Change perspective"));
+    SPItem *item = selection->singleItem();
+    if (item && SP_IS_BOX3D(item)) {
+        // FIXME: Also deal with multiple selected boxes
+        SPBox3D *box = SP_BOX3D(item);
+        Persp3D *persp = box3d_get_perspective(box);
+        persp_repr = SP_OBJECT_REPR(persp);
+        if (persp_repr) {
+            g_object_set_data(tbl, "repr", persp_repr);
+            Inkscape::GC::anchor(persp_repr);
+            sp_repr_add_listener(persp_repr, &box3d_persp_tb_repr_events, tbl);
+            sp_repr_synthesize_events(persp_repr, &box3d_persp_tb_repr_events, tbl);
         }
-    }
-    //g_object_set_data(G_OBJECT(dataKludge), "freeze", GINT_TO_POINTER(FALSE));
-}
 
-static void sp_3dbox_vpx_angle_changed(GtkAdjustment *adj, GObject *dataKludge )
-{
-    sp_3dbox_vp_angle_changed (adj, dataKludge, Box3D::X);
-}
+        inkscape_active_document()->current_persp3d = persp3d_get_from_repr(persp_repr);
+        prefs_set_string_attribute("tools.shapes.3dbox", "persp", persp_repr->attribute("id"));
 
-static void sp_3dbox_vpy_angle_changed(GtkAdjustment *adj, GObject *dataKludge )
-{
-    sp_3dbox_vp_angle_changed (adj, dataKludge, Box3D::Y);
+        box3d_resync_toolbar(persp_repr, tbl);
+    }
 }
 
-static void sp_3dbox_vpz_angle_changed(GtkAdjustment *adj, GObject *dataKludge )
+static void
+box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis)
 {
-    sp_3dbox_vp_angle_changed (adj, dataKludge, Box3D::Z);
-}
+    SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" );
+    SPDocument *document = sp_desktop_document(desktop);
 
-// normalize angle so that it lies in the interval [0,360]
-static double sp_3dbox_normalize_angle (double a) {
-    double angle = a + ((int) (a/360.0))*360;
-    if (angle < 0) {
-        angle += 360.0;
+    // quit if run by the attr_changed listener
+    // note: it used to work without the differently called freeze_ attributes (here and in
+    //       box3d_persp_tb_event_attr_changed()) but I now it doesn't so I'm leaving them in for now
+    if (g_object_get_data( dataKludge, "freeze_attr" )) {
+        return;
     }
-    return angle;
-}
 
-static void sp_3dbox_tb_event_attr_changed(Inkscape::XML::Node */*repr*/, gchar const *name,
-                                           gchar const */*old_value*/, gchar const */*new_value*/,
-                                           bool /*is_interactive*/, gpointer data)
-{
-    GtkWidget *tbl = GTK_WIDGET(data);
+    // in turn, prevent listener from responding
+    g_object_set_data(dataKludge, "freeze_angle", GINT_TO_POINTER(TRUE));
 
-    // FIXME: if we check for "freeze" as in other tools, no action is performed at all ...
-    /***
-    // quit if run by the _changed callbacks
-    if (g_object_get_data(G_OBJECT(tbl), "freeze")) {
+    //Persp3D *persp = document->current_persp3d;
+    std::list<Persp3D *> sel_persps = sp_desktop_selection(desktop)->perspList();
+    if (sel_persps.empty()) {
+        // this can happen when the document is created; we silently ignore it
         return;
     }
+    Persp3D *persp = sel_persps.front();
 
-    // in turn, prevent callbacks from responding
-    g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE));
-    ***/
+    persp->tmat.set_infinite_direction (axis, adj->value);
+    SP_OBJECT(persp)->updateRepr();
 
-    if (!strcmp(name, "inkscape:perspective")) {
-        GtkAdjustment *adj = 0;
-        double angle;
-        SPDesktop *desktop = (SPDesktop *) g_object_get_data(G_OBJECT(tbl), "desktop");
-        Box3D::Perspective3D *persp = sp_desktop_document (desktop)->current_perspective;
+    // TODO: use the correct axis here, too
+    sp_document_maybe_done(document, "perspangle", SP_VERB_CONTEXT_3DBOX, _("3D Box: Change perspective (angle of infinite axis)"));
 
-        adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "dir_vp_x"));
-        angle = sp_3dbox_normalize_angle (persp->get_vanishing_point (Box3D::X)->get_angle());
-        gtk_adjustment_set_value(adj, angle);
+    g_object_set_data( dataKludge, "freeze_angle", GINT_TO_POINTER(FALSE) );
+}
 
-        adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "dir_vp_y"));
-        angle = sp_3dbox_normalize_angle (persp->get_vanishing_point (Box3D::Y)->get_angle());
-        gtk_adjustment_set_value(adj, angle);
 
-        adj = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(tbl), "dir_vp_z"));
-        angle = sp_3dbox_normalize_angle (persp->get_vanishing_point (Box3D::Z)->get_angle());
-        gtk_adjustment_set_value(adj, angle);
-    }
+static void
+box3d_angle_x_value_changed(GtkAdjustment *adj, GObject *dataKludge)
+{
+    box3d_angle_value_changed(adj, dataKludge, Proj::X);
 }
 
-static Inkscape::XML::NodeEventVector sp_3dbox_tb_repr_events =
+static void
+box3d_angle_y_value_changed(GtkAdjustment *adj, GObject *dataKludge)
 {
-    NULL, /* child_added */
-    NULL, /* child_removed */
-    sp_3dbox_tb_event_attr_changed,
-    NULL, /* content_changed */
-    NULL  /* order_changed */
-};
+    box3d_angle_value_changed(adj, dataKludge, Proj::Y);
+}
 
-/**
- *  \param selection Should not be NULL.
- */
 static void
-sp_3dbox_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl)
+box3d_angle_z_value_changed(GtkAdjustment *adj, GObject *dataKludge)
 {
-    Inkscape::XML::Node *repr = NULL;
-    purge_repr_listener(tbl, tbl);
+    box3d_angle_value_changed(adj, dataKludge, Proj::Z);
+}
 
-    SPItem *item = selection->singleItem();
-    if (item) {
-        repr = SP_OBJECT_REPR(item);
-        if (repr) {
-            g_object_set_data(tbl, "repr", repr);
-            Inkscape::GC::anchor(repr);
-            sp_repr_add_listener(repr, &sp_3dbox_tb_repr_events, tbl);
-            sp_repr_synthesize_events(repr, &sp_3dbox_tb_repr_events, tbl);
-        }
+
+static void box3d_vp_state_changed( GtkToggleAction *act, GtkAction */*box3d_angle*/, Proj::Axis axis )
+{
+    // TODO: Take all selected perspectives into account
+    std::list<Persp3D *> sel_persps = sp_desktop_selection(inkscape_active_desktop())->perspList();
+    if (sel_persps.empty()) {
+        // this can happen when the document is created; we silently ignore it
+        return;
     }
+    Persp3D *persp = sel_persps.front();
+
+    bool set_infinite = gtk_toggle_action_get_active(act);
+    persp3d_set_VP_state (persp, axis, set_infinite ? Proj::VP_INFINITE : Proj::VP_FINITE);
+}
+
+static void box3d_vp_x_state_changed( GtkToggleAction *act, GtkAction *box3d_angle )
+{
+    box3d_vp_state_changed(act, box3d_angle, Proj::X);
+}
+
+static void box3d_vp_y_state_changed( GtkToggleAction *act, GtkAction *box3d_angle )
+{
+    box3d_vp_state_changed(act, box3d_angle, Proj::Y);
+}
+
+static void box3d_vp_z_state_changed( GtkToggleAction *act, GtkAction *box3d_angle )
+{
+    box3d_vp_state_changed(act, box3d_angle, Proj::Z);
 }
 
-static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
+static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 {
     EgeAdjustmentAction* eact = 0;
     SPDocument *document = sp_desktop_document (desktop);
-    Box3D::Perspective3D *persp = document->current_perspective;
-    bool toggled = false;
-
-    /* angle of VP in X direction */
-    eact = create_adjustment_action("3DBoxPosAngleXAction",
-                                    _("Angle X"), _("Angle X:"), _("Angle of infinite vanishing point in X direction"),
-                                    "tools.shapes.3dbox", "dir_vp_x", persp->get_vanishing_point (Box3D::X)->get_angle(),
-                                    GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
-                                    0.0, 360.0, 1.0, 10.0,
-                                    0, 0, 0, // labels, values, G_N_ELEMENTS(labels),
-                                    sp_3dbox_vpx_angle_changed,
-                                    0.1, 1);
-    gtk_action_group_add_action(mainActions, GTK_ACTION(eact));
-    g_object_set_data(holder, "box3d_angle_x_action", eact);
-    if (!persp->get_vanishing_point (Box3D::X)->is_finite()) {
-        gtk_action_set_sensitive(GTK_ACTION(eact), TRUE);
+    Persp3D *persp = document->current_persp3d;
+
+    EgeAdjustmentAction* box3d_angle_x = 0;
+    EgeAdjustmentAction* box3d_angle_y = 0;
+    EgeAdjustmentAction* box3d_angle_z = 0;
+
+    /* Angle X */
+    {
+        gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
+        gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
+        eact = create_adjustment_action( "3DBoxAngleXAction",
+                                         _("Angle in X direction"), _("Angle X:"),
+                                         // Translators: PL is short for 'perspective line'
+                                         _("Angle of PLs in X direction"),
+                                         "tools.shapes.3dbox", "box3d_angle_x", 30,
+                                         GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-box3d",
+                                         -360.0, 360.0, 1.0, 10.0,
+                                         labels, values, G_N_ELEMENTS(labels),
+                                         box3d_angle_x_value_changed );
+        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+        g_object_set_data( holder, "box3d_angle_x_action", eact );
+        box3d_angle_x = eact;
+    }
+
+    if (!persp3d_VP_is_finite(persp, Proj::X)) {
+        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
     } else {
-        gtk_action_set_sensitive(GTK_ACTION(eact), FALSE);
+        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
     }
 
-    /* toggle VP in X direction */
+
+    /* VP X state */
     {
-    InkToggleAction* act = ink_toggle_action_new("3DBoxVPXAction",
-                                                  _("Toggle VP in X direction"),
-                                                  _("Toggle VP in X direction between 'finite' and 'infinite' (=parallel)"),
-                                                  "toggle_vp_x",
-                                                  Inkscape::ICON_SIZE_DECORATION);
-    gtk_action_group_add_action(mainActions, GTK_ACTION(act));
-    if (persp) {
-        toggled = !persp->get_vanishing_point(Box3D::X)->is_finite();
-    }
-    gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), toggled);
-    /* we connect the signal after setting the state to avoid switching the state again */
-    g_signal_connect_after(G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_x_changed), holder);
-    }
-
-    /* angle of VP in Y direction */
-    eact = create_adjustment_action("3DBoxPosAngleYAction",
-                                    _("Angle Y"), _("Angle Y:"), _("Angle of infinite vanishing point in Y direction"),
-                                    "tools.shapes.3dbox", "dir_vp_y", persp->get_vanishing_point (Box3D::Y)->get_angle(),
-                                    GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
-                                    0.0, 360.0, 1.0, 10.0,
-                                    0, 0, 0, // labels, values, G_N_ELEMENTS(labels),
-                                    sp_3dbox_vpy_angle_changed,
-                                    0.1, 1);
-    gtk_action_group_add_action(mainActions, GTK_ACTION(eact));
-    g_object_set_data(holder, "box3d_angle_y_action", eact);
-    if (!persp->get_vanishing_point (Box3D::Y)->is_finite()) {
-        gtk_action_set_sensitive(GTK_ACTION(eact), TRUE);
-    } else {
-        gtk_action_set_sensitive(GTK_ACTION(eact), FALSE);
+        InkToggleAction* act = ink_toggle_action_new( "3DBoxVPXStateAction",
+                                                      // Translators: VP is short for 'vanishing point'
+                                                      _("State of VP in X direction"),
+                                                      _("Toggle VP in X direction between 'finite' and 'infinite' (=parallel)"),
+                                                      "toggle_vp_x",
+                                                      Inkscape::ICON_SIZE_DECORATION );
+        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+        g_object_set_data( holder, "box3d_vp_x_state_action", act );
+        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_x_state_changed), box3d_angle_x );
+        gtk_action_set_sensitive( GTK_ACTION(box3d_angle_x), !prefs_get_int_attribute( "tools.shapes.3dbox", "vp_x_state", 1 ) );
+        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.shapes.3dbox", "vp_x_state", 1 ) );
     }
 
-    /* toggle VP in Y direction */
+    /* Angle Y */
     {
-    InkToggleAction* act = ink_toggle_action_new("3DBoxVPYAction",
-                                                 _("Toggle VP in Y direction"),
-                                                 _("Toggle VP in Y direction between 'finite' and 'infinite' (=parallel)"),
-                                                 "toggle_vp_y",
-                                                 Inkscape::ICON_SIZE_DECORATION);
-    gtk_action_group_add_action(mainActions, GTK_ACTION(act));
-    if (persp) {
-        toggled = !persp->get_vanishing_point(Box3D::Y)->is_finite();
-    }
-    gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), toggled);
-    /* we connect the signal after setting the state to avoid switching the state again */
-    g_signal_connect_after(G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_y_changed), holder);
-    }
-
-    /* angle of VP in Z direction */
-    eact = create_adjustment_action("3DBoxPosAngleZAction",
-                                    _("Angle Z"), _("Angle Z:"), _("Angle of infinite vanishing point in Z direction"),
-                                    "tools.shapes.3dbox", "dir_vp_z", persp->get_vanishing_point (Box3D::Z)->get_angle(),
-                                    GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
-                                     0.0, 360.0, 1.0, 10.0,
-                                    0, 0, 0, // labels, values, G_N_ELEMENTS(labels),
-                                    sp_3dbox_vpz_angle_changed,
-                                    0.1, 1);
-
-    gtk_action_group_add_action(mainActions, GTK_ACTION(eact));
-    g_object_set_data(holder, "box3d_angle_z_action", eact);
-    if (!persp->get_vanishing_point (Box3D::Z)->is_finite()) {
-        gtk_action_set_sensitive(GTK_ACTION(eact), TRUE);
+        gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
+        gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
+        eact = create_adjustment_action( "3DBoxAngleYAction",
+                                         _("Angle in Y direction"), _("Angle Y:"),
+                                         // Translators: PL is short for 'perspective line'
+                                         _("Angle of PLs in Y direction"),
+                                         "tools.shapes.3dbox", "box3d_angle_y", 30,
+                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
+                                         -360.0, 360.0, 1.0, 10.0,
+                                         labels, values, G_N_ELEMENTS(labels),
+                                         box3d_angle_y_value_changed );
+        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+        g_object_set_data( holder, "box3d_angle_y_action", eact );
+        box3d_angle_y = eact;
+    }
+
+    if (!persp3d_VP_is_finite(persp, Proj::Y)) {
+        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
     } else {
-        gtk_action_set_sensitive(GTK_ACTION(eact), FALSE);
+        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
     }
 
-    /* toggle VP in Z direction */
+    /* VP Y state */
     {
-    InkToggleAction* act = ink_toggle_action_new("3DBoxVPZAction",
-                                                 _("Toggle VP in Z direction"),
-                                                 _("Toggle VP in Z direction between 'finite' and 'infinite' (=parallel)"),
-                                                 "toggle_vp_z",
-                                                 Inkscape::ICON_SIZE_DECORATION);
-    gtk_action_group_add_action(mainActions, GTK_ACTION(act));
-    if (persp) {
-        toggled = !persp->get_vanishing_point(Box3D::Z)->is_finite();
+        InkToggleAction* act = ink_toggle_action_new( "3DBoxVPYStateAction",
+                                                      // Translators: VP is short for 'vanishing point'
+                                                      _("State of VP in Y direction"),
+                                                      _("Toggle VP in Y direction between 'finite' and 'infinite' (=parallel)"),
+                                                      "toggle_vp_y",
+                                                      Inkscape::ICON_SIZE_DECORATION );
+        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+        g_object_set_data( holder, "box3d_vp_y_state_action", act );
+        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_y_state_changed), box3d_angle_y );
+        gtk_action_set_sensitive( GTK_ACTION(box3d_angle_y), !prefs_get_int_attribute( "tools.shapes.3dbox", "vp_y_state", 1 ) );
+        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.shapes.3dbox", "vp_y_state", 1 ) );
+    }
+
+    /* Angle Z */
+    {
+        gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 };
+        gdouble values[] = {-90, -60, -30, 0, 30, 60, 90};
+        eact = create_adjustment_action( "3DBoxAngleZAction",
+                                         _("Angle in Z direction"), _("Angle Z:"),
+                                         // Translators: PL is short for 'perspective line'
+                                         _("Angle of PLs in Z direction"),
+                                         "tools.shapes.3dbox", "box3d_angle_z", 30,
+                                         GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
+                                         -360.0, 360.0, 1.0, 10.0,
+                                         labels, values, G_N_ELEMENTS(labels),
+                                         box3d_angle_z_value_changed );
+        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+        g_object_set_data( holder, "box3d_angle_z_action", eact );
+        box3d_angle_z = eact;
     }
-    /* we connect the signal after setting the state to avoid switching the state again */
-    gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), toggled);
-    g_signal_connect_after(G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_z_changed), holder);
+
+    if (!persp3d_VP_is_finite(persp, Proj::Z)) {
+        gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
+    } else {
+        gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
+    }
+
+    /* VP Z state */
+    {
+        InkToggleAction* act = ink_toggle_action_new( "3DBoxVPZStateAction",
+                                                      // Translators: VP is short for 'vanishing point'
+                                                      _("State of VP in Z direction"),
+                                                      _("Toggle VP in Z direction between 'finite' and 'infinite' (=parallel)"),
+                                                      "toggle_vp_z",
+                                                      Inkscape::ICON_SIZE_DECORATION );
+        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+        g_object_set_data( holder, "box3d_vp_z_state_action", act );
+        g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_z_state_changed), box3d_angle_z );
+        gtk_action_set_sensitive( GTK_ACTION(box3d_angle_z), !prefs_get_int_attribute( "tools.shapes.3dbox", "vp_z_state", 1 ) );
+        gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.shapes.3dbox", "vp_z_state", 1 ) );
     }
 
     sigc::connection *connection = new sigc::connection(
-        sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_3dbox_toolbox_selection_changed), (GObject *)holder))
+        sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), (GObject *)holder))
        );
     g_signal_connect(holder, "destroy", G_CALLBACK(delete_connection), connection);
     g_signal_connect(holder, "destroy", G_CALLBACK(purge_repr_listener), holder);
@@ -2601,7 +3056,7 @@ sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_nam
         if (SP_IS_SPIRAL((SPItem *) items->data)) {
             Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data);
             sp_repr_set_svg_double( repr, namespaced_name, adj->value );
-            SP_OBJECT((SPItem *) items->data)->updateRepr(repr, SP_OBJECT_WRITE_EXT);
+            SP_OBJECT((SPItem *) items->data)->updateRepr();
             modmade = true;
         }
     }
@@ -2740,6 +3195,7 @@ sp_spiral_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl
 static void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 {
     EgeAdjustmentAction* eact = 0;
+    Inkscape::IconSize secondarySize = prefToSize("toolbox", "secondary", 1);
 
     {
         EgeOutputAction* act = ege_output_action_new( "SpiralStateAction", _("<b>New:</b>"), "", 0 );
@@ -2796,7 +3252,7 @@ static void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio
                                           _("Defaults"),
                                           _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"),
                                           GTK_STOCK_CLEAR,
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_spl_tb_defaults), holder );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
     }
@@ -2813,17 +3269,245 @@ static void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio
 //##     Pen/Pencil    ##
 //########################
 
+static void sp_pc_spiro_spline_mode_changed(EgeSelectOneAction* act, GObject* /*tbl*/)
+{
+    prefs_set_int_attribute("tools.freehand", "spiro-spline-mode", ege_select_one_action_get_active(act));
+}
+
+static void sp_add_spiro_toggle(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil)
+{
+    // FIXME: No action is needed, we only want a simple label. But sp_toolbox_add_label() always
+    //        adds the label at the end of the toolbar, whence this workarund. How to avoid this?
+    {
+        EgeOutputAction* act = ege_output_action_new(
+            tool_is_pencil ?
+            "FreehandModeActionPencilTemp" :
+            "FreehandModeActionPenTemp",
+            _("<b>Mode:</b>"), "", 0 );
+        ege_output_action_set_use_markup( act, TRUE );
+        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+        g_object_set_data( holder, "freehand_mode_action", act );
+    }
+
+    /* Freehand mode toggle buttons */
+    {
+        //gchar const *flatsidedstr = prefs_get_string_attribute( "tools.shapes.star", "isflatsided" );
+        //bool isSpiroMode = flatsidedstr ? (strcmp(flatsidedstr, "false") != 0) : true;
+        guint spiroMode = prefs_get_int_attribute("tools.freehand", "spiro-spline-mode", 0);
+        Inkscape::IconSize secondarySize = prefToSize("toolbox", "secondary", 1);
+
+        {
+            GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );
+
+            GtkTreeIter iter;
+            gtk_list_store_append( model, &iter );
+            gtk_list_store_set( model, &iter,
+                                0, _("Bézier"),
+                                1, _("Regular Bézier mode"),
+                                2, "bezier_mode",
+                                -1 );
+
+            gtk_list_store_append( model, &iter );
+            gtk_list_store_set( model, &iter,
+                                0, _("Spiro"),
+                                1, _("Spiro splines mode"),
+                                2, "spiro_splines_mode",
+                                -1 );
+
+            EgeSelectOneAction* act = ege_select_one_action_new(tool_is_pencil ?
+                                                                "FreehandModeActionPencil" :
+                                                                "FreehandModeActionPen",
+                                                                (""), (""), NULL, GTK_TREE_MODEL(model) );
+            gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
+            g_object_set_data( holder, "freehande_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 );
+            ege_select_one_action_set_icon_column( act, 2 );
+            ege_select_one_action_set_icon_size( act, secondarySize );
+            ege_select_one_action_set_tooltip_column( act, 1  );
+
+            ege_select_one_action_set_active( act, spiroMode);
+            g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_pc_spiro_spline_mode_changed), holder);
+        }
+    }
+}
+
+static void sp_freehand_change_shape(EgeSelectOneAction* act, GObject */*dataKludge*/) {
+    gint shape = ege_select_one_action_get_active( act );
+    prefs_set_int_attribute("tools.freehand", "shape", shape);
+}
+
+/**
+ * \brief Generate the list of freehand advanced shape option entries.
+ */
+GList * freehand_shape_dropdown_items_list() {
+    GList *glist = NULL;
+
+    glist = g_list_append (glist, _("None"));
+    glist = g_list_append (glist, _("Clipboard"));
+    glist = g_list_append (glist, _("Crescendo"));
+    glist = g_list_append (glist, _("Decrescendo"));
+
+    return glist;
+}
+
+static void
+sp_freehand_add_advanced_shape_options(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil) {
+    /*advanced shape options */
+    {
+        GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT );
+
+        GList* items = 0;
+        gint count = 0;
+        for ( items = freehand_shape_dropdown_items_list(); items ; items = g_list_next(items) )
+        {
+            GtkTreeIter iter;
+            gtk_list_store_append( model, &iter );
+            gtk_list_store_set( model, &iter, 0, reinterpret_cast<gchar*>(items->data), 1, count, -1 );
+            count++;
+        }
+        g_list_free( items );
+        items = 0;
+        EgeSelectOneAction* act1 = ege_select_one_action_new(
+            tool_is_pencil ? "SetPencilShapeAction" : "SetPenShapeAction",
+            _("Shape:"), (""), NULL, GTK_TREE_MODEL(model));
+        g_object_set( act1, "short_label", _("Shape:"), NULL );
+        ege_select_one_action_set_appearance( act1, "compact" );
+        ege_select_one_action_set_active( act1, prefs_get_int_attribute("tools.freehand", "shape", 0) );
+        g_signal_connect( G_OBJECT(act1), "changed", G_CALLBACK(sp_freehand_change_shape), holder );
+        gtk_action_group_add_action( mainActions, GTK_ACTION(act1) );
+        g_object_set_data( holder, "shape_action", act1 );
+    }
+}
+
+static void sp_pen_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* mainActions, GObject* holder)
+{
+    sp_add_spiro_toggle(mainActions, holder, false);
+    sp_freehand_add_advanced_shape_options(mainActions, holder, false);
+}
+
 
-static void sp_pen_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* /*mainActions*/, GObject* /*holder*/)
+static void
+sp_pencil_tb_defaults(GtkWidget */*widget*/, GtkObject *obj)
+{
+    GtkWidget *tbl = GTK_WIDGET(obj);
+
+    GtkAdjustment *adj;
+
+    // fixme: make settable
+    gdouble tolerance = 4;
+
+    adj = (GtkAdjustment*)gtk_object_get_data(obj, "tolerance");
+    gtk_adjustment_set_value(adj, tolerance);
+    gtk_adjustment_value_changed(adj);
+
+    spinbutton_defocus(GTK_OBJECT(tbl));
+}
+
+static void
+sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tbl)
 {
-    // Put stuff here
+
+    // quit if run by the attr_changed listener
+    if (g_object_get_data( tbl, "freeze" )) {
+        return;
+    }
+    // in turn, prevent listener from responding
+    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
+    prefs_set_double_attribute("tools.freehand.pencil",
+                               "tolerance", adj->value);
+    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
+
+}
+
+
+
+static void
+sp_pencil_tb_tolerance_value_changed_external(Inkscape::XML::Node */*repr*/,
+                                              const gchar */*key*/,
+                                              const gchar */*oldval*/,
+                                              const gchar */*newval*/,
+                                              bool /*is_interactive*/,
+                                              void * data)
+{
+    GObject* tbl = G_OBJECT(data);
+    if (g_object_get_data( tbl, "freeze" )) {
+        return;
+    }
+
+    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
+
+    GtkAdjustment * adj = (GtkAdjustment*)g_object_get_data(tbl,
+                                                            "tolerance");
+
+    double v = prefs_get_double_attribute("tools.freehand.pencil",
+                                            "tolerance", adj->value);
+    gtk_adjustment_set_value(adj, v);
+    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
+
 }
 
-static void sp_pencil_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* /*mainActions*/, GObject* /*holder*/)
+static Inkscape::XML::NodeEventVector pencil_node_events =
+{
+    NULL,
+    NULL,
+    sp_pencil_tb_tolerance_value_changed_external,
+    NULL,
+    NULL,
+};
+
+
+static void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 {
-    // Put stuff here
+    sp_add_spiro_toggle(mainActions, holder, true);
+
+    EgeAdjustmentAction* eact = 0;
+
+    /* Tolerance */
+    {
+
+        eact = create_adjustment_action( "PencilToleranceAction",
+                 _("Number of pixels allowed in interpolating"),
+                                         _("Tolerance:"), _("Tolerance"),
+                                         "tools.freehand.pencil", "tolerance",
+                                         3.0,
+                                         GTK_WIDGET(desktop->canvas), NULL,
+                                         holder, TRUE, "altx-pencil",
+                                         0.5, 100.0, 0.5, 0,
+                                         NULL, NULL, 0,
+                                         sp_pencil_tb_tolerance_value_changed,
+                                         1, 2);
+        ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
+        gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+
+        Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE,
+                                                      "tools.freehand.pencil");
+        repr->addListener(&pencil_node_events, G_OBJECT(holder));
+        g_object_set_data(G_OBJECT(holder), "repr", repr);
+
+    }
+
+    /* advanced shape options */
+    sp_freehand_add_advanced_shape_options(mainActions, holder, true);
+
+    /* Reset */
+    {
+        InkAction* inky = ink_action_new( "PencilResetAction",
+                                          _("Defaults"),
+                                          _("Reset pencil parameters to defaults (use Inkscape Preferences > Tools to change defaults)"),
+                                          GTK_STOCK_CLEAR,
+                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+        g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_pencil_tb_defaults), holder );
+        gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
+    }
+
+    g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder );
+
 }
 
+
 //########################
 //##       Tweak        ##
 //########################
@@ -2895,6 +3579,8 @@ static void tweak_toggle_doo (GtkToggleAction *act, gpointer /*data*/) {
 
 static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 {
+    Inkscape::IconSize secondarySize = prefToSize("toolbox", "secondary", 1);
+
     {
         /* Width */
         gchar const* labels[] = {_("(pinch tweak)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad tweak)")};
@@ -2903,9 +3589,10 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
                                                               _("Width"), _("Width:"), _("The width of the tweak area (relative to the visible canvas area)"),
                                                               "tools.tweak", "width", 15,
                                                               GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-tweak",
-                                                              1, 100, 1.0, 10.0,
+                                                              1, 100, 1.0, 0.0,
                                                               labels, values, G_N_ELEMENTS(labels),
                                                               sp_tweak_width_value_changed,  0.01, 0, 100 );
+        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 );
     }
@@ -2919,9 +3606,10 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
                                                               _("Force"), _("Force:"), _("The force of the tweak action"),
                                                               "tools.tweak", "force", 20,
                                                               GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "tweak-force",
-                                                              1, 100, 1.0, 10.0,
+                                                              1, 100, 1.0, 0.0,
                                                               labels, values, G_N_ELEMENTS(labels),
                                                               sp_tweak_force_value_changed,  0.01, 0, 100 );
+        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 );
     }
@@ -2996,6 +3684,7 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
         ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE );
         g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL );
         ege_select_one_action_set_icon_column( act, 2 );
+        ege_select_one_action_set_icon_size( act, secondarySize );
         ege_select_one_action_set_tooltip_column( act, 1  );
 
         gint mode = prefs_get_int_attribute("tools.tweak", "mode", 0);
@@ -3022,6 +3711,7 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
                                                       _("In color mode, act on objects' hue"),
                                                       NULL,
                                                       Inkscape::ICON_SIZE_DECORATION );
+        //TRANSLATORS:  "H" here stands for hue
         g_object_set( act, "short_label", _("H"), NULL );
         gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
         g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doh), desktop );
@@ -3036,6 +3726,7 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
                                                       _("In color mode, act on objects' saturation"),
                                                       NULL,
                                                       Inkscape::ICON_SIZE_DECORATION );
+        //TRANSLATORS: "S" here stands for Saturation
         g_object_set( act, "short_label", _("S"), NULL );
         gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
         g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dos), desktop );
@@ -3050,6 +3741,7 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
                                                       _("In color mode, act on objects' lightness"),
                                                       NULL,
                                                       Inkscape::ICON_SIZE_DECORATION );
+        //TRANSLATORS: "L" here stands for Lightness
         g_object_set( act, "short_label", _("L"), NULL );
         gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
         g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dol), desktop );
@@ -3064,6 +3756,7 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
                                                       _("In color mode, act on objects' opacity"),
                                                       NULL,
                                                       Inkscape::ICON_SIZE_DECORATION );
+        //TRANSLATORS: "O" here stands for Opacity
         g_object_set( act, "short_label", _("O"), NULL );
         gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
         g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doo), desktop );
@@ -3110,88 +3803,182 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
 //########################
 //##     Calligraphy    ##
 //########################
+static void update_presets_list(GObject *dataKludge ){
+    EgeSelectOneAction *sel = static_cast<EgeSelectOneAction *>(g_object_get_data(dataKludge, "profile_selector"));
+    if (sel) {
+        ege_select_one_action_set_active(sel, 0 );
+    }
+}
 
-static void sp_ddc_mass_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
+static void sp_ddc_mass_value_changed( GtkAdjustment *adj, GObject* tbl )
 {
-    prefs_set_double_attribute( "tools.calligraphic", "mass", adj->value );
+    prefs_set_double_attribute( "tools.calligraphic", "mass", adj->value * 0.01 );
+    update_presets_list(tbl);
 }
 
-static void sp_ddc_wiggle_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
+static void sp_ddc_wiggle_value_changed( GtkAdjustment *adj, GObject* tbl )
 {
-    prefs_set_double_attribute( "tools.calligraphic", "wiggle", adj->value );
+    prefs_set_double_attribute( "tools.calligraphic", "wiggle", adj->value * 0.01 );
+    update_presets_list(tbl);
 }
 
-static void sp_ddc_angle_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
+static void sp_ddc_angle_value_changed( GtkAdjustment *adj, GObject* tbl )
 {
     prefs_set_double_attribute( "tools.calligraphic", "angle", adj->value );
+    update_presets_list(tbl);
 }
 
-static void sp_ddc_width_value_changed( GtkAdjustment *adj, GObject */*tbl*/ )
+static void sp_ddc_width_value_changed( GtkAdjustment *adj, GObject *tbl )
 {
     prefs_set_double_attribute( "tools.calligraphic", "width", adj->value * 0.01 );
+    update_presets_list(tbl);
 }
 
-static void sp_ddc_velthin_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
+static void sp_ddc_velthin_value_changed( GtkAdjustment *adj, GObject* tbl )
 {
-    prefs_set_double_attribute("tools.calligraphic", "thinning", adj->value);
+    prefs_set_double_attribute("tools.calligraphic", "thinning", adj->value * 0.01 );
+    update_presets_list(tbl);
 }
 
-static void sp_ddc_flatness_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
+static void sp_ddc_flatness_value_changed( GtkAdjustment *adj, GObject* tbl )
 {
-    prefs_set_double_attribute( "tools.calligraphic", "flatness", adj->value );
+    prefs_set_double_attribute( "tools.calligraphic", "flatness", adj->value * 0.01);
+    update_presets_list(tbl);
 }
 
-static void sp_ddc_tremor_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
+static void sp_ddc_tremor_value_changed( GtkAdjustment *adj, GObject* tbl )
 {
-    prefs_set_double_attribute( "tools.calligraphic", "tremor", adj->value );
+    prefs_set_double_attribute( "tools.calligraphic", "tremor", adj->value * 0.01 );
+    update_presets_list(tbl);
 }
 
-static void sp_ddc_cap_rounding_value_changed( GtkAdjustment *adj, GObject* /*tbl*/ )
+static void sp_ddc_cap_rounding_value_changed( GtkAdjustment *adj, GObject* tbl )
 {
     prefs_set_double_attribute( "tools.calligraphic", "cap_rounding", adj->value );
+    update_presets_list(tbl);
 }
 
-static void sp_ddc_pressure_state_changed( GtkToggleAction *act, gpointer /*data*/ )
+static void sp_ddc_pressure_state_changed( GtkToggleAction *act, GObject*  tbl )
 {
     prefs_set_int_attribute( "tools.calligraphic", "usepressure", gtk_toggle_action_get_active( act ) ? 1 : 0);
+    update_presets_list(tbl);
 }
 
-static void sp_ddc_trace_background_changed( GtkToggleAction *act, gpointer /*data*/ )
+static void sp_ddc_trace_background_changed( GtkToggleAction *act, GObject*  tbl )
 {
     prefs_set_int_attribute( "tools.calligraphic", "tracebackground", gtk_toggle_action_get_active( act ) ? 1 : 0);
+    update_presets_list(tbl);
 }
 
-static void sp_ddc_tilt_state_changed( GtkToggleAction *act, GtkAction *calligraphy_angle )
+static void sp_ddc_tilt_state_changed( GtkToggleAction *act, GObject*  tbl )
 {
+    GtkAction * calligraphy_angle = static_cast<GtkAction *> (g_object_get_data(tbl,"angle"));
     prefs_set_int_attribute( "tools.calligraphic", "usetilt", gtk_toggle_action_get_active( act ) ? 1 : 0 );
+    update_presets_list(tbl);
+    if (calligraphy_angle )
+        gtk_action_set_sensitive( calligraphy_angle, !gtk_toggle_action_get_active( act ) );
+}
+
+
+#define PROFILE_FLOAT_SIZE 7
+#define PROFILE_INT_SIZE 4
+struct ProfileFloatElement {
+    char const *name;
+    double def;
+    double min;
+    double max;
+};
+struct ProfileIntElement {
+    char const *name;
+    int def;
+    int min;
+    int max;
+};
+
+
+
+static ProfileFloatElement f_profile[PROFILE_FLOAT_SIZE] = {
+    {"mass",2, 0.0, 100},
+    {"wiggle",0.0, 0.0, 100},
+    {"angle",30.0, -90.0, 90.0},
+    {"thinning",10, -100, 100},
+    {"tremor",0.0, 0.0, 100},
+    {"flatness",90, 0.0, 100},
+    {"cap_rounding",0.0, 0.0, 5.0}
+};
+static ProfileIntElement i_profile[PROFILE_INT_SIZE] = {
+    {"width",15, 1, 100},
+    {"usepressure",1,0,1},
+    {"tracebackground",0,0,1},
+    {"usetilt",1,0,1},
+};
+
+
+
+static void sp_dcc_save_profile( GtkWidget */*widget*/, GObject *dataKludge ){
+    SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" );
+    if (! desktop) return;
+
+    Inkscape::UI::Dialogs::CalligraphicProfileDialog::show(desktop);
+    if ( ! Inkscape::UI::Dialogs::CalligraphicProfileDialog::applied()) return;
+    Glib::ustring profile_name = Inkscape::UI::Dialogs::CalligraphicProfileDialog::getProfileName();
+
+    unsigned int new_index = pref_path_number_of_children("tools.calligraphic.preset") +1;
+    gchar *profile_id = g_strdup_printf("dcc%d", new_index);
+    gchar *pref_path = create_pref("tools.calligraphic.preset",profile_id);
 
-    gtk_action_set_sensitive( calligraphy_angle, !gtk_toggle_action_get_active( act ) );
+    for (unsigned i = 0; i < PROFILE_FLOAT_SIZE; ++i) {
+        ProfileFloatElement const &pe = f_profile[i];
+        double v = prefs_get_double_attribute_limited("tools.calligraphic",pe.name, pe.def, pe.min, pe.max);
+        prefs_set_double_attribute(pref_path,pe.name,v);
+    }
+    for (unsigned i = 0; i < PROFILE_INT_SIZE; ++i) {
+        ProfileIntElement const &pe = i_profile[i];
+        int v = prefs_get_int_attribute_limited("tools.calligraphic",pe.name, pe.def,pe.min, pe.max);
+        prefs_set_int_attribute(pref_path,pe.name,v);
+    }
+    prefs_set_string_attribute(pref_path,"name",profile_name.c_str());
+
+    EgeSelectOneAction* selector = static_cast<EgeSelectOneAction *>(g_object_get_data(dataKludge, "profile_selector"));
+    GtkListStore* model = GTK_LIST_STORE(ege_select_one_action_get_model(selector));
+    GtkTreeIter iter;
+    gtk_list_store_append( model, &iter );
+    gtk_list_store_set( model, &iter, 0, profile_name.c_str(), 1, new_index, -1 );
+
+    free(profile_id);
+    free(pref_path);
+
+    ege_select_one_action_set_active(selector, new_index);
 }
 
-static void sp_ddc_defaults(GtkWidget *, GObject *dataKludge)
-{
-    // FIXME: make defaults settable via Inkscape Options
-    struct KeyValue {
-        char const *key;
-        double value;
-    } const key_values[] = {
-        {"mass", 0.02},
-        {"wiggle", 0.0},
-        {"angle", 30.0},
-        {"width", 15},
-        {"thinning", 0.1},
-        {"tremor", 0.0},
-        {"flatness", 0.9},
-        {"cap_rounding", 0.0}
-    };
 
-    for (unsigned i = 0; i < G_N_ELEMENTS(key_values); ++i) {
-        KeyValue const &kv = key_values[i];
-        GtkAdjustment* adj = static_cast<GtkAdjustment *>(g_object_get_data(dataKludge, kv.key));
-        if ( adj ) {
-            gtk_adjustment_set_value(adj, kv.value);
+static void sp_ddc_change_profile(EgeSelectOneAction* act, GObject *dataKludge) {
+
+    gint preset_index = ege_select_one_action_get_active( act );
+    gchar *profile_name = get_pref_nth_child("tools.calligraphic.preset", preset_index);
+
+    if ( profile_name) {
+        g_object_set_data(dataKludge, "profile_selector",NULL); //temporary hides the selector so no one will updadte it
+        for (unsigned i = 0; i < PROFILE_FLOAT_SIZE; ++i) {
+            ProfileFloatElement const &pe = f_profile[i];
+            double v = prefs_get_double_attribute_limited(profile_name, pe.name, pe.def, pe.min, pe.max);
+            GtkAdjustment* adj = static_cast<GtkAdjustment *>(g_object_get_data(dataKludge, pe.name));
+            if ( adj ) {
+                gtk_adjustment_set_value(adj, v);
+            }
+        }
+        for (unsigned i = 0; i < PROFILE_INT_SIZE; ++i) {
+            ProfileIntElement const &pe = i_profile[i];
+            int v = prefs_get_int_attribute_limited(profile_name, pe.name, pe.def, pe.min, pe.max);
+            GtkToggleAction* toggle = static_cast<GtkToggleAction *>(g_object_get_data(dataKludge, pe.name));
+            if ( toggle ) {
+                gtk_toggle_action_set_active(toggle, v);
+            } else printf("No toggle");
         }
+        free(profile_name);
+        g_object_set_data(dataKludge, "profile_selector",act); //restore selector visibility
     }
+
 }
 
 
@@ -3209,9 +3996,10 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
                                                               _("The width of the calligraphic pen (relative to the visible canvas area)"),
                                                               "tools.calligraphic", "width", 15,
                                                               GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-calligraphy",
-                                                              1, 100, 1.0, 10.0,
+                                                              1, 100, 1.0, 0.0,
                                                               labels, values, G_N_ELEMENTS(labels),
                                                               sp_ddc_width_value_changed,  0.01, 0, 100 );
+        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 );
         }
@@ -3219,15 +4007,15 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
         {
         /* Thinning */
             gchar const* labels[] = {_("(speed blows up stroke)"), 0, 0, _("(slight widening)"), _("(constant width)"), _("(slight thinning, default)"), 0, 0, _("(speed deflates stroke)")};
-            gdouble values[] = {-1, -0.4, -0.2, -0.1, 0, 0.1, 0.2, 0.4, 1};
+            gdouble values[] = {-100, -40, -20, -10, 0, 10, 20, 40, 100};
         EgeAdjustmentAction* eact = create_adjustment_action( "ThinningAction",
                                                               _("Stroke Thinning"), _("Thinning:"),
                                                               _("How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 makes them broader, 0 makes width independent of velocity)"),
-                                                              "tools.calligraphic", "thinning", 0.1,
+                                                              "tools.calligraphic", "thinning", 10,
                                                               GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
-                                                              -1.0, 1.0, 0.01, 0.1,
+                                                              -100, 100, 1, 0.1,
                                                               labels, values, G_N_ELEMENTS(labels),
-                                                              sp_ddc_velthin_value_changed, 0.01, 2);
+                                                              sp_ddc_velthin_value_changed, 0.01, 0, 100);
         gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
         gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
         }
@@ -3246,21 +4034,22 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
                                                               sp_ddc_angle_value_changed, 1, 0 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
         gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
+        g_object_set_data( holder, "angle", eact );
         calligraphy_angle = eact;
         }
 
         {
         /* Fixation */
             gchar const* labels[] = {_("(perpendicular to stroke, \"brush\")"), 0, 0, 0, _("(almost fixed, default)"), _("(fixed by Angle, \"pen\")")};
-        gdouble values[] = {0, 0.2, 0.4, 0.6, 0.9, 1.0};
+        gdouble values[] = {0, 20, 40, 60, 90, 100};
         EgeAdjustmentAction* eact = create_adjustment_action( "FixationAction",
                                                               _("Fixation"), _("Fixation:"),
                                                               _("Angle behavior (0 = nib always perpendicular to stroke direction, 1 = fixed angle)"),
-                                                              "tools.calligraphic", "flatness", 0.9,
+                                                              "tools.calligraphic", "flatness", 90,
                                                               GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
-                                                              0.0, 1.0, 0.01, 0.1,
+                                                              0.0, 100, 1.0, 10.0,
                                                               labels, values, G_N_ELEMENTS(labels),
-                                                              sp_ddc_flatness_value_changed, 0.01, 2 );
+                                                              sp_ddc_flatness_value_changed, 0.01, 0, 100 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
         gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
         }
@@ -3285,16 +4074,17 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
         {
         /* Tremor */
             gchar const* labels[] = {_("(smooth line)"), _("(slight tremor)"), _("(noticeable tremor)"), 0, 0, _("(maximum tremor)")};
-        gdouble values[] = {0, 0.1, 0.2, 0.4, 0.6, 1.0};
+        gdouble values[] = {0, 10, 20, 40, 60, 100};
         EgeAdjustmentAction* eact = create_adjustment_action( "TremorAction",
                                                               _("Stroke Tremor"), _("Tremor:"),
                                                               _("Increase to make strokes rugged and trembling"),
                                                               "tools.calligraphic", "tremor", 0.0,
                                                               GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
-                                                              0.0, 1.0, 0.01, 0.1,
+                                                              0.0, 100, 1, 0.0,
                                                               labels, values, G_N_ELEMENTS(labels),
-                                                              sp_ddc_tremor_value_changed, 0.01, 2 );
+                                                              sp_ddc_tremor_value_changed, 0.01, 0, 100 );
 
+        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 );
         }
@@ -3302,15 +4092,16 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
         {
         /* Wiggle */
         gchar const* labels[] = {_("(no wiggle)"), _("(slight deviation)"), 0, 0, _("(wild waves and curls)")};
-        gdouble values[] = {0, 0.2, 0.4, 0.6, 1.0};
+        gdouble values[] = {0, 20, 40, 60, 100};
         EgeAdjustmentAction* eact = create_adjustment_action( "WiggleAction",
                                                               _("Pen Wiggle"), _("Wiggle:"),
                                                               _("Increase to make the pen waver and wiggle"),
                                                               "tools.calligraphic", "wiggle", 0.0,
                                                               GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
-                                                              0.0, 1.0, 0.01, 0.1,
+                                                              0.0, 100, 1, 0.0,
                                                               labels, values, G_N_ELEMENTS(labels),
-                                                              sp_ddc_wiggle_value_changed, 0.01, 2 );
+                                                              sp_ddc_wiggle_value_changed, 0.01, 0, 100 );
+        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 );
         }
@@ -3318,15 +4109,16 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
         {
         /* Mass */
             gchar const* labels[] = {_("(no inertia)"), _("(slight smoothing, default)"), _("(noticeable lagging)"), 0, 0, _("(maximum inertia)")};
-        gdouble values[] = {0.0, 0.02, 0.1, 0.2, 0.5, 1.0};
+        gdouble values[] = {0.0, 2, 10, 20, 50, 100};
         EgeAdjustmentAction* eact = create_adjustment_action( "MassAction",
                                                               _("Pen Mass"), _("Mass:"),
                                                               _("Increase to make the pen drag behind, as if slowed by inertia"),
-                                                              "tools.calligraphic", "mass", 0.02,
+                                                              "tools.calligraphic", "mass", 2.0,
                                                               GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL,
-                                                              0.0, 1.0, 0.01, 0.1,
+                                                              0.0, 100, 1, 0.0,
                                                               labels, values, G_N_ELEMENTS(labels),
-                                                              sp_ddc_mass_value_changed, 0.01, 2 );
+                                                              sp_ddc_mass_value_changed, 0.01, 0, 100 );
+        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 );
         }
@@ -3340,8 +4132,9 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
                                                           "trace_background",
                                                           Inkscape::ICON_SIZE_DECORATION );
             gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
-            g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_trace_background_changed), NULL);
+            g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_trace_background_changed), holder);
             gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.calligraphic", "tracebackground", 0 ) );
+            g_object_set_data( holder, "tracebackground", act );
         }
 
         /* Use Pressure button */
@@ -3352,8 +4145,9 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
                                                           "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_ddc_pressure_state_changed), NULL);
+            g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_pressure_state_changed), holder);
             gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.calligraphic", "usepressure", 1 ) );
+            g_object_set_data( holder, "usepressure", act );
         }
 
         /* Use Tilt button */
@@ -3364,20 +4158,55 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
                                                           "use_tilt",
                                                           Inkscape::ICON_SIZE_DECORATION );
             gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
-            g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_tilt_state_changed), calligraphy_angle );
+            g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_tilt_state_changed), holder );
             gtk_action_set_sensitive( GTK_ACTION(calligraphy_angle), !prefs_get_int_attribute( "tools.calligraphic", "usetilt", 1 ) );
             gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.calligraphic", "usetilt", 1 ) );
+            g_object_set_data( holder, "usetilt", act );
         }
 
-        /* Reset */
+        /*calligraphic profile */
+        {
+            GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT );
+            gchar *pref_path;
+
+
+            GtkTreeIter iter;
+            gtk_list_store_append( model, &iter );
+            gtk_list_store_set( model, &iter, 0, _("No preset"), 1, 0, -1 );
+
+            //TODO: switch back to prefs API
+            Inkscape::XML::Node *repr = inkscape_get_repr(INKSCAPE, "tools.calligraphic.preset" );
+            Inkscape::XML::Node *child_repr = sp_repr_children(repr);
+            int ii=1;
+            while (child_repr) {
+                GtkTreeIter iter;
+                char *preset_name = (char *) child_repr->attribute("name");
+                gtk_list_store_append( model, &iter );
+                gtk_list_store_set( model, &iter, 0, preset_name, 1, ++ii, -1 );
+                child_repr = sp_repr_next(child_repr);
+            }
+
+            pref_path = NULL;
+            EgeSelectOneAction* act1 = ege_select_one_action_new( "SetProfileAction", "" , (_("Change calligraphic profile")), NULL, GTK_TREE_MODEL(model) );
+            ege_select_one_action_set_appearance( act1, "compact" );
+            g_signal_connect( G_OBJECT(act1), "changed", G_CALLBACK(sp_ddc_change_profile), holder );
+            gtk_action_group_add_action( mainActions, GTK_ACTION(act1) );
+            g_object_set_data( holder, "profile_selector", act1 );
+
+        }
+
+        /*Save or delete calligraphic profile */
         {
-            GtkAction* act = gtk_action_new( "CalligraphyResetAction",
+            GtkAction* act = gtk_action_new( "SaveDeleteProfileAction",
                                              _("Defaults"),
-                                             _("Reset all parameters to defaults"),
-                                             GTK_STOCK_CLEAR );
-            g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_ddc_defaults), holder );
+                                             _("Save current settings as new profile"),
+                                             GTK_STOCK_SAVE );
+            g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_dcc_save_profile), holder );
+
+
             gtk_action_group_add_action( mainActions, act );
             gtk_action_set_sensitive( act, TRUE );
+            g_object_set_data( holder, "profile_save_delete", act );
         }
     }
 }
@@ -3472,6 +4301,29 @@ static void sp_arctb_end_value_changed(GtkAdjustment *adj, GObject *tbl)
     sp_arctb_startend_value_changed(adj,  tbl, "end", "start");
 }
 
+
+static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl )
+{
+    SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
+    gint eraserMode = (ege_select_one_action_get_active( act ) != 0) ? 1 : 0;
+    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
+        prefs_set_int_attribute( "tools.eraser", "mode", eraserMode );
+    }
+
+    // only take action if run by the attr_changed listener
+    if (!g_object_get_data( tbl, "freeze" )) {
+        // in turn, prevent listener from responding
+        g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
+
+        if ( eraserMode != 0 ) {
+        } else {
+        }
+        // TODO finish implementation
+
+        g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
+    }
+}
+
 static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl )
 {
     SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
@@ -3501,7 +4353,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl )
             if (SP_IS_ARC((SPItem *) items->data)) {
                 Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data);
                 repr->setAttribute("sodipodi:open", "true");
-                SP_OBJECT((SPItem *) items->data)->updateRepr(repr, SP_OBJECT_WRITE_EXT);
+                SP_OBJECT((SPItem *) items->data)->updateRepr();
                 modmade = true;
             }
         }
@@ -3513,7 +4365,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl )
             if (SP_IS_ARC((SPItem *) items->data))    {
                 Inkscape::XML::Node *repr = SP_OBJECT_REPR((SPItem *) items->data);
                 repr->setAttribute("sodipodi:open", NULL);
-                SP_OBJECT((SPItem *) items->data)->updateRepr(repr, SP_OBJECT_WRITE_EXT);
+                SP_OBJECT((SPItem *) items->data)->updateRepr();
                 modmade = true;
             }
         }
@@ -3632,6 +4484,7 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb
 static void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 {
     EgeAdjustmentAction* eact = 0;
+    Inkscape::IconSize secondarySize = prefToSize("toolbox", "secondary", 1);
 
 
     {
@@ -3694,6 +4547,7 @@ static void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions,
         ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE );
         g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL );
         ege_select_one_action_set_icon_column( act, 2 );
+        ege_select_one_action_set_icon_size( act, secondarySize );
         ege_select_one_action_set_tooltip_column( act, 1  );
 
         gchar const *openstr = prefs_get_string_attribute("tools.shapes.arc", "open");
@@ -3708,7 +4562,7 @@ static void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions,
                                           _("Make whole"),
                                           _("Make the shape a whole ellipse, not arc or segment"),
                                           "reset_circle",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_arctb_defaults), holder );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
         gtk_action_set_sensitive( GTK_ACTION(inky), TRUE );
@@ -3771,12 +4625,19 @@ static void sp_dropper_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* main
 {
     gint pickAlpha = prefs_get_int_attribute( "tools.dropper", "pick", 1 );
 
+    {
+        EgeOutputAction* act = ege_output_action_new( "DropperOpacityAction", _("Opacity:"), "", 0 );
+        ege_output_action_set_use_markup( act, TRUE );
+        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+    }
+
     {
         InkToggleAction* act = ink_toggle_action_new( "DropperPickAlphaAction",
-                                                      _("Pick alpha"),
+                                                      _("Pick opacity"),
                                                       _("Pick both the color and the alpha (transparency) under cursor; otherwise, pick only the visible color premultiplied by alpha"),
-                                                      "color_alpha_get",
+                                                      NULL,
                                                       Inkscape::ICON_SIZE_DECORATION );
+        g_object_set( act, "short_label", _("Pick"), NULL );
         gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
         g_object_set_data( holder, "pick_action", act );
         gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), pickAlpha );
@@ -3785,10 +4646,11 @@ static void sp_dropper_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* main
 
     {
         InkToggleAction* act = ink_toggle_action_new( "DropperSetAlphaAction",
-                                                      _("Set alpha"),
+                                                      _("Assign opacity"),
                                                       _("If alpha was picked, assign it to selection as fill or stroke transparency"),
-                                                      "color_alpha_set",
+                                                      NULL,
                                                       Inkscape::ICON_SIZE_DECORATION );
+        g_object_set( act, "short_label", _("Assign"), NULL );
         gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
         g_object_set_data( holder, "set_action", act );
         gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.dropper", "setalpha", 1 ) );
@@ -3799,6 +4661,61 @@ static void sp_dropper_toolbox_prep(SPDesktop */*desktop*/, GtkActionGroup* main
 }
 
 
+
+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, 0.0,
+                                                              labels, values, G_N_ELEMENTS(labels),
+                                                              sp_ddc_width_value_changed,  0.01, 0, 100 );
+        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;
+        gtk_list_store_append( model, &iter );
+        gtk_list_store_set( model, &iter,
+                            0, _("Delete"),
+                            1, _("Delete objects touched by the eraser"),
+                            2, "delete_object",
+                            -1 );
+
+        gtk_list_store_append( model, &iter );
+        gtk_list_store_set( model, &iter,
+                            0, _("Cut"),
+                            1, _("Cut out from objects"),
+                            2, "difference",
+                            -1 );
+
+        EgeSelectOneAction* act = ege_select_one_action_new( "EraserModeAction", (""), (""), NULL, GTK_TREE_MODEL(model) );
+        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 );
+        ege_select_one_action_set_icon_column( act, 2 );
+        ege_select_one_action_set_tooltip_column( act, 1  );
+
+        gint eraserMode = (prefs_get_int_attribute("tools.eraser", "mode", 0) != 0) ? 1 : 0;
+        ege_select_one_action_set_active( act, eraserMode );
+        g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_erasertb_mode_changed), holder );
+    }
+
+}
+
 //########################
 //##    Text Toolbox    ##
 //########################
@@ -3835,7 +4752,8 @@ sp_text_letter_rotation_changed(GtkAdjustment *adj, GtkWidget *tbl)
 
 namespace {
 
-bool visible = false;
+bool popdown_visible = false;
+bool popdown_hasfocus = false;
 
 void
 sp_text_toolbox_selection_changed (Inkscape::Selection */*selection*/, GObject *tbl)
@@ -3843,6 +4761,8 @@ sp_text_toolbox_selection_changed (Inkscape::Selection */*selection*/, GObject *
     SPStyle *query =
         sp_style_new (SP_ACTIVE_DOCUMENT);
 
+//    int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
+
     int result_family =
         sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
 
@@ -3875,15 +4795,27 @@ sp_text_toolbox_selection_changed (Inkscape::Selection */*selection*/, GObject *
             GtkWidget *entry = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "family-entry"));
             gtk_entry_set_text (GTK_ENTRY (entry), "");
 
-        } else if (query->text->font_family.value) {
+        } else if (query->text->font_specification.value || query->text->font_family.value) {
 
             GtkWidget *entry = GTK_WIDGET (g_object_get_data (G_OBJECT (tbl), "family-entry"));
-            gtk_entry_set_text (GTK_ENTRY (entry), query->text->font_family.value);
+
+            // Get the font that corresponds
+            Glib::ustring familyName;
+
+            font_instance * font = font_factory::Default()->FaceFromStyle(query);
+            if (font) {
+                familyName = font_factory::Default()->GetUIFamilyString(font->descr);
+                font->Unref();
+                font = NULL;
+            }
+
+            gtk_entry_set_text (GTK_ENTRY (entry), familyName.c_str());
 
             Gtk::TreePath path;
             try {
-                path = Inkscape::FontLister::get_instance()->get_row_for_font (query->text->font_family.value);
+                path = Inkscape::FontLister::get_instance()->get_row_for_font (familyName);
             } catch (...) {
+                g_warning("Family name %s does not have an entry in the font lister.", familyName.c_str());
                 return;
             }
 
@@ -4009,13 +4941,10 @@ sp_text_toolbox_family_changed (GtkTreeSelection    *selection,
 {
     SPDesktop    *desktop = SP_ACTIVE_DESKTOP;
     GtkTreeModel *model = 0;
-    GtkWidget    *popdown = GTK_WIDGET (g_object_get_data (tbl, "family-popdown-window"));
     GtkWidget    *entry = GTK_WIDGET (g_object_get_data (tbl, "family-entry"));
     GtkTreeIter   iter;
     char         *family = 0;
 
-    (void)popdown;
-
     gdk_pointer_ungrab (GDK_CURRENT_TIME);
     gdk_keyboard_ungrab (GDK_CURRENT_TIME);
 
@@ -4036,14 +4965,58 @@ sp_text_toolbox_family_changed (GtkTreeSelection    *selection,
     SPStyle *query =
         sp_style_new (SP_ACTIVE_DOCUMENT);
 
-    int result_numbers =
-        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+    int result_fontspec =
+        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
+
+    //font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query);
 
     SPCSSAttr *css = sp_repr_css_attr_new ();
-    sp_repr_css_set_property (css, "font-family", family);
 
-    // If querying returned nothing, read the style from the text tool prefs (default style for new texts)
-    if (result_numbers == QUERY_STYLE_NOTHING)
+
+    // First try to get the font spec from the stored value
+    Glib::ustring fontSpec = query->text->font_specification.set ?  query->text->font_specification.value : "";
+
+    if (fontSpec.empty()) {
+        // Construct a new font specification if it does not yet exist
+        font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query);
+        fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle);
+        fontFromStyle->Unref();
+    }
+
+    if (!fontSpec.empty()) {
+        Glib::ustring newFontSpec = font_factory::Default()->ReplaceFontSpecificationFamily(fontSpec, family);
+        if (!newFontSpec.empty() && fontSpec != newFontSpec) {
+            font_instance *font = font_factory::Default()->FaceFromFontSpecification(newFontSpec.c_str());
+            if (font) {
+                sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str());
+
+                // Set all the these just in case they were altered when finding the best
+                // match for the new family and old style...
+
+                gchar c[256];
+
+                font->Family(c, 256);
+                sp_repr_css_set_property (css, "font-family", c);
+
+                font->Attribute( "weight", c, 256);
+                sp_repr_css_set_property (css, "font-weight", c);
+
+                font->Attribute("style", c, 256);
+                sp_repr_css_set_property (css, "font-style", c);
+
+                font->Attribute("stretch", c, 256);
+                sp_repr_css_set_property (css, "font-stretch", c);
+
+                font->Attribute("variant", c, 256);
+                sp_repr_css_set_property (css, "font-variant", c);
+
+                font->Unref();
+            }
+        }
+    }
+
+    // If querying returned nothing, set the default style of the tool (for new texts)
+    if (result_fontspec == QUERY_STYLE_NOTHING)
     {
         sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style");
         sp_text_edit_dialog_default_set_insensitive (); //FIXME: Replace trough a verb
@@ -4158,29 +5131,59 @@ sp_text_toolbox_style_toggled (GtkToggleButton  *button,
     int          prop       = GPOINTER_TO_INT(data);
     bool         active     = gtk_toggle_button_get_active (button);
 
+    SPStyle *query =
+        sp_style_new (SP_ACTIVE_DOCUMENT);
+
+    int result_fontspec =
+        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION);
+
+    //int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
+    //int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE);
+    //int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+
+    Glib::ustring fontSpec = query->text->font_specification.set ?  query->text->font_specification.value : "";
+    Glib::ustring newFontSpec = "";
+
+    if (fontSpec.empty()) {
+        // Construct a new font specification if it does not yet exist
+        font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query);
+        fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle);
+        fontFromStyle->Unref();
+    }
 
     switch (prop)
     {
         case 0:
         {
-            sp_repr_css_set_property (css, "font-weight", active ? "bold" : "normal" );
+            if (!fontSpec.empty()) {
+                newFontSpec = font_factory::Default()->FontSpecificationSetBold(fontSpec, active);
+            }
+            if (fontSpec != newFontSpec) {
+                // Don't even set the bold if the font didn't exist on the system
+                sp_repr_css_set_property (css, "font-weight", active ? "bold" : "normal" );
+            }
             break;
         }
 
         case 1:
         {
-            sp_repr_css_set_property (css, "font-style", active ? "italic" : "normal");
+            if (!fontSpec.empty()) {
+                newFontSpec = font_factory::Default()->FontSpecificationSetItalic(fontSpec, active);
+            }
+            if (fontSpec != newFontSpec) {
+                // Don't even set the italic if the font didn't exist on the system
+                sp_repr_css_set_property (css, "font-style", active ? "italic" : "normal");
+            }
             break;
         }
     }
 
-    SPStyle *query =
-        sp_style_new (SP_ACTIVE_DOCUMENT);
-    int result_numbers =
-        sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
+    if (!newFontSpec.empty()) {
+        sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str());
+    }
 
     // If querying returned nothing, read the style from the text tool prefs (default style for new texts)
-    if (result_numbers == QUERY_STYLE_NOTHING)
+    if (result_fontspec == QUERY_STYLE_NOTHING)
     {
         sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.text"), css, "style");
     }
@@ -4242,26 +5245,6 @@ sp_text_toolbox_orientation_toggled (GtkRadioButton  *button,
     gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
 }
 
-gboolean
-sp_text_toolbox_size_keypress (GtkWidget */*w*/, GdkEventKey *event, gpointer /*data*/)
-{
-    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
-    if (!desktop) return FALSE;
-
-    switch (get_group0_keyval (event)) {
-        case GDK_Escape: // defocus
-            gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
-            return TRUE; // I consumed the event
-            break;
-        case GDK_Return: // defocus
-        case GDK_KP_Enter:
-            gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
-            return TRUE; // I consumed the event
-            break;
-    }
-    return FALSE;
-}
-
 gboolean
 sp_text_toolbox_family_keypress (GtkWidget */*w*/, GdkEventKey *event, GObject *tbl)
 {
@@ -4289,10 +5272,19 @@ sp_text_toolbox_family_list_keypress (GtkWidget *w, GdkEventKey *event, GObject
         case GDK_Return:
         case GDK_Escape: // defocus
             gtk_widget_hide (w);
-            visible = false;
+            popdown_visible = false;
             gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
             return TRUE; // I consumed the event
             break;
+        case GDK_w:
+        case GDK_W:
+            if (event->state & GDK_CONTROL_MASK) {
+                gtk_widget_hide (w);
+                popdown_visible = false;
+                gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+                return TRUE; // I consumed the event
+            }
+            break;
     }
     return FALSE;
 }
@@ -4306,20 +5298,30 @@ sp_text_toolbox_size_changed  (GtkComboBox *cbox,
 
     if (g_object_get_data (tbl, "size-block")) return;
 
-#if GTK_CHECK_VERSION(2,6,0)
-    char *text = gtk_combo_box_get_active_text (cbox);
-#else // GTK_CHECK_VERSION(2,6,0)
-    GtkTreeModel *model = gtk_combo_box_get_model (cbox);
-    GtkTreeIter iter;
-    char *text = NULL;
+    // If this is not from selecting a size in the list (in which case get_active will give the
+    // index of the selected item, otherwise -1) and not from user pressing Enter/Return, do not
+    // process this event. This fixes GTK's stupid insistence on sending an activate change every
+    // time any character gets typed or deleted, which made this control nearly unusable in 0.45.
+    if (gtk_combo_box_get_active (cbox) < 0 && !g_object_get_data (tbl, "enter-pressed"))
+        return;
 
-    if (gtk_combo_box_get_active_iter (cbox, &iter) && model)
-        gtk_tree_model_get (model, &iter, 0, &text, -1);
-#endif // GTK_CHECK_VERSION(2,6,0)
+    gchar *endptr;
+    gdouble value = -1;
+    char *text = gtk_combo_box_get_active_text (cbox);
+    if (text) {
+        value = g_strtod (text, &endptr);
+        if (endptr == text) // conversion failed, non-numeric input
+            value = -1;
+        free (text);
+    }
+    if (value <= 0) {
+        return; // could not parse value
+    }
 
     SPCSSAttr *css = sp_repr_css_attr_new ();
-    sp_repr_css_set_property (css, "font-size", text);
-    free (text);
+    Inkscape::CSSOStringStream osfs;
+    osfs << value;
+    sp_repr_css_set_property (css, "font-size", osfs.str().c_str());
 
     SPStyle *query =
         sp_style_new (SP_ACTIVE_DOCUMENT);
@@ -4339,9 +5341,49 @@ sp_text_toolbox_size_changed  (GtkComboBox *cbox,
                                    _("Text: Change font size"));
     sp_repr_css_attr_unref (css);
 
+    gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+}
 
-    if (gtk_combo_box_get_active (cbox) > 0) // if this was from drop-down (as opposed to type-in), defocus
-        gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+gboolean
+sp_text_toolbox_size_focusout (GtkWidget */*w*/, GdkEventFocus */*event*/, GObject *tbl)
+{
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+    if (!desktop) return FALSE;
+
+    if (!g_object_get_data (tbl, "esc-pressed")) {
+        g_object_set_data (tbl, "enter-pressed", gpointer(1));
+        GtkComboBox *cbox = GTK_COMBO_BOX(g_object_get_data (G_OBJECT (tbl), "combo-box-size"));
+        sp_text_toolbox_size_changed (cbox, tbl);
+        g_object_set_data (tbl, "enter-pressed", gpointer(0));
+    }
+    return FALSE; // I consumed the event
+}
+
+
+gboolean
+sp_text_toolbox_size_keypress (GtkWidget */*w*/, GdkEventKey *event, GObject *tbl)
+{
+    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+    if (!desktop) return FALSE;
+
+    switch (get_group0_keyval (event)) {
+        case GDK_Escape: // defocus
+            g_object_set_data (tbl, "esc-pressed", gpointer(1));
+            gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+            g_object_set_data (tbl, "esc-pressed", gpointer(0));
+            return TRUE; // I consumed the event
+            break;
+        case GDK_Return: // defocus
+        case GDK_KP_Enter:
+            g_object_set_data (tbl, "enter-pressed", gpointer(1));
+            GtkComboBox *cbox = GTK_COMBO_BOX(g_object_get_data (G_OBJECT (tbl), "combo-box-size"));
+            sp_text_toolbox_size_changed (cbox, tbl);
+            gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+            g_object_set_data (tbl, "enter-pressed", gpointer(0));
+            return TRUE; // I consumed the event
+            break;
+    }
+    return FALSE;
 }
 
 void
@@ -4352,11 +5394,12 @@ sp_text_toolbox_text_popdown_clicked    (GtkButton          */*button*/,
     GtkWidget *widget = GTK_WIDGET (g_object_get_data (tbl, "family-entry"));
     int x, y;
 
-    if (!visible)
+    if (!popdown_visible)
     {
         gdk_window_get_origin (widget->window, &x, &y);
         gtk_window_move (GTK_WINDOW (popdown), x, y + widget->allocation.height + 2); //2px of grace space
         gtk_widget_show_all (popdown);
+        //sp_transientize (popdown);
 
         gdk_pointer_grab (widget->window, TRUE,
                           GdkEventMask (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK |
@@ -4366,14 +5409,16 @@ sp_text_toolbox_text_popdown_clicked    (GtkButton          */*button*/,
 
         gdk_keyboard_grab (widget->window, TRUE, GDK_CURRENT_TIME);
 
-        visible = true;
+        popdown_visible = true;
     }
     else
     {
+        SPDesktop *desktop = SP_ACTIVE_DESKTOP;
         gdk_pointer_ungrab (GDK_CURRENT_TIME);
         gdk_keyboard_ungrab (GDK_CURRENT_TIME);
+        gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
         gtk_widget_hide (popdown);
-        visible = false;
+        popdown_visible = false;
     }
 }
 
@@ -4393,12 +5438,26 @@ sp_text_toolbox_popdown_focus_out (GtkWidget        *popdown,
 {
     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
 
-    gtk_widget_hide (popdown);
-    visible = false;
-    gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+    if (popdown_hasfocus) {
+        gtk_widget_hide (popdown);
+        popdown_hasfocus = false;
+        popdown_visible = false;
+        gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas));
+        return TRUE;
+    }
+    return FALSE;
+}
+
+gboolean
+sp_text_toolbox_popdown_focus_in (GtkWidget        */*popdown*/,
+                                   GdkEventFocus    */*event*/,
+                                   GObject          */*tbl*/)
+{
+    popdown_hasfocus = true;
     return TRUE;
 }
 
+
 void
 cell_data_func  (GtkTreeViewColumn */*column*/,
                  GtkCellRenderer   *cell,
@@ -4437,7 +5496,8 @@ static void delete_completion(GObject */*obj*/, GtkWidget *entry) {
 GtkWidget*
 sp_text_toolbox_new (SPDesktop *desktop)
 {
-    GtkWidget   *tbl = gtk_hbox_new (FALSE, 0);
+    GtkToolbar   *tbl = GTK_TOOLBAR(gtk_toolbar_new());
+    GtkIconSize secondarySize = static_cast<GtkIconSize>(prefToSize("toolbox", "secondary", 1));
 
     gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas);
     gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop);
@@ -4460,14 +5520,13 @@ sp_text_toolbox_new (SPDesktop *desktop)
     g_object_set (G_OBJECT(completion), "inline-completion", TRUE, "popup-completion", TRUE, NULL);
     gtk_entry_set_completion (GTK_ENTRY(entry), completion);
     gtk_object_set_data(GTK_OBJECT(entry), "completion", completion);
-    aux_toolbox_space (tbl, 1);
-    gtk_box_pack_start (GTK_BOX (tbl), entry, FALSE, FALSE, 0);
+    gtk_toolbar_append_widget( tbl, entry, "", "" );
     g_signal_connect(G_OBJECT(tbl), "destroy", G_CALLBACK(delete_completion), entry);
 
     //Button
     GtkWidget   *button = gtk_button_new ();
     gtk_container_add       (GTK_CONTAINER (button), gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_NONE));
-    gtk_box_pack_start      (GTK_BOX (tbl), button, FALSE, FALSE, 0);
+    gtk_toolbar_append_widget( tbl, button, "", "");
 
     //Popdown
     GtkWidget           *sw = gtk_scrolled_window_new (NULL, NULL);
@@ -4482,9 +5541,7 @@ sp_text_toolbox_new (SPDesktop *desktop)
 
     gtk_tree_view_set_model (GTK_TREE_VIEW (treeview), GTK_TREE_MODEL (Glib::unwrap(store)));
     gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
-#if GTK_CHECK_VERSION(2,6,0)
     gtk_tree_view_set_fixed_height_mode (GTK_TREE_VIEW (treeview), TRUE);
-#endif // GTK_CHECK_VERSION(2,6,0)
 
     //gtk_tree_view_set_enable_search (GTK_TREE_VIEW (treeview), TRUE);
 
@@ -4501,6 +5558,7 @@ sp_text_toolbox_new (SPDesktop *desktop)
     g_signal_connect (G_OBJECT (button), "clicked", G_CALLBACK (sp_text_toolbox_text_popdown_clicked), tbl);
 
     g_signal_connect (G_OBJECT (window), "focus-out-event", G_CALLBACK (sp_text_toolbox_popdown_focus_out), tbl);
+    g_signal_connect (G_OBJECT (window), "focus-in-event", G_CALLBACK (sp_text_toolbox_popdown_focus_in), tbl);
     g_signal_connect (G_OBJECT (window), "key-press-event", G_CALLBACK(sp_text_toolbox_family_list_keypress), tbl);
 
     GtkTreeSelection *tselection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
@@ -4512,11 +5570,10 @@ sp_text_toolbox_new (SPDesktop *desktop)
     g_object_set_data (G_OBJECT (tbl), "family-tree-selection", tselection);
     g_object_set_data (G_OBJECT (tbl), "family-tree-view", treeview);
 
-    GtkWidget *image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_SMALL_TOOLBAR);
-    aux_toolbox_space (tbl, 1);
+    GtkWidget *image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, secondarySize);
     GtkWidget *box = gtk_event_box_new ();
     gtk_container_add (GTK_CONTAINER (box), image);
-    gtk_box_pack_start (GTK_BOX (tbl), box, FALSE, FALSE, 4);
+    gtk_toolbar_append_widget( tbl, box, "", "");
     g_object_set_data (G_OBJECT (tbl), "warning-image", box);
     GtkTooltips *tooltips = gtk_tooltips_new ();
     gtk_tooltips_set_tip (tooltips, box, _("This font is currently not installed on your system. Inkscape will use the default font instead."), "");
@@ -4533,15 +5590,11 @@ sp_text_toolbox_new (SPDesktop *desktop)
     GtkWidget *cbox = gtk_combo_box_entry_new_text ();
     for (unsigned int n = 0; n < G_N_ELEMENTS (sizes); gtk_combo_box_append_text (GTK_COMBO_BOX(cbox), sizes[n++]));
     gtk_widget_set_size_request (cbox, 80, -1);
-    aux_toolbox_space (tbl, 1);
-    gtk_box_pack_start (GTK_BOX (tbl), cbox, FALSE, FALSE, 0);
+    gtk_toolbar_append_widget( tbl, cbox, "", "");
     g_object_set_data (G_OBJECT (tbl), "combo-box-size", cbox);
     g_signal_connect (G_OBJECT (cbox), "changed", G_CALLBACK (sp_text_toolbox_size_changed), tbl);
-    gtk_signal_connect(GTK_OBJECT(cbox), "key-press-event", GTK_SIGNAL_FUNC(sp_text_toolbox_size_keypress), NULL);
-
-    //spacer
-    aux_toolbox_space (tbl, 4);
-    gtk_box_pack_start (GTK_BOX (tbl), gtk_vseparator_new (), FALSE, FALSE, 4);
+    gtk_signal_connect(GTK_OBJECT(gtk_bin_get_child(GTK_BIN(cbox))), "key-press-event", GTK_SIGNAL_FUNC(sp_text_toolbox_size_keypress), tbl);
+    gtk_signal_connect(GTK_OBJECT(gtk_bin_get_child(GTK_BIN(cbox))), "focus-out-event", GTK_SIGNAL_FUNC(sp_text_toolbox_size_focusout), tbl);
 
     ////////////Text anchor
     GtkWidget *group   = gtk_radio_button_new (NULL);
@@ -4551,7 +5604,7 @@ sp_text_toolbox_new (SPDesktop *desktop)
     // left
     GtkWidget *rbutton = group;
     gtk_button_set_relief       (GTK_BUTTON (rbutton), GTK_RELIEF_NONE);
-    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_JUSTIFY_LEFT, GTK_ICON_SIZE_SMALL_TOOLBAR));
+    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_JUSTIFY_LEFT, secondarySize));
     gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (rbutton), FALSE);
 
     gtk_box_pack_start  (GTK_BOX  (row), rbutton, FALSE, FALSE, 0);
@@ -4562,7 +5615,7 @@ sp_text_toolbox_new (SPDesktop *desktop)
     // center
     rbutton = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group)));
     gtk_button_set_relief       (GTK_BUTTON (rbutton), GTK_RELIEF_NONE);
-    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_JUSTIFY_CENTER, GTK_ICON_SIZE_SMALL_TOOLBAR));
+    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_JUSTIFY_CENTER, secondarySize));
     gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (rbutton), FALSE);
 
     gtk_box_pack_start  (GTK_BOX  (row), rbutton, FALSE, FALSE, 0);
@@ -4573,7 +5626,7 @@ sp_text_toolbox_new (SPDesktop *desktop)
     // right
     rbutton = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group)));
     gtk_button_set_relief       (GTK_BUTTON (rbutton), GTK_RELIEF_NONE);
-    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_JUSTIFY_RIGHT, GTK_ICON_SIZE_SMALL_TOOLBAR));
+    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_JUSTIFY_RIGHT, secondarySize));
     gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (rbutton), FALSE);
 
     gtk_box_pack_start  (GTK_BOX  (row), rbutton, FALSE, FALSE, 0);
@@ -4584,7 +5637,7 @@ sp_text_toolbox_new (SPDesktop *desktop)
     // fill
     rbutton = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group)));
     gtk_button_set_relief       (GTK_BUTTON (rbutton), GTK_RELIEF_NONE);
-    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_JUSTIFY_FILL, GTK_ICON_SIZE_SMALL_TOOLBAR));
+    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_JUSTIFY_FILL, secondarySize));
     gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (rbutton), FALSE);
 
     gtk_box_pack_start  (GTK_BOX  (row), rbutton, FALSE, FALSE, 0);
@@ -4592,11 +5645,10 @@ sp_text_toolbox_new (SPDesktop *desktop)
     g_signal_connect    (G_OBJECT (rbutton), "toggled", G_CALLBACK (sp_text_toolbox_anchoring_toggled), gpointer(3));
     gtk_tooltips_set_tip(tt, rbutton, _("Justify"), NULL);
 
-    aux_toolbox_space (tbl, 1);
-    gtk_box_pack_start (GTK_BOX (tbl), row, FALSE, FALSE, 4);
+    gtk_toolbar_append_widget( tbl, row, "", "");
 
     //spacer
-    gtk_box_pack_start (GTK_BOX (tbl), gtk_vseparator_new (), FALSE, FALSE, 4);
+    gtk_toolbar_append_widget( tbl, gtk_vseparator_new(), "", "" );
 
     ////////////Text style
     row = gtk_hbox_new (FALSE, 4);
@@ -4604,7 +5656,7 @@ sp_text_toolbox_new (SPDesktop *desktop)
     // bold
     rbutton = gtk_toggle_button_new ();
     gtk_button_set_relief       (GTK_BUTTON (rbutton), GTK_RELIEF_NONE);
-    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_BOLD, GTK_ICON_SIZE_SMALL_TOOLBAR));
+    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_BOLD, secondarySize));
     gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (rbutton), FALSE);
     gtk_tooltips_set_tip(tt, rbutton, _("Bold"), NULL);
 
@@ -4615,7 +5667,7 @@ sp_text_toolbox_new (SPDesktop *desktop)
     // italic
     rbutton = gtk_toggle_button_new ();
     gtk_button_set_relief       (GTK_BUTTON (rbutton), GTK_RELIEF_NONE);
-    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_ITALIC, GTK_ICON_SIZE_SMALL_TOOLBAR));
+    gtk_container_add           (GTK_CONTAINER (rbutton), gtk_image_new_from_stock (GTK_STOCK_ITALIC, secondarySize));
     gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (rbutton), FALSE);
     gtk_tooltips_set_tip(tt, rbutton, _("Italic"), NULL);
 
@@ -4623,11 +5675,10 @@ sp_text_toolbox_new (SPDesktop *desktop)
     g_object_set_data   (G_OBJECT (tbl), "style-italic", rbutton);
     g_signal_connect    (G_OBJECT (rbutton), "toggled", G_CALLBACK (sp_text_toolbox_style_toggled), gpointer (1));
 
-    aux_toolbox_space (tbl, 1);
-    gtk_box_pack_start (GTK_BOX (tbl), row, FALSE, FALSE, 4);
+    gtk_toolbar_append_widget( tbl, row, "", "");
 
     //spacer
-    gtk_box_pack_start (GTK_BOX (tbl), gtk_vseparator_new (), FALSE, FALSE, 4);
+    gtk_toolbar_append_widget( tbl, gtk_vseparator_new(), "", "" );
 
     ////////////Text orientation
     group   = gtk_radio_button_new (NULL);
@@ -4637,7 +5688,8 @@ sp_text_toolbox_new (SPDesktop *desktop)
     // horizontal
     rbutton = group;
     gtk_button_set_relief       (GTK_BUTTON (rbutton), GTK_RELIEF_NONE);
-    gtk_container_add           (GTK_CONTAINER (rbutton), sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_WRITING_MODE_LR));
+    gtk_container_add           (GTK_CONTAINER (rbutton),
+                                 sp_icon_new (static_cast<Inkscape::IconSize>(secondarySize), INKSCAPE_STOCK_WRITING_MODE_LR));
     gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (rbutton), FALSE);
     gtk_tooltips_set_tip(tt, rbutton, _("Horizontal text"), NULL);
 
@@ -4648,14 +5700,15 @@ sp_text_toolbox_new (SPDesktop *desktop)
     // vertical
     rbutton = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group)));
     gtk_button_set_relief       (GTK_BUTTON (rbutton), GTK_RELIEF_NONE);
-    gtk_container_add           (GTK_CONTAINER (rbutton), sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_WRITING_MODE_TB));
+    gtk_container_add           (GTK_CONTAINER (rbutton),
+                                 sp_icon_new (static_cast<Inkscape::IconSize>(secondarySize), INKSCAPE_STOCK_WRITING_MODE_TB));
     gtk_toggle_button_set_mode  (GTK_TOGGLE_BUTTON (rbutton), FALSE);
     gtk_tooltips_set_tip(tt, rbutton, _("Vertical text"), NULL);
 
     gtk_box_pack_start  (GTK_BOX  (row), rbutton, FALSE, FALSE, 0);
     g_object_set_data   (G_OBJECT (tbl), "orientation-vertical", rbutton);
     g_signal_connect    (G_OBJECT (rbutton), "toggled", G_CALLBACK (sp_text_toolbox_orientation_toggled), gpointer (1));
-    gtk_box_pack_start (GTK_BOX (tbl), row, FALSE, FALSE, 4);
+    gtk_toolbar_append_widget( tbl, row, "", "" );
 
 
     //watch selection
@@ -4679,171 +5732,9 @@ sp_text_toolbox_new (SPDesktop *desktop)
     Inkscape::ConnectionPool::connect_destroy (G_OBJECT (tbl), pool);
 
 
-#if 0
-    // horizontal
-    {
-        GtkWidget *px= sp_icon_new(Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_WRITING_MODE_LR);
-        GtkWidget *b = group = gtk_radio_button_new (NULL);
-        gtk_container_add (GTK_CONTAINER (b), px);
-        gtk_tooltips_set_tip (tt, b, _("Horizontal text"), NULL);
-        gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE);
-        gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE );
-        gtk_box_pack_start (GTK_BOX (tbl), b, FALSE, FALSE, 0);
-    }
-
-    // vertical
-    {
-        GtkWidget *px = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_WRITING_MODE_TB);
-        GtkWidget *b = gtk_radio_button_new (gtk_radio_button_group (GTK_RADIO_BUTTON (group)));
-        gtk_container_add (GTK_CONTAINER (b), px);
-        gtk_tooltips_set_tip (tt, b, _("Vertical text"), NULL);
-        gtk_button_set_relief (GTK_BUTTON (b), GTK_RELIEF_NONE);
-        gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON (b), FALSE );
-        gtk_box_pack_start (GTK_BOX (tbl), b, FALSE, FALSE, 0);
-    }
-
-    aux_toolbox_space(tbl, AUX_BETWEEN_BUTTON_GROUPS);
-
-    // letter spacing
-    {
-        {
-            GtkWidget *image = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_TEXT_LETTER_SPACING);
-            GtkWidget *hb = gtk_hbox_new(FALSE, 1);
-            gtk_container_add (GTK_CONTAINER (hb), image);
-            gtk_widget_show(image);
-            gtk_box_pack_start (GTK_BOX (tbl), hb, FALSE, FALSE, 0);
-        }
-
-        {
-            GtkWidget *hb = sp_tb_spinbutton((""), _("Spacing between letters"),
-                                             "tools.text", "letter_spacing", 0.0,
-                                             us, tbl, FALSE, NULL,
-                                             -1000.0, 1000.0, 0.1, 0.1,
-                                             sp_text_letter_changed, 0.1, 1);
-            gtk_widget_set_size_request (hb, 45, 6);
-            gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 6);
-        }
-    }
-
-    // line spacing
-    {
-        {
-            GtkWidget *image = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_TEXT_LINE_SPACING);
-            GtkWidget *hb = gtk_hbox_new(FALSE, 1);
-            gtk_container_add (GTK_CONTAINER (hb), image);
-            gtk_widget_show(image);
-            gtk_box_pack_start (GTK_BOX (tbl), hb, FALSE, FALSE, 0);
-        }
-
-        {
-            GtkWidget *hb = sp_tb_spinbutton((""), _("Spacing between lines"),
-                                             "tools.text", "line_spacing", 0,
-                                             us, tbl, FALSE, NULL,
-                                             -1000.0, 1000.0, 0.1, 0.1,
-                                             sp_text_line_changed, 0.1, 1);
-            gtk_widget_set_size_request (hb, 45, 0);
-            gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 3);
-        }
-    }
-
-    {
-        // horizontal kerning/vertical kerning units menu: create
-        GtkWidget *us = sp_unit_selector_new(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE);
-        sp_unit_selector_setsize(us, AUX_OPTION_MENU_WIDTH, AUX_OPTION_MENU_HEIGHT);
-        sp_unit_selector_set_unit(SP_UNIT_SELECTOR(us), desktop->namedview->doc_units);
-
-        aux_toolbox_space(tbl, AUX_BETWEEN_BUTTON_GROUPS);
-
-        // horizontal kerning
-        {
-            {
-                GtkWidget *image = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_TEXT_HORZ_KERN);
-                GtkWidget *hb = gtk_hbox_new(FALSE, 1);
-                gtk_container_add (GTK_CONTAINER (hb), image);
-                gtk_widget_show(image);
-                gtk_box_pack_start (GTK_BOX (tbl), hb, FALSE, FALSE, 0);
-            }
-
-            {
-                GtkWidget *hb = sp_tb_spinbutton((""), _("Horizontal kerning"),
-                                                 "tools.text", "horizontal_kerning", 0,
-                                                 us, tbl, FALSE, NULL,
-                                                 -100.00, 100.00, 0.01, 0.1,
-                                                 sp_text_horiz_kern_changed);
-                gtk_widget_set_size_request (hb, 45, 0);
-                gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 6);
-            }
-        }
-
-        // vertical kerning
-        {
-            {
-                GtkWidget *image = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_TEXT_VERT_KERN);
-                GtkWidget *hb = gtk_hbox_new(FALSE, 1);
-                gtk_container_add (GTK_CONTAINER (hb), image);
-                gtk_widget_show(image);
-                gtk_box_pack_start (GTK_BOX (tbl), hb, FALSE, FALSE, 0);
-            }
-
-            {
-                GtkWidget *hb = sp_tb_spinbutton((""), _("Vertical kerning"),
-                                                 "tools.text", "vertical_kerning", 0,
-                                                 us, tbl, FALSE, NULL,
-                                                 -100.00, 100.00, 0.01, 0.1,
-                                                 sp_text_vert_kern_changed);
-                gtk_widget_set_size_request (hb, 45, 0);
-                gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 5);
-            }
-        }
-
-        // add the units menu
-        gtk_widget_show(us);
-        gtk_box_pack_start(GTK_BOX(tbl), us, FALSE, FALSE, 1);
-        gtk_object_set_data(GTK_OBJECT(tbl), "units", us);
-    }
-
-    // letter rotation
-    aux_toolbox_space(tbl, AUX_BETWEEN_BUTTON_GROUPS);
-    {
-        {
-            GtkWidget *image = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_TEXT_ROTATION);
-            GtkWidget *hb = gtk_hbox_new(FALSE, 1);
-            gtk_container_add (GTK_CONTAINER (hb), image);
-            gtk_widget_show(image);
-            gtk_box_pack_start (GTK_BOX (tbl), hb, FALSE, FALSE, 0);
-        }
-        {
-            GtkWidget *hb = sp_tb_spinbutton((""), _("Letter rotation"),
-                                             "tools.text", "letter_rotation", 0,
-                                             us, tbl, FALSE, NULL,
-                                             -180.0, 180.0, 0.1, 0.1,
-                                             sp_text_letter_rotation_changed, 0.1, 1);
-            gtk_widget_set_size_request (hb, 45, 0);
-            gtk_box_pack_start(GTK_BOX(tbl), hb, FALSE, FALSE, 6);
-        }
-        // rotation degree label
-        {
-            GtkWidget *label = gtk_widget_new (GTK_TYPE_LABEL, "label", "\302\260", "xalign", 0.0, NULL);
-            gtk_box_pack_start(GTK_BOX(tbl), label, FALSE, FALSE, 0);
-        }
-    }
-
-    // Remove Manual Kerns
-    {
-        GtkWidget *px = sp_icon_new (Inkscape::ICON_SIZE_SMALL_TOOLBAR, INKSCAPE_STOCK_TEXT_REMOVE_KERNS);
-        GtkWidget *button = gtk_button_new ();
-        gtk_container_add (GTK_CONTAINER (button), px);
-        gtk_widget_show(button);
-        gtk_tooltips_set_tip (tt, button, _("Remove manual kerns"), NULL);
-        gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
-        gtk_widget_set_sensitive(button, TRUE);
-        gtk_box_pack_start (GTK_BOX (tbl), button, FALSE, FALSE, AUX_BETWEEN_BUTTON_GROUPS);
-    }
-#endif
-
-    gtk_widget_show_all (tbl);
-    return tbl;
+    gtk_widget_show_all( GTK_WIDGET(tbl) );
 
+    return GTK_WIDGET(tbl);
 } // end of sp_text_toolbox_new()
 
 }//<unnamed> namespace
@@ -4995,12 +5886,14 @@ static Inkscape::XML::NodeEventVector connector_tb_repr_events = {
 
 static void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder )
 {
+    Inkscape::IconSize secondarySize = prefToSize("toolbox", "secondary", 1);
+
     {
         InkAction* inky = ink_action_new( "ConnectorAvoidAction",
                                           _("Avoid"),
                                           _("Make connectors avoid selected objects"),
                                           "connector_avoid",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_path_set_avoid), holder );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
     }
@@ -5010,7 +5903,7 @@ static void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainA
                                           _("Ignore"),
                                           _("Make connectors ignore selected objects"),
                                           "connector_ignore",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_path_set_ignore), holder );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
     }
@@ -5034,7 +5927,7 @@ static void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainA
                                           _("Graph"),
                                           _("Nicely arrange selected connector network"),
                                           "graph_layout",
-                                          Inkscape::ICON_SIZE_SMALL_TOOLBAR );
+                                          secondarySize );
         g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_graph_layout), holder );
         gtk_action_group_add_action( mainActions, GTK_ACTION(inky) );
     }
@@ -5188,16 +6081,19 @@ static void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
             _("Fill Threshold"), _("Threshold:"),
             _("The maximum allowed difference between the clicked pixel and the neighboring pixels to be counted in the fill"),
             "tools.paintbucket", "threshold", 5, GTK_WIDGET(desktop->canvas), NULL, holder, TRUE,
-            "inkscape:paintbucket-threshold", 0, 100.0, 1.0, 10.0,
+            "inkscape:paintbucket-threshold", 0, 100.0, 1.0, 0.0,
             0, 0, 0,
             paintbucket_threshold_changed, 1, 0 );
 
+        ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
         gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
     }
 
     // Create the units menu.
     UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE );
-    tracker->setActiveUnit(sp_unit_get_by_abbreviation(prefs_get_string_attribute("tools.paintbucket", "offsetunits")));
+    const gchar *stored_unit = prefs_get_string_attribute("tools.paintbucket", "offsetunits");
+    if (stored_unit)
+        tracker->setActiveUnit(sp_unit_get_by_abbreviation(stored_unit));
     g_object_set_data( holder, "tracker", tracker );
     {
         GtkAction* act = tracker->createAction( "PaintbucketUnitsAction", _("Units"), ("") );
@@ -5267,3 +6163,6 @@ static void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
 */
 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
 
+
+
+