Code

Punctuation in UI
[inkscape.git] / src / ui / dialog / transformation.cpp
index 9182209f516658a062589c24102e0773fec644d5..c25e9a8c4bbd647f505538c170d59cf052b4914a 100644 (file)
@@ -1,12 +1,11 @@
-/**
- * \brief Object Transformation dialog
- *
- * Authors:
+/** @file
+ * \brief Transform dialog - implementation
+ */
+/* Authors:
  *   Bryce W. Harrington <bryce@bryceharrington.org>
  *   buliabyak@gmail.com
  *
  * Copyright (C) 2004, 2005 Authors
- *
  * Released under GNU GPL.  Read the file 'COPYING' for more information.
  */
 
 #endif
 
 #include <gtkmm/stock.h>
+#include <gtkmm/dialog.h>
 
 #include "document.h"
 #include "desktop-handles.h"
 #include "transformation.h"
+#include "align-and-distribute.h"
 #include "libnr/nr-matrix-ops.h"
 #include "inkscape.h"
 #include "selection.h"
 #include "selection-chemistry.h"
 #include "verbs.h"
-#include "prefs-utils.h"
+#include "preferences.h"
+#include "sp-namedview.h"
 #include "sp-item-transform.h"
 #include "macros.h"
 #include "sp-item.h"
