Code

Merge from trunk.
[inkscape.git] / src / widgets / desktop-widget.cpp
index e3bf1ae9c5efecb60323a6052b7f4e1f4760d246..4620b15328e0137603f11dcf50078cf0426513a5 100644 (file)
@@ -1,5 +1,3 @@
-#define __SP_DESKTOP_WIDGET_C__
-
 /** \file
  * Desktop widget implementation
  */
@@ -10,6 +8,8 @@
  *   Ralf Stephan <ralf@ark.in-berlin.de>
  *   John Bintz <jcoswell@coswellproductions.org>
  *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
+ *   Jon A. Cruz <jon@joncruz.org>
+ *   Abhishek Sharma
  *
  * Copyright (C) 2007 Johan Engelen
  * Copyright (C) 2006 John Bintz
@@ -41,6 +41,7 @@
 #include <extension/db.h>
 #include "file.h"
 #include "helper/units.h"
+#include "helper/unit-tracker.h"
 #include "inkscape-private.h"
 #include "interface.h"
 #include "macros.h"
 #include "sp-image.h"
 #include "sp-item.h"
 #include "sp-namedview.h"
-#include "toolbox.h"
 #include "ui/dialog/dialog-manager.h"
 #include "ui/dialog/swatches.h"
 #include "ui/icon-names.h"
 #include "ui/widget/dock.h"
 #include "ui/widget/layer-selector.h"
 #include "ui/widget/selected-style.h"
-#include "widgets/button.h"
-#include "widgets/ruler.h"
-#include "widgets/spinbutton-events.h"
-#include "widgets/spw-utilities.h"
-#include "widgets/toolbox.h"
-#include "widgets/widget-sizes.h"
+#include "ui/uxmanager.h"
+#include "util/ege-appear-time-tracker.h"
+
+// We're in the "widgets" directory, so no need to explicitly prefix these:
+#include "button.h"
+#include "ruler.h"
+#include "spinbutton-events.h"
+#include "spw-utilities.h"
+#include "toolbox.h"
+#include "widget-sizes.h"
 
 #if defined (SOLARIS) && (SOLARIS == 8)
 #include "round.h"
 using Inkscape::round;
 #endif
 
+using Inkscape::UnitTracker;
+using Inkscape::UI::UXManager;
+using Inkscape::UI::ToolboxFactory;
+using ege::AppearTimeTracker;
+
 #ifdef WITH_INKBOARD
 #endif
 
