Code

Improve behavior when pasting, DnDing and importing bitmap images
[inkscape.git] / src / ui / dialog / align-and-distribute.cpp
index 627f10c0c4c12c3ab1ba0ee0d8f7013729b886f8..8c8d64ec00554f4d181ed0af779ec0081b22d0a5 100644 (file)
@@ -1,7 +1,7 @@
-/**
- * \brief Align and Distribute dialog
- *
- * Authors:
+/** @file
+ * @brief Align and Distribute dialog - implementation
+ */
+/* Authors:
  *   Bryce W. Harrington <bryce@bryceharrington.org>
  *   Aubanel MONNIER <aubi@libertysurf.fr>
  *   Frank Felfe <innerspace@iname.com>
 # include <config.h>
 #endif
 
-#include "verbs.h"
-
-#include "dialogs/unclump.h"
-#include "removeoverlap/removeoverlap.h"
-#include "graphlayout/graphlayout.h"
-
 #include <gtkmm/spinbutton.h>
 
-
-
-
-#include "util/glib-list-iterators.h"
-
-#include "widgets/icon.h"
-
-#include "inkscape.h"
-#include "document.h"
-#include "selection.h"
 #include "desktop-handles.h"
+#include "unclump.h"
+#include "document.h"
+#include "enums.h"
+#include "graphlayout/graphlayout.h"
+#include "inkscape.h"
 #include "macros.h"
+#include "preferences.h"
+#include "removeoverlap/removeoverlap.h"
+#include "selection.h"
+#include "sp-flowtext.h"
 #include "sp-item-transform.h"
-#include "prefs-utils.h"
-#include "enums.h"
-
 #include "sp-text.h"
-#include "sp-flowtext.h"
 #include "text-editing.h"
-
-#include "node-context.h"  //For access to ShapeEditor
-#include "shape-editor.h" //For node align/distribute methods
-
 #include "tools-switch.h"
+#include "ui/icon-names.h"
+#include "ui/tool/node-tool.h"
+#include "ui/tool/multi-path-manipulator.h"
+#include "util/glib-list-iterators.h"
+#include "verbs.h"
+#include "widgets/icon.h"
 
 #include "align-and-distribute.h"
 
@@ -122,7 +113,8 @@ private :
         Inkscape::Selection *selection = sp_desktop_selection(desktop);
         if (!selection) return;
 
-        bool sel_as_group = (prefs_get_int_attribute("dialogs.align", "sel-as-groups", 0) != 0);
+        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+        bool sel_as_group = prefs->getBool("/dialogs/align/sel-as-groups");
 
         using Inkscape::Util::GSListConstIterator;
         std::list<SPItem *> selected;
@@ -153,11 +145,14 @@ private :
                 );
             //remove the master from the selection
             SPItem * thing = *master;
-            if (!sel_as_group) {
+            // TODO: either uncomment or remove the following commented lines, depending on which
+            //       behaviour of moving objects makes most sense; also cf. discussion at
+            //       https://bugs.launchpad.net/inkscape/+bug/255933
+            /*if (!sel_as_group) { */
                 selected.erase(master);
-            }
+            /*}*/
             //Compute the anchor point
-            boost::optional<NR::Rect> b = sp_item_bbox_desktop (thing);
+            Geom::OptRect b = sp_item_bbox_desktop (thing);
             if (b) {
                 mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
                                a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]);
