Code

Clear the mssage context after drag filling
[inkscape.git] / src / sp-namedview.cpp
index 4be180237da119729dc7461c799463b5bcbacadd..a11904570dd626b2e08d61f231460900685f0a6b 100644 (file)
@@ -7,6 +7,7 @@
  *   Lauris Kaplinski <lauris@kaplinski.com>
  *   bulia byak <buliabyak@users.sf.net>
  *
+ * Copyright (C) 2006      Johan Engelen <johan@shouraizou.nl>
  * Copyright (C) 1999-2005 Authors
  * Copyright (C) 2000-2001 Ximian, Inc.
  *
@@ -23,6 +24,7 @@
 #include "document.h"
 #include "desktop-events.h"
 #include "desktop-handles.h"
+#include "event-log.h"
 #include "sp-guide.h"
 #include "sp-item-group.h"
 #include "sp-namedview.h"
@@ -104,9 +106,6 @@ static void sp_namedview_class_init(SPNamedViewClass * klass)
 
 static void sp_namedview_init(SPNamedView *nv)
 {
-    // explicitly call a contructor
-    new(nv) SPNamedView();
-
     nv->editable = TRUE;
     nv->showgrid = FALSE;
     nv->showguides = TRUE;
@@ -115,10 +114,13 @@ static void sp_namedview_init(SPNamedView *nv)
 
     nv->guides = NULL;
     nv->viewcount = 0;
+    nv->grids = NULL;
 
     nv->default_layer_id = 0;
 
     nv->connector_spacing = defaultConnSpacing;
+
+    new (&nv->snap_manager) SnapManager(nv);
 }
 
 static void sp_namedview_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
@@ -137,7 +139,6 @@ static void sp_namedview_build(SPObject *object, SPDocument *document, Inkscape:
     sp_object_read_attr(object, "gridtolerance");
     sp_object_read_attr(object, "guidetolerance");
     sp_object_read_attr(object, "objecttolerance");
-    sp_object_read_attr(object, "inkscape:has_abs_tolerance");
     sp_object_read_attr(object, "gridoriginx");
     sp_object_read_attr(object, "gridoriginy");
     sp_object_read_attr(object, "gridspacingx");
@@ -166,12 +167,12 @@ static void sp_namedview_build(SPObject *object, SPDocument *document, Inkscape:
     sp_object_read_attr(object, "inkscape:window-height");
     sp_object_read_attr(object, "inkscape:window-x");
     sp_object_read_attr(object, "inkscape:window-y");
-    sp_object_read_attr(object, "inkscape:grid-bbox");
+/*  sp_object_read_attr(object, "inkscape:grid-bbox");
     sp_object_read_attr(object, "inkscape:guide-bbox");
     sp_object_read_attr(object, "inkscape:object-bbox");
     sp_object_read_attr(object, "inkscape:grid-points");
     sp_object_read_attr(object, "inkscape:guide-points");
-    sp_object_read_attr(object, "inkscape:object-points");
+    sp_object_read_attr(object, "inkscape:object-points");*/
     sp_object_read_attr(object, "inkscape:object-paths");
     sp_object_read_attr(object, "inkscape:object-nodes");
     sp_object_read_attr(object, "inkscape:current-layer");
@@ -202,11 +203,18 @@ static void sp_namedview_release(SPObject *object)
         namedview->gridviews = g_slist_remove(namedview->gridviews, namedview->gridviews->data);
     }
 
+    // delete grids:
+    while ( namedview->grids ) {
+        Inkscape::CanvasGrid *gr = (Inkscape::CanvasGrid *)namedview->grids->data;
+        delete gr;
+        namedview->grids = g_slist_remove_link(namedview->grids, namedview->grids);
+    }
+
     if (((SPObjectClass *) parent_class)->release) {
         ((SPObjectClass *) parent_class)->release(object);
     }
 
-    namedview->~SPNamedView();
+    namedview->snap_manager.~SnapManager();
 }
 
 static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *value)
@@ -222,6 +230,8 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va
        case SP_ATTR_SHOWGRID:
             nv->showgrid = sp_str_to_bool(value);
             sp_namedview_setup_grid(nv);
