Code

rename, rearrange stroke shapes; add elliptic
[inkscape.git] / src / widgets / toolbox.cpp
index 8fa52c2815ab29a01a8f8e8db5101c99027a09a7..3eb3b9973fcde9058445a979565a625ba007f8a8 100644 (file)
@@ -51,6 +51,7 @@
 #include "desktop-handles.h"
 #include "xml/repr.h"
 #include "xml/node-event-vector.h"
+#include "xml/attribute-record.h"
 #include <glibmm/i18n.h>
 #include "helper/unit-menu.h"
 #include "helper/units.h"
@@ -79,6 +80,7 @@
 #include "sp-clippath.h"
 #include "sp-mask.h"
 #include "style.h"
+#include "tools-switch.h"
 #include "selection.h"
 #include "selection-chemistry.h"
 #include "document-private.h"
@@ -365,14 +367,12 @@ 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' />"
@@ -385,7 +385,6 @@ static gchar const * ui_descr =
         "  <toolbar name='CalligraphyToolbar'>"
         "    <separator />"
         "    <toolitem action='SetProfileAction'/>"
-        "    <toolitem action='SaveDeleteProfileAction'/>"
         "    <separator />"
         "    <toolitem action='CalligraphyWidthAction' />"
         "    <toolitem action='PressureAction' />"
@@ -512,7 +511,7 @@ Glib::RefPtr<VerbAction> VerbAction::create(Inkscape::Verb* verb, Inkscape::Verb
 }
 
 VerbAction::VerbAction(Inkscape::Verb* verb, Inkscape::Verb* verb2, Inkscape::UI::View::View *view, GtkTooltips *tooltips) :
-    Gtk::Action(Glib::ustring(verb->get_id()), Gtk::StockID(GTK_STOCK_ABOUT), Glib::ustring(_(verb->get_name())), Glib::ustring(_(verb->get_tip()))),
+    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),
@@ -527,6 +526,11 @@ 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;
@@ -1597,7 +1601,7 @@ setup_tool_toolbox(GtkWidget *toolbox, SPDesktop *desktop)
 
 
 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))
@@ -3264,31 +3268,27 @@ static void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio
 //##     Pen/Pencil    ##
 //########################
 
-static void sp_pc_spiro_spline_mode_changed(EgeSelectOneAction* act, GObject* /*tbl*/)
+static char const *
+freehand_tool_name(GObject *dataKludge)
 {
-    prefs_set_int_attribute("tools.freehand", "spiro-spline-mode", ege_select_one_action_get_active(act));
+    SPDesktop *desktop = (SPDesktop *) g_object_get_data(dataKludge, "desktop");
+    return ( tools_isactive(desktop, TOOLS_FREEHAND_PEN)
+             ? "tools.freehand.pen"
+             : "tools.freehand.pencil" );
 }
 
-static void sp_add_spiro_toggle(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil)
+static void sp_pc_spiro_spline_mode_changed(EgeSelectOneAction* act, GObject* tbl)
 {
-    // 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 );
-    }
+    prefs_set_int_attribute(freehand_tool_name(tbl), "spiro-spline-mode", ege_select_one_action_get_active(act));
+}
 