@@ -174,7 +169,7 @@ private :
 
         case AlignAndDistribute::DRAWING:
         {
-            boost::optional<NR::Rect> b = sp_item_bbox_desktop
+            Geom::OptRect b = sp_item_bbox_desktop
                 ( (SPItem *) sp_document_root (sp_desktop_document (desktop)) );
             if (b) {
                 mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
@@ -187,7 +182,7 @@ private :
 
         case AlignAndDistribute::SELECTION:
         {
-            boost::optional<NR::Rect> b =  selection->bounds();
+            Geom::OptRect b =  selection->bounds();
             if (b) {
                 mp = Geom::Point(a.mx0 * b->min()[Geom::X] + a.mx1 * b->max()[Geom::X],
                                a.my0 * b->min()[Geom::Y] + a.my1 * b->max()[Geom::Y]);
@@ -208,11 +203,11 @@ private :
         // a selected original, they will be unmoved too, possibly contrary to user's
         // expecation. However this is a minor point compared to making align/distribute always
         // work as expected, and "unmoved" is the default option anyway.
-        int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
-        prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
+        int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
+        prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
 
         bool changed = false;
-        boost::optional<NR::Rect> b;
+        Geom::OptRect b;
         if (sel_as_group)
             b = selection->bounds();
 
@@ -229,14 +224,14 @@ private :
                                      a.sy0 * b->min()[Geom::Y] + a.sy1 * b->max()[Geom::Y]);
                 Geom::Point const mp_rel( mp - sp );
                 if (LInfty(mp_rel) > 1e-9) {
-                    sp_item_move_rel(*it, NR::translate(mp_rel));
+                    sp_item_move_rel(*it, Geom::Translate(mp_rel));
                     changed = true;
                 }
             }
         }
 
         // restore compensation setting
-        prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation);
+        prefs->setInt("/options/clonecompensation/value", saved_compensation);
 
         if (changed) {
             sp_document_done ( sp_desktop_document (desktop) , SP_VERB_DIALOG_ALIGN_DISTRIBUTE,
@@ -327,17 +322,18 @@ private :
             it != selected.end();
             ++it)
         {
-            boost::optional<NR::Rect> bbox = sp_item_bbox_desktop(*it);
+            Geom::OptRect bbox = sp_item_bbox_desktop(*it);
             if (bbox) {
-                sorted.push_back(BBoxSort(*it, to_2geom(*bbox), _orientation, _kBegin, _kEnd));
+                sorted.push_back(BBoxSort(*it, *bbox, _orientation, _kBegin, _kEnd));
             }
         }
         //sort bbox by anchors
         std::sort(sorted.begin(), sorted.end());
 
         // see comment in ActionAlign above
-        int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
-        prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
+        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+        int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
+        prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
 
         unsigned int len = sorted.size();
         bool changed = false;
@@ -362,7 +358,7 @@ private :
                 if (!NR_DF_TEST_CLOSE (pos, it->bbox.min()[_orientation], 1e-6)) {
                     Geom::Point t(0.0, 0.0);
                     t[_orientation] = pos - it->bbox.min()[_orientation];
-                    sp_item_move_rel(it->item, NR::translate(t));
+                    sp_item_move_rel(it->item, Geom::Translate(t));
                     changed = true;
                 }
                 pos += it->bbox[_orientation].extent();
@@ -387,14 +383,14 @@ private :
                     Geom::Point t(0.0, 0.0);
                     t[_orientation] = pos - it.anchor;
                     //translate
-                    sp_item_move_rel(it.item, NR::translate(t));
+                    sp_item_move_rel(it.item, Geom::Translate(t));
                     changed = true;
                 }
             }
         }
 
         // restore compensation setting
-        prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation);
+        prefs->setInt("/options/clonecompensation/value", saved_compensation);
 
         if (changed) {
             sp_document_done ( sp_desktop_document (desktop), SP_VERB_DIALOG_ALIGN_DISTRIBUTE,
@@ -433,12 +429,13 @@ private :
 
         if (!_dialog.getDesktop()) return;
         SPEventContext *event_context = sp_desktop_event_context(_dialog.getDesktop());
-        if (!SP_IS_NODE_CONTEXT (event_context)) return ;
+        if (!INK_IS_NODE_TOOL (event_context)) return;
+        InkNodeTool *nt = INK_NODE_TOOL(event_context);
 
         if (_distribute)
-            SP_NODE_CONTEXT (event_context)->shape_editor->distribute((NR::Dim2)_orientation);
+            nt->_multipath->distributeNodes(_orientation);
         else
-            SP_NODE_CONTEXT (event_context)->shape_editor->align((NR::Dim2)_orientation);
+            nt->_multipath->alignNodes(_orientation);
 
     }
 };
@@ -463,17 +460,19 @@ public:
 
         removeOverlapXGap.set_digits(1);
         removeOverlapXGap.set_size_request(60, -1);
-        removeOverlapXGap.set_increments(1.0, 5.0);
+        removeOverlapXGap.set_increments(1.0, 0);
         removeOverlapXGap.set_range(-1000.0, 1000.0);
         removeOverlapXGap.set_value(0);
         dialog.tooltips().set_tip(removeOverlapXGap,
                                   _("Minimum horizontal gap (in px units) between bounding boxes"));