+            /* Disable grid snaps if the grid is turned off */
+            nv->snap_manager.grid.setEnabled(nv->showgrid);
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
        case SP_ATTR_SHOWGUIDES:
@@ -257,13 +267,6 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va
             }
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
-       case SP_ATTR_ABS_TOLERANCE:
-             if (!value)
-                 nv->has_abs_tolerance = true;
-             else
-                 nv->has_abs_tolerance = (sp_str_to_bool (value) == TRUE);
-             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
-             break;
        case SP_ATTR_GRIDORIGINX:
        case SP_ATTR_GRIDORIGINY:
        {
@@ -292,7 +295,7 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
        }
-       case SP_ATTR_GRIDCOLOR:
+    case SP_ATTR_GRIDCOLOR:
             nv->gridcolor = (nv->gridcolor & 0xff) | (DEFAULTGRIDCOLOR & 0xffffff00);
             if (value) {
                 nv->gridcolor = (nv->gridcolor & 0xff) | sp_svg_read_color(value, nv->gridcolor);
@@ -432,7 +435,7 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va
             nv->window_y = value ? atoi(value) : -1; // -1 means not set
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
-       case SP_ATTR_INKSCAPE_GRID_BBOX:
+/*     case SP_ATTR_INKSCAPE_GRID_BBOX:
             nv->snap_manager.grid.setSnapTo(Inkscape::Snapper::BBOX_POINT, value ? sp_str_to_bool(value) : TRUE);
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
@@ -456,6 +459,7 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va
             nv->snap_manager.object.setSnapTo(Inkscape::Snapper::SNAP_POINT, (value) ? sp_str_to_bool(value) : FALSE);
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
             break;
+*/
         case SP_ATTR_INKSCAPE_OBJECT_PATHS:
             nv->snap_manager.object.setSnapToPaths(value ? sp_str_to_bool(value) : TRUE);
             object->requestModified(SP_OBJECT_MODIFIED_FLAG);
@@ -522,6 +526,47 @@ static void sp_namedview_set(SPObject *object, unsigned int key, const gchar *va
     }
 }
 