@@ -85,7 +94,6 @@ enum {
 /* SPDesktopWidget */
 
 static void sp_desktop_widget_class_init (SPDesktopWidgetClass *klass);
-static void sp_desktop_widget_init (SPDesktopWidget *widget);
 static void sp_desktop_widget_destroy (GtkObject *object);
 
 static void sp_desktop_widget_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
@@ -97,7 +105,6 @@ static void sp_dtw_color_profile_event(EgeColorProfTracker *widget, SPDesktopWid
 static void cms_adjust_toggled( GtkWidget *button, gpointer data );
 static void cms_adjust_set_sensitive( SPDesktopWidget *dtw, bool enabled );
 static void sp_desktop_widget_adjustment_value_changed (GtkAdjustment *adj, SPDesktopWidget *dtw);
-static void sp_desktop_widget_namedview_modified (SPObject *obj, guint flags, SPDesktopWidget *dtw);
 
 static gdouble sp_dtw_zoom_value_to_display (gdouble value);
 static gdouble sp_dtw_zoom_display_to_value (gdouble value);
@@ -116,6 +123,30 @@ static void sp_dtw_sticky_zoom_toggled (GtkMenuItem *item, gpointer data);
 
 SPViewWidgetClass *dtw_parent_class;
 
+static GTimer *baseTimer = 0;
+static bool timeReported = false;
+
+static void timeGoing(gchar const* id)
+{
+    if ( !baseTimer ) {
+        g_message("Starting time at point [%s]", id);
+        baseTimer = g_timer_new();
+    }
+}
+
+static void checkTime(gchar const* msg)
+{
+    if ( baseTimer && !timeReported ) {
+        timeReported = true;
+        g_timer_stop(baseTimer);
+        gulong msCount = 0;
+        gdouble secs = g_timer_elapsed( baseTimer, &msCount );
+        g_message("Time ended at %2.3f with [%s]", secs, msg);
+    }
+}
+
+
+
 class CMSPrefWatcher {
 public:
     CMSPrefWatcher() :
@@ -238,13 +269,16 @@ SPDesktopWidget::window_get_pointer()
     return Geom::Point(x,y);
 }
 
+static GTimer *overallTimer = 0;
+
 /**
  * Registers SPDesktopWidget class and returns its type number.
  */
-GType sp_desktop_widget_get_type(void)
+GType SPDesktopWidget::getType(void)
 {
     static GtkType type = 0;
     if (!type) {
+        timeGoing("SPDesktopWidget::getType");
         GTypeInfo info = {
             sizeof(SPDesktopWidgetClass),
             0, // base_init
@@ -254,10 +288,12 @@ GType sp_desktop_widget_get_type(void)
             0, // class_data
             sizeof(SPDesktopWidget),
             0, // n_preallocs
-            (GInstanceInitFunc)sp_desktop_widget_init,
+            (GInstanceInitFunc)SPDesktopWidget::init,
             0 // value_table
         };
         type = g_type_register_static(SP_TYPE_VIEW_WIDGET, "SPDesktopWidget", &info, static_cast<GTypeFlags>(0));
+        // Begin a timer to watch for the first desktop to appear on-screen
+        overallTimer = g_timer_new();
     }
     return type;
 }
@@ -268,6 +304,7 @@ GType sp_desktop_widget_get_type(void)
 static void
 sp_desktop_widget_class_init (SPDesktopWidgetClass *klass)
 {
+    timeGoing("sp_desktop_widget_class_init");
     dtw_parent_class = (SPViewWidgetClass*)gtk_type_class (SP_TYPE_VIEW_WIDGET);
 
     GtkObjectClass *object_class = (GtkObjectClass *) klass;
@@ -282,14 +319,13 @@ sp_desktop_widget_class_init (SPDesktopWidgetClass *klass)
 /**
  * Callback for SPDesktopWidget object initialization.
  */
-static void
-sp_desktop_widget_init (SPDesktopWidget *dtw)
+void SPDesktopWidget::init( SPDesktopWidget *dtw )
 {
+    timeGoing("SPDesktopWidget::init");
     GtkWidget *widget;
     GtkWidget *tbl;
     GtkWidget *canvas_tbl;
 
-    GtkWidget *hbox;
     GtkWidget *eventbox;
     GtkStyle *style;
 
@@ -320,24 +356,26 @@ sp_desktop_widget_init (SPDesktopWidget *dtw)
         gtk_box_pack_end( GTK_BOX( dtw->vbox ), GTK_WIDGET(dtw->panels->gobj()), FALSE, TRUE, 0 );
     }
 
-    hbox = gtk_hbox_new (FALSE, 0);
-    gtk_box_pack_end (GTK_BOX (dtw->vbox), hbox, TRUE, TRUE, 0);
-    gtk_widget_show (hbox);
-
-    dtw->aux_toolbox = sp_aux_toolbox_new ();
+    dtw->hbox = gtk_hbox_new(FALSE, 0);
+    gtk_box_pack_end( GTK_BOX (dtw->vbox), dtw->hbox, TRUE, TRUE, 0 );
+    gtk_widget_show(dtw->hbox);
+    dtw->aux_toolbox = ToolboxFactory::createAuxToolbox();
     gtk_box_pack_end (GTK_BOX (dtw->vbox), dtw->aux_toolbox, FALSE, TRUE, 0);
 
-    dtw->snap_toolbox = sp_snap_toolbox_new ();
-    gtk_box_pack_end (GTK_BOX (dtw->vbox), dtw->snap_toolbox, FALSE, TRUE, 0);
+    dtw->snap_toolbox = ToolboxFactory::createSnapToolbox();
+    ToolboxFactory::setOrientation( dtw->snap_toolbox, GTK_ORIENTATION_VERTICAL );
+    gtk_box_pack_end( GTK_BOX(dtw->hbox), dtw->snap_toolbox, FALSE, TRUE, 0 );
 
-    dtw->commands_toolbox = sp_commands_toolbox_new ();
+    dtw->commands_toolbox = ToolboxFactory::createCommandsToolbox();
     gtk_box_pack_end (GTK_BOX (dtw->vbox), dtw->commands_toolbox, FALSE, TRUE, 0);
 
-    dtw->tool_toolbox = sp_tool_toolbox_new ();
-    gtk_box_pack_start (GTK_BOX (hbox), dtw->tool_toolbox, FALSE, TRUE, 0);
+    dtw->tool_toolbox = ToolboxFactory::createToolToolbox();
+    ToolboxFactory::setOrientation( dtw->tool_toolbox, GTK_ORIENTATION_VERTICAL );
+    gtk_box_pack_start( GTK_BOX(dtw->hbox), dtw->tool_toolbox, FALSE, TRUE, 0 );
 
     tbl = gtk_table_new (2, 3, FALSE);
-    gtk_box_pack_start (GTK_BOX (hbox), tbl, TRUE, TRUE, 1);
+    gtk_box_pack_start( GTK_BOX(dtw->hbox), tbl, TRUE, TRUE, 1 );
 
     canvas_tbl = gtk_table_new (3, 3, FALSE);
 
@@ -528,8 +566,10 @@ sp_desktop_widget_init (SPDesktopWidget *dtw)
 
     dtw->_tracker = ege_color_prof_tracker_new(GTK_WIDGET(dtw->layer_selector->gobj()));
 #if ENABLE_LCMS
-    {
+    bool fromDisplay = prefs->getBool( "/options/displayprofile/from_display");
+    if ( fromDisplay ) {
         Glib::ustring id = Inkscape::colorprofile_get_display_id( 0, 0 );
+
         bool enabled = false;
         if ( dtw->canvas->cms_key ) {
             *(dtw->canvas->cms_key) = id;
@@ -557,6 +597,18 @@ sp_desktop_widget_init (SPDesktopWidget *dtw)
     gtk_widget_show_all (dtw->vbox);
 
     gtk_widget_grab_focus (GTK_WIDGET(dtw->canvas));
+
+    // If this is the first desktop created, report the time it takes to show up
+    if ( overallTimer ) {
+        if ( prefs->getBool("/dialogs/debug/trackAppear", false) ) {
+            // Time tracker takes ownership of the timer.
+            AppearTimeTracker *tracker = new AppearTimeTracker(overallTimer, GTK_WIDGET(dtw), "first SPDesktopWidget");
+            tracker->setAutodelete(true);
+        } else {
+            g_timer_destroy(overallTimer);
+        }
+        overallTimer = 0;
+    }
 }
 
 /**
@@ -567,6 +619,8 @@ sp_desktop_widget_destroy (GtkObject *object)
 {
     SPDesktopWidget *dtw = SP_DESKTOP_WIDGET (object);
 
+    UXManager::getInstance()->delTrack(dtw);
+
     if (dtw->desktop) {
         if ( watcher ) {
             watcher->remove(dtw);
@@ -613,12 +667,20 @@ SPDesktopWidget::updateTitle(gchar const* uri)
         if (this->desktop->number > 1) {
             if (this->desktop->getMode() == Inkscape::RENDERMODE_OUTLINE) {
                 g_string_printf (name, _("%s: %d (outline) - Inkscape"), fname, this->desktop->number);
+            } else if (this->desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) {
+                g_string_printf (name, _("%s: %d (no filters) - Inkscape"), fname, this->desktop->number);
+            } else if (this->desktop->getMode() == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW) {
+                g_string_printf (name, _("%s: %d (print colors preview) - Inkscape"), fname, this->desktop->number);
             } else {
                 g_string_printf (name, _("%s: %d - Inkscape"), fname, this->desktop->number);
             }
         } else {
             if (this->desktop->getMode() == Inkscape::RENDERMODE_OUTLINE) {
                 g_string_printf (name, _("%s (outline) - Inkscape"), fname);
+            } else if (this->desktop->getMode() == Inkscape::RENDERMODE_NO_FILTERS) {
+                g_string_printf (name, _("%s (no filters) - Inkscape"), fname);
+            } else if (this->desktop->getMode() == Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW) {
+                g_string_printf (name, _("%s (print colors preview) - Inkscape"), fname);
             } else {
                 g_string_printf (name, _("%s - Inkscape"), fname);
             }
@@ -692,30 +754,29 @@ sp_desktop_widget_realize (GtkWidget *widget)
     NRRect d;
     d.x0 = 0.0;
     d.y0 = 0.0;
-    d.x1 = sp_document_width (dtw->desktop->doc());
-    d.y1 = sp_document_height (dtw->desktop->doc());
+    d.x1 = (dtw->desktop->doc())->getWidth ();
+    d.y1 = (dtw->desktop->doc())->getHeight ();
 
     if ((fabs (d.x1 - d.x0) < 1.0) || (fabs (d.y1 - d.y0) < 1.0)) return;
 
     dtw->desktop->set_display_area (d.x0, d.y0, d.x1, d.y1, 10);
 
-    sp_desktop_widget_update_namedview(dtw);
+    dtw->updateNamedview();
 }
 
 /* This is just to provide access to common functionality from sp_desktop_widget_realize() above
    as well as from SPDesktop::change_document() */
-void
-sp_desktop_widget_update_namedview (SPDesktopWidget *dtw) {
-    g_return_if_fail(dtw);
-
-    /* Listen on namedview modification */
+void SPDesktopWidget::updateNamedview()
+{
+    // Listen on namedview modification
     // originally (prior to the sigc++ conversion) the signal was simply
     // connected twice rather than disconnecting the first connection
-    dtw->modified_connection.disconnect();
-    dtw->modified_connection = dtw->desktop->namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_desktop_widget_namedview_modified), dtw));
-    sp_desktop_widget_namedview_modified (dtw->desktop->namedview, SP_OBJECT_MODIFIED_FLAG, dtw);
+    modified_connection.disconnect();
+
+    modified_connection = desktop->namedview->connectModified(sigc::mem_fun(*this, &SPDesktopWidget::namedviewModified));
+    namedviewModified(desktop->namedview, SP_OBJECT_MODIFIED_FLAG);
 
-    dtw->updateTitle(SP_DOCUMENT_NAME (dtw->desktop->doc()));
+    updateTitle( desktop->doc()->getName() );
 }
 
 /**
@@ -782,6 +843,11 @@ void cms_adjust_toggled( GtkWidget */*button*/, gpointer data )
         dtw->requestCanvasUpdate();
         Inkscape::Preferences *prefs = Inkscape::Preferences::get();
         prefs->setBool("/options/displayprofile/enable", down);
+        if (down) {
+            dtw->setMessage (Inkscape::NORMAL_MESSAGE, _("Color-managed display is <b>enabled</b> in this window"));
+        } else {
+            dtw->setMessage (Inkscape::NORMAL_MESSAGE, _("Color-managed display is <b>disabled</b> in this window"));
+        }
     }
 #endif // ENABLE_LCMS
 }