-        /* TRANSLATORS: Horizontal gap. Only put "H:" equivalent in the translation */
+        //TRANSLATORS: only translate "string" in "context|string".
+        // For more details, see http://developer.gnome.org/doc/API/2.0/glib/glib-I18N.html#Q-:CAPS
+        // "H:" stands for horizontal gap
         removeOverlapXGapLabel.set_label(Q_("gap|H:"));
 
         removeOverlapYGap.set_digits(1);
         removeOverlapYGap.set_size_request(60, -1);
-        removeOverlapYGap.set_increments(1.0, 5.0);
+        removeOverlapYGap.set_increments(1.0, 0);
         removeOverlapYGap.set_range(-1000.0, 1000.0);
         removeOverlapYGap.set_value(0);
         dialog.tooltips().set_tip(removeOverlapYGap,
@@ -494,8 +493,9 @@ private :
         if (!_dialog.getDesktop()) return;
 
         // see comment in ActionAlign above
-        int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
-        prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
+        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+        int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
+        prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
 
         // xGap and yGap are the minimum space required between bounding rectangles.
         double const xGap = removeOverlapXGap.get_value();
@@ -504,7 +504,7 @@ private :
                       xGap, yGap);
 
         // restore compensation setting
-        prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation);
+        prefs->setInt("/options/clonecompensation/value", saved_compensation);
 
         sp_document_done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE,
                          _("Remove overlaps"));
@@ -528,13 +528,14 @@ private :
         if (!_dialog.getDesktop()) return;
 
         // see comment in ActionAlign above
-        int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
-        prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
+        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+        int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
+        prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
 
         graphlayout(sp_desktop_selection(_dialog.getDesktop())->itemList());
 
         // restore compensation setting
-        prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation);
+        prefs->setInt("/options/clonecompensation/value", saved_compensation);
 
         sp_document_done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE,
                          _("Arrange connector network"));
@@ -558,13 +559,14 @@ private :
         if (!_dialog.getDesktop()) return;
 
         // see comment in ActionAlign above
-        int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
-        prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
+        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+        int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
+        prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
 
         unclump ((GSList *) sp_desktop_selection(_dialog.getDesktop())->itemList());
 
         // restore compensation setting
-        prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation);
+        prefs->setInt("/options/clonecompensation/value", saved_compensation);
 
         sp_document_done (sp_desktop_document (_dialog.getDesktop()), SP_VERB_DIALOG_ALIGN_DISTRIBUTE,
                           _("Unclump"));
@@ -599,7 +601,7 @@ private :
         //Check 2 or more selected objects
         if (selected.size() < 2) return;
 
-        boost::optional<NR::Rect> sel_bbox = selection->bounds();
+        Geom::OptRect sel_bbox = selection->bounds();
         if (!sel_bbox) {
             return;
         }
@@ -608,33 +610,34 @@ private :
         // nor drift on sequential randomizations. Discard cache on global (or better active
         // desktop's) selection_change signal.
         if (!_dialog.randomize_bbox) {
-            _dialog.randomize_bbox = to_2geom(*sel_bbox);
+            _dialog.randomize_bbox = *sel_bbox;
         }
 
         // see comment in ActionAlign above
-        int saved_compensation = prefs_get_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
-        prefs_set_int_attribute("options.clonecompensation", "value", SP_CLONE_COMPENSATION_UNMOVED);
+        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+        int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
+        prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED);
 
         for (std::list<SPItem *>::iterator it(selected.begin());
             it != selected.end();
             ++it)
         {
             sp_document_ensure_up_to_date(sp_desktop_document (desktop));
-            boost::optional<NR::Rect> item_box = sp_item_bbox_desktop (*it);
+            Geom::OptRect item_box = sp_item_bbox_desktop (*it);
             if (item_box) {
                 // find new center, staying within bbox
-                double x = _dialog.randomize_bbox->min()[Geom::X] + (*item_box).extent(Geom::X)/2 +
-                    g_random_double_range (0, (*_dialog.randomize_bbox)[Geom::X].extent() - (*item_box).extent(Geom::X));
-                double y = _dialog.randomize_bbox->min()[Geom::Y] + (*item_box).extent(Geom::Y)/2 +
-                    g_random_double_range (0, (*_dialog.randomize_bbox)[Geom::Y].extent() - (*item_box).extent(Geom::Y));
+                double x = _dialog.randomize_bbox->min()[Geom::X] + (*item_box)[Geom::X].extent() /2 +
+                    g_random_double_range (0, (*_dialog.randomize_bbox)[Geom::X].extent() - (*item_box)[Geom::X].extent());
+                double y = _dialog.randomize_bbox->min()[Geom::Y] + (*item_box)[Geom::Y].extent()/2 +
+                    g_random_double_range (0, (*_dialog.randomize_bbox)[Geom::Y].extent() - (*item_box)[Geom::Y].extent());
                 // displacement is the new center minus old:
-                NR::Point t = NR::Point (x, y) - 0.5*(item_box->max() + item_box->min());
-                sp_item_move_rel(*it, NR::translate(t));
+                Geom::Point t = Geom::Point (x, y) - 0.5*(item_box->max() + item_box->min());
+                sp_item_move_rel(*it, Geom::Translate(t));
             }
         }
 
         // restore compensation setting