+/**
+* add a grid item from SVG-repr. Check if this namedview already has a gridobject for this one! If desktop=null, add grid-canvasitem to all desktops of this namedview,
+* otherwise only add it to the specified desktop.
+*/
+static Inkscape::CanvasGrid* 
+sp_namedview_add_grid(SPNamedView *nv, Inkscape::XML::Node *repr, SPDesktop *desktop) {
+    Inkscape::CanvasGrid* grid = NULL;
+    //check if namedview already has an object for this grid
+    for (GSList *l = nv->grids; l != NULL; l = l->next) {
+        Inkscape::CanvasGrid* g = (Inkscape::CanvasGrid*) l->data;
+        if (repr == g->repr) {
+            grid = g;
+            break;
+        }
+    }
+    
+    if (!grid) {
+        //create grid object
+        const char * gridtype = repr->attribute("type");
+        if (!gridtype) {
+            gridtype = "xygrid"; // use this as default gridtype when none is specified
+            repr->setAttribute("type", gridtype);
+        }
+        grid = Inkscape::CanvasGrid::NewGrid(nv, repr, gridtype);
+        nv->grids = g_slist_append(nv->grids, grid);
+    }
+    
+    if (!desktop) {
+        //add canvasitem to all desktops
+        for (GSList *l = nv->views; l != NULL; l = l->next) {
+            SPDesktop *dt = static_cast<SPDesktop*>(l->data);
+            grid->createCanvasItem(dt);
+        }
+    } else {
+        //add canvasitem only for specified desktop
+        grid->createCanvasItem(desktop);
+    }
+
+    return grid;
+}
+
 static void sp_namedview_child_added(SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref)
 {
     SPNamedView *nv = (SPNamedView *) object;
@@ -531,27 +576,31 @@ static void sp_namedview_child_added(SPObject *object, Inkscape::XML::Node *chil
     }
 
     const gchar *id = child->attribute("id");
-    SPObject *no = object->document->getObjectById(id);
-    g_assert(SP_IS_OBJECT(no));
-
-    if (SP_IS_GUIDE(no)) {
-        SPGuide *g = (SPGuide *) no;
-        nv->guides = g_slist_prepend(nv->guides, g);
-        g_object_set(G_OBJECT(g), "color", nv->guidecolor, "hicolor", nv->guidehicolor, NULL);
-        if (nv->editable) {
-            for (GSList *l = nv->views; l != NULL; l = l->next) {
-                sp_guide_show(g, static_cast<SPDesktop*>(l->data)->guides, (GCallback) sp_dt_guide_event);
-                if (static_cast<SPDesktop*>(l->data)->guides_active)
-                    sp_guide_sensitize(g,
-                                       sp_desktop_canvas(static_cast<SPDesktop*> (l->data)),
-                                       TRUE);
-                if (nv->showguides) {
-                    for (GSList *v = SP_GUIDE(g)->views; v != NULL; v = v->next) {
-                        sp_canvas_item_show(SP_CANVAS_ITEM(v->data));
-                    }
-                } else {
-                    for (GSList *v = SP_GUIDE(g)->views; v != NULL; v = v->next) {
-                        sp_canvas_item_hide(SP_CANVAS_ITEM(v->data));
+    if (!strcmp(child->name(), "inkscape:grid")) {
+        sp_namedview_add_grid(nv, child, NULL);
+    } else {
+        SPObject *no = object->document->getObjectById(id);
+        g_assert(SP_IS_OBJECT(no));
+
+        if (SP_IS_GUIDE(no)) {
+            SPGuide *g = (SPGuide *) no;
+            nv->guides = g_slist_prepend(nv->guides, g);
+            g_object_set(G_OBJECT(g), "color", nv->guidecolor, "hicolor", nv->guidehicolor, NULL);
+            if (nv->editable) {
+                for (GSList *l = nv->views; l != NULL; l = l->next) {
+                    sp_guide_show(g, static_cast<SPDesktop*>(l->data)->guides, (GCallback) sp_dt_guide_event);
+                    if (static_cast<SPDesktop*>(l->data)->guides_active)
+                        sp_guide_sensitize(g,
+                                           sp_desktop_canvas(static_cast<SPDesktop*> (l->data)),
+                                           TRUE);
+                    if (nv->showguides) {
+                        for (GSList *v = SP_GUIDE(g)->views; v != NULL; v = v->next) {
+                            sp_canvas_item_show(SP_CANVAS_ITEM(v->data));
+                        }
+                    } else {
+                        for (GSList *v = SP_GUIDE(g)->views; v != NULL; v = v->next) {
+                            sp_canvas_item_hide(SP_CANVAS_ITEM(v->data));
+                        }
                     }
                 }
             }
@@ -563,15 +612,26 @@ static void sp_namedview_remove_child(SPObject *object, Inkscape::XML::Node *chi
 {
     SPNamedView *nv = (SPNamedView *) object;
 
-    GSList **ref = &nv->guides;
-    for ( GSList *iter = nv->guides ; iter ; iter = iter->next ) {
-        if ( SP_OBJECT_REPR((SPObject *)iter->data) == child ) {
-            *ref = iter->next;
-            iter->next = NULL;
-            g_slist_free_1(iter);
-            break;
+    if (!strcmp(child->name(), "inkscape:grid")) {
+        for ( GSList *iter = nv->grids ; iter ; iter = iter->next ) {
+            Inkscape::CanvasGrid *gr = (Inkscape::CanvasGrid *)iter->data;
+            if ( gr->repr == child ) {
+                delete gr;
+                nv->grids = g_slist_remove_link(nv->grids, iter);
+                break;
+            }
+        }
+    } else {
+        GSList **ref = &nv->guides;
+        for ( GSList *iter = nv->guides ; iter ; iter = iter->next ) {
+            if ( SP_OBJECT_REPR((SPObject *)iter->data) == child ) {
+                *ref = iter->next;
+                iter->next = NULL;
+                g_slist_free_1(iter);
+                break;
+            }
+            ref = &iter->next;
         }
-        ref = &iter->next;
     }
 
     if (((SPObjectClass *) (parent_class))->remove_child) {
@@ -587,7 +647,8 @@ static Inkscape::XML::Node *sp_namedview_write(SPObject *object, Inkscape::XML::
         if (repr) {
             repr->mergeFrom(SP_OBJECT_REPR(object), "id");
         } else {
-            repr = SP_OBJECT_REPR(object)->duplicate();
+             /// \todo FIXME:  Plumb an appropriate XML::Document into this
+             repr = SP_OBJECT_REPR(object)->duplicate(NULL);
         }
     }
 
@@ -614,13 +675,26 @@ void SPNamedView::show(SPDesktop *desktop)
 
     views = g_slist_prepend(views, desktop);
 
-    SPCanvasItem *item = sp_canvas_item_new(sp_desktop_grid(desktop), SP_TYPE_CGRID, NULL);
+    SPCanvasItem * item = sp_canvas_item_new(sp_desktop_gridgroup(desktop), INKSCAPE_TYPE_CXYGRID, NULL);
     // since we're keeping a copy, we need to bump up the ref count
     gtk_object_ref(GTK_OBJECT(item));
     gridviews = g_slist_prepend(gridviews, item);
-    sp_namedview_setup_grid_item(this, item);
+
+    // generate grids specified in SVG:
+    Inkscape::XML::Node *repr = SP_OBJECT_REPR(this);
+    if (repr) {
+        for (Inkscape::XML::Node * child = repr->firstChild() ; child != NULL; child = child->next() ) {
+            if (!strcmp(child->name(), "inkscape:grid")) {
+                sp_namedview_add_grid(this, child, desktop);
+            }
+        }
+    }
+    
+    sp_namedview_setup_grid(this);
 }
 
+#define MIN_ONSCREEN_DISTANCE 50
+
 /*
  * Restores window geometry from the document settings
  */
@@ -631,10 +705,18 @@ void sp_namedview_window_from_document(SPDesktop *desktop)
 
     // restore window size and position
     if (save_geometry) {
-        if (nv->window_width != -1 && nv->window_height != -1)
-            desktop->setWindowSize(nv->window_width, nv->window_height);
-        if (nv->window_x != -1 && nv->window_y != -1)
-            desktop->setWindowPosition(NR::Point(nv->window_x, nv->window_y));
+        gint w = MIN(gdk_screen_width(), nv->window_width);
+        gint h = MIN(gdk_screen_height(), nv->window_height);
+        gint x = MIN(gdk_screen_width() - MIN_ONSCREEN_DISTANCE, nv->window_x);
+        gint y = MIN(gdk_screen_height() - MIN_ONSCREEN_DISTANCE, nv->window_y);
+        if (w>0 && h>0 && x>0 && y>0) {
+            x = MIN(gdk_screen_width() - w, x);
+            y = MIN(gdk_screen_height() - h, y);
+        }
+        if (w>0 && h>0)
+            desktop->setWindowSize(w, h);
+        if (x>0 && y>0)
+            desktop->setWindowPosition(NR::Point(x, y));
     }
 
     // restore zoom and view
@@ -651,9 +733,13 @@ void sp_namedview_window_from_document(SPDesktop *desktop)
         g_list_free(desktop->zooms_past);
         desktop->zooms_past = NULL;
     }
+}
 
+void sp_namedview_update_layers_from_document (SPDesktop *desktop)
+{
     SPObject *layer = NULL;
     SPDocument *document = desktop->doc();
+    SPNamedView *nv = desktop->namedview;
     if ( nv->default_layer_id != 0 ) {
         layer = document->getObjectById(g_quark_to_string(nv->default_layer_id));
     }
@@ -673,6 +759,9 @@ void sp_namedview_window_from_document(SPDesktop *desktop)
     if (layer) {
         desktop->setCurrentLayer(layer);
     }
+
+    // FIXME: find a better place to do this
+    desktop->event_log->updateUndoVerbs();
 }
 
 void sp_namedview_document_from_window(SPDesktop *desktop)
@@ -682,8 +771,8 @@ void sp_namedview_document_from_window(SPDesktop *desktop)
     NR::Rect const r = desktop->get_display_area();
 
     // saving window geometry is not undoable
-    gboolean saved = sp_document_get_undo_sensitive(sp_desktop_document(desktop));
-    sp_document_set_undo_sensitive(sp_desktop_document(desktop), FALSE);
+    bool saved = sp_document_get_undo_sensitive(sp_desktop_document(desktop));
+    sp_document_set_undo_sensitive(sp_desktop_document(desktop), false);
 
     sp_repr_set_svg_double(view, "inkscape:zoom", desktop->current_zoom());
     sp_repr_set_svg_double(view, "inkscape:cx", r.midpoint()[NR::X]);
@@ -717,16 +806,24 @@ void SPNamedView::hide(SPDesktop const *desktop)
 
     GSList *l;
     for (l = gridviews; l != NULL; l = l->next) {
-        if (SP_CANVAS_ITEM(l->data)->canvas == sp_desktop_canvas(desktop)) {
-            break;
+        if (! l->data) {
+            continue;
         }
-    }
+        SPCanvasItem *item = static_cast<SPCanvasItem*>(l->data);
 
-    g_assert(l);
+        if (item->canvas == sp_desktop_canvas(desktop)) {
+            sp_canvas_item_hide(SP_CANVAS_ITEM(l->data));
+            gtk_object_unref(GTK_OBJECT(l->data));
+            gridviews = g_slist_remove(gridviews, l->data);
+        }
+    }
 
-    sp_canvas_item_hide(SP_CANVAS_ITEM(l->data));
-    gtk_object_unref(GTK_OBJECT(l->data));
-    gridviews = g_slist_remove(gridviews, l->data);
+    // delete grids:
+    while ( grids ) {
+        Inkscape::CanvasGrid *gr = (Inkscape::CanvasGrid *)grids->data;
+        delete gr;
+        grids = g_slist_remove_link(grids, grids);
+    }
 }
 
 void SPNamedView::activateGuides(gpointer desktop, gboolean active)
@@ -766,8 +863,8 @@ void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr)
         v = !v;
     }
 
-    gboolean saved = sp_document_get_undo_sensitive(doc);
-    sp_document_set_undo_sensitive(doc, FALSE);
+    bool saved = sp_document_get_undo_sensitive(doc);
+    sp_document_set_undo_sensitive(doc, false);
 
     sp_repr_set_boolean(repr, "showguides", v);
 
@@ -781,8 +878,8 @@ void sp_namedview_toggle_grid(SPDocument *doc, Inkscape::XML::Node *repr)
     sp_repr_get_boolean(repr, "showgrid", &v);
     v = !v;
 
-    gboolean saved = sp_document_get_undo_sensitive(doc);
-    sp_document_set_undo_sensitive(doc, FALSE);
+    bool saved = sp_document_get_undo_sensitive(doc);
+    sp_document_set_undo_sensitive(doc, false);
 
     sp_repr_set_boolean(repr, "showgrid", v);
 
@@ -799,7 +896,7 @@ static void sp_namedview_setup_grid(SPNamedView *nv)
 
 static void sp_namedview_setup_grid_item(SPNamedView *nv, SPCanvasItem *item)
 {
-    if (nv->showgrid) {
+    if ( nv->showgrid ) {
         sp_canvas_item_show(item);
     } else {
         sp_canvas_item_hide(item);
@@ -816,6 +913,7 @@ static void sp_namedview_setup_grid_item(SPNamedView *nv, SPCanvasItem *item)
                        NULL);
 }
 
+
 gchar const *SPNamedView::getName() const
 {
     SPException ex;
@@ -908,7 +1006,7 @@ static gboolean sp_nv_read_opacity(const gchar *str, guint32 *color)
     }
 
     gchar *u;
-    gdouble v = strtod(str, &u);
+    gdouble v = g_ascii_strtod(str, &u);
     if (!u) {
         return FALSE;
     }
@@ -958,4 +1056,4 @@ SPMetric SPNamedView::getDefaultMetric() const
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtab