Code

move shape_editor from node context to the parent class, event context
[inkscape.git] / src / desktop.cpp
index 27f7179eda170c3fe3626e845afc6cc162508ffb..8b60291ef36c8c39df023a0bc1ee2037acaf3c78 100644 (file)
@@ -57,6 +57,7 @@
 #include <sigc++/functors/mem_fun.h>
 #include <gtkmm.h>
 
+#include <2geom/rect.h>
 #include "macros.h"
 #include "inkscape-private.h"
 #include "desktop.h"
@@ -69,7 +70,7 @@
 #include "sp-namedview.h"
 #include "color.h"
 #include "sp-item-group.h"
-#include "prefs-utils.h"
+#include "preferences.h"
 #include "object-hierarchy.h"
 #include "helper/units.h"
 #include "display/canvas-arena.h"
@@ -79,7 +80,6 @@
 #include "display/sp-canvas-util.h"
 #include "display/canvas-temporary-item-list.h"
 #include "display/snap-indicator.h"
-#include "libnr/nr-rect-ops.h"
 #include "ui/dialog/dialog-manager.h"
 #include "xml/repr.h"
 #include "message-context.h"
@@ -133,6 +133,7 @@ SPDesktop::SPDesktop() :
     page( 0 ),
     page_border( 0 ),
     current( 0 ),
+    _focusMode(false),
     zooms_past( 0 ),
     zooms_future( 0 ),
     dkey( 0 ),
@@ -155,7 +156,7 @@ SPDesktop::SPDesktop() :
     _active( false ),
     _w2d(),
     _d2w(),
