Code

dropper modes: replace undecipherable icons with text labels
[inkscape.git] / src / desktop.cpp
index 903a6bd7c90c46e3ea7980fc54b6d4e2f7f43b54..f9d17b01ad6bbc5e938c8c9c5df0e2b8007427ab 100644 (file)
@@ -9,8 +9,10 @@
  *   bulia byak <buliabyak@users.sf.net>
  *   Ralf Stephan <ralf@ark.in-berlin.de>
  *   John Bintz <jcoswell@coswellproductions.org>
+ *   Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
  *
- * Copyright (C) 2006 Johan Engelen <johan@shouraizou.nl>
+ * Copyright (C) 2007 Jon A. Cruz
+ * Copyright (C) 2006-2008 Johan Engelen
  * Copyright (C) 2006 John Bintz
  * Copyright (C) 2004 MenTaLguY
  * Copyright (C) 1999-2002 Lauris Kaplinski
@@ -53,6 +55,7 @@
 
 #include <glibmm/i18n.h>
 #include <sigc++/functors/mem_fun.h>
+#include <gtkmm.h>
 
 #include "macros.h"
 #include "inkscape-private.h"
@@ -74,6 +77,8 @@
 #include "display/gnome-canvas-acetate.h"
 #include "display/sodipodi-ctrlrect.h"
 #include "display/sp-canvas-util.h"
+#include "display/canvas-temporary-item-list.h"
+#include "display/snap-indicator.h"
 #include "libnr/nr-matrix-div.h"
 #include "libnr/nr-rect-ops.h"
 #include "ui/dialog/dialog-manager.h"
 #include "message-context.h"
 #include "layer-manager.h"
 #include "event-log.h"
+#include "display/canvas-grid.h"
+#include "widgets/desktop-widget.h"
+#include "box3d-context.h"
+
+#include "display/sp-canvas.h"
 
 namespace Inkscape { namespace XML { class Node; }}
 
@@ -100,47 +110,59 @@ static void _update_snap_distances (SPDesktop *desktop);
  * \pre namedview != NULL.
  * \pre canvas != NULL.
  */
-SPDesktop::SPDesktop()
-{
-    _dlg_mgr = NULL;
-    _widget = 0;
-    namedview = NULL;
-    selection = NULL;
-    acetate = NULL;
-    main = NULL;
-    grid = NULL;
-    guides = NULL;
-    drawing = NULL;
-    sketch = NULL;
-    controls = NULL;
-    event_context = 0;
-    layer_manager = 0;
-
+SPDesktop::SPDesktop() :
+    _dlg_mgr( 0 ),
+    namedview( 0 ),
+    canvas( 0 ),
+    selection( 0 ),
+    event_context( 0 ),
+    layer_manager( 0 ),
+    event_log( 0 ),
+    temporary_item_list( 0 ),
+    snapindicator( 0 ),
+    acetate( 0 ),
+    main( 0 ),
+    gridgroup( 0 ),
+    guides( 0 ),
+    drawing( 0 ),
+    sketch( 0 ),
+    controls( 0 ),
+    tempgroup ( 0 ),
+    table( 0 ),
+    page( 0 ),
+    page_border( 0 ),
+    current( 0 ),
+    zooms_past( 0 ),
+    zooms_future( 0 ),
+    dkey( 0 ),
+    number( 0 ),
+    window_state(0),
+    interaction_disabled_counter( 0 ),
+    waiting_cursor( false ),
+    guides_active( false ),
+    gr_item( 0 ),
+    gr_point_type( 0 ),
+    gr_point_i( 0 ),
+    gr_fill_or_stroke( true ),
+    _layer_hierarchy( 0 ),
+    _reconstruction_old_layer_id( 0 ),
+    _widget( 0 ),
+    _inkscape( 0 ),
+    _guides_message_context( 0 ),
+    _active( false ),
+    _w2d(),
+    _d2w(),
+    _doc2dt( NR::Matrix(NR::scale(1, -1)) ),
+    grids_visible( false )
+{
     _d2w.set_identity();
     _w2d.set_identity();
-    _doc2dt = NR::Matrix(NR::scale(1, -1));
-
-    guides_active = false;
-
-    zooms_past = NULL;
-    zooms_future = NULL;
-
-    is_fullscreen = false;
-
-    gr_item = NULL;
-    gr_point_type = 0;
-    gr_point_i = 0;
-    gr_fill_or_stroke = true;
 
-    _layer_hierarchy = NULL;
-    _active = false;
-
-    selection = Inkscape::GC::release (new Inkscape::Selection (this));
+    selection = Inkscape::GC::release( new Inkscape::Selection(this) );
 }
 
 void
 SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
-
 {
     _guides_message_context = new Inkscape::MessageContext(const_cast<Inkscape::MessageStack*>(messageStack()));
 
@@ -154,7 +176,7 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
     sp_document_ensure_up_to_date (document);
 
     /* Setup Dialog Manager */
-    _dlg_mgr = new Inkscape::UI::Dialog::DialogManager();
+    _dlg_mgr = &Inkscape::UI::Dialog::DialogManager::getInstance();
 
     dkey = sp_item_display_key_new (1);
 
@@ -197,10 +219,11 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
         setDisplayModeNormal();
     }
 
-    grid = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
+    gridgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
     guides = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
     sketch = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
     controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
+    tempgroup = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
 
     /* Push select tool to the bottom of stack */
     /** \todo
@@ -257,9 +280,7 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
     _reconstruction_finish_connection =
         document->connectReconstructionFinish(sigc::bind(sigc::ptr_fun(_reconstruction_finish), this));
     _reconstruction_old_layer_id = NULL;
-    
-    _commit_connection = document->connectCommit(sigc::mem_fun(*this, &SPDesktop::updateNow));
-    
+
     // ?
     // sp_active_desktop_set (desktop);
     _inkscape = INKSCAPE;
@@ -294,11 +315,27 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
     /* setup LayerManager */
     //   (Setting up after the connections are all in place, as it may use some of them)
     layer_manager = new Inkscape::LayerManager( this );
+
+    showGrids(namedview->grids_visible, false);
+
+    temporary_item_list = new Inkscape::Display::TemporaryItemList( this );
+    snapindicator = new Inkscape::Display::SnapIndicator ( this );
 }
 
 
 void SPDesktop::destroy()
 {
+    if (snapindicator) {
+        delete snapindicator;
+        snapindicator = NULL;
+    }
+    if (temporary_item_list) {
+        delete temporary_item_list;
+        temporary_item_list = NULL;
+    }
+
+    namedview->hide(this);
+
     _activate_connection.disconnect();
     _deactivate_connection.disconnect();
     _sel_modified_connection.disconnect();
@@ -321,6 +358,12 @@ void SPDesktop::destroy()
 
     if (_layer_hierarchy) {
         delete _layer_hierarchy;
+//        _layer_hierarchy = NULL; //this should be here, but commented to find other bug somewhere else.
+    }
+
+    if (layer_manager) {
+        delete layer_manager;
+        layer_manager = NULL;
     }
 
     if (_inkscape) {
@@ -344,9 +387,30 @@ SPDesktop::~SPDesktop() {}
 //--------------------------------------------------------------------
 /* Public methods */
 
+
+/** Note that lifetime is measured in milliseconds
+* it is perfectly safe to ignore the returned pointer: the object is deleted by itself, so don't delete it elsewhere!
+* The return value should only be used as argument for SPDesktop::remove_temporary_canvasitem, because the object might be deleted already.
+*/
+Inkscape::Display::TemporaryItem *
+SPDesktop::add_temporary_canvasitem (SPCanvasItem *item, guint lifetime)
+{
+    return temporary_item_list->add_item(item, lifetime);
+}
+
+/** It is perfectly safe to call this function while the object has already been deleted due to a timeout.
+*/
+void
+SPDesktop::remove_temporary_canvasitem (Inkscape::Display::TemporaryItem * tempitem)
+{
+    // check for non-null temporary_item_list, because during destruction of desktop, some destructor might try to access this list!
+    if (tempitem && temporary_item_list) {
+        temporary_item_list->delete_item(tempitem);
+    }
+}
+
 void SPDesktop::setDisplayModeNormal()
 {
-    prefs_set_int_attribute("options.outlinemode", "value", 0);
     SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_NORMAL;
     canvas->rendermode = RENDERMODE_NORMAL; // canvas needs that for choosing the best buffer size
     displayMode = RENDERMODE_NORMAL;
@@ -356,7 +420,6 @@ void SPDesktop::setDisplayModeNormal()
 
 void SPDesktop::setDisplayModeOutline()
 {
-    prefs_set_int_attribute("options.outlinemode", "value", 1);
     SP_CANVAS_ARENA (drawing)->arena->rendermode = RENDERMODE_OUTLINE;
     canvas->rendermode = RENDERMODE_OUTLINE; // canvas needs that for choosing the best buffer size
     displayMode = RENDERMODE_OUTLINE;
@@ -366,9 +429,9 @@ void SPDesktop::setDisplayModeOutline()
 
 void SPDesktop::displayModeToggle()
 {
-    if (prefs_get_int_attribute("options.outlinemode", "value", prefs_get_int_attribute("options.startmode", "outline", 0)))
+    if (displayMode == RENDERMODE_OUTLINE)
         setDisplayModeNormal();
-    else 
+    else
         setDisplayModeOutline();
 }
 
@@ -390,7 +453,7 @@ SPObject *SPDesktop::currentLayer() const
 
 /**
  * Sets the current layer of the desktop.
- * 
+ *
  * Make \a object the top layer.
  */
 void SPDesktop::setCurrentLayer(SPObject *object) {
@@ -429,8 +492,12 @@ bool SPDesktop::isLayer(SPObject *object) const {
 bool SPDesktop::isWithinViewport (SPItem *item) const
 {
     NR::Rect const viewport = get_display_area();
-    NR::Rect const bbox = sp_item_bbox_desktop(item);
-    return viewport.contains(bbox);
+    NR::Maybe<NR::Rect> const bbox = sp_item_bbox_desktop(item);
+    if (bbox) {
+        return viewport.contains(*bbox);
+    } else {
+        return true;
+    }
 }
 
 ///
@@ -476,6 +543,15 @@ SPDesktop::change_document (SPDocument *theDocument)
     selection->clear();
 
     setDocument (theDocument);
+
+    /* update the rulers, connect the desktop widget's signal to the new namedview etc.
+       (this can probably be done in a better way) */
+    Gtk::Window *parent = this->getToplevel();
+    g_assert(parent != NULL);
+    SPDesktopWidget *dtw = (SPDesktopWidget *) parent->get_data("desktopwidget");
+    if (dtw) dtw->desktop = this;
+    sp_desktop_widget_update_namedview(dtw);
+
     _namedview_modified (namedview, SP_OBJECT_MODIFIED_FLAG, this);
     _document_replaced_signal.emit (this, theDocument);
 }
@@ -620,7 +696,7 @@ SPDesktop::push_current_zoom (GList **history)
 }
 
 /**
- * Set viewbox.
+ * Set viewbox (x0, x1, y0 and y1 are in document pixels. Border is in screen pixels).
  */
 void
 SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double border, bool log)
@@ -648,7 +724,7 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double
         newscale = viewbox.dimensions()[NR::Y] / (y1 - y0);
     }
 
-    newscale = CLAMP(newscale, SP_DESKTOP_ZOOM_MIN, SP_DESKTOP_ZOOM_MAX);
+    newscale = CLAMP(newscale, SP_DESKTOP_ZOOM_MIN, SP_DESKTOP_ZOOM_MAX); // unit: 'screen pixels' per 'document pixels'
 
     int clear = FALSE;
     if (!NR_DF_TEST_CLOSE (newscale, scale, 1e-4 * scale)) {
@@ -659,13 +735,16 @@ SPDesktop::set_display_area (double x0, double y0, double x1, double y1, double
         clear = TRUE;
     }
 
-    /* Calculate top left corner */
+    /* 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;
 
     /* Scroll */
     sp_canvas_scroll_to (canvas, x0 * newscale - border, y1 * -newscale - border, clear);
 
+    /*  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);
+
     _widget->updateRulers();
     _widget->updateScrollbars(expansion(_d2w));
     _widget->updateZoom();
@@ -821,7 +900,7 @@ SPDesktop::zoom_page()
     NR::Rect d(NR::Point(0, 0),
                NR::Point(sp_document_width(doc()), sp_document_height(doc())));
 
-    if (d.dimensions()[NR::X] < 1.0 || d.dimensions()[NR::Y] < 1.0) {
+    if (d.isEmpty(1.0)) {
         return;
     }
 
@@ -852,13 +931,13 @@ SPDesktop::zoom_page_width()
 void
 SPDesktop::zoom_selection()
 {
-    NR::Rect const d = selection->bounds();
+    NR::Maybe<NR::Rect> const d = selection->bounds();
 
-    if (d.dimensions()[NR::X] < 0.1 || d.dimensions()[NR::Y] < 0.1) {
+    if ( !d || d->isEmpty(0.1) ) {
         return;
     }
 
-    set_display_area(d, 10);
+    set_display_area(*d, 10);
 }
 
 /**
@@ -880,29 +959,32 @@ SPDesktop::zoom_drawing()
     SPItem *docitem = SP_ITEM (sp_document_root (doc()));
     g_return_if_fail (docitem != NULL);
 
-    NR::Rect d = sp_item_bbox_desktop(docitem);
+    NR::Maybe<NR::Rect> d = sp_item_bbox_desktop(docitem);
 
     /* Note that the second condition here indicates that
     ** there are no items in the drawing.
     */
-    if ( d.dimensions()[NR::X] < 1.0 || d.dimensions()[NR::Y] < 1.0 ) {
+    if ( !d || d->isEmpty(1.0) ) {
         return;
     }
 
-    set_display_area(d, 10);
+    set_display_area(*d, 10);
 }
 
 /**
  * Scroll canvas by specific coordinate amount.
  */
 void
-SPDesktop::scroll_world (double dx, double dy)
+SPDesktop::scroll_world (double dx, double dy, bool is_scrolling)
 {
     g_assert(_widget);
 
     NR::Rect const viewbox = canvas->getViewbox();
 
-    sp_canvas_scroll_to(canvas, viewbox.min()[NR::X] - dx, viewbox.min()[NR::Y] - dy, FALSE);
+    sp_canvas_scroll_to(canvas, viewbox.min()[NR::X] - dx, viewbox.min()[NR::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);
 
     _widget->updateRulers();
     _widget->updateScrollbars(expansion(_d2w));
@@ -953,6 +1035,36 @@ SPDesktop::scroll_to_point (NR::Point const *p, gdouble autoscrollspeed)
     return false;
 }
 
+bool
+SPDesktop::is_iconified()
+{
+    return 0!=(window_state & GDK_WINDOW_STATE_ICONIFIED);
+}
+
+void
+SPDesktop::iconify()
+{
+    _widget->setIconified();
+}
+
+bool
+SPDesktop::is_maximized()
+{
+    return 0!=(window_state & GDK_WINDOW_STATE_MAXIMIZED);
+}
+
+void
+SPDesktop::maximize()
+{
+    _widget->setMaximized();
+}
+
+bool
+SPDesktop::is_fullscreen()
+{
+    return 0!=(window_state & GDK_WINDOW_STATE_FULLSCREEN);
+}
+
 void
 SPDesktop::fullscreen()
 {
@@ -983,6 +1095,12 @@ SPDesktop::setWindowTransient (void *p, int transient_policy)
     _widget->setTransient (p, transient_policy);
 }
 
+Gtk::Window*
+SPDesktop::getToplevel( )
+{
+    return _widget->getWindow();
+}
+
 void
 SPDesktop::presentWindow()
 {
@@ -1025,6 +1143,37 @@ SPDesktop::shutdown()
     return _widget->shutdown();
 }
 
+bool SPDesktop::onDeleteUI (GdkEventAny*)
+{
+    if(shutdown()) 
+        return true;
+
+    destroyWidget();
+    return false;
+}
+
+/**
+ *  onWindowStateEvent
+ *
+ *  Called when the window changes its maximize/fullscreen/iconify/pinned state.
+ *  Since GTK doesn't have a way to query this state information directly, we
+ *  record it for the desktop here, and also possibly trigger a layout.
+ */
+bool
+SPDesktop::onWindowStateEvent (GdkEventWindowState* event)
+{
+       // Record the desktop window's state
+    window_state = event->new_window_state;
+
+    // Layout may differ depending on full-screen mode or not
+    GdkWindowState changed = event->changed_mask;
+    if (changed & (GDK_WINDOW_STATE_FULLSCREEN|GDK_WINDOW_STATE_MAXIMIZED)) {
+        layoutWidget();
+    }
+
+       return false;
+}
+
 void
 SPDesktop::setToolboxFocusTo (gchar const *label)
 {
@@ -1037,6 +1186,12 @@ SPDesktop::setToolboxAdjustmentValue (gchar const* id, double val)
     _widget->setToolboxAdjustmentValue (id, val);
 }
 
+void
+SPDesktop::setToolboxSelectOneValue (gchar const* id, gint val)
+{
+    _widget->setToolboxSelectOneValue (id, val);
+}
+
 bool
 SPDesktop::isToolboxButtonActive (gchar const *id)
 {
@@ -1067,6 +1222,64 @@ void SPDesktop::disableInteraction()
   _widget->disableInteraction();
 }
 
+void SPDesktop::setWaitingCursor()
+{
+    GdkCursor *waiting = gdk_cursor_new(GDK_WATCH);
+    gdk_window_set_cursor(GTK_WIDGET(sp_desktop_canvas(this))->window, waiting);
+    gdk_cursor_unref(waiting);
+    waiting_cursor = true;
+
+    // Stupidly broken GDK cannot just set the new cursor right now - it needs some main loop iterations for that
+    // Since setting waiting_cursor is usually immediately followed by some Real Work, we must run the iterations here
+    // CAUTION: iterations may redraw, and redraw may be interrupted, so you cannot assume that anything is the same
+    // after the call to setWaitingCursor as it was before
+    while( Gtk::Main::events_pending() )
+       Gtk::Main::iteration();
+}
+
+void SPDesktop::clearWaitingCursor()
+{
+  if (waiting_cursor)
+      sp_event_context_update_cursor(sp_desktop_event_context(this));
+}
+
+void SPDesktop::toggleColorProfAdjust()
+{
+    _widget->toggleColorProfAdjust();
+}
+
+void SPDesktop::toggleGrids()
+{
+    if (namedview->grids) {
+        if(gridgroup) {
+            showGrids(!grids_visible);
+        }
+    } else {
+        //there is no grid present at the moment. add a rectangular grid and make it visible
+        Inkscape::XML::Node *repr = SP_OBJECT_REPR(namedview);
+        Inkscape::CanvasGrid::writeNewGridToRepr(repr, sp_desktop_document(this), Inkscape::GRID_RECTANGULAR);
+        showGrids(true);
+    }
+}
+
+void SPDesktop::showGrids(bool show, bool dirty_document)
+{
+    grids_visible = show;
+    sp_namedview_show_grids(namedview, grids_visible, dirty_document);
+    if (show) {
+        sp_canvas_item_show(SP_CANVAS_ITEM(gridgroup));
+    } else {
+        sp_canvas_item_hide(SP_CANVAS_ITEM(gridgroup));
+    }
+}
+
+void SPDesktop::toggleSnapping()
+{
+    bool v = namedview->snap_manager.getSnapEnabledGlobally();
+    Inkscape::XML::Node *repr = SP_OBJECT_REPR(namedview);
+    sp_repr_set_boolean(repr, "inkscape:snap-global", !v);
+}
+
 //----------------------------------------------------------------------
 // Callback implementations. The virtual ones are connected by the view.
 
@@ -1077,7 +1290,7 @@ SPDesktop::onPositionSet (double x, double y)
 }
 
 void
-SPDesktop::onResized (double x, double y)
+SPDesktop::onResized (double /*x*/, double /*y*/)
 {
    // Nothing called here
 }
@@ -1102,7 +1315,6 @@ SPDesktop::updateCanvasNow()
 /**
  * Associate document with desktop.
  */
-/// \todo fixme: refactor SPDesktop::init to use setDocument
 void
 SPDesktop::setDocument (SPDocument *doc)
 {
@@ -1129,10 +1341,11 @@ SPDesktop::setDocument (SPDocument *doc)
     _commit_connection = doc->connectCommit(sigc::mem_fun(*this, &SPDesktop::updateNow));
 
     /// \todo fixme: This condition exists to make sure the code
-    /// inside is called only once on initialization. But there
+    /// inside is NOT called on initialization, only on replacement. But there
     /// are surely more safe methods to accomplish this.
+    // TODO since the comment had reversed logic, check the intent of this block of code:
     if (drawing) {
-        NRArenaItem *ai;
+        NRArenaItem *ai = 0;
 
         namedview = sp_document_namedview (doc, NULL);
         _modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this));
@@ -1203,7 +1416,7 @@ SPDesktop::_onDeactivate (SPDesktop* dt)
 
 void
 SPDesktop::_onSelectionModified
-(Inkscape::Selection *selection, guint flags, SPDesktop *dt)
+(Inkscape::Selection */*selection*/, guint /*flags*/, SPDesktop *dt)
 {
     if (!dt->_widget) return;
     dt->_widget->updateScrollbars (expansion(dt->_d2w));
@@ -1233,7 +1446,7 @@ _onSelectionChanged
  * \todo fixme
  */
 static gint
-_arena_handler (SPCanvasArena *arena, NRArenaItem *ai, GdkEvent *event, SPDesktop *desktop)
+_arena_handler (SPCanvasArena */*arena*/, NRArenaItem *ai, GdkEvent *event, SPDesktop *desktop)
 {
     if (ai) {
         SPItem *spi = (SPItem*)NR_ARENA_ITEM_GET_DATA (ai);
@@ -1258,7 +1471,7 @@ _layer_deactivated(SPObject *layer, SPDesktop *desktop) {
 
 /// Callback
 static void
-_layer_hierarchy_changed(SPObject *top, SPObject *bottom,
+_layer_hierarchy_changed(SPObject */*top*/, SPObject *bottom,
                                          SPDesktop *desktop)
 {
     desktop->_layer_changed_signal.emit (bottom);
@@ -1350,7 +1563,7 @@ _namedview_modified (SPObject *obj, guint flags, SPDesktop *desktop)
                     ((CtrlRect *) desktop->page)->setShadow(0, 0x00000000);
                 }
         }
-       
+
         /* Show/hide page shadow */
         if (nv->showpageshadow && nv->pageshadow) {
             ((CtrlRect *) desktop->page_border)->setShadow(nv->pageshadow, nv->bordercolor);
@@ -1380,16 +1593,18 @@ _update_snap_distances (SPDesktop *desktop)
 
     SPNamedView &nv = *desktop->namedview;
 
-    nv.snap_manager.grid.setDistance(sp_convert_distance_full(nv.gridtolerance,
-                                                                      *nv.gridtoleranceunit,
-                                                                      px));
-    nv.snap_manager.axonomgrid.setDistance(sp_convert_distance_full(nv.gridtolerance,
+    //tell all grid snappers
+    for ( GSList const *l = nv.grids; l != NULL; l = l->next) {
+        Inkscape::CanvasGrid *grid = (Inkscape::CanvasGrid*) l->data;
+        grid->snapper->setSnapperTolerance(sp_convert_distance_full(nv.gridtolerance,
                                                                       *nv.gridtoleranceunit,
                                                                       px));
-    nv.snap_manager.guide.setDistance(sp_convert_distance_full(nv.guidetolerance,
+    }
+
+    nv.snap_manager.guide.setSnapperTolerance(sp_convert_distance_full(nv.guidetolerance,
                                                                        *nv.guidetoleranceunit,
                                                                        px));
-    nv.snap_manager.object.setDistance(sp_convert_distance_full(nv.objecttolerance,
+    nv.snap_manager.object.setSnapperTolerance(sp_convert_distance_full(nv.objecttolerance,
                                                                         *nv.objecttoleranceunit,
                                                                         px));
 }