-        prefs_set_int_attribute("options.clonecompensation", "value", saved_compensation);
+        prefs->setInt("/options/clonecompensation/value", saved_compensation);
 
         sp_document_done (sp_desktop_document (desktop), SP_VERB_DIALOG_ALIGN_DISTRIBUTE,
                           _("Randomize positions"));
@@ -703,14 +706,16 @@ private :
         {
             if (SP_IS_TEXT (*it) || SP_IS_FLOWTEXT (*it)) {
                 Inkscape::Text::Layout const *layout = te_get_layout(*it);
-                Geom::Point base = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(*it);
-                if (base[Geom::X] < b_min[Geom::X]) b_min[Geom::X] = base[Geom::X];
-                if (base[Geom::Y] < b_min[Geom::Y]) b_min[Geom::Y] = base[Geom::Y];
-                if (base[Geom::X] > b_max[Geom::X]) b_max[Geom::X] = base[Geom::X];
-                if (base[Geom::Y] > b_max[Geom::Y]) b_max[Geom::Y] = base[Geom::Y];
-
-                Baselines b (*it, base, _orientation);
-                sorted.push_back(b);
+                boost::optional<Geom::Point> pt = layout->baselineAnchorPoint();
+                if (pt) {
+                    Geom::Point base = *pt * sp_item_i2d_affine(*it);
+                    if (base[Geom::X] < b_min[Geom::X]) b_min[Geom::X] = base[Geom::X];
+                    if (base[Geom::Y] < b_min[Geom::Y]) b_min[Geom::Y] = base[Geom::Y];
+                    if (base[Geom::X] > b_max[Geom::X]) b_max[Geom::X] = base[Geom::X];
+                    if (base[Geom::Y] > b_max[Geom::Y]) b_max[Geom::Y] = base[Geom::Y];
+                    Baselines b (*it, base, _orientation);
+                    sorted.push_back(b);
+                }
             }
         }
 
@@ -728,7 +733,7 @@ private :
                 Geom::Point base = sorted[i]._base;
                 Geom::Point t(0.0, 0.0);
                 t[_orientation] = b_min[_orientation] + step * i - base[_orientation];
-                sp_item_move_rel(item, NR::translate(t));
+                sp_item_move_rel(item, Geom::Translate(t));
                 changed = true;
             }
 
@@ -744,11 +749,14 @@ private :
             {
                 if (SP_IS_TEXT (*it) || SP_IS_FLOWTEXT (*it)) {
                     Inkscape::Text::Layout const *layout = te_get_layout(*it);
-                    Geom::Point base = layout->characterAnchorPoint(layout->begin()) * sp_item_i2d_affine(*it);
-                    Geom::Point t(0.0, 0.0);
-                    t[_orientation] = b_min[_orientation] - base[_orientation];
-                    sp_item_move_rel(*it, NR::translate(t));
-                    changed = true;
+                    boost::optional<Geom::Point> pt = layout->baselineAnchorPoint();
+                    if (pt) {
+                        Geom::Point base = *pt * sp_item_i2d_affine(*it);
+                        Geom::Point t(0.0, 0.0);
+                        t[_orientation] = b_min[_orientation] - base[_orientation];
+                        sp_item_move_rel(*it, Geom::Translate(t));
+                        changed = true;
+                    }
                 }
             }
 
@@ -771,7 +779,7 @@ void on_tool_changed(Inkscape::Application */*inkscape*/, SPEventContext */*cont
 
 void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection */*selection*/, AlignAndDistribute *daad)
 {
-    daad->randomize_bbox = boost::optional<Geom::Rect>();
+    daad->randomize_bbox = Geom::OptRect();
 }
 
 /////////////////////////////////////////////////////////
