Code

Fix behavior when loading a document
[inkscape.git] / src / desktop.cpp
index 1f2baccbba2ed61559eb7d0ef70362dd9832accf..1953ae2a6e8db730bfff77ff61f52a8f398ba6dd 100644 (file)
 #include "widgets/desktop-widget.h"
 #include "box3d-context.h"
 
+// TODO those includes are only for node tool quick zoom. Remove them after fixing it.
+#include "ui/tool/node-tool.h"
+#include "ui/tool/control-point-selection.h"
+
 #include "display/sp-canvas.h"
 
 namespace Inkscape { namespace XML { class Node; }}
@@ -148,14 +152,13 @@ SPDesktop::SPDesktop() :
     _layer_hierarchy( 0 ),
     _reconstruction_old_layer_id( 0 ),
     _display_mode(Inkscape::RENDERMODE_NORMAL),
-    _saved_display_mode(Inkscape::RENDERMODE_NORMAL),
     _widget( 0 ),
     _inkscape( 0 ),
     _guides_message_context( 0 ),
     _active( false ),
     _w2d(),
     _d2w(),
-    _doc2dt( Geom::Scale(1, -1) ),
+    _doc2dt( Geom::identity() ),
     grids_visible( false )
 {
     _d2w.setIdentity();
@@ -165,8 +168,10 @@ SPDesktop::SPDesktop() :
 }
 
 void
-SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
+SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas, Inkscape::UI::View::EditWidgetInterface *widget)
 {
+    _widget = widget;
+
     // Temporary workaround for link order issues:
     Inkscape::DeviceManager::getManager().getDevices();
     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
@@ -226,11 +231,18 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
         setDisplayModeNormal();
     }
 
+    // The order in which these canvas items are added determines the z-order. It's therefore
+    // important to add the tempgroup (which will contain the snapindicator) before adding the
+    // controls. Only this way one will be able to quickly (before the snap indicator has
+    // disappeared) reselect a node after snapping it. If the z-order is wrong however, this
+    // will not work (the snap indicator is on top of the node handler; is the snapindicator
+    // being selected? or does it intercept some of the events that should have gone to the
+    // node handler? see bug https://bugs.launchpad.net/inkscape/+bug/414142)
     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);
+    controls = (SPCanvasGroup *) sp_canvas_item_new (main, SP_TYPE_CANVAS_GROUP, NULL);
 
     /* Push select tool to the bottom of stack */
     /** \todo
@@ -260,7 +272,6 @@ SPDesktop::init (SPNamedView *nv, SPCanvas *aCanvas)
 
 
     /* Connect event for page resize */
-    _doc2dt[5] = sp_document_height (document);
     sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (drawing), _doc2dt);
 
     _modified_connection = namedview->connectModified(sigc::bind<2>(sigc::ptr_fun(&_namedview_modified), this));
@@ -437,18 +448,24 @@ void SPDesktop::_setDisplayMode(Inkscape::RenderMode mode) {
     SP_CANVAS_ARENA (drawing)->arena->rendermode = mode;
     canvas->rendermode = mode;
     _display_mode = mode;
-    if (mode != Inkscape::RENDERMODE_OUTLINE) {
-        _saved_display_mode = _display_mode;
-    }
     sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (main), _d2w); // redraw
     _widget->setTitle(SP_DOCUMENT_NAME(sp_desktop_document(this)));
 }
 
 void SPDesktop::displayModeToggle() {
-    if (_display_mode == Inkscape::RENDERMODE_OUTLINE) {
-        _setDisplayMode(_saved_display_mode);
-    } else {
+    switch (_display_mode) {
+    case Inkscape::RENDERMODE_NORMAL:
+        _setDisplayMode(Inkscape::RENDERMODE_NO_FILTERS);
+        break;
+    case Inkscape::RENDERMODE_NO_FILTERS:
         _setDisplayMode(Inkscape::RENDERMODE_OUTLINE);
+        break;
+    case Inkscape::RENDERMODE_OUTLINE:
+        _setDisplayMode(Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW);
+        break;
+    case Inkscape::RENDERMODE_PRINT_COLORS_PREVIEW:
+    default:
+        _setDisplayMode(Inkscape::RENDERMODE_NORMAL);
     }
 }
 
@@ -591,8 +608,10 @@ SPDesktop::change_document (SPDocument *theDocument)
     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);
+    if (dtw) {
+        dtw->desktop = this;
+    }
+    dtw->updateNamedview();
 
     _namedview_modified (namedview, SP_OBJECT_MODIFIED_FLAG, this);
     _document_replaced_signal.emit (this, theDocument);