-    _doc2dt( NR::Matrix(NR::scale(1, -1)) ),
+    _doc2dt( Geom::Scale(1, -1) ),
     grids_visible( false )
 {
     _d2w.setIdentity();
@@ -169,10 +170,11 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
 {
     // Temporary workaround for link order issues:
     Inkscape::DeviceManager::getManager().getDevices();
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
 
     _guides_message_context = new Inkscape::MessageContext(const_cast<Inkscape::MessageStack*>(messageStack()));
 
-    current = sp_repr_css_attr_inherited (inkscape_get_repr (INKSCAPE, "desktop"), "style");
+    current = prefs->getStyle("/desktop/style");
 
     namedview = nv;
     canvas = aCanvas;
@@ -204,7 +206,7 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
     g_signal_connect (G_OBJECT (main), "event", G_CALLBACK (sp_desktop_root_handler), this);
 
     table = sp_canvas_item_new (main, SP_TYPE_CTRLRECT, NULL);
-    SP_CTRLRECT(table)->setRectangle(NR::Rect(Geom::Point(-80000, -80000), Geom::Point(80000, 80000)));
+    SP_CTRLRECT(table)->setRectangle(Geom::Rect(Geom::Point(-80000, -80000), Geom::Point(80000, 80000)));
     SP_CTRLRECT(table)->setColor(0x00000000, true, 0x00000000);
     sp_canvas_item_move_to_z (table, 0);
 
@@ -215,9 +217,9 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
     drawing = sp_canvas_item_new (main, SP_TYPE_CANVAS_ARENA, NULL);
     g_signal_connect (G_OBJECT (drawing), "arena_event", G_CALLBACK (_arena_handler), this);
 
-    SP_CANVAS_ARENA (drawing)->arena->delta = prefs_get_double_attribute ("options.cursortolerance", "value", 1.0); // default is 1 px
+    SP_CANVAS_ARENA (drawing)->arena->delta = prefs->getDouble("/options/cursortolerance/value", 1.0); // default is 1 px
 
-    if (prefs_get_int_attribute("options.startmode", "outline", 0)) {
+    if (prefs->getBool("/options/startmode/outline")) {
         // Start in outline mode
         setDisplayModeOutline();
     } else {
@@ -237,12 +239,12 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
      * call "set" instead of "push".  Can we assume that there is only one
      * context ever?
      */
-    push_event_context (SP_TYPE_SELECT_CONTEXT, "tools.select", SP_EVENT_CONTEXT_STATIC);
+    push_event_context (SP_TYPE_SELECT_CONTEXT, "/tools/select", SP_EVENT_CONTEXT_STATIC);
 
     // display rect and zoom are now handled in sp_desktop_widget_realize()
 
-    NR::Rect const d(Geom::Point(0.0, 0.0),
-                     Geom::Point(sp_document_width(document), sp_document_height(document)));
+    Geom::Rect const d(Geom::Point(0.0, 0.0),
+                       Geom::Point(sp_document_width(document), sp_document_height(document)));
 
     SP_CTRLRECT(page)->setRectangle(d);
     SP_CTRLRECT(page_border)->setRectangle(d);
@@ -339,6 +341,11 @@ void SPDesktop::destroy()
         temporary_item_list = NULL;
     }
 
+    if (selection) {
+        delete selection;
+        selection = NULL;
+    }
+
     namedview->hide(this);
 
     _activate_connection.disconnect();
@@ -527,8 +534,8 @@ bool SPDesktop::isLayer(SPObject *object) const {
  */
 bool SPDesktop::isWithinViewport (SPItem *item) const
 {
-    NR::Rect const viewport = get_display_area();
-    boost::optional<NR::Rect> const bbox = sp_item_bbox_desktop(item);
+    Geom::Rect const viewport = get_display_area();
+    Geom::OptRect const bbox = sp_item_bbox_desktop(item);
     if (bbox) {
         return viewport.contains(*bbox);
     } else {
@@ -607,8 +614,7 @@ SPDesktop::set_event_context (GtkType type, const gchar *config)
         g_object_unref (G_OBJECT (ec));
     }
 
-    Inkscape::XML::Node *repr = (config) ? inkscape_get_repr (_inkscape, config) : NULL;
-    ec = sp_event_context_new (type, this, repr, SP_EVENT_CONTEXT_STATIC);
+    ec = sp_event_context_new (type, this, config, SP_EVENT_CONTEXT_STATIC);
     ec->next = event_context;
     event_context = ec;
     sp_event_context_activate (ec);
@@ -622,7 +628,6 @@ void
 SPDesktop::push_event_context (GtkType type, const gchar *config, unsigned int key)
 {
     SPEventContext *ref, *ec;
-    Inkscape::XML::Node *repr;
 
     if (event_context && event_context->key == key) return;
     ref = event_context;
@@ -635,8 +640,7 @@ SPDesktop::push_event_context (GtkType type, const gchar *config, unsigned int k
     }
 
     if (event_context) sp_event_context_deactivate (event_context);
-    repr = (config) ? inkscape_get_repr (INKSCAPE, config) : NULL;
-    ec = sp_event_context_new (type, this, repr, key);
+    ec = sp_event_context_new (type, this, config, key);
     ec->next = event_context;
     event_context = ec;
     sp_event_context_activate (ec);
@@ -692,15 +696,15 @@ SPDesktop::point() const
     Geom::Point pw = sp_canvas_window_to_world (canvas, p);
     p = w2d(pw);
 
-    NR::Rect const r = canvas->getViewbox();
+    Geom::Rect const r = canvas->getViewbox();
 
     Geom::Point r0 = w2d(r.min());
     Geom::Point r1 = w2d(r.max());
 
-    if (p[NR::X] >= r0[NR::X] &&
-        p[NR::X] <= r1[NR::X] &&
-        p[NR::Y] >= r1[NR::Y] &&
-        p[NR::Y] <= r0[NR::Y])
+    if (p[Geom::X] >= r0[Geom::X] &&
+        p[Geom::X] <= r1[Geom::X] &&
+        p[Geom::Y] >= r1[Geom::Y] &&
+        p[Geom::Y] <= r0[Geom::Y])
     {
         return p;
     } else {
@@ -714,13 +718,13 @@ SPDesktop::point() const
 void
 SPDesktop::push_current_zoom (GList **history)
 {
-    NR::Rect const area = get_display_area();
+    Geom::Rect const area = get_display_area();
 
     NRRect *old_zoom = g_new(NRRect, 1);
-    old_zoom->x0 = area.min()[NR::X];
-    old_zoom->x1 = area.max()[NR::X];
-    old_zoom->y0 = area.min()[NR::Y];
-    old_zoom->y1 = area.max()[NR::Y];
+    old_zoom->x0 = area.min()[Geom::X];
+    old_zoom->x1 = area.max()[Geom::X];
+    old_zoom->y0 = area.min()[Geom::Y];
+    old_zoom->y1 = area.max()[Geom::Y];
     if ( *history == NULL
          || !( ( ((NRRect *) ((*history)->data))->x0 == old_zoom->x0 ) &&
                ( ((NRRect *) ((*history)->data))->x1 == old_zoom->x1 ) &&
@@ -750,14 +754,16 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double
     double const cx = 0.5 * (x0 + x1);
     double const cy = 0.5 * (y0 + y1);
 
-    NR::Rect const viewbox = NR::expand(canvas->getViewbox(), border);
+    // FIXME: This 2geom idiom doesn't allow us to declare dbox const
+    Geom::Rect viewbox = canvas->getViewbox();
+    viewbox.expandBy(-border);
 
     double scale = _d2w.descrim();
     double newscale;
-    if (((x1 - x0) * viewbox.dimensions()[NR::Y]) > ((y1 - y0) * viewbox.dimensions()[NR::X])) {
-        newscale = viewbox.dimensions()[NR::X] / (x1 - x0);
+    if (((x1 - x0) * viewbox.dimensions()[Geom::Y]) > ((y1 - y0) * viewbox.dimensions()[Geom::X])) {
+        newscale = viewbox.dimensions()[Geom::X] / (x1 - x0);
     } else {
-        newscale = viewbox.dimensions()[NR::Y] / (y1 - y0);
+        newscale = viewbox.dimensions()[Geom::Y] / (y1 - y0);
     }
 
     newscale = CLAMP(newscale, SP_DESKTOP_ZOOM_MIN, SP_DESKTOP_ZOOM_MAX); // unit: 'screen pixels' per 'document pixels'
@@ -765,15 +771,15 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double
     int clear = FALSE;
     if (!NR_DF_TEST_CLOSE (newscale, scale, 1e-4 * scale)) {
         /* Set zoom factors */
-        _d2w = NR::Matrix(NR::scale(newscale, -newscale));
-        _w2d = NR::Matrix(NR::scale(1/newscale, 1/-newscale));
+        _d2w = Geom::Scale(newscale, -newscale);
+        _w2d = Geom::Scale(1/newscale, 1/-newscale);
         sp_canvas_item_affine_absolute(SP_CANVAS_ITEM(main), _d2w);
         clear = TRUE;
     }
 
     /* Calculate top left corner (in document pixels) */
-    x0 = cx - 0.5 * viewbox.dimensions()[NR::X] / newscale;
-    y1 = cy + 0.5 * viewbox.dimensions()[NR::Y] / newscale;
+    x0 = cx - 0.5 * viewbox.dimensions()[Geom::X] / newscale;
+    y1 = cy + 0.5 * viewbox.dimensions()[Geom::Y] / newscale;
 
     /* Scroll */
     sp_canvas_scroll_to (canvas, x0 * newscale - border, y1 * -newscale - border, clear);
@@ -786,22 +792,22 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double
     _widget->updateZoom();
 }
 
-void SPDesktop::set_display_area(NR::Rect const &a, NR::Coord b, bool log)
+void SPDesktop::set_display_area(Geom::Rect const &a, Geom::Coord b, bool log)
 {
-    set_display_area(a.min()[NR::X], a.min()[NR::Y], a.max()[NR::X], a.max()[NR::Y], b, log);
+    set_display_area(a.min()[Geom::X], a.min()[Geom::Y], a.max()[Geom::X], a.max()[Geom::Y], b, log);
 }
 
 /**
  * Return viewbox dimensions.
  */
-NR::Rect SPDesktop::get_display_area() const
+Geom::Rect SPDesktop::get_display_area() const
 {
-    NR::Rect const viewbox = canvas->getViewbox();
+    Geom::Rect const viewbox = canvas->getViewbox();
 
     double const scale = _d2w[0];
 
-    return NR::Rect(Geom::Point(viewbox.min()[NR::X] / scale, viewbox.max()[NR::Y] / -scale),
-                    Geom::Point(viewbox.max()[NR::X] / scale, viewbox.min()[NR::Y] / -scale));
+    return Geom::Rect(Geom::Point(viewbox.min()[Geom::X] / scale, viewbox.max()[Geom::Y] / -scale),
+                      Geom::Point(viewbox.max()[Geom::X] / scale, viewbox.min()[Geom::Y] / -scale));
 }
 
 /**
@@ -854,6 +860,101 @@ SPDesktop::next_zoom()
     zooms_future = g_list_remove (zooms_future, ((NRRect *) zooms_future->data));
 }
 
+#include "tools-switch.h"
+#include "node-context.h"
+#include "shape-editor.h"
+#include "nodepath.h"
+
+/** \brief  Performs a quick zoom into what the user is working on
+    \param  enable  Whether we're going in or out of quick zoom
+
+*/
+void 
+SPDesktop::zoom_quick (bool enable)
+{
+    if (enable == _quick_zoom_enabled) {
+        return;
+    }
+
+    if (enable == true) {
+        _quick_zoom_stored_area = get_display_area();
+        bool zoomed = false;
+
+        if (!zoomed) {
+            SPItem * singleItem = selection->singleItem();
+            if (singleItem != NULL && tools_isactive(this, TOOLS_NODES)) {
+
+                Inkscape::NodePath::Path * nodepath = event_context->shape_editor->get_nodepath();
+                // printf("I've got a nodepath, crazy\n");
+
+                Geom::Rect nodes;
+                bool firstnode = true;
+
+                if (nodepath->selected) {
+                    for (GList *spl = nodepath->subpaths; spl != NULL; spl = spl->next) {
+                       Inkscape::NodePath::SubPath *subpath = (Inkscape::NodePath::SubPath *) spl->data;
+                        for (GList *nl = subpath->nodes; nl != NULL; nl = nl->next) {
+                           Inkscape::NodePath::Node *node = (Inkscape::NodePath::Node *) nl->data;
+                            if (node->selected) {
+                                // printf("\tSelected node\n");
+                                if (firstnode) {
+                                    nodes = Geom::Rect(node->pos, node->pos);
+                                    firstnode = false;
+                                } else {
+                                    nodes.expandTo(node->pos);
+                                }
+
+                                if (node->p.other != NULL) {
+                                    /* Include previous node pos */
+                                    nodes.expandTo(node->p.other->pos);
+
+                                    /* Include previous handle */
+                                    if (!sp_node_side_is_line(node, &node->p)) {
+                                        nodes.expandTo(node->p.pos);
+                                    }
+                                }
+
+                                if (node->n.other != NULL) {
+                                    /* Include previous node pos */
+                                    nodes.expandTo(node->n.other->pos);
+
+                                    /* Include previous handle */
+                                    if (!sp_node_side_is_line(node, &node->n)) {
+                                        nodes.expandTo(node->n.pos);
+                                    }
+                                }
+                            }
+                        }
+                    }
+
+                    if (!firstnode && nodes.area() * 2.0 < _quick_zoom_stored_area.area()) {
+                        set_display_area(nodes, 10);
+                        zoomed = true;
+                    }
+                }
+            }
+        }
+
+        if (!zoomed) {
+            Geom::OptRect const d = selection->bounds();
+            if (d && d->area() * 2.0 < _quick_zoom_stored_area.area()) {
+                set_display_area(*d, 10);
+                zoomed = true;
+            } 
+        }
+
+        if (!zoomed) {
+            zoom_relative(_quick_zoom_stored_area.midpoint()[Geom::X], _quick_zoom_stored_area.midpoint()[Geom::Y], 2.0);
+            zoomed = true;
+        }
+    } else {
+        set_display_area(_quick_zoom_stored_area, 0);
+    }
+
+    _quick_zoom_enabled = enable;
+    return;
+}
+
 /**
  * Zoom to point with absolute zoom factor.
  */
@@ -868,10 +969,10 @@ SPDesktop::zoom_absolute_keep_point (double cx, double cy, double px, double py,
     if (fabs(_d2w.descrim() - zoom) < 0.0001*zoom && (fabs(SP_DESKTOP_ZOOM_MAX - zoom) < 0.01 || fabs(SP_DESKTOP_ZOOM_MIN - zoom) < 0.000001))
         return;
 
-    NR::Rect const viewbox = canvas->getViewbox();
+    Geom::Rect const viewbox = canvas->getViewbox();
 
-    double const width2 = viewbox.dimensions()[NR::X] / zoom;
-    double const height2 = viewbox.dimensions()[NR::Y] / zoom;
+    double const width2 = viewbox.dimensions()[Geom::X] / zoom;
+    double const height2 = viewbox.dimensions()[Geom::Y] / zoom;
 
     set_display_area(cx - px * width2,
                      cy - py * height2,
@@ -895,24 +996,24 @@ SPDesktop::zoom_absolute (double cx, double cy, double zoom)
 void
 SPDesktop::zoom_relative_keep_point (double cx, double cy, double zoom)
 {
-    NR::Rect const area = get_display_area();
+    Geom::Rect const area = get_display_area();
 
-    if (cx < area.min()[NR::X]) {
-        cx = area.min()[NR::X];
+    if (cx < area.min()[Geom::X]) {
+        cx = area.min()[Geom::X];
     }
-    if (cx > area.max()[NR::X]) {
-        cx = area.max()[NR::X];
+    if (cx > area.max()[Geom::X]) {
+        cx = area.max()[Geom::X];
     }
-    if (cy < area.min()[NR::Y]) {
-        cy = area.min()[NR::Y];
+    if (cy < area.min()[Geom::Y]) {
+        cy = area.min()[Geom::Y];
     }
-    if (cy > area.max()[NR::Y]) {
-        cy = area.max()[NR::Y];
+    if (cy > area.max()[Geom::Y]) {
+        cy = area.max()[Geom::Y];
     }
 
     gdouble const scale = _d2w.descrim() * zoom;
-    double const px = (cx - area.min()[NR::X]) / area.dimensions()[NR::X];
-    double const py = (cy - area.min()[NR::Y]) / area.dimensions()[NR::Y];
+    double const px = (cx - area.min()[Geom::X]) / area.dimensions()[Geom::X];
+    double const py = (cy - area.min()[Geom::Y]) / area.dimensions()[Geom::Y];
 
     zoom_absolute_keep_point(cx, cy, px, py, scale);
 }
@@ -933,10 +1034,10 @@ SPDesktop::zoom_relative (double cx, double cy, double zoom)
 void
 SPDesktop::zoom_page()
 {
-    NR::Rect d(Geom::Point(0, 0),
-               Geom::Point(sp_document_width(doc()), sp_document_height(doc())));
+    Geom::Rect d(Geom::Point(0, 0),
+                 Geom::Point(sp_document_width(doc()), sp_document_height(doc())));
 
-    if (d.isEmpty(1.0)) {
+    if (d.minExtent() < 1.0) {
         return;
     }
 
@@ -949,14 +1050,14 @@ SPDesktop::zoom_page()
 void
 SPDesktop::zoom_page_width()
 {
-    NR::Rect const a = get_display_area();
+    Geom::Rect const a = get_display_area();
 
     if (sp_document_width(doc()) < 1.0) {
         return;
     }
 
-    NR::Rect d(Geom::Point(0, a.midpoint()[NR::Y]),
-               Geom::Point(sp_document_width(doc()), a.midpoint()[NR::Y]));
+    Geom::Rect d(Geom::Point(0, a.midpoint()[Geom::Y]),
+                 Geom::Point(sp_document_width(doc()), a.midpoint()[Geom::Y]));
 
     set_display_area(d, 10);
 }
@@ -967,9 +1068,9 @@ SPDesktop::zoom_page_width()
 void
 SPDesktop::zoom_selection()
 {
-    boost::optional<NR::Rect> const d = selection->bounds();
+    Geom::OptRect const d = selection->bounds();
 
-    if ( !d || d->isEmpty(0.1) ) {
+    if ( !d || d->minExtent() < 0.1 ) {
         return;
     }
 
@@ -995,12 +1096,12 @@ SPDesktop::zoom_drawing()
     SPItem *docitem = SP_ITEM (sp_document_root (doc()));
     g_return_if_fail (docitem != NULL);
 
-    boost::optional<NR::Rect> d = sp_item_bbox_desktop(docitem);
+    Geom::OptRect d = sp_item_bbox_desktop(docitem);
 
     /* Note that the second condition here indicates that
     ** there are no items in the drawing.
     */
-    if ( !d || d->isEmpty(1.0) ) {
+    if ( !d || d->minExtent() < 0.1 ) {
         return;
     }
 
@@ -1025,9 +1126,9 @@ SPDesktop::scroll_world (double dx, double dy, bool is_scrolling)
 {
     g_assert(_widget);
 
-    NR::Rect const viewbox = canvas->getViewbox();
+    Geom::Rect const viewbox = canvas->getViewbox();
 
-    sp_canvas_scroll_to(canvas, viewbox.min()[NR::X] - dx, viewbox.min()[NR::Y] - dy, FALSE, is_scrolling);
+    sp_canvas_scroll_to(canvas, viewbox.min()[Geom::X] - dx, viewbox.min()[Geom::Y] - dy, FALSE, is_scrolling);
 
     /*  update perspective lines if we are in the 3D box tool (so that infinite ones are shown correctly) */
     sp_box3d_context_update_lines(event_context);
@@ -1039,39 +1140,45 @@ SPDesktop::scroll_world (double dx, double dy, bool is_scrolling)
 bool
 SPDesktop::scroll_to_point (Geom::Point const &p, gdouble autoscrollspeed)
 {
-    gdouble autoscrolldistance = (gdouble) prefs_get_int_attribute_limited ("options.autoscrolldistance", "value", 0, -1000, 10000);
+    using Geom::X;
+    using Geom::Y;
+
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    gdouble autoscrolldistance = (gdouble) prefs->getIntLimited("/options/autoscrolldistance/value", 0, -1000, 10000);
 
     // autoscrolldistance is in screen pixels, but the display area is in document units
     autoscrolldistance /= _d2w.descrim();
-    NR::Rect const dbox = NR::expand(get_display_area(), -autoscrolldistance);
+    // FIXME: This 2geom idiom doesn't allow us to declare dbox const
+    Geom::Rect dbox = get_display_area();
+    dbox.expandBy(-autoscrolldistance);
 
-    if (!(p[NR::X] > dbox.min()[NR::X] && p[NR::X] < dbox.max()[NR::X]) ||
-        !(p[NR::Y] > dbox.min()[NR::Y] && p[NR::Y] < dbox.max()[NR::Y])   ) {
+    if (!(p[X] > dbox.min()[X] && p[X] < dbox.max()[X]) ||
+        !(p[Y] > dbox.min()[Y] && p[Y] < dbox.max()[Y])   ) {
 
         Geom::Point const s_w( p * (Geom::Matrix)_d2w );
 
         gdouble x_to;
-        if (p[NR::X] < dbox.min()[NR::X])
-            x_to = dbox.min()[NR::X];
-        else if (p[NR::X] > dbox.max()[NR::X])
-            x_to = dbox.max()[NR::X];
+        if (p[X] < dbox.min()[X])
+            x_to = dbox.min()[X];
+        else if (p[X] > dbox.max()[X])
+            x_to = dbox.max()[X];
         else
-            x_to = p[NR::X];
+            x_to = p[X];
 
         gdouble y_to;
-        if (p[NR::Y] < dbox.min()[NR::Y])
-            y_to = dbox.min()[NR::Y];
-        else if (p[NR::Y] > dbox.max()[NR::Y])
-            y_to = dbox.max()[NR::Y];
+        if (p[Y] < dbox.min()[Y])
+            y_to = dbox.min()[Y];
+        else if (p[Y] > dbox.max()[Y])
+            y_to = dbox.max()[Y];
         else
-            y_to = p[NR::Y];
+            y_to = p[Y];
 
         Geom::Point const d_dt(x_to, y_to);
         Geom::Point const d_w( d_dt * _d2w );
         Geom::Point const moved_w( d_w - s_w );
 
         if (autoscrollspeed == 0)
-            autoscrollspeed = prefs_get_double_attribute_limited ("options.autoscrollspeed", "value", 1, 0, 10);
+            autoscrollspeed = prefs->getDoubleLimited("/options/autoscrollspeed/value", 1, 0, 10);
 
         if (autoscrollspeed != 0)
             scroll_world (autoscrollspeed * moved_w);
@@ -1117,6 +1224,33 @@ SPDesktop::fullscreen()
     _widget->setFullscreen();
 }
 
+/** \brief  Checks to see if the user is working in focused mode
+
+    Returns the value of \c _focusMode
+*/
+bool
+SPDesktop::is_focusMode()
+{
+    return _focusMode;
+}
+
+/** \brief  Changes whether the user is in focus mode or not
+    \param  mode  Which mode the view should be in
+
+*/
+void
+SPDesktop::focusMode (bool mode)
+{
+    if (mode == _focusMode) { return; }
+
+    _focusMode = mode;
+
+    layoutWidget();
+    //sp_desktop_widget_layout(SPDesktopWidget);
+
+    return;
+}
+
 void
 SPDesktop::getWindowGeometry (gint &x, gint &y, gint &w, gint &h)
 {
@@ -1208,7 +1342,7 @@ bool SPDesktop::onDeleteUI (GdkEventAny*)
 bool
 SPDesktop::onWindowStateEvent (GdkEventWindowState* event)
 {
-       // Record the desktop window's state
+    // Record the desktop window's state
     window_state = event->new_window_state;
 
     // Layout may differ depending on full-screen mode or not
@@ -1217,7 +1351,7 @@ SPDesktop::onWindowStateEvent (GdkEventWindowState* event)
         layoutWidget();
     }
 
-       return false;
+    return false;
 }
 
 void
@@ -1247,8 +1381,8 @@ SPDesktop::isToolboxButtonActive (gchar const *id)
 void
 SPDesktop::emitToolSubselectionChanged(gpointer data)
 {
-       _tool_subselection_changed.emit(data);
-       inkscape_subselection_changed (this);
+    _tool_subselection_changed.emit(data);
+    inkscape_subselection_changed (this);
 }
 
 void
@@ -1316,7 +1450,7 @@ void SPDesktop::showGrids(bool show, bool dirty_document)
 
 void SPDesktop::toggleSnapping()
 {
-    bool v = namedview->snap_manager.getSnapEnabledGlobally();
+    bool v = namedview->snap_manager.snapprefs.getSnapEnabledGlobally();
     Inkscape::XML::Node *repr = SP_OBJECT_REPR(namedview);
     sp_repr_set_boolean(repr, "inkscape:snap-global", !v);
 }
@@ -1434,7 +1568,7 @@ SPDesktop::onDocumentResized (gdouble width, gdouble height)
 {
     _doc2dt[5] = height;
     sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (drawing), _doc2dt);
-    NR::Rect const a(Geom::Point(0, 0), Geom::Point(width, height));
+    Geom::Rect const a(Geom::Point(0, 0), Geom::Point(width, height));
     SP_CTRLRECT(page)->setRectangle(a);
     SP_CTRLRECT(page_border)->setRectangle(a);
 }
@@ -1595,7 +1729,7 @@ _namedview_modified (SPObject *obj, guint flags, SPDesktop *desktop)
                 int order = sp_canvas_item_order (desktop->page_border);
                 int morder = sp_canvas_item_order (desktop->drawing);
                 if (morder > order) sp_canvas_item_raise (desktop->page_border,
-                                   morder - order);
+                    morder - order);
             }
         } else {
                 sp_canvas_item_hide (desktop->page_border);
@@ -1611,14 +1745,15 @@ _namedview_modified (SPObject *obj, guint flags, SPDesktop *desktop)
             ((CtrlRect *) desktop->page_border)->setShadow(0, 0x00000000);
         }
 
+        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
         if (SP_RGBA32_A_U(nv->pagecolor) < 128 ||
             (SP_RGBA32_R_U(nv->pagecolor) +
              SP_RGBA32_G_U(nv->pagecolor) +
              SP_RGBA32_B_U(nv->pagecolor)) >= 384) {
             // the background color is light or transparent, use black outline
-            SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = prefs_get_int_attribute("options.wireframecolors", "onlight", 0xff);
+            SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = prefs->getInt("/options/wireframecolors/onlight", 0xff);
         } else { // use white outline
-            SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = prefs_get_int_attribute("options.wireframecolors", "ondark", 0xffffffff);
+            SP_CANVAS_ARENA (desktop->drawing)->arena->outlinecolor = prefs->getInt("/options/wireframecolors/ondark", 0xffffffff);
         }
     }
 }
@@ -1670,6 +1805,12 @@ Geom::Matrix SPDesktop::doc2dt() const
     return _doc2dt;
 }
 
+Geom::Matrix SPDesktop::dt2doc() const
+{
+    // doc2dt is its own inverse
+    return _doc2dt;
+}
+
 Geom::Point SPDesktop::doc2dt(Geom::Point const &p) const
 {
     return p * _doc2dt;
@@ -1677,7 +1818,7 @@ Geom::Point SPDesktop::doc2dt(Geom::Point const &p) const
 
 Geom::Point SPDesktop::dt2doc(Geom::Point const &p) const
 {
-    return p * _doc2dt.inverse();
+    return p * dt2doc();
 }