+static void sp_add_spiro_toggle(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil)
+{
     /* 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);
+        // FIXME: spiroMode seems not to be read correctly here during startup, although the
+        //        correct mode is used in pen/pencil tool later on; same for freehand shapes
+        guint spiroMode = prefs_get_int_attribute(freehand_tool_name(holder), "spiro-spline-mode", 0);
         Inkscape::IconSize secondarySize = prefToSize("toolbox", "secondary", 1);
 
         {
@@ -3297,24 +3297,23 @@ static void sp_add_spiro_toggle(GtkActionGroup* mainActions, GObject* holder, bo
             GtkTreeIter iter;
             gtk_list_store_append( model, &iter );
             gtk_list_store_set( model, &iter,
-                                0, _("Bézier"),
-                                1, _("Regular Bézier mode"),
+                                0, _("Bezier"),
+                                1, _("Create regular Bezier path"),
                                 2, "bezier_mode",
                                 -1 );
 
             gtk_list_store_append( model, &iter );
             gtk_list_store_set( model, &iter,
                                 0, _("Spiro"),
-                                1, _("Spiro splines mode"),
+                                1, _("Create Spiro path"),
                                 2, "spiro_splines_mode",
                                 -1 );
 
             EgeSelectOneAction* act = ege_select_one_action_new(tool_is_pencil ?
                                                                 "FreehandModeActionPencil" :
                                                                 "FreehandModeActionPen",
-                                                                (""), (""), NULL, GTK_TREE_MODEL(model) );
+                                                                ("Mode:"), ("Mode"), 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 );
@@ -3331,7 +3330,7 @@ static void sp_add_spiro_toggle(GtkActionGroup* mainActions, GObject* holder, bo
 
 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);
+    prefs_set_int_attribute(freehand_tool_name(dataKludge), "shape", shape);
 }
 
 /**
@@ -3341,8 +3340,10 @@ 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, _("Decrescendo"));
+    glist = g_list_append (glist, _("Triangle in"));
+    glist = g_list_append (glist, _("Triangle out"));
+    glist = g_list_append (glist, _("Ellipse"));
+    glist = g_list_append (glist, _("From clipboard"));
 
     return glist;
 }
@@ -3366,10 +3367,10 @@ sp_freehand_add_advanced_shape_options(GtkActionGroup* mainActions, GObject* hol
         items = 0;
         EgeSelectOneAction* act1 = ege_select_one_action_new(
             tool_is_pencil ? "SetPencilShapeAction" : "SetPenShapeAction",
-            _("Shape:"), (""), NULL, GTK_TREE_MODEL(model));
+            _("Shape:"), ("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) );
+        ege_select_one_action_set_active( act1, prefs_get_int_attribute(freehand_tool_name(holder), "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 );
@@ -3419,11 +3420,11 @@ sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tbl)
 
 
 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,
+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);
@@ -3461,16 +3462,17 @@ static void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio
 
     /* Tolerance */
     {
-
+        gchar const* labels[] = {_("(many nodes, rough)"), ("(default)"), 0, 0, 0, 0, ("(few nodes, smooth)")};
+        gdouble values[] = {1, 10, 20, 30, 50, 75, 100};
         eact = create_adjustment_action( "PencilToleranceAction",
-                 _("Number of pixels allowed in interpolating"),
-                                         _("Tolerance:"), _("Tolerance"),
+                                         _("Smoothing:"), _("Smoothing"),
+                 _("How much smoothing (simplifying) is applied to the line"),
                                          "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,
+                                         1, 100.0, 0.5, 0,
+                                         labels, values, G_N_ELEMENTS(labels),
                                          sp_pencil_tb_tolerance_value_changed,
                                          1, 2);
         ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT );
@@ -3797,22 +3799,26 @@ 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"));
+static void update_presets_list (GObject *tbl){
+
+    if (g_object_get_data(tbl, "presets_blocked")) 
+        return;
+
+    EgeSelectOneAction *sel = static_cast<EgeSelectOneAction *>(g_object_get_data(tbl, "profile_selector"));
     if (sel) {
-        ege_select_one_action_set_active(sel, 0 );
+        ege_select_one_action_set_active(sel, 0);
     }
 }
 
 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 )
 {
-    prefs_set_double_attribute( "tools.calligraphic", "wiggle", adj->value );
+    prefs_set_double_attribute( "tools.calligraphic", "wiggle", adj->value * 0.01 );
     update_presets_list(tbl);
 }
 
@@ -3830,19 +3836,19 @@ static void sp_ddc_width_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 )
 {
-    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 )
 {
-    prefs_set_double_attribute( "tools.calligraphic", "tremor", adj->value );
+    prefs_set_double_attribute( "tools.calligraphic", "tremor", adj->value * 0.01 );
     update_presets_list(tbl);
 }
 