@@ -608,9 +627,12 @@ SPDesktop::set_event_context (GtkType type, const gchar *config)
     while (event_context) {
         ec = event_context;
         sp_event_context_deactivate (ec);
-        event_context = ec->next;
+        // we have to keep event_context valid during destruction - otherwise writing
+        // destructors is next to impossible
+        SPEventContext *next = ec->next;
         sp_event_context_finish (ec);
         g_object_unref (G_OBJECT (ec));
+        event_context = next;
     }
 
     ec = sp_event_context_new (type, this, config, SP_EVENT_CONTEXT_STATIC);
@@ -769,19 +791,20 @@ 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 = Geom::Scale(newscale, -newscale);
-        _w2d = Geom::Scale(1/newscale, 1/-newscale);
+        // zoom changed - set new zoom factors
+        _d2w = Geom::Scale(newscale);
+        _w2d = Geom::Scale(1/newscale);
         sp_canvas_item_affine_absolute(SP_CANVAS_ITEM(main), _d2w);
         clear = TRUE;
+        signal_zoom_changed.emit(_d2w.descrim());
     }
 
     /* Calculate top left corner (in document pixels) */
     x0 = cx - 0.5 * viewbox.dimensions()[Geom::X] / newscale;
-    y1 = cy + 0.5 * viewbox.dimensions()[Geom::Y] / newscale;
+    y0 = cy - 0.5 * viewbox.dimensions()[Geom::Y] / newscale;
 
     /* Scroll */
-    sp_canvas_scroll_to (canvas, x0 * newscale - border, y1 * -newscale - border, clear);
+    sp_canvas_scroll_to (canvas, x0 * newscale - border, y0 * 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);
@@ -805,8 +828,7 @@ Geom::Rect SPDesktop::get_display_area() const
 
     double const scale = _d2w[0];
 
-    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));
+    return viewbox * (1./scale);
 }
 
 /**
@@ -859,11 +881,6 @@ 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
 
@@ -879,57 +896,18 @@ SPDesktop::zoom_quick (bool enable)
         _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;
-                    }
+        // TODO This needs to migrate into the node tool, but currently the design
+        // of this method is sufficiently wrong to prevent this.
+        if (!zoomed && INK_IS_NODE_TOOL(event_context)) {
+            InkNodeTool *nt = static_cast<InkNodeTool*>(event_context);
+            if (!nt->_selected_nodes->empty()) {
+                Geom::Rect nodes = *nt->_selected_nodes->bounds();
+                double area = nodes.area();
+                // do not zoom if a single cusp node is selected aand the bounds
+                // have zero area.
+                if (!Geom::are_near(area, 0) && area * 2.0 < _quick_zoom_stored_area.area()) {
+                    set_display_area(nodes, true);
+                    zoomed = true;
                 }
             }
         }
@@ -937,7 +915,7 @@ SPDesktop::zoom_quick (bool enable)
         if (!zoomed) {
             Geom::OptRect const d = selection->bounds();
             if (d && d->area() * 2.0 < _quick_zoom_stored_area.area()) {
-                set_display_area(*d, 10);
+                set_display_area(*d, true);
                 zoomed = true;
             }
         }
@@ -947,7 +925,7 @@ SPDesktop::zoom_quick (bool enable)
             zoomed = true;
         }
     } else {
-        set_display_area(_quick_zoom_stored_area, 0);
+        set_display_area(_quick_zoom_stored_area, false);
     }
 
     _quick_zoom_enabled = enable;
@@ -1565,7 +1543,6 @@ SPDesktop::onDocumentURISet (gchar const* uri)
 void
 SPDesktop::onDocumentResized (gdouble width, gdouble height)
 {
-    _doc2dt[5] = height;
     sp_canvas_item_affine_absolute (SP_CANVAS_ITEM (drawing), _doc2dt);
     Geom::Rect const a(Geom::Point(0, 0), Geom::Point(width, height));
     SP_CTRLRECT(page)->setRectangle(a);
@@ -1655,7 +1632,7 @@ static void
 _reconstruction_start (SPDesktop * desktop)
 {
     // printf("Desktop, starting reconstruction\n");
-    desktop->_reconstruction_old_layer_id = g_strdup(SP_OBJECT_ID(desktop->currentLayer()));
+    desktop->_reconstruction_old_layer_id = g_strdup(desktop->currentLayer()->getId());
     desktop->_layer_hierarchy->setBottom(desktop->currentRoot());
 
     /*
@@ -1788,7 +1765,7 @@ Geom::Point SPDesktop::dt2doc(Geom::Point const &p) const
 }
 
 
-/**
+/*
  * Pop event context from desktop's context stack. Never used.
  */
 // void
@@ -1830,4 +1807,4 @@ Geom::Point SPDesktop::dt2doc(Geom::Point const &p) const
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :