Code

Avoid crash by uninitialized perspectives.
[inkscape.git] / src / lpe-tool-context.cpp
index 9b0a8380b9de78b8d3a5596dd654e73f81f6cb0d..be465e32469b1eaf08d7b63163844306dfe1848e 100644 (file)
 #include <gtk/gtk.h>
 #include "desktop.h"
 #include "message-context.h"
-#include "prefs-utils.h"
+#include "preferences.h"
 #include "shape-editor.h"
 #include "selection.h"
 #include "desktop-handles.h"
 #include "document.h"
 #include "display/curve.h"
 #include "display/canvas-bpath.h"
+#include "display/canvas-text.h"
 #include "message-stack.h"
 #include "sp-path.h"
 #include "helper/units.h"
@@ -45,22 +46,24 @@ static void sp_lpetool_context_init(SPLPEToolContext *erc);
 static void sp_lpetool_context_dispose(GObject *object);
 
 static void sp_lpetool_context_setup(SPEventContext *ec);
-static void sp_lpetool_context_set(SPEventContext *ec, gchar const *key, gchar const *val);
+static void sp_lpetool_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *);
+static gint sp_lpetool_context_item_handler(SPEventContext *ec, SPItem *item, GdkEvent *event);
 static gint sp_lpetool_context_root_handler(SPEventContext *ec, GdkEvent *event);
 
 void sp_lpetool_context_selection_changed(Inkscape::Selection *selection, gpointer data);
 
 const int num_subtools = 8;
 
-Inkscape::LivePathEffect::EffectType lpesubtools[] = {
-    Inkscape::LivePathEffect::INVALID_LPE, // this must be here to account for the "all inactive" action
-    Inkscape::LivePathEffect::LINE_SEGMENT,
-    Inkscape::LivePathEffect::CIRCLE_3PTS,
-    Inkscape::LivePathEffect::CIRCLE_WITH_RADIUS,
-    Inkscape::LivePathEffect::PARALLEL,
-    Inkscape::LivePathEffect::PERP_BISECTOR,
-    Inkscape::LivePathEffect::ANGLE_BISECTOR,
-    Inkscape::LivePathEffect::MIRROR_SYMMETRY,
+SubtoolEntry lpesubtools[] = {
+    // this must be here to account for the "all inactive" action
+    {Inkscape::LivePathEffect::INVALID_LPE, "draw-geometry-inactive"},
+    {Inkscape::LivePathEffect::LINE_SEGMENT, "draw-geometry-line-segment"},
+    {Inkscape::LivePathEffect::CIRCLE_3PTS, "draw-geometry-circle-from-three-points"},
+    {Inkscape::LivePathEffect::CIRCLE_WITH_RADIUS, "draw-geometry-circle-from-radius"},
+    {Inkscape::LivePathEffect::PARALLEL, "draw-geometry-line-parallel"},
+    {Inkscape::LivePathEffect::PERP_BISECTOR, "draw-geometry-line-perpendicular"},
+    {Inkscape::LivePathEffect::ANGLE_BISECTOR, "draw-geometry-angle-bisector"},
+    {Inkscape::LivePathEffect::MIRROR_SYMMETRY, "draw-geometry-mirror"}
 };
 
 static SPPenContextClass *lpetool_parent_class = 0;
@@ -99,6 +102,7 @@ sp_lpetool_context_class_init(SPLPEToolContextClass *klass)
     event_context_class->setup = sp_lpetool_context_setup;
     event_context_class->set = sp_lpetool_context_set;
     event_context_class->root_handler = sp_lpetool_context_root_handler;
+    event_context_class->item_handler = sp_lpetool_context_item_handler;
 }
 
 static void
@@ -162,13 +166,15 @@ sp_lpetool_context_setup(SPEventContext *ec)
 
 // TODO temp force:
     ec->enableSelectionCue();
+    
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
 
     if (item) {
         lc->shape_editor->set_item(item, SH_NODEPATH);
         lc->shape_editor->set_item(item, SH_KNOTHOLDER);
     }
 