@@ -837,7 +903,7 @@ SPDesktopWidget::shutdown()
                 GTK_BUTTONS_NONE,
                 _("<span weight=\"bold\" size=\"larger\">Save changes to document \"%s\" before closing?</span>\n\n"
                   "If you close without saving, your changes will be discarded."),
-                SP_DOCUMENT_NAME(doc));
+                doc->getName());
             // fix for bug 1767940:
             GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(GTK_MESSAGE_DIALOG(dialog)->label), GTK_CAN_FOCUS);
 
@@ -859,12 +925,12 @@ SPDesktopWidget::shutdown()
             {
                 Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
 
-                sp_document_ref(doc);
+                doc->doRef();
                 sp_namedview_document_from_window(desktop);
                 if (sp_file_save_document(*window, doc)) {
-                    sp_document_unref(doc);
+                    doc->doUnref();
                 } else { // save dialog cancelled or save failed
-                    sp_document_unref(doc);
+                    doc->doUnref();
                     return TRUE;
                 }
 
@@ -879,7 +945,7 @@ SPDesktopWidget::shutdown()
         }
         /* Code to check data loss */
         bool allow_data_loss = FALSE;
-        while (sp_document_repr_root(doc)->attribute("inkscape:dataloss") != NULL && allow_data_loss == FALSE) {
+        while (doc->getReprRoot()->attribute("inkscape:dataloss") != NULL && allow_data_loss == FALSE) {
             GtkWidget *dialog;
 
             /** \todo
@@ -892,8 +958,8 @@ SPDesktopWidget::shutdown()
                 GTK_MESSAGE_WARNING,
                 GTK_BUTTONS_NONE,
                 _("<span weight=\"bold\" size=\"larger\">The file \"%s\" was saved with a format (%s) that may cause data loss!</span>\n\n"
-                  "Do you want to save this file as an Inkscape SVG?"),
-                SP_DOCUMENT_NAME(doc),
+                  "Do you want to save this file as Inkscape SVG?"),
+                doc->getName() ? doc->getName() : "Unnamed",
                 SP_MODULE_KEY_OUTPUT_SVG_INKSCAPE);
             // fix for bug 1767940:
             GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(GTK_MESSAGE_DIALOG(dialog)->label), GTK_CAN_FOCUS);
@@ -917,14 +983,14 @@ SPDesktopWidget::shutdown()
             switch (response) {
             case GTK_RESPONSE_YES:
             {
-                sp_document_ref(doc);
+                doc->doRef();
 
                 Gtk::Window *window = (Gtk::Window*)gtk_object_get_data (GTK_OBJECT(this), "window");
 
                 if (sp_file_save_dialog(*window, doc, Inkscape::Extension::FILE_SAVE_METHOD_INKSCAPE_SVG)) {
-                    sp_document_unref(doc);
+                    doc->doUnref();
                 } else { // save dialog cancelled or save failed
-                    sp_document_unref(doc);
+                    doc->doUnref();
                     return TRUE;
                 }
 
@@ -1191,18 +1257,18 @@ sp_desktop_widget_fullscreen(SPDesktopWidget *dtw)
 /**
  * Hide whatever the user does not want to see in the window
  */
-void
-sp_desktop_widget_layout (SPDesktopWidget *dtw)
+void SPDesktopWidget::layoutWidgets()
 {
+    SPDesktopWidget *dtw = this;
     Glib::ustring pref_root;
     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
 
     if (dtw->desktop->is_focusMode()) {
-           pref_root = "/focus/";
+        pref_root = "/focus/";
     } else if (dtw->desktop->is_fullscreen()) {
-           pref_root = "/fullscreen/";
+        pref_root = "/fullscreen/";
     } else {
-           pref_root = "/window/";
+        pref_root = "/window/";
     }
 
 #ifndef GDK_WINDOWING_QUARTZ
@@ -1220,17 +1286,17 @@ sp_desktop_widget_layout (SPDesktopWidget *dtw)
     }
 
     if (!prefs->getBool(pref_root + "snaptoolbox/state", true)) {
-               gtk_widget_hide_all (dtw->snap_toolbox);
-       } else {
-               gtk_widget_show_all (dtw->snap_toolbox);
-       }
+        gtk_widget_hide_all (dtw->snap_toolbox);
+    } else {
+        gtk_widget_show_all (dtw->snap_toolbox);
+    }
 
     if (!prefs->getBool(pref_root + "toppanel/state", true)) {
         gtk_widget_hide_all (dtw->aux_toolbox);
     } else {
         // we cannot just show_all because that will show all tools' panels;
         // this is a function from toolbox.cpp that shows only the current tool's panel
-        show_aux_toolbox (dtw->aux_toolbox);
+        ToolboxFactory::showAuxToolbox(dtw->aux_toolbox);
     }
 
     if (!prefs->getBool(pref_root + "toolbox/state", true)) {
@@ -1328,8 +1394,55 @@ SPDesktopWidget::isToolboxButtonActive (const gchar* id)
     return isActive;
 }
 
-SPViewWidget *
-sp_desktop_widget_new (SPNamedView *namedview)
+void SPDesktopWidget::setToolboxPosition(Glib::ustring const& id, GtkPositionType pos)
+{
+    // Note - later on these won't be individual member variables.
+    GtkWidget* toolbox = 0;
+    if (id == "ToolToolbar") {
+        toolbox = tool_toolbox;
+    } else if (id == "AuxToolbar") {
+        toolbox = aux_toolbox;
+    } else if (id == "CommandsToolbar") {
+        toolbox = commands_toolbox;
+    } else if (id == "SnapToolbar") {
+        toolbox = snap_toolbox;
+    }
+
+
+    if (toolbox) {
+        switch(pos) {
+            case GTK_POS_TOP:
+            case GTK_POS_BOTTOM:
+                if ( gtk_widget_is_ancestor(toolbox, hbox) ) {
+                    gtk_widget_reparent( toolbox, vbox );
+                    gtk_box_set_child_packing(GTK_BOX(vbox), toolbox, FALSE, TRUE, 0, GTK_PACK_START);
+                }
+                ToolboxFactory::setOrientation(toolbox, GTK_ORIENTATION_HORIZONTAL);
+                break;
+            case GTK_POS_LEFT:
+            case GTK_POS_RIGHT:
+                if ( !gtk_widget_is_ancestor(toolbox, hbox) ) {
+                    gtk_widget_reparent( toolbox, hbox );
+                    gtk_box_set_child_packing(GTK_BOX(hbox), toolbox, FALSE, TRUE, 0, GTK_PACK_START);
+                    if (pos == GTK_POS_LEFT) {
+                        gtk_box_reorder_child( GTK_BOX(hbox), toolbox, 0 );
+                    }
+                }
+                ToolboxFactory::setOrientation(toolbox, GTK_ORIENTATION_VERTICAL);
+                break;
+        }
+    }
+}
+
+
+SPViewWidget *sp_desktop_widget_new( SPNamedView *namedview )
+{
+    SPDesktopWidget* dtw = SPDesktopWidget::createInstance(namedview);
+
+    return SP_VIEW_WIDGET(dtw);
+}
+
+SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview)
 {
     SPDesktopWidget *dtw = (SPDesktopWidget*)g_object_new(SP_TYPE_DESKTOP_WIDGET, NULL);
 
@@ -1354,7 +1467,7 @@ sp_desktop_widget_new (SPNamedView *namedview)
     sp_view_widget_set_view (SP_VIEW_WIDGET (dtw), dtw->desktop);
 
     /* Listen on namedview modification */
-    dtw->modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_desktop_widget_namedview_modified), dtw));
+    dtw->modified_connection = namedview->connectModified(sigc::mem_fun(*dtw, &SPDesktopWidget::namedviewModified));
 
     dtw->layer_selector->setDesktop(dtw->desktop);
 