@@ -3866,7 +3872,7 @@ static void sp_ddc_trace_background_changed( GtkToggleAction *act, GObject*  tbl
 
 static void sp_ddc_tilt_state_changed( GtkToggleAction *act, GObject*  tbl )
 {
-    GtkAction * calligraphy_angle = static_cast<GtkAction *> (g_object_get_data(tbl,"angle"));
+    GtkAction * calligraphy_angle = static_cast<GtkAction *> (g_object_get_data(tbl,"angle_action"));
     prefs_set_int_attribute( "tools.calligraphic", "usetilt", gtk_toggle_action_get_active( act ) ? 1 : 0 );
     update_presets_list(tbl);
     if (calligraphy_angle )
@@ -3874,103 +3880,175 @@ static void sp_ddc_tilt_state_changed( GtkToggleAction *act, GObject*  tbl )
 }
 
 
-#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;
+#define NUMBER_OF_PRESET_PARAMS 11
+static gchar * widget_names[NUMBER_OF_PRESET_PARAMS] = {
+    "width",
+    "mass",
+    "wiggle",
+    "angle",
+    "thinning",
+    "tremor",
+    "flatness",
+    "cap_rounding",
+    "usepressure",
+    "tracebackground",
+    "usetilt"
 };
 
 
+static void sp_dcc_build_presets_list(GObject *tbl) 
+{
+    EgeSelectOneAction* selector = static_cast<EgeSelectOneAction *>(g_object_get_data(tbl, "profile_selector"));
+    GtkListStore* model = GTK_LIST_STORE(ege_select_one_action_get_model(selector));
+    gtk_list_store_clear (model);
 
-static ProfileFloatElement f_profile[PROFILE_FLOAT_SIZE] = {
-    {"mass",0.02, 0.0, 1.0},
-    {"wiggle",0.0, 0.0, 1.0},
-    {"angle",30.0, -90.0, 90.0},
-    {"thinning",0.1, -1.0, 1.0},
-    {"tremor",0.0, 0.0, 1.0},
-    {"flatness",0.9, 0.0, 1.0},
-    {"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},
-};
+    {
+        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);
+    }
 
+    {
+        GtkTreeIter iter;
+        gtk_list_store_append( model, &iter );
+        gtk_list_store_set( model, &iter, 0, _("Save..."), 1, ii, -1 );
+        g_object_set_data(tbl, "save_presets_index", GINT_TO_POINTER(ii));
+    }
 
-static void sp_dcc_save_profile( GtkWidget */*widget*/, GObject *dataKludge ){
-    SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" );
+    update_presets_list (tbl);
+}
+
+static void sp_dcc_save_profile (GtkWidget */*widget*/, GObject *tbl)
+{
+    SPDesktop *desktop = (SPDesktop *) g_object_get_data(tbl, "desktop" );
     if (! desktop) return;
 
+    if (g_object_get_data(tbl, "presets_blocked")) 
+        return;
+
     Inkscape::UI::Dialogs::CalligraphicProfileDialog::show(desktop);
-    if ( ! Inkscape::UI::Dialogs::CalligraphicProfileDialog::applied()) return;
+    if ( ! Inkscape::UI::Dialogs::CalligraphicProfileDialog::applied()) {
+        // dialog cancelled
+        update_presets_list (tbl);
+        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);
-
-    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);
+    if (!profile_name.c_str() || *profile_name.c_str() == 0) {
+        // empty name entered
+        update_presets_list (tbl);
+        return;
     }
-    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);
+
+    int new_index = -1;
+    gchar *pref_path = NULL;
+    int total_prefs = pref_path_number_of_children("tools.calligraphic.preset");
+
+    for (int i = 1; i <= total_prefs; i++) {
+        gchar *path = get_pref_nth_child("tools.calligraphic.preset", i);
+        const gchar *name = prefs_get_string_attribute(path, "name");
+        if (name && !strcmp(name, profile_name.c_str())) {
+            // we already have preset with this name, replace its values
+            new_index = i;
+            pref_path = g_strdup(path);
+            break;
+        }
     }
-    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 );
+    if (new_index == -1) {
+        // no preset with this name, create 
+        new_index = total_prefs + 1;
+        gchar *profile_id = g_strdup_printf("dcc%d", new_index);
+        pref_path = create_pref("tools.calligraphic.preset", profile_id);
+        free(profile_id);
+    }
+
+    for (unsigned i = 0; i < NUMBER_OF_PRESET_PARAMS; ++i) {
+        gchar *widget_name = widget_names[i];
+        void *widget = g_object_get_data(tbl, widget_name);
+        if (widget) {
+            if (GTK_IS_ADJUSTMENT(widget)) {
+                GtkAdjustment* adj = static_cast<GtkAdjustment *>(widget);
+                double v = gtk_adjustment_get_value(adj);
+                prefs_set_double_attribute(pref_path, widget_name, v);
+                //std::cout << "wrote adj " << widget_name << ": " << v << "\n";
+            } else if (GTK_IS_TOGGLE_ACTION(widget)) {
+                GtkToggleAction* toggle = static_cast<GtkToggleAction *>(widget);
+                int v = gtk_toggle_action_get_active(toggle);
+                prefs_set_int_attribute(pref_path, widget_name, v);
+                //std::cout << "wrote tog " << widget_name << ": " << v << "\n";
+            } else {
+               g_warning("Unknown widget type for preset: %s\n", widget_name);
+            }
+        } else {
+            g_warning("Bad key when writing preset: %s\n", widget_name);
+        }
+    }
+    prefs_set_string_attribute(pref_path, "name", profile_name.c_str());
 