-    if (prefs_get_int_attribute("tools.lpetool", "selcue", 0) != 0) {
+    if (prefs->getBool("/tools/lpetool/selcue")) {
         ec->enableSelectionCue();
     }
 
@@ -197,18 +203,50 @@ sp_lpetool_context_selection_changed(Inkscape::Selection *selection, gpointer da
 }
 
 static void
-sp_lpetool_context_set(SPEventContext *ec, gchar const *key, gchar const *val)
+sp_lpetool_context_set(SPEventContext *ec, Inkscape::Preferences::Entry *val)
 {
-    // FIXME: how to set this correcly? the value from preferences-skeleton.h doesn't seem to get
-    // read (it wants to set drag = 1)
-    lpetool_parent_class->set(ec, key, "drag");
+    if (val->getEntryName() == "mode") {
+        Inkscape::Preferences::get()->setString("/tools/geometric/mode", "drag");
+        SP_PEN_CONTEXT(ec)->mode = SP_PEN_CONTEXT_MODE_DRAG;
+    }
 
-    /**
+    /*
     //pass on up to parent class to handle common attributes.
     if ( lpetool_parent_class->set ) {
         lpetool_parent_class->set(ec, key, val);
     }
-    **/
+    */
+}
+
+static gint 
+sp_lpetool_context_item_handler(SPEventContext *ec, SPItem *item, GdkEvent *event)
+{
+    gint ret = FALSE;
+
+    switch (event->type) {
+        case GDK_BUTTON_PRESS:
+        {
+            // select the clicked item but do nothing else
+            Inkscape::Selection * const selection = sp_desktop_selection(ec->desktop);
+            selection->clear();
+            selection->add(item);
+            ret = TRUE;
+            break;
+        }
+        case GDK_BUTTON_RELEASE:
+            // TODO: do we need to catch this or can we pass it on to the parent handler?
+            ret = TRUE;
+            break;
+        default:
+            break;
+    }
+
+    if (!ret) {
+        if (((SPEventContextClass *) lpetool_parent_class)->item_handler)
+            ret = ((SPEventContextClass *) lpetool_parent_class)->item_handler(ec, item, event);
+    }
+
+    return ret;
 }
 
 gint
@@ -230,7 +268,9 @@ sp_lpetool_context_root_handler(SPEventContext *event_context, GdkEvent *event)
         case GDK_BUTTON_PRESS:
             if (event->button.button == 1 && !event_context->space_panning) {
                 if (lc->mode == Inkscape::LivePathEffect::INVALID_LPE) {
-                    // don't do anything for now if we are inactive
+                    // don't do anything for now if we are inactive (except clearing the selection
+                    // since this was a click into empty space)
+                    selection->clear();
                     desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Choose a construction tool from the toolbar."));
                     ret = true;
                     break;
@@ -244,10 +284,11 @@ sp_lpetool_context_root_handler(SPEventContext *event_context, GdkEvent *event)
 
                 using namespace Inkscape::LivePathEffect;
 
-                int mode = prefs_get_int_attribute("tools.lpetool", "mode", 0);
-                EffectType type = lpesubtools[mode];
+                Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+                int mode = prefs->getInt("/tools/lpetool/mode");
+                EffectType type = lpesubtools[mode].type;
 
-                //bool over_stroke = lc->shape_editor->is_over_stroke(NR::Point(event->button.x, event->button.y), true);
+                //bool over_stroke = lc->shape_editor->is_over_stroke(Geom::Point(event->button.x, event->button.y), true);
 
                 sp_pen_context_wait_for_LPE_mouse_clicks(lc, type, Inkscape::LivePathEffect::Effect::acceptsNumClicks(type));
 
@@ -262,7 +303,7 @@ sp_lpetool_context_root_handler(SPEventContext *event_context, GdkEvent *event)
             }
 
             bool over_stroke = false;
-            over_stroke = lc->shape_editor->is_over_stroke(NR::Point(event->motion.x, event->motion.y), false);
+            over_stroke = lc->shape_editor->is_over_stroke(Geom::Point(event->motion.x, event->motion.y), false);
 
             if (over_stroke) {
                 event_context->cursor_shape = cursor_node_xpm;
@@ -325,7 +366,7 @@ sp_lpetool_context_root_handler(SPEventContext *event_context, GdkEvent *event)
 int
 lpetool_mode_to_index(Inkscape::LivePathEffect::EffectType const type) {
     for (int i = 0; i < num_subtools; ++i) {
-        if (lpesubtools[i] == type) {
+        if (lpesubtools[i].type == type) {
             return i;
         }
     }
@@ -336,7 +377,7 @@ lpetool_mode_to_index(Inkscape::LivePathEffect::EffectType const type) {
  * Checks whether an item has a construction applied as LPE and if so returns the index in
  * lpesubtools of this construction
  */
-int lpetool_item_has_construction(SPLPEToolContext *lc, SPItem *item)
+int lpetool_item_has_construction(SPLPEToolContext */*lc*/, SPItem *item)
 {
     if (!SP_IS_LPE_ITEM(item)) {
         return -1;
@@ -384,11 +425,12 @@ void
 lpetool_get_limiting_bbox_corners(SPDocument *document, Geom::Point &A, Geom::Point &B) {
     Geom::Coord w = sp_document_width(document);
     Geom::Coord h = sp_document_height(document);
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
 
-    double ulx = prefs_get_double_attribute ("tools.lpetool", "bbox_upperleftx", 0);
-    double uly = prefs_get_double_attribute ("tools.lpetool", "bbox_upperlefty", 0);
-    double lrx = prefs_get_double_attribute ("tools.lpetool", "bbox_lowerrightx", w);
-    double lry = prefs_get_double_attribute ("tools.lpetool", "bbox_lowerrighty", h);
+    double ulx = prefs->getDouble("/tools/lpetool/bbox_upperleftx", 0);
+    double uly = prefs->getDouble("/tools/lpetool/bbox_upperlefty", 0);
+    double lrx = prefs->getDouble("/tools/lpetool/bbox_lowerrightx", w);
+    double lry = prefs->getDouble("/tools/lpetool/bbox_lowerrighty", h);
 
     A = Geom::Point(ulx, uly);
     B = Geom::Point(lrx, lry);
@@ -406,14 +448,15 @@ lpetool_context_reset_limiting_bbox(SPLPEToolContext *lc)
         lc->canvas_bbox = NULL;
     }
 
-    if (prefs_get_int_attribute("tools.lpetool", "show_bbox", 1) == 0)
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    if (!prefs->getBool("/tools/lpetool/show_bbox", true))
         return;
 
     SPDocument *document = sp_desktop_document(lc->desktop);
 
     Geom::Point A, B;
     lpetool_get_limiting_bbox_corners(document, A, B);
-    NR::Matrix doc2dt(lc->desktop->doc2dt());
+    Geom::Matrix doc2dt(lc->desktop->doc2dt());
     A *= doc2dt;
     B *= doc2dt;
 
@@ -426,7 +469,7 @@ lpetool_context_reset_limiting_bbox(SPLPEToolContext *lc)
 
 static void
 set_pos_and_anchor(SPCanvasText *canvas_text, const Geom::Piecewise<Geom::D2<Geom::SBasis> > &pwd2,
-                   const double t, const double length, bool use_curvature = false)
+                   const double t, const double length, bool /*use_curvature*/ = false)
 {
     using namespace Geom;
 
@@ -444,10 +487,11 @@ set_pos_and_anchor(SPCanvasText *canvas_text, const Geom::Piecewise<Geom::D2<Geo
 void
 lpetool_create_measuring_items(SPLPEToolContext *lc, Inkscape::Selection *selection)
 {
-    bool show = prefs_get_int_attribute ("tools.lpetool", "show_measuring_info",  1) == 1 ? true : false;
     if (!selection) {
         selection = sp_desktop_selection(lc->desktop);
     }
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    bool show = prefs->getBool("/tools/lpetool/show_measuring_info",  true);
 
     SPPath *path;
     SPCurve *curve;
@@ -465,7 +509,7 @@ lpetool_create_measuring_items(SPLPEToolContext *lc, Inkscape::Selection *select
             if (!show)
                 sp_canvas_item_hide(SP_CANVAS_ITEM(canvas_text));
 
-            SPUnitId unitid = static_cast<SPUnitId>(prefs_get_int_attribute("tools.lpetool", "unitid", SP_UNIT_PX));
+            SPUnitId unitid = static_cast<SPUnitId>(prefs->getInt("/tools/lpetool/unitid", SP_UNIT_PX));
             SPUnit unit = sp_unit_get_by_id(unitid);
 
             lengthval = Geom::length(pwd2);
@@ -493,6 +537,7 @@ lpetool_delete_measuring_items(SPLPEToolContext *lc)
 void
 lpetool_update_measuring_items(SPLPEToolContext *lc)
 {
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
     SPPath *path;
     SPCurve *curve;
     double lengthval;
@@ -502,7 +547,7 @@ lpetool_update_measuring_items(SPLPEToolContext *lc)
         path = i->first;
         curve = sp_shape_get_curve(SP_SHAPE(path));
         Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = Geom::paths_to_pw(curve->get_pathvector());
-        SPUnitId unitid = static_cast<SPUnitId>(prefs_get_int_attribute("tools.lpetool", "unitid", SP_UNIT_PX));
+        SPUnitId unitid = static_cast<SPUnitId>(prefs->getInt("/tools/lpetool/unitid", SP_UNIT_PX));
         SPUnit unit = sp_unit_get_by_id(unitid);
         lengthval = Geom::length(pwd2);
         gboolean success;