@@ -1364,16 +1477,20 @@ sp_desktop_widget_new (SPNamedView *namedview)
     gtk_box_pack_start (GTK_BOX (dtw->vbox), dtw->menubar, FALSE, FALSE, 0);
 #endif
 
-    sp_desktop_widget_layout (dtw);
+    dtw->layoutWidgets();
 
-    sp_tool_toolbox_set_desktop (dtw->tool_toolbox, dtw->desktop);
-    sp_aux_toolbox_set_desktop (dtw->aux_toolbox, dtw->desktop);
-    sp_commands_toolbox_set_desktop (dtw->commands_toolbox, dtw->desktop);
-    sp_snap_toolbox_set_desktop (dtw->snap_toolbox, dtw->desktop);
+    std::vector<GtkWidget *> toolboxes;
+    toolboxes.push_back(dtw->tool_toolbox);
+    toolboxes.push_back(dtw->aux_toolbox);
+    toolboxes.push_back(dtw->commands_toolbox);
+    toolboxes.push_back(dtw->snap_toolbox);
 
     dtw->panels->setDesktop( dtw->desktop );
 
-    return SP_VIEW_WIDGET (dtw);
+    UXManager::getInstance()->addTrack(dtw);
+    UXManager::getInstance()->connectToDesktop( toolboxes, dtw->desktop );
+
+    return dtw;
 }
 
 void