@@ -780,7 +788,7 @@ void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selecti
 
 
 AlignAndDistribute::AlignAndDistribute()
-    : UI::Widget::Panel ("", "dialogs.align", SP_VERB_DIALOG_ALIGN_DISTRIBUTE),
+    : UI::Widget::Panel ("", "/dialogs/align", SP_VERB_DIALOG_ALIGN_DISTRIBUTE),
       randomize_bbox(),
       _alignFrame(_("Align")),
       _distributeFrame(_("Distribute")),
@@ -795,112 +803,116 @@ AlignAndDistribute::AlignAndDistribute()
       _anchorLabel(_("Relative to: ")),
       _selgrpLabel(_("Treat selection as group: "))
 {
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
 
     //Instanciate the align buttons
-    addAlignButton("al_left_out",
-                   _("Align right sides of objects to left side of anchor"),
+    addAlignButton(INKSCAPE_ICON_ALIGN_HORIZONTAL_RIGHT_TO_ANCHOR,
+                   _("Align right edges of objects to the left edge of the anchor"),
                    0, 0);
-    addAlignButton("al_left_in",
-                   _("Align left sides"),
+    addAlignButton(INKSCAPE_ICON_ALIGN_HORIZONTAL_LEFT,
+                   _("Align left edges"),
                    0, 1);
-    addAlignButton("al_center_hor",
+    addAlignButton(INKSCAPE_ICON_ALIGN_HORIZONTAL_CENTER,
                    _("Center on vertical axis"),
                    0, 2);
-    addAlignButton("al_right_in",
+    addAlignButton(INKSCAPE_ICON_ALIGN_HORIZONTAL_RIGHT,
                    _("Align right sides"),
                    0, 3);
-    addAlignButton("al_right_out",
-                   _("Align left sides of objects to right side of anchor"),
+    addAlignButton(INKSCAPE_ICON_ALIGN_HORIZONTAL_LEFT_TO_ANCHOR,
+                   _("Align left edges of objects to the right edge of the anchor"),
                    0, 4);
-    addAlignButton("al_top_out",
-                   _("Align bottoms of objects to top of anchor"),
+    addAlignButton(INKSCAPE_ICON_ALIGN_VERTICAL_BOTTOM_TO_ANCHOR,
+                   _("Align bottom edges of objects to the top edge of the anchor"),
                    1, 0);
-    addAlignButton("al_top_in",
-                   _("Align tops"),
+    addAlignButton(INKSCAPE_ICON_ALIGN_VERTICAL_TOP,
+                   _("Align top edges"),
                    1, 1);
-    addAlignButton("al_center_ver",
+    addAlignButton(INKSCAPE_ICON_ALIGN_VERTICAL_CENTER,
                    _("Center on horizontal axis"),
                    1, 2);
-    addAlignButton("al_bottom_in",
-                   _("Align bottoms"),
+    addAlignButton(INKSCAPE_ICON_ALIGN_VERTICAL_BOTTOM,
+                   _("Align bottom edges"),
                    1, 3);
-    addAlignButton("al_bottom_out",
-                   _("Align tops of objects to bottom of anchor"),
+    addAlignButton(INKSCAPE_ICON_ALIGN_VERTICAL_TOP_TO_ANCHOR,
+                   _("Align top edges of objects to the bottom edge of the anchor"),
                    1, 4);
 
     //Baseline aligns
-    addBaselineButton("al_baselines_vert",
-                   _("Align baseline anchors of texts vertically"),
-                      0, 5, this->align_table(), Geom::X, false);
-    addBaselineButton("al_baselines_hor",
+    addBaselineButton(INKSCAPE_ICON_ALIGN_HORIZONTAL_BASELINE,
                    _("Align baseline anchors of texts horizontally"),
+                      0, 5, this->align_table(), Geom::X, false);
+    addBaselineButton(INKSCAPE_ICON_ALIGN_VERTICAL_BASELINE,
+                   _("Align baselines of texts"),
                      1, 5, this->align_table(), Geom::Y, false);
 
     //The distribute buttons
-    addDistributeButton("distribute_hdist",
+    addDistributeButton(INKSCAPE_ICON_DISTRIBUTE_HORIZONTAL_GAPS,
                         _("Make horizontal gaps between objects equal"),
                         0, 4, true, Geom::X, .5, .5);
 
-    addDistributeButton("distribute_left",
-                        _("Distribute left sides equidistantly"),
+    addDistributeButton(INKSCAPE_ICON_DISTRIBUTE_HORIZONTAL_LEFT,
+                        _("Distribute left edges equidistantly"),
                         0, 1, false, Geom::X, 1., 0.);
-    addDistributeButton("distribute_hcentre",
+    addDistributeButton(INKSCAPE_ICON_DISTRIBUTE_HORIZONTAL_CENTER,
                         _("Distribute centers equidistantly horizontally"),
                         0, 2, false, Geom::X, .5, .5);
-    addDistributeButton("distribute_right",
-                        _("Distribute right sides equidistantly"),
+    addDistributeButton(INKSCAPE_ICON_DISTRIBUTE_HORIZONTAL_RIGHT,
+                        _("Distribute right edges equidistantly"),
                         0, 3, false, Geom::X, 0., 1.);
 
-    addDistributeButton("distribute_vdist",
+    addDistributeButton(INKSCAPE_ICON_DISTRIBUTE_VERTICAL_GAPS,
                         _("Make vertical gaps between objects equal"),
                         1, 4, true, Geom::Y, .5, .5);
 
-    addDistributeButton("distribute_top",
-                        _("Distribute tops equidistantly"),
+    addDistributeButton(INKSCAPE_ICON_DISTRIBUTE_VERTICAL_TOP,
+                        _("Distribute top edges equidistantly"),
                         1, 1, false, Geom::Y, 0, 1);
-    addDistributeButton("distribute_vcentre",
+    addDistributeButton(INKSCAPE_ICON_DISTRIBUTE_VERTICAL_CENTER,
                         _("Distribute centers equidistantly vertically"),
                         1, 2, false, Geom::Y, .5, .5);
-    addDistributeButton("distribute_bottom",
-                        _("Distribute bottoms equidistantly"),
+    addDistributeButton(INKSCAPE_ICON_DISTRIBUTE_VERTICAL_BOTTOM,
+                        _("Distribute bottom edges equidistantly"),
                         1, 3, false, Geom::Y, 1., 0.);
 
     //Baseline distribs
-    addBaselineButton("distribute_baselines_hor",
+    addBaselineButton(INKSCAPE_ICON_DISTRIBUTE_HORIZONTAL_BASELINE,
                    _("Distribute baseline anchors of texts horizontally"),
                       0, 5, this->distribute_table(), Geom::X, true);
-    addBaselineButton("distribute_baselines_vert",
-                   _("Distribute baseline anchors of texts vertically"),
+    addBaselineButton(INKSCAPE_ICON_DISTRIBUTE_VERTICAL_BASELINE,
+                   _("Distribute baselines of texts vertically"),
                      1, 5, this->distribute_table(), Geom::Y, true);
 
     //Randomize & Unclump
-    addRandomizeButton("distribute_randomize",
+    addRandomizeButton(INKSCAPE_ICON_DISTRIBUTE_RANDOMIZE,
                         _("Randomize centers in both dimensions"),
                         2, 2);
-    addUnclumpButton("unclump",
+    addUnclumpButton(INKSCAPE_ICON_DISTRIBUTE_UNCLUMP,
                         _("Unclump objects: try to equalize edge-to-edge distances"),
                         2, 4);
 
     //Remove overlaps
-    addRemoveOverlapsButton("remove_overlaps",
+    addRemoveOverlapsButton(INKSCAPE_ICON_DISTRIBUTE_REMOVE_OVERLAPS,
                             _("Move objects as little as possible so that their bounding boxes do not overlap"),
                             0, 0);
     //Graph Layout
-    addGraphLayoutButton("graph_layout",
+    addGraphLayoutButton(INKSCAPE_ICON_DISTRIBUTE_GRAPH,
                             _("Nicely arrange selected connector network"),
                             0, 0);
 
     //Node Mode buttons
-    addNodeButton("node_halign",
-                  _("Align selected nodes horizontally"),
+    // NOTE: "align nodes vertically" means "move nodes vertically until they align on a common
+    // _horizontal_ line". This is analogous to what the "align-vertical-center" icon means.
+    // There is no doubt some ambiguity. For this reason the descriptions are different.
+    addNodeButton(INKSCAPE_ICON_ALIGN_VERTICAL_NODES,
+                  _("Align selected nodes to a common horizontal line"),
                   0, Geom::X, false);
-    addNodeButton("node_valign",
-                  _("Align selected nodes vertically"),
+    addNodeButton(INKSCAPE_ICON_ALIGN_HORIZONTAL_NODES,
+                  _("Align selected nodes to a common vertical line"),
                   1, Geom::Y, false);
-    addNodeButton("node_hdistribute",
+    addNodeButton(INKSCAPE_ICON_DISTRIBUTE_HORIZONTAL_NODE,
                   _("Distribute selected nodes horizontally"),
                   2, Geom::X, true);
-    addNodeButton("node_vdistribute",
+    addNodeButton(INKSCAPE_ICON_DISTRIBUTE_VERTICAL_NODE,
                   _("Distribute selected nodes vertically"),
                   3, Geom::Y, true);
 
@@ -908,13 +920,13 @@ AlignAndDistribute::AlignAndDistribute()
 
     _combo.append_text(_("Last selected"));
     _combo.append_text(_("First selected"));
-    _combo.append_text(_("Biggest item"));
-    _combo.append_text(_("Smallest item"));
+    _combo.append_text(_("Biggest object"));
+    _combo.append_text(_("Smallest object"));
     _combo.append_text(_("Page"));
     _combo.append_text(_("Drawing"));
     _combo.append_text(_("Selection"));
 
-    _combo.set_active(prefs_get_int_attribute("dialogs.align", "align-to", 6));
+    _combo.set_active(prefs->getInt("/dialogs/align/align-to", 6));
     _combo.signal_changed().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_ref_change));
 
     _anchorBox.pack_start(_anchorLabel);
@@ -922,7 +934,7 @@ AlignAndDistribute::AlignAndDistribute()
 
     _selgrpBox.pack_start(_selgrpLabel);
     _selgrpBox.pack_start(_selgrp);
-    _selgrp.set_active(prefs_get_int_attribute("dialogs.align", "sel-as-groups", 0));
+    _selgrp.set_active(prefs->getBool("/dialogs/align/sel-as-groups"));
     _selgrp.signal_toggled().connect(sigc::mem_fun(*this, &AlignAndDistribute::on_selgrp_toggled));
 
     _alignBox.pack_start(_anchorBox);
@@ -951,7 +963,7 @@ AlignAndDistribute::AlignAndDistribute()
 
     // Connect to the global selection change, to invalidate cached randomize_bbox
     g_signal_connect (G_OBJECT (INKSCAPE), "change_selection", G_CALLBACK (on_selection_changed), this);
-    randomize_bbox = boost::optional<Geom::Rect>();
+    randomize_bbox = Geom::OptRect();
 
     show_all_children();
 
@@ -969,15 +981,15 @@ AlignAndDistribute::~AlignAndDistribute()
 }
 
 void AlignAndDistribute::on_ref_change(){
-
-    prefs_set_int_attribute("dialogs.align", "align-to", _combo.get_active_row_number());
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    prefs->setInt("/dialogs/align/align-to", _combo.get_active_row_number());
 
     //Make blink the master
 }
 
 void AlignAndDistribute::on_selgrp_toggled(){
-
-    prefs_set_int_attribute("dialogs.align", "sel-as-groups", _selgrp.get_active());
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    prefs->setInt("/dialogs/align/sel-as-groups", _selgrp.get_active());
 
     //Make blink the master
 }
@@ -1096,9 +1108,9 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem
     {
         gdouble max = -1e18;
         for (std::list<SPItem *>::iterator it = list.begin(); it != list.end(); it++) {
-            boost::optional<NR::Rect> b = sp_item_bbox_desktop (*it);
+            Geom::OptRect b = sp_item_bbox_desktop (*it);
             if (b) {
-                gdouble dim = (*b).extent(horizontal ? Geom::X : Geom::Y);
+                gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent();
                 if (dim > max) {
                     max = dim;
                     master = it;
@@ -1113,9 +1125,9 @@ std::list<SPItem *>::iterator AlignAndDistribute::find_master( std::list<SPItem
     {
         gdouble max = 1e18;
         for (std::list<SPItem *>::iterator it = list.begin(); it != list.end(); it++) {
-            boost::optional<NR::Rect> b = sp_item_bbox_desktop (*it);
+            Geom::OptRect b = sp_item_bbox_desktop (*it);
             if (b) {
-                gdouble dim = (*b).extent(horizontal ? Geom::X : Geom::Y);
+                gdouble dim = (*b)[horizontal ? Geom::X : Geom::Y].extent();
                 if (dim < max) {
                     max = dim;
                     master = it;