-    free(profile_id);
-    free(pref_path);
+    sp_dcc_build_presets_list (tbl);
 
-    ege_select_one_action_set_active(selector, new_index);
+    free (pref_path);
 }
 
 
-static void sp_ddc_change_profile(EgeSelectOneAction* act, GObject *dataKludge) {
+static void sp_ddc_change_profile(EgeSelectOneAction* act, GObject* tbl) {
 
     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);
+    gint save_presets_index = GPOINTER_TO_INT(g_object_get_data(tbl, "save_presets_index"));
+
+    if (preset_index == save_presets_index) {
+        // this is the Save command
+        sp_dcc_save_profile(NULL, tbl);
+        return;
+    }
+
+    gchar *preset_path = get_pref_nth_child("tools.calligraphic.preset", preset_index);
+
+    if (preset_path) {
+        g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); //temporarily block the selector so no one will updadte it while we're reading it
+
+        Inkscape::XML::Node *preset_repr = inkscape_get_repr(INKSCAPE, preset_path);
+
+        for ( Inkscape::Util::List<Inkscape::XML::AttributeRecord const> iter = preset_repr->attributeList();
+              iter; 
+              ++iter ) {
+            const gchar *attr_name = g_quark_to_string(iter->key);
+            if (!strcmp(attr_name, "id") || !strcmp(attr_name, "name"))
+                continue;
+            void *widget = g_object_get_data(tbl, attr_name);
+            if (widget) {
+                if (GTK_IS_ADJUSTMENT(widget)) {
+                    double v = prefs_get_double_attribute(preset_path, attr_name, 0); // fixme: no min/max checks here, add?
+                    GtkAdjustment* adj = static_cast<GtkAdjustment *>(widget);
+                    gtk_adjustment_set_value(adj, v);
+                    //std::cout << "set adj " << attr_name << " to " << v << "\n";
+                } else if (GTK_IS_TOGGLE_ACTION(widget)) {
+                    int v = prefs_get_int_attribute(preset_path, attr_name, 0); // fixme: no min/max checks here, add?
+                    GtkToggleAction* toggle = static_cast<GtkToggleAction *>(widget);
+                    gtk_toggle_action_set_active(toggle, v);
+                    //std::cout << "set toggle " << attr_name << " to " << v << "\n";
+                } else {
+                    g_warning("Unknown widget type for preset: %s\n", attr_name);
+                }
+            } else {
+                g_warning("Bad key found in a preset record: %s\n", attr_name);
             }
         }
-        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
+        free(preset_path);
+        g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE));
     }
 
 }
@@ -4001,15 +4079,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 );
         }
@@ -4027,23 +4105,23 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
                                                               labels, values, G_N_ELEMENTS(labels),
                                                               sp_ddc_angle_value_changed, 1, 0 );
         gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+        g_object_set_data( holder, "angle_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 );
         }