@@ -1428,22 +1545,56 @@ sp_desktop_widget_update_vruler (SPDesktopWidget *dtw)
 }
 
 
-static void
-sp_desktop_widget_namedview_modified (SPObject *obj, guint flags, SPDesktopWidget *dtw)
+void SPDesktopWidget::namedviewModified(SPObject *obj, guint flags)
 {
     SPNamedView *nv=SP_NAMEDVIEW(obj);
-    if (flags & SP_OBJECT_MODIFIED_FLAG) {
-       dtw->dt2r = 1.0 / nv->doc_units->unittobase;
-        dtw->ruler_origin = Geom::Point(0,0); //nv->gridorigin;   Why was the grid origin used here?
-
-        sp_ruler_set_metric (GTK_RULER (dtw->vruler), nv->getDefaultMetric());
-        sp_ruler_set_metric (GTK_RULER (dtw->hruler), nv->getDefaultMetric());
 
-        gtk_tooltips_set_tip (dtw->tt, dtw->hruler_box, gettext(sp_unit_get_plural (nv->doc_units)), NULL);
-        gtk_tooltips_set_tip (dtw->tt, dtw->vruler_box, gettext(sp_unit_get_plural (nv->doc_units)), NULL);
-
-        sp_desktop_widget_update_rulers (dtw);
-        update_snap_toolbox(dtw->desktop, NULL, dtw->snap_toolbox);
+    if (flags & SP_OBJECT_MODIFIED_FLAG) {
+        this->dt2r = 1.0 / nv->doc_units->unittobase;
+        this->ruler_origin = Geom::Point(0,0); //nv->gridorigin;   Why was the grid origin used here?
+
+        sp_ruler_set_metric(GTK_RULER (this->vruler), nv->getDefaultMetric());
+        sp_ruler_set_metric(GTK_RULER (this->hruler), nv->getDefaultMetric());
+
+        /* This loops through all the grandchildren of aux toolbox,
+         * and for each that it finds, it performs an sp_search_by_data_recursive(),
+         * looking for widgets that hold some "tracker" data (this is used by
+         * all toolboxes to refer to the unit selector). The default document units 
+         * is then selected within these unit selectors.
+         *
+         * Of course it would be nice to be able to refer to the toolbox and the
+         * unit selector directly by name, but I don't yet see a way to do that.
+         * 
+         * This should solve: https://bugs.launchpad.net/inkscape/+bug/362995
+         */
+        if (GTK_IS_CONTAINER(aux_toolbox)) {
+            GList *ch = gtk_container_get_children (GTK_CONTAINER(aux_toolbox));
+            for (GList *i = ch; i != NULL; i = i->next) {
+                if (GTK_IS_CONTAINER(i->data)) {
+                    GList *grch = gtk_container_get_children (GTK_CONTAINER(i->data));
+                    for (GList *j = grch; j != NULL; j = j->next) {                        
+                        if (!GTK_IS_WIDGET(j->data)) // wasn't a widget
+                            continue;
+
+                        gpointer t = sp_search_by_data_recursive(GTK_WIDGET(j->data), (gpointer) "tracker");
+                        if (t == NULL) // didn't find any tracker data
+                            continue;
+
+                        UnitTracker *tracker = reinterpret_cast<UnitTracker*>( t );
+                        if (tracker == NULL) // it's null when inkscape is first opened
+                            continue;
+
+                        tracker->setActiveUnit( nv->doc_units );
+                    } // grandchildren
+                } // if child is a container
+            } // children
+        } // if aux_toolbox is a container
+
+        gtk_tooltips_set_tip(this->tt, this->hruler_box, gettext(sp_unit_get_plural (nv->doc_units)), NULL);
+        gtk_tooltips_set_tip(this->tt, this->vruler_box, gettext(sp_unit_get_plural (nv->doc_units)), NULL);
+
+        sp_desktop_widget_update_rulers(this);
+        ToolboxFactory::updateSnapToolbox(this->desktop, 0, this->snap_toolbox);
     }
 }
 
@@ -1469,7 +1620,7 @@ bool SPDesktopWidget::onFocusInEvent(GdkEventFocus*)
 {
     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     if (prefs->getBool("/options/bitmapautoreload/value", true)) {
-        GSList const *imageList = sp_document_get_resource_list(desktop->doc(), "image");
+        GSList const *imageList = (desktop->doc())->getResourceList("image");
         for (GSList const *p = imageList; p; p = p->next) {
             SPImage* image = SP_IMAGE(p->data);
             sp_image_refresh_if_outdated( image );
@@ -1731,11 +1882,11 @@ sp_desktop_widget_update_scrollbars (SPDesktopWidget *dtw, double scale)
 
     /* The desktop region we always show unconditionally */
     SPDocument *doc = dtw->desktop->doc();
-    Geom::Rect darea ( Geom::Point(-sp_document_width(doc), -sp_document_height(doc)),
-                     Geom::Point(2 * sp_document_width(doc), 2 * sp_document_height(doc))  );
+    Geom::Rect darea ( Geom::Point(-doc->getWidth(), -doc->getHeight()),
+                     Geom::Point(2 * doc->getWidth(), 2 * doc->getHeight())  );
     SPObject* root = doc->root;
     SPItem* item = SP_ITEM(root);
-    Geom::OptRect deskarea = Geom::unify(darea, sp_item_bbox_desktop(item));
+    Geom::OptRect deskarea = Geom::unify(darea, item->getBboxDesktop());
 
     /* Canvas region we always show unconditionally */
     Geom::Rect carea( Geom::Point(deskarea->min()[Geom::X] * scale - 64, deskarea->max()[Geom::Y] * -scale - 64),