+#include "util/glib-list-iterators.h"
 
 namespace Inkscape {
 namespace UI {
 namespace Dialog {
 
-void on_selection_changed(Inkscape::Application *inkscape, Inkscape::Selection *selection, Transformation *daad)
+void on_selection_changed(Inkscape::Application */*inkscape*/, Inkscape::Selection *selection, Transformation *daad)
 {
     int page = daad->getCurrentPage();
     daad->updateSelection((Inkscape::UI::Dialog::Transformation::PageType)page, selection);
 }
 
-void on_selection_modified ( Inkscape::Application *inkscape, 
-                               Inkscape::Selection *selection, 
-                               guint flags,
-                               Transformation *daad )
+void on_selection_modified( Inkscape::Application */*inkscape*/,
+                            Inkscape::Selection *selection,
+                            guint /*flags*/,
+                            Transformation *daad )
 {
     int page = daad->getCurrentPage();
     daad->updateSelection((Inkscape::UI::Dialog::Transformation::PageType)page, selection);
@@ -71,33 +74,33 @@ void on_selection_modified ( Inkscape::Application *inkscape,
  *
  */
 Transformation::Transformation()
-    : Dialog ("dialogs.transformation", SP_VERB_DIALOG_TRANSFORM),
+    : UI::Widget::Panel ("", "/dialogs/transformation", SP_VERB_DIALOG_TRANSFORM),
       _page_move              (4, 2),
       _page_scale             (4, 2),
       _page_rotate            (4, 2),
       _page_skew              (4, 2),
       _page_transform         (3, 3),
-      _scalar_move_horizontal (_("_Horizontal"), _("Horizontal displacement (relative) or position (absolute)"), UNIT_TYPE_LINEAR, 
-                               "", "arrows_hor", &_units_move),
-      _scalar_move_vertical   (_("_Vertical"),  _("Vertical displacement (relative) or position (absolute)"), UNIT_TYPE_LINEAR, 
-                               "", "arrows_ver", &_units_move),
-      _scalar_scale_horizontal(_("_Width"), _("Horizontal size increment (absolute or percentage)"), UNIT_TYPE_DIMENSIONLESS, 
-                               "", "transform_scale_hor", &_units_scale),
-      _scalar_scale_vertical  (_("_Height"),  _("Vertical size increment (absolute or percentage)"), UNIT_TYPE_DIMENSIONLESS, 
-                               "", "transform_scale_ver", &_units_scale),
-      _scalar_rotate          (_("A_ngle"), _("Rotation angle (positive = counterclockwise)"), UNIT_TYPE_RADIAL, 
-                               "", "transform_rotate", &_units_rotate),
-      _scalar_skew_horizontal (_("_Horizontal"), _("Horizontal skew angle (positive = counterclockwise), or absolute displacement, or percentage displacement"), UNIT_TYPE_LINEAR, 
-                               "", "arrows_hor", &_units_skew),
-      _scalar_skew_vertical   (_("_Vertical"),  _("Vertical skew angle (positive = counterclockwise), or absolute displacement, or percentage displacement"),  UNIT_TYPE_LINEAR, 
-                               "", "arrows_ver", &_units_skew),
-
-      _scalar_transform_a     ("_A", _("Transformation matrix element A")),
-      _scalar_transform_b     ("_B", _("Transformation matrix element B")),
-      _scalar_transform_c     ("_C", _("Transformation matrix element C")),
-      _scalar_transform_d     ("_D", _("Transformation matrix element D")),
-      _scalar_transform_e     ("_E", _("Transformation matrix element E")),
-      _scalar_transform_f     ("_F", _("Transformation matrix element F")),
+      _scalar_move_horizontal (_("_Horizontal:"), _("Horizontal displacement (relative) or position (absolute)"), UNIT_TYPE_LINEAR,
+                               "", "transform-move-horizontal", &_units_move),
+      _scalar_move_vertical   (_("_Vertical:"),  _("Vertical displacement (relative) or position (absolute)"), UNIT_TYPE_LINEAR,
+                               "", "transform-move-vertical", &_units_move),
+      _scalar_scale_horizontal(_("_Width:"), _("Horizontal size (absolute or percentage of current)"), UNIT_TYPE_DIMENSIONLESS,
+                               "", "transform-scale-horizontal", &_units_scale),
+      _scalar_scale_vertical  (_("_Height:"),  _("Vertical size (absolute or percentage of current)"), UNIT_TYPE_DIMENSIONLESS,
+                               "", "transform-scale-vertical", &_units_scale),
+      _scalar_rotate          (_("A_ngle:"), _("Rotation angle (positive = counterclockwise)"), UNIT_TYPE_RADIAL,
+                               "", "transform-rotate", &_units_rotate),
+      _scalar_skew_horizontal (_("_Horizontal:"), _("Horizontal skew angle (positive = counterclockwise), or absolute displacement, or percentage displacement"), UNIT_TYPE_LINEAR,
+                               "", "transform-skew-horizontal", &_units_skew),
+      _scalar_skew_vertical   (_("_Vertical:"),  _("Vertical skew angle (positive = counterclockwise), or absolute displacement, or percentage displacement"),  UNIT_TYPE_LINEAR,
+                               "", "transform-skew-vertical", &_units_skew),
+
+      _scalar_transform_a     ("_A:", _("Transformation matrix element A")),
+      _scalar_transform_b     ("_B:", _("Transformation matrix element B")),
+      _scalar_transform_c     ("_C:", _("Transformation matrix element C")),
+      _scalar_transform_d     ("_D:", _("Transformation matrix element D")),
+      _scalar_transform_e     ("_E:", _("Transformation matrix element E")),
+      _scalar_transform_f     ("_F:", _("Transformation matrix element F")),
 
       _check_move_relative    (_("Rela_tive move"), _("Add the specified relative displacement to the current position; otherwise, edit the current absolute position directly")),
       _check_scale_proportional (_("Scale proportionally"), _("Preserve the width/height ratio of the scaled objects")),
@@ -105,12 +108,12 @@ Transformation::Transformation()
       _check_replace_matrix    (_("Edit c_urrent matrix"), _("Edit the current transform= matrix; otherwise, post-multiply transform= by this matrix"))
 
 {
-    // Top level vbox
-    Gtk::VBox *vbox = get_vbox();
-    vbox->set_spacing(0);
+    Gtk::Box *contents = _getContents();
+
+    contents->set_spacing(0);
 
     // Notebook for individual transformations
-    vbox->pack_start(_notebook, true, true);
+    contents->pack_start(_notebook, true, true);
 
     _notebook.append_page(_page_move, _("_Move"), true);
     layoutPageMove();
@@ -130,22 +133,32 @@ Transformation::Transformation()
     _notebook.signal_switch_page().connect(sigc::mem_fun(*this, &Transformation::onSwitchPage));
 
     // Apply separately
-    vbox->pack_start(_check_apply_separately, true, true);
-    _check_apply_separately.set_active(prefs_get_int_attribute_limited ("dialogs.transformation", "applyseparately", 0, 0, 1));
+    contents->pack_start(_check_apply_separately, true, true);
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    _check_apply_separately.set_active(prefs->getBool("/dialogs/transformation/applyseparately"));
     _check_apply_separately.signal_toggled().connect(sigc::mem_fun(*this, &Transformation::onApplySeparatelyToggled));
 
+    // make sure all spinbuttons activate Apply on pressing Enter
+      ((Gtk::Entry *) (_scalar_move_horizontal.getWidget()))->set_activates_default(true);
+      ((Gtk::Entry *) (_scalar_move_vertical.getWidget()))->set_activates_default(true);
+      ((Gtk::Entry *) (_scalar_scale_horizontal.getWidget()))->set_activates_default(true);
+      ((Gtk::Entry *) (_scalar_scale_vertical.getWidget()))->set_activates_default(true);
+      ((Gtk::Entry *) (_scalar_rotate.getWidget()))->set_activates_default(true);
+      ((Gtk::Entry *) (_scalar_skew_horizontal.getWidget()))->set_activates_default(true);
+      ((Gtk::Entry *) (_scalar_skew_vertical.getWidget()))->set_activates_default(true);
+
     updateSelection(PAGE_MOVE, _getSelection());
 
-    resetButton = add_button(Gtk::Stock::CLEAR, 0);
+    resetButton = addResponseButton(Gtk::Stock::CLEAR, 0);
     if (resetButton) {
-        tooltips.set_tip((*resetButton), _("Reset the values on the current tab to defaults"));
+        _tooltips.set_tip((*resetButton), _("Reset the values on the current tab to defaults"));
         resetButton->set_sensitive(true);
         resetButton->signal_clicked().connect(sigc::mem_fun(*this, &Transformation::onClear));
     }
 
-    applyButton = add_button(Gtk::Stock::APPLY,   Gtk::RESPONSE_APPLY);
+    applyButton = addResponseButton(Gtk::Stock::APPLY, Gtk::RESPONSE_APPLY);
     if (applyButton) {
-        tooltips.set_tip((*applyButton), _("Apply transformation to selection"));
+        _tooltips.set_tip((*applyButton), _("Apply transformation to selection"));
         applyButton->set_sensitive(false);
     }
 
@@ -162,17 +175,16 @@ Transformation::~Transformation()
 }
 
 
-
 /*########################################################################
 # U T I L I T Y
 ########################################################################*/
 
 void
-Transformation::present(Transformation::PageType page)
+Transformation::presentPage(Transformation::PageType page)
 {
     _notebook.set_current_page(page);
-    Gtk::Dialog::show();
-    Gtk::Dialog::present();
+    show();
+    present();
 }
 
 
@@ -187,6 +199,14 @@ void
 Transformation::layoutPageMove()
 {
     _units_move.setUnitType(UNIT_TYPE_LINEAR);
+    
+    // Setting default unit to document unit
+    SPDesktop *dt = getDesktop();
+    SPNamedView *nv = sp_desktop_namedview(dt);
+    if (nv->doc_units) {
+        _units_move.setUnit(nv->doc_units->abbr);
+    }
+    
     _scalar_move_horizontal.initScalar(-1e6, 1e6);
     _scalar_move_horizontal.setDigits(3);
     _scalar_move_horizontal.setIncrements(0.1, 1.0);
@@ -227,14 +247,14 @@ Transformation::layoutPageScale()
     _units_scale.setUnitType(UNIT_TYPE_LINEAR);
 
     _scalar_scale_horizontal.initScalar(-1e6, 1e6);
-    _scalar_scale_horizontal.setValue(0.0, "%");
+    _scalar_scale_horizontal.setValue(100.0, "%");
     _scalar_scale_horizontal.setDigits(3);
     _scalar_scale_horizontal.setIncrements(0.1, 1.0);
     _scalar_scale_horizontal.setAbsoluteIsIncrement(true);
     _scalar_scale_horizontal.setPercentageIsIncrement(true);
 
     _scalar_scale_vertical.initScalar(-1e6, 1e6);
-    _scalar_scale_vertical.setValue(0.0, "%");
+    _scalar_scale_vertical.setValue(100.0, "%");
     _scalar_scale_vertical.setDigits(3);
     _scalar_scale_vertical.setIncrements(0.1, 1.0);
     _scalar_scale_vertical.setAbsoluteIsIncrement(true);
@@ -429,29 +449,32 @@ Transformation::updateSelection(PageType page, Inkscape::Selection *selection)
         }
     }
 
-    set_response_sensitive(Gtk::RESPONSE_APPLY,
-                           selection && !selection->isEmpty());
+    setResponseSensitive(Gtk::RESPONSE_APPLY,
+                         selection && !selection->isEmpty());
 }
 
 void
-Transformation::onSwitchPage(GtkNotebookPage *page,
+Transformation::onSwitchPage(GtkNotebookPage */*page*/,
                                    guint pagenum)
 {
-    updateSelection((PageType)pagenum, SP_DT_SELECTION(SP_ACTIVE_DESKTOP));
+    updateSelection((PageType)pagenum, sp_desktop_selection(getDesktop()));
 }
 
+
 void
 Transformation::updatePageMove(Inkscape::Selection *selection)
 {
     if (selection && !selection->isEmpty()) {
         if (!_check_move_relative.get_active()) {
-
-            NR::Rect bbox = selection->bounds();
-            double x = bbox.min()[NR::X];
-            double y = bbox.min()[NR::Y];
-
-            _scalar_move_horizontal.setValue(x, "px");
-            _scalar_move_vertical.setValue(y, "px");
+            Geom::OptRect bbox = selection->bounds();
+            if (bbox) {
+                double x = bbox->min()[Geom::X];
+                double y = bbox->min()[Geom::Y];
+
+                double conversion = _units_move.getConversion("px");
+                _scalar_move_horizontal.setValue(x / conversion);
+                _scalar_move_vertical.setValue(y / conversion);
+            }
         } else {
             // do nothing, so you can apply the same relative move to many objects in turn
         }
@@ -465,13 +488,17 @@ void
 Transformation::updatePageScale(Inkscape::Selection *selection)
 {
     if (selection && !selection->isEmpty()) {
-        NR::Rect bbox = selection->bounds();
-        double w = bbox.extent(NR::X);
-        double h = bbox.extent(NR::Y);
-        _scalar_scale_horizontal.setHundredPercent(w);
-        _scalar_scale_vertical.setHundredPercent(h);
-        onScaleXValueChanged(); // to update x/y proportionality if switch is on
-        _page_scale.set_sensitive(true);
+        Geom::OptRect bbox = selection->bounds();
+        if (bbox) {
+            double w = bbox->dimensions()[Geom::X];
+            double h = bbox->dimensions()[Geom::Y];
+            _scalar_scale_horizontal.setHundredPercent(w);
+            _scalar_scale_vertical.setHundredPercent(h);
+            onScaleXValueChanged(); // to update x/y proportionality if switch is on
+            _page_scale.set_sensitive(true);
+        } else {
+            _page_scale.set_sensitive(false);
+        }
     } else {
         _page_scale.set_sensitive(false);
     }
@@ -491,7 +518,16 @@ void
 Transformation::updatePageSkew(Inkscape::Selection *selection)
 {
     if (selection && !selection->isEmpty()) {
-        _page_skew.set_sensitive(true);
+        Geom::OptRect bbox = selection->bounds();
+        if (bbox) {
+            double w = bbox->dimensions()[Geom::X];
+            double h = bbox->dimensions()[Geom::Y];
+            _scalar_skew_vertical.setHundredPercent(w);
+            _scalar_skew_horizontal.setHundredPercent(h);
+            _page_skew.set_sensitive(true);
+        } else {
+            _page_skew.set_sensitive(false);
+        }
     } else {
         _page_skew.set_sensitive(false);
     }
@@ -502,9 +538,9 @@ Transformation::updatePageTransform(Inkscape::Selection *selection)
 {
     if (selection && !selection->isEmpty()) {
         if (_check_replace_matrix.get_active()) {
-            NR::Matrix current (SP_ITEM(selection->itemList()->data)->transform); // take from the first item in selection
+            Geom::Matrix current (SP_ITEM(selection->itemList()->data)->transform); // take from the first item in selection
 
-            NR::Matrix new_displayed = current;
+            Geom::Matrix new_displayed = current;
 
             _scalar_transform_a.setValue(new_displayed[0]);
             _scalar_transform_b.setValue(new_displayed[1]);
@@ -564,7 +600,7 @@ Transformation::_apply()
     }
 
     //Let's play with never turning this off
-    //set_response_sensitive(Gtk::RESPONSE_APPLY, false);
+    //setResponseSensitive(Gtk::RESPONSE_APPLY, false);
 }
 
 void
@@ -573,15 +609,86 @@ Transformation::applyPageMove(Inkscape::Selection *selection)
     double x = _scalar_move_horizontal.getValue("px");
     double y = _scalar_move_vertical.getValue("px");
 
-    if (_check_move_relative.get_active()) {
-        sp_selection_move_relative(selection, x, y);
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    if (!prefs->getBool("/dialogs/transformation/applyseparately")) {
+        // move selection as a whole
+        if (_check_move_relative.get_active()) {
+            sp_selection_move_relative(selection, x, y);
+        } else {
+            Geom::OptRect bbox = selection->bounds();
+            if (bbox) {
+                sp_selection_move_relative(selection,
+                                           x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]);
+            }
+        }
     } else {
-        NR::Rect bbox = selection->bounds();
-        sp_selection_move_relative(selection,
-            x - bbox.min()[NR::X], y - bbox.min()[NR::Y]);
+
+        if (_check_move_relative.get_active()) {
+            // shift each object relatively to the previous one
+            using Inkscape::Util::GSListConstIterator;
+            std::list<SPItem *> selected;
+            selected.insert<GSListConstIterator<SPItem *> >(selected.end(), selection->itemList(), NULL);
+            if (selected.empty()) return;
+
+            if (fabs(x) > 1e-6) {
+                std::vector< BBoxSort  > sorted;
+                for (std::list<SPItem *>::iterator it(selected.begin());
+                     it != selected.end();
+                     ++it)
+                {
+                    Geom::OptRect bbox = sp_item_bbox_desktop(*it);
+                    if (bbox) {
+                        sorted.push_back(BBoxSort(*it, *bbox, Geom::X, x > 0? 1. : 0., x > 0? 0. : 1.));
+                    }
+                }
+                //sort bbox by anchors
+                std::sort(sorted.begin(), sorted.end());
+
+                double move = x;
+                for ( std::vector<BBoxSort> ::iterator it (sorted.begin());
+                      it < sorted.end();
+                      it ++ )
+                {
+                    sp_item_move_rel(it->item, Geom::Translate(move, 0));
+                    // move each next object by x relative to previous
+                    move += x;
+                }
+            }
+            if (fabs(y) > 1e-6) {
+                std::vector< BBoxSort  > sorted;
+                for (std::list<SPItem *>::iterator it(selected.begin());
+                     it != selected.end();
+                     ++it)
+                {
+                    Geom::OptRect bbox = sp_item_bbox_desktop(*it);
+                    if (bbox) {
+                        sorted.push_back(BBoxSort(*it, *bbox, Geom::Y, y > 0? 1. : 0., y > 0? 0. : 1.));
+                    }
+                }
+                //sort bbox by anchors
+                std::sort(sorted.begin(), sorted.end());
+
+                double move = y;
+                for ( std::vector<BBoxSort> ::iterator it (sorted.begin());
+                      it < sorted.end();
+                      it ++ )
+                {
+                    sp_item_move_rel(it->item, Geom::Translate(0, move));
+                    // move each next object by x relative to previous
+                    move += y;
+                }
+            }
+        } else {
+            Geom::OptRect bbox = selection->bounds();
+            if (bbox) {
+                sp_selection_move_relative(selection,
+                                           x - bbox->min()[Geom::X], y - bbox->min()[Geom::Y]);
+            }
+        }
     }
 
-    sp_document_done ( SP_DT_DOCUMENT (selection->desktop()) );
+    sp_document_done ( sp_desktop_document (selection->desktop()) , SP_VERB_DIALOG_TRANSFORM,
+                       _("Move"));
 }
 
 void
@@ -590,49 +697,55 @@ Transformation::applyPageScale(Inkscape::Selection *selection)
     double scaleX = _scalar_scale_horizontal.getValue("px");
     double scaleY = _scalar_scale_vertical.getValue("px");
 
-    if (prefs_get_int_attribute_limited ("dialogs.transformation", "applyseparately", 0, 0, 1) == 1) {
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    if (prefs->getBool("/dialogs/transformation/applyseparately")) {
         for (GSList const *l = selection->itemList(); l != NULL; l = l->next) {
             SPItem *item = SP_ITEM(l->data);
-            NR::Rect  bbox (sp_item_bbox_desktop(item));
-            NR::scale scale (0,0);
-            // the values are increments! 
+            Geom::Scale scale (0,0);
+            // the values are increments!
             if (_units_scale.isAbsolute()) {
-                double new_width = bbox.extent(NR::X) + scaleX;
-                if (new_width < 1e-6) new_width = 1e-6; // not 0, as this would result in a nasty no-bbox object
-                double new_height = bbox.extent(NR::Y) + scaleY;
-                if (new_height < 1e-6) new_height = 1e-6;
-                scale = NR::scale(new_width / bbox.extent(NR::X), new_height / bbox.extent(NR::Y));
+                Geom::OptRect bbox(sp_item_bbox_desktop(item));
+                if (bbox) {
+                    double new_width = scaleX;
+                    if (fabs(new_width) < 1e-6) new_width = 1e-6; // not 0, as this would result in a nasty no-bbox object
+                    double new_height = scaleY;
+                    if (fabs(new_height) < 1e-6) new_height = 1e-6;
+                    scale = Geom::Scale(new_width / bbox->dimensions()[Geom::X], new_height / bbox->dimensions()[Geom::Y]);
+                }
             } else {
-                double new_width = 100 + scaleX;
-                if (new_width < 1e-6) new_width = 1e-6;
-                double new_height = 100 + scaleY;
-                if (new_height < 1e-6) new_height = 1e-6;
-                scale = NR::scale(new_width / 100.0, new_height / 100.0);
+                double new_width = scaleX;
+                if (fabs(new_width) < 1e-6) new_width = 1e-6;
+                double new_height = scaleY;
+                if (fabs(new_height) < 1e-6) new_height = 1e-6;
+                scale = Geom::Scale(new_width / 100.0, new_height / 100.0);
             }
             sp_item_scale_rel (item, scale);
         }
     } else {
-        NR::Rect  bbox(selection->bounds());
-        NR::Point center(bbox.midpoint());
-        NR::scale scale (0,0);
-        // the values are increments!
-        if (_units_scale.isAbsolute()) {
-            double new_width = bbox.extent(NR::X) + scaleX;
-            if (new_width < 1e-6) new_width = 1e-6;
-            double new_height = bbox.extent(NR::Y) + scaleY;
-            if (new_height < 1e-6) new_height = 1e-6;
-            scale = NR::scale(new_width / bbox.extent(NR::X), new_height / bbox.extent(NR::Y));
-        } else {
-            double new_width = 100 + scaleX;
-            if (new_width < 1e-6) new_width = 1e-6;
-            double new_height = 100 + scaleY;
-            if (new_height < 1e-6) new_height = 1e-6;
-            scale = NR::scale(new_width / 100.0, new_height / 100.0);
+        Geom::OptRect bbox(selection->bounds());
+        if (bbox) {
+            Geom::Point center(bbox->midpoint()); // use rotation center?
+            Geom::Scale scale (0,0);
+            // the values are increments!
+            if (_units_scale.isAbsolute()) {
+                double new_width = scaleX;
+                if (fabs(new_width) < 1e-6) new_width = 1e-6;
+                double new_height = scaleY;
+                if (fabs(new_height) < 1e-6) new_height = 1e-6;
+                scale = Geom::Scale(new_width / bbox->dimensions()[Geom::X], new_height / bbox->dimensions()[Geom::Y]);
+            } else {
+                double new_width = scaleX;
+                if (fabs(new_width) < 1e-6) new_width = 1e-6;
+                double new_height = scaleY;
+                if (fabs(new_height) < 1e-6) new_height = 1e-6;
+                scale = Geom::Scale(new_width / 100.0, new_height / 100.0);
+            }
+            sp_selection_scale_relative(selection, center, scale);
         }
-        sp_selection_scale_relative(selection, center, scale);
     }
 
-    sp_document_done(SP_DT_DOCUMENT(selection->desktop()));
+    sp_document_done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM,
+                     _("Scale"));
 }
 
 void
@@ -640,25 +753,28 @@ Transformation::applyPageRotate(Inkscape::Selection *selection)
 {
     double angle = _scalar_rotate.getValue("deg");
 
-    if (prefs_get_int_attribute_limited ("dialogs.transformation", "applyseparately", 0, 0, 1) == 1) {
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    if (prefs->getBool("/dialogs/transformation/applyseparately")) {
         for (GSList const *l = selection->itemList(); l != NULL; l = l->next) {
             SPItem *item = SP_ITEM(l->data);
-            sp_item_rotate_rel(item, NR::rotate (angle*M_PI/180.0));
+            sp_item_rotate_rel(item, Geom::Rotate (angle*M_PI/180.0));
         }
     } else {
-        NR::Rect  bbox   = selection->bounds();
-        NR::Point center = bbox.midpoint();
-        sp_selection_rotate_relative(selection, center, angle);
+        boost::optional<Geom::Point> center = selection->center();
+        if (center) {
+            sp_selection_rotate_relative(selection, *center, angle);
+        }
     }
 
-    sp_document_done(SP_DT_DOCUMENT(selection->desktop()));
-
+    sp_document_done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM,
+                     _("Rotate"));
 }
 
 void
 Transformation::applyPageSkew(Inkscape::Selection *selection)
 {
-    if (prefs_get_int_attribute_limited ("dialogs.transformation", "applyseparately", 0, 0, 1) == 1) {
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    if (prefs->getBool("/dialogs/transformation/applyseparately")) {
         for (GSList const *l = selection->itemList(); l != NULL; l = l->next) {
             SPItem *item = SP_ITEM(l->data);
 
@@ -675,36 +791,42 @@ Transformation::applyPageSkew(Inkscape::Selection *selection)
             } else { // absolute displacement
                 double skewX = _scalar_skew_horizontal.getValue("px");
                 double skewY = _scalar_skew_vertical.getValue("px");
-                NR::Rect bbox(sp_item_bbox_desktop(item));
-                double width = bbox.dimensions()[NR::X];
-                double height = bbox.dimensions()[NR::Y];
-                sp_item_skew_rel (item, skewX/height, skewY/width);
+                Geom::OptRect bbox(sp_item_bbox_desktop(item));
+                if (bbox) {
+                    double width = bbox->dimensions()[Geom::X];
+                    double height = bbox->dimensions()[Geom::Y];
+                    sp_item_skew_rel (item, skewX/height, skewY/width);
+                }
             }
         }
     } else { // transform whole selection
-        NR::Rect bbox = selection->bounds();
-        double width  = bbox.max()[NR::X] - bbox.min()[NR::X];
-        double height = bbox.max()[NR::Y] - bbox.min()[NR::Y];
-        NR::Point center = bbox.midpoint();
-
-        if (!_units_skew.isAbsolute()) { // percentage
-            double skewX = _scalar_skew_horizontal.getValue("%");
-            double skewY = _scalar_skew_vertical.getValue("%");
-            sp_selection_skew_relative(selection, center, 0.01*skewX, 0.01*skewY);
-        } else if (_units_skew.isRadial()) { //deg or rad
-            double angleX = _scalar_skew_horizontal.getValue("rad");
-            double angleY = _scalar_skew_vertical.getValue("rad");
-            double skewX = tan(-angleX);
-            double skewY = tan(angleY);
-            sp_selection_skew_relative(selection, center, skewX, skewY);
-        } else { // absolute displacement
-            double skewX = _scalar_skew_horizontal.getValue("px");
-            double skewY = _scalar_skew_vertical.getValue("px");
-            sp_selection_skew_relative(selection, center, skewX/height, skewY/width);
+        Geom::OptRect bbox = selection->bounds();
+        boost::optional<Geom::Point> center = selection->center();
+
+        if ( bbox && center ) {
+            double width  = bbox->dimensions()[Geom::X];
+            double height = bbox->dimensions()[Geom::Y];
+
+            if (!_units_skew.isAbsolute()) { // percentage
+                double skewX = _scalar_skew_horizontal.getValue("%");
+                double skewY = _scalar_skew_vertical.getValue("%");
+                sp_selection_skew_relative(selection, *center, 0.01*skewX, 0.01*skewY);
+            } else if (_units_skew.isRadial()) { //deg or rad
+                double angleX = _scalar_skew_horizontal.getValue("rad");
+                double angleY = _scalar_skew_vertical.getValue("rad");
+                double skewX = tan(-angleX);
+                double skewY = tan(angleY);
+                sp_selection_skew_relative(selection, *center, skewX, skewY);
+            } else { // absolute displacement
+                double skewX = _scalar_skew_horizontal.getValue("px");
+                double skewY = _scalar_skew_vertical.getValue("px");
+                sp_selection_skew_relative(selection, *center, skewX/height, skewY/width);
+            }
         }
     }
 
-    sp_document_done(SP_DT_DOCUMENT(selection->desktop()));
+    sp_document_done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM,
+                     _("Skew"));
 }
 
 
@@ -718,18 +840,20 @@ Transformation::applyPageTransform(Inkscape::Selection *selection)
     double e = _scalar_transform_e.getValue();
     double f = _scalar_transform_f.getValue();
 
-    NR::Matrix displayed(a, b, c, d, e, f);
+    Geom::Matrix displayed(a, b, c, d, e, f);
 
     if (_check_replace_matrix.get_active()) {
         for (GSList const *l = selection->itemList(); l != NULL; l = l->next) {
             SPItem *item = SP_ITEM(l->data);
             sp_item_set_item_transform(item, displayed);
+            SP_OBJECT(item)->updateRepr();
         }
     } else {
         sp_selection_apply_affine(selection, displayed); // post-multiply each object's transform
     }
 
-    sp_document_done(SP_DT_DOCUMENT(selection->desktop()));
+    sp_document_done(sp_desktop_document(selection->desktop()), SP_VERB_DIALOG_TRANSFORM,
+                     _("Edit transformation matrix"));
 }
 
 
@@ -743,7 +867,7 @@ Transformation::applyPageTransform(Inkscape::Selection *selection)
 void
 Transformation::onMoveValueChanged()
 {
-    set_response_sensitive(Gtk::RESPONSE_APPLY, true);
+    setResponseSensitive(Gtk::RESPONSE_APPLY, true);
 }
 
 void
@@ -757,22 +881,25 @@ Transformation::onMoveRelativeToggled()
     double x = _scalar_move_horizontal.getValue("px");
     double y = _scalar_move_vertical.getValue("px");
 
+    double conversion = _units_move.getConversion("px");
+
     //g_message("onMoveRelativeToggled: %f, %f px\n", x, y);
 
-    NR::Rect bbox = selection->bounds();
+    Geom::OptRect bbox = selection->bounds();
 
-    if (_check_move_relative.get_active()) {
-        // From absolute to relative
-        _scalar_move_horizontal.setValue(x - bbox.min()[NR::X], "px");
-        _scalar_move_vertical.setValue(  y - bbox.min()[NR::Y], "px");
-    } else {
-        // From relative to absolute
-        _scalar_move_horizontal.setValue(bbox.min()[NR::X] + x, "px");
-        _scalar_move_vertical.setValue(  bbox.min()[NR::Y] + y, "px");
+    if (bbox) {
+        if (_check_move_relative.get_active()) {
+            // From absolute to relative
+            _scalar_move_horizontal.setValue((x - bbox->min()[Geom::X]) / conversion);
+            _scalar_move_vertical.setValue((  y - bbox->min()[Geom::Y]) / conversion);
+        } else {
+            // From relative to absolute
+            _scalar_move_horizontal.setValue((bbox->min()[Geom::X] + x) / conversion);
+            _scalar_move_vertical.setValue((  bbox->min()[Geom::Y] + y) / conversion);
+        }
     }
 
-
-    set_response_sensitive(Gtk::RESPONSE_APPLY, true);
+    setResponseSensitive(Gtk::RESPONSE_APPLY, true);
 }
 
 void
@@ -783,7 +910,7 @@ Transformation::onScaleXValueChanged()
         return;
     }
 
-    set_response_sensitive(Gtk::RESPONSE_APPLY, true);
+    setResponseSensitive(Gtk::RESPONSE_APPLY, true);
 
     if (_check_scale_proportional.get_active()) {
         if (!_units_scale.isAbsolute()) { // percentage, just copy over
@@ -803,7 +930,7 @@ Transformation::onScaleYValueChanged()
         return;
     }
 
-    set_response_sensitive(Gtk::RESPONSE_APPLY, true);
+    setResponseSensitive(Gtk::RESPONSE_APPLY, true);
 
     if (_check_scale_proportional.get_active()) {
         if (!_units_scale.isAbsolute()) { // percentage, just copy over
@@ -818,13 +945,13 @@ Transformation::onScaleYValueChanged()
 void
 Transformation::onRotateValueChanged()
 {
-    set_response_sensitive(Gtk::RESPONSE_APPLY, true);
+    setResponseSensitive(Gtk::RESPONSE_APPLY, true);
 }
 
 void
 Transformation::onSkewValueChanged()
 {
-    set_response_sensitive(Gtk::RESPONSE_APPLY, true);
+    setResponseSensitive(Gtk::RESPONSE_APPLY, true);
 }
 
 void
@@ -843,7 +970,7 @@ Transformation::onTransformValueChanged()
     //          a, b, c, d, e ,f);
     */
 
-    set_response_sensitive(Gtk::RESPONSE_APPLY, true);
+    setResponseSensitive(Gtk::RESPONSE_APPLY, true);
 }
 
 void
@@ -861,10 +988,10 @@ Transformation::onReplaceMatrixToggled()
     double e = _scalar_transform_e.getValue();
     double f = _scalar_transform_f.getValue();
 
-    NR::Matrix displayed (a, b, c, d, e, f);
-    NR::Matrix current (SP_ITEM(selection->itemList()->data)->transform); // take from the first item in selection
+    Geom::Matrix displayed (a, b, c, d, e, f);
+    Geom::Matrix current = SP_ITEM(selection->itemList()->data)->transform; // take from the first item in selection
 
-    NR::Matrix new_displayed;
+    Geom::Matrix new_displayed;
     if (_check_replace_matrix.get_active()) {
         new_displayed = current;
     } else {
@@ -898,9 +1025,11 @@ Transformation::onClear()
             _scalar_move_horizontal.setValue(0);
             _scalar_move_vertical.setValue(0);
         } else {
-            NR::Rect bbox = selection->bounds();
-            _scalar_move_horizontal.setValue(bbox.min()[NR::X], "px");
-            _scalar_move_vertical.setValue(bbox.min()[NR::Y], "px");
+            Geom::OptRect bbox = selection->bounds();
+            if (bbox) {
+                _scalar_move_horizontal.setValue(bbox->min()[Geom::X], "px");
+                _scalar_move_vertical.setValue(bbox->min()[Geom::Y], "px");
+            }
         }
         break;
     }
@@ -909,8 +1038,8 @@ Transformation::onClear()
         break;
     }
     case PAGE_SCALE: {
-        _scalar_scale_horizontal.setValue(0);
-        _scalar_scale_vertical.setValue(0);
+        _scalar_scale_horizontal.setValue(100, "%");
+        _scalar_scale_vertical.setValue(100, "%");
         break;
     }
     case PAGE_SKEW: {
@@ -933,7 +1062,8 @@ Transformation::onClear()
 void
 Transformation::onApplySeparatelyToggled()
 {
-    prefs_set_int_attribute ("dialogs.transformation", "applyseparately", _check_apply_separately.get_active()? 1 : 0);
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    prefs->setBool("/dialogs/transformation/applyseparately", _check_apply_separately.get_active());
 }
 
 
@@ -941,8 +1071,6 @@ Transformation::onApplySeparatelyToggled()
 } // namespace UI
 } // namespace Inkscape
 
-
-
 /*
   Local Variables:
   mode:c++