@@ -4068,15 +4146,15 @@ 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.0,
+                                                              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) );
@@ -4086,15 +4164,15 @@ 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.0,
+                                                              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 );
@@ -4103,15 +4181,15 @@ 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.0,
+                                                              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 );
@@ -4160,47 +4238,15 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
 
         /*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( "SaveDeleteProfileAction",
-                                             _("Defaults"),
-                                             _("Save current settings as new profile"),
-                                             GTK_STOCK_SAVE );
-            g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_dcc_save_profile), holder );
+            GtkListStore* model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
+            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_object_set_data (holder, "profile_selector", act1 );
 
+            sp_dcc_build_presets_list (holder);
 
-            gtk_action_group_add_action( mainActions, act );
-            gtk_action_set_sensitive( act, TRUE );
-            g_object_set_data( holder, "profile_save_delete", act );
+            g_signal_connect(G_OBJECT(act1), "changed", G_CALLBACK(sp_ddc_change_profile), holder);
+            gtk_action_group_add_action(mainActions, GTK_ACTION(act1));
         }
     }
 }
@@ -4769,18 +4815,24 @@ sp_text_toolbox_selection_changed (Inkscape::Selection */*selection*/, GObject *
     gtk_widget_hide (GTK_WIDGET (g_object_get_data (G_OBJECT(tbl), "warning-image")));
 
     // If querying returned nothing, read the style from the text tool prefs (default style for new texts)
-    if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING)
-    {
+    if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING) {
+        // there are no texts in selection, read from prefs
         Inkscape::XML::Node *repr = inkscape_get_repr (INKSCAPE, "tools.text");
-
-        if (repr)
-        {
+        if (repr) {
             sp_style_read_from_repr (query, repr);
-        }
-        else
-        {
+            if (g_object_get_data(tbl, "text_style_from_prefs")) {
+                // do not reset the toolbar style from prefs if we already did it last time
+                sp_style_unref(query);
+                return;
+            }
+            g_object_set_data(tbl, "text_style_from_prefs", GINT_TO_POINTER(TRUE));
+        } else {
+            sp_style_unref(query);
             return;
         }
+    } else {
+        g_object_set_data(tbl, "text_style_from_prefs", GINT_TO_POINTER(FALSE));
     }
 
     if (query->text)
@@ -4810,6 +4862,7 @@ sp_text_toolbox_selection_changed (Inkscape::Selection */*selection*/, GObject *
                 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());
+                sp_style_unref(query);
                 return;
             }
 
@@ -6016,7 +6069,7 @@ static void paintbucket_offset_changed(GtkAdjustment *adj, GObject *tbl)
     prefs_set_string_attribute("tools.paintbucket", "offsetunits", sp_unit_get_abbreviation(unit));
 }
 
-static void paintbucket_defaults(GtkWidget *, GObject *dataKludge)
+static void paintbucket_defaults (GtkWidget *, GObject *tbl)
 {
     // FIXME: make defaults settable via Inkscape Options
     struct KeyValue {
@@ -6029,15 +6082,15 @@ static void paintbucket_defaults(GtkWidget *, GObject *dataKludge)
 
     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));
+        GtkAdjustment* adj = static_cast<GtkAdjustment *>(g_object_get_data(tbl, kv.key));
         if ( adj ) {
             gtk_adjustment_set_value(adj, kv.value);
         }
     }
 
-    EgeSelectOneAction* channels_action = EGE_SELECT_ONE_ACTION( g_object_get_data( dataKludge, "channels_action" ) );
+    EgeSelectOneAction* channels_action = EGE_SELECT_ONE_ACTION( g_object_get_data (tbl, "channels_action" ) );
     ege_select_one_action_set_active( channels_action, FLOOD_CHANNELS_RGB );
-    EgeSelectOneAction* autogap_action = EGE_SELECT_ONE_ACTION( g_object_get_data( dataKludge, "autogap_action" ) );
+    EgeSelectOneAction* autogap_action = EGE_SELECT_ONE_ACTION( g_object_get_data (tbl, "autogap_action" ) );
     ege_select_one_action_set_active( autogap_action, 0 );
 }