Code

- Created a SPLPEItem class that handles applying a LPE to an Item
authorbgk <bgk@users.sourceforge.net>
Fri, 28 Mar 2008 19:13:14 +0000 (19:13 +0000)
committerbgk <bgk@users.sourceforge.net>
Fri, 28 Mar 2008 19:13:14 +0000 (19:13 +0000)
- LPEs can now be applied to groups
- Updated the bend path to work properly with groups

24 files changed:
src/Makefile_insert
src/box3d-side.cpp
src/draw-context.cpp
src/live_effects/Makefile_insert
src/live_effects/effect.cpp
src/live_effects/effect.h
src/live_effects/lpe-pathalongpath.cpp
src/live_effects/lpe-pathalongpath.h
src/nodepath.cpp
src/path-chemistry.cpp
src/selection-chemistry.cpp
src/sp-ellipse.cpp
src/sp-item-group.cpp
src/sp-item-group.h
src/sp-item.cpp
src/sp-path.cpp
src/sp-shape.cpp
src/sp-shape.h
src/sp-spiral.cpp
src/sp-star.cpp
src/tweak-context.cpp
src/ui/clipboard.cpp
src/ui/dialog/livepatheffect-editor.cpp
src/widgets/toolbox.cpp

index 99fed18c37a3aca5f03a22d8c1be7da5d30b2648..c4f196dd5cd82e754a178c31ee96ad459bc569f7 100644 (file)
@@ -232,6 +232,7 @@ libinkpre_a_SOURCES =       \
        sp-line.cpp sp-line.h   \
        sp-linear-gradient-fns.h        \
        sp-linear-gradient.h    \
+       sp-lpe-item.cpp sp-lpe-item.h   \
        sp-marker-loc.h \
        marker.cpp marker.h     \
        sp-mask.cpp sp-mask.h   \
index 4cd3765c90967aeda7cbb4adf28988a263ccf7b4..632a697afbc051e59ad761c5f65e7b60b0d362ab 100644 (file)
@@ -236,7 +236,7 @@ box3d_side_set_shape (SPShape *shape)
     sp_curve_lineto (c, box3d_get_corner_screen(box, corners[3]));
 
     sp_curve_closepath (c);
-    sp_shape_perform_path_effect(c, SP_SHAPE (side));
+    sp_lpe_item_perform_path_effect(SP_LPE_ITEM (side), c);
     sp_shape_set_curve_insync (SP_SHAPE (side), c, TRUE);
     sp_curve_unref (c);
 }
index 13ba9f82848358ef418b5df40d0ce809fb495e02..adcbc3b3c994346b98a852fadaad0fdea47a1ea1 100644 (file)
@@ -528,9 +528,7 @@ spdc_flush_white(SPDrawContext *dc, SPCurve *gc)
         Inkscape::XML::Node *repr;
         if (dc->white_item) {
             repr = SP_OBJECT_REPR(dc->white_item);
-            LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(SP_SHAPE(dc->white_item));
-            if (lpeobj) 
-                has_lpe = true;
+            has_lpe = sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(dc->white_item));
         } else {
             repr = xml_doc->createElement("svg:path");
             /* Set style */
index d7cc55939a3e012cff2c8d03011b8172c5a517e2..fee34a9d675341322e76e1e3175fa98c6494b416 100644 (file)
@@ -10,6 +10,8 @@ live_effects_liblive_effects_a_SOURCES = \
        live_effects/effect.h   \
        live_effects/lpeobject.cpp      \
        live_effects/lpeobject.h        \
+       live_effects/lpegroupbbox.cpp   \
+       live_effects/lpegroupbbox.h     \
        live_effects/lpeobject-reference.cpp    \
        live_effects/lpeobject-reference.h      \
        live_effects/n-art-bpath-2geom.cpp      \
index 777be6e77a2796ab92c3a90cb0ddf9a7b7649938..dc43af0d5073023a93f7fbfaeef94c7fee01e999 100644 (file)
@@ -132,6 +132,13 @@ Effect::getName()
         return Glib::ustring( _("No effect") );
 }
 
+void
+Effect::doBeforeEffect (SPLPEItem *lpeitem)
+{
+    //Do nothing for simple effects
+}
+
+
 /*
  *  Here be the doEffect function chain:
  */
index 6b5295071724a32f4bf97435104911ae66758b2a..b13ec5f6d1428d4254ddce176b5ea3c4b52c968d 100644 (file)
@@ -16,6 +16,7 @@
 #include <2geom/path.h>
 #include "ui/widget/registry.h"
 #include "util/enums.h"
+#include "sp-lpe-item.h"
 
 #define  LPE_CONVERSION_TOLERANCE 0.01    // FIXME: find good solution for this.
 
@@ -75,6 +76,8 @@ public:
 
     virtual ~Effect();
 
+    virtual void doBeforeEffect (SPLPEItem *lpeitem);
+
     virtual void doEffect (SPCurve * curve);
 
     virtual Gtk::Widget * newWidget(Gtk::Tooltips * tooltips);
index 0475f46033ef8efbd71ec04f9fcb28f1f34535ab..d17a0f84fa4dd5073865993dc81eb28e8a2fb936 100644 (file)
@@ -2,6 +2,7 @@
 
 /*
  * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ * Copyright (C) Steren Giannini 2008 <steren.giannini@gmail.com>
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -10,6 +11,7 @@
 #include "sp-shape.h"
 #include "sp-item.h"
 #include "sp-path.h"
+#include "sp-item-group.h"
 #include "display/curve.h"
 #include <libnr/n-art-bpath.h>
 #include <libnr/nr-matrix-fns.h>
@@ -66,6 +68,8 @@ LPEPathAlongPath::LPEPathAlongPath(LivePathEffectObject *lpeobject) :
 
     prop_scale.param_set_digits(3);
     prop_scale.param_set_increments(0.01, 0.10);
+
+    groupSpecialBehavior = false;
 }
 
 LPEPathAlongPath::~LPEPathAlongPath()
@@ -73,6 +77,30 @@ LPEPathAlongPath::~LPEPathAlongPath()
 
 }
 
+void
+LPEPathAlongPath::doBeforeEffect (SPLPEItem *lpeitem)
+{
+    if(SP_IS_GROUP(lpeitem))
+    {
+    groupSpecialBehavior = true;
+
+            using namespace Geom;
+            Piecewise<D2<SBasis> > pwd2;
+            std::vector<Geom::Path> temppath;  
+
+            recursive_original_bbox(SP_GROUP(lpeitem), pwd2, temppath);
+
+    for (unsigned int i=0; i < temppath.size(); i++) {
+        pwd2.concat( temppath[i].toPwSb() );
+        }
+
+    D2<Piecewise<SBasis> > d2pw = make_cuts_independant(pwd2);
+    boundingbox_X = bounds_exact(d2pw[0]);
+    boundingbox_Y = bounds_exact(d2pw[1]);
+    }    
+
+}
+
 
 Geom::Piecewise<Geom::D2<Geom::SBasis> >
 LPEPathAlongPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in)
@@ -89,14 +117,19 @@ LPEPathAlongPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2
     D2<Piecewise<SBasis> > patternd2 = make_cuts_independant(pwd2_in);
     Piecewise<SBasis> x = vertical_pattern.get_value() ? Piecewise<SBasis>(patternd2[1]) : Piecewise<SBasis>(patternd2[0]);
     Piecewise<SBasis> y = vertical_pattern.get_value() ? Piecewise<SBasis>(patternd2[0]) : Piecewise<SBasis>(patternd2[1]);
-    Interval pattBnds = bounds_exact(x);
-    x -= pattBnds.min();
-    Interval pattBndsY = bounds_exact(y);
-    y -= pattBndsY.middle();
 
-    double scaling = uskeleton.cuts.back()/pattBnds.extent();
+//We use the group bounding box size or the path bbox size to translate well x and y 
+    if(groupSpecialBehavior == false)
+    {
+        boundingbox_X = bounds_exact(x);
+        boundingbox_Y = bounds_exact(y);
+    }
+    x-= boundingbox_X.min();
+    y-= boundingbox_Y.middle();
+
+  double scaling = uskeleton.cuts.back()/boundingbox_X.extent();
 
-    if (scaling != 1.0) {
+  if (scaling != 1.0) {
         x*=scaling;
     }
 
@@ -106,6 +139,7 @@ LPEPathAlongPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2
         if (prop_scale != 1.0) y *= prop_scale;
     }
 
+
     Piecewise<D2<SBasis> > output = compose(uskeleton,x) + y*compose(n,x);
     return output;
 }
@@ -113,29 +147,45 @@ LPEPathAlongPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2
 void
 LPEPathAlongPath::resetDefaults(SPItem * item)
 {
-    if (!SP_IS_PATH(item)) return;
+    if (SP_IS_PATH(item) || SP_IS_GROUP(item))
+    {
+        // set the bend path to run horizontally in the middle of the bounding box of the original path
+        using namespace Geom;
+        Piecewise<D2<SBasis> > pwd2;
+        std::vector<Geom::Path> temppath;        
+
+        if (SP_IS_PATH(item))
+        {
+            //TODO : this won't work well with LPE stacking
+            temppath = SVGD_to_2GeomPath( SP_OBJECT_REPR(item)->attribute("inkscape:original-d"));
+        }
+        else if (SP_IS_GROUP(item))
+        {
+            recursive_original_bbox(SP_GROUP(item), pwd2, temppath);
+        }
 
-    using namespace Geom;
-
-    // set the bend path to run horizontally in the middle of the bounding box of the original path
-    Piecewise<D2<SBasis> > pwd2;
-    std::vector<Geom::Path> temppath = SVGD_to_2GeomPath( SP_OBJECT_REPR(item)->attribute("inkscape:original-d"));
     for (unsigned int i=0; i < temppath.size(); i++) {
         pwd2.concat( temppath[i].toPwSb() );
-    }
+        }
+
     D2<Piecewise<SBasis> > d2pw = make_cuts_independant(pwd2);
-    Interval bndsX = bounds_exact(d2pw[0]);
-    Interval bndsY = bounds_exact(d2pw[1]);
-    Point start(bndsX.min(), (bndsY.max()+bndsY.min())/2);
-    Point end(bndsX.max(), (bndsY.max()+bndsY.min())/2);
+    boundingbox_X = bounds_exact(d2pw[0]);
+    boundingbox_Y = bounds_exact(d2pw[1]);
+
+
+    Point start(boundingbox_X.min(), (boundingbox_Y.max()+boundingbox_Y.min())/2);
+    Point end(boundingbox_X.max(), (boundingbox_Y.max()+boundingbox_Y.min())/2);
 
     if ( Geom::are_near(start,end) ) {
-        end += Point(1.,0.);
-    }
+       end += Point(1.,0.);
+       }
     Geom::Path path;
     path.start( start );
     path.appendNew<Geom::LineSegment>( end );
     bend_path.param_set_and_write_new_value( path.toPwSb() );
+
+
+    }
 }
 
 void
index 11d28530a2b6b2c84bd3ec59e64ddf5fff93c028..f1578d5bfdb0666803a04af2a9e975efbeb1a2d4 100644 (file)
@@ -4,7 +4,8 @@
 /*
  * Inkscape::LPEPathAlongPath
  *
-* Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ * Copyright (C) Steren Giannini 2008 <steren.giannini@gmail.com>
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 #include "live_effects/parameter/enum.h"
 #include "live_effects/parameter/bool.h"
 
+#include <2geom/sbasis.h>
+#include <2geom/sbasis-geometric.h>
+#include <2geom/bezier-to-sbasis.h>
+#include <2geom/sbasis-to-bezier.h>
+#include <2geom/d2.h>
+#include <2geom/piecewise.h>
+
+#include "live_effects/lpegroupbbox.h"
+
 namespace Inkscape {
 namespace LivePathEffect {
 
-class LPEPathAlongPath : public Effect {
+//for Bend path on group : we need information concerning the group Bounding box
+class LPEPathAlongPath : public Effect, LivePathEffect_group_bbox {
 public:
     LPEPathAlongPath(LivePathEffectObject *lpeobject);
     virtual ~LPEPathAlongPath();
 
+    virtual void doBeforeEffect (SPLPEItem *lpeitem);
+
     virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in);
 
     virtual void resetDefaults(SPItem * item);
@@ -34,6 +47,8 @@ private:
     BoolParam scale_y_rel;
     BoolParam    vertical_pattern;
 
+    bool groupSpecialBehavior;    
+
     void on_pattern_pasted();
 
     LPEPathAlongPath(const LPEPathAlongPath&);
index a563696cccbb4efbf1cbb395676974197cd81423..84d1125f44e2e7fbce5dd2d612a061494fe4a799 100644 (file)
@@ -231,10 +231,10 @@ Inkscape::NodePath::Path *sp_nodepath_new(SPDesktop *desktop, SPObject *object,
         }
     } else {
         np->repr_nodetypes_key = g_strdup("sodipodi:nodetypes");
-        if ( SP_SHAPE(np->object)->path_effect_href ) {
+        if ( sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(np->object)) ) {
             np->repr_key = g_strdup("inkscape:original-d");
 
-            LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(SP_SHAPE(np->object));
+            LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(SP_LPE_ITEM(np->object));
             if (lpeobj && lpeobj->lpe) {
                 lpeobj->lpe->setup_nodepath(np);
             }
@@ -4555,7 +4555,7 @@ void sp_nodepath_set_curve (Inkscape::NodePath::Path *np, SPCurve *curve) {
         return;
 
     if (SP_IS_PATH(np->object)) {
-        if (SP_SHAPE(np->object)->path_effect_href) {
+        if (sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(np->object))) {
             sp_path_set_original_curve(SP_PATH(np->object), curve, true, false);
         } else {
             sp_shape_set_curve(SP_SHAPE(np->object), curve, true);
index 46c81fa97f48f00db01e48ce00a78029ad637423..49c1a1063adeeda6235e0ba4ebdacbb7c768d276 100644 (file)
@@ -42,6 +42,8 @@
 
 /* Helper functions for sp_selected_path_to_curves */
 static void sp_selected_path_to_curves0(gboolean do_document_done, guint32 text_grouping_policy);
+static bool sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_select);
+
 enum {
     /* Not used yet. This is the placeholder of Lauris's idea. */
     SP_TOCURVE_INTERACTIVE       = 1 << 0,
@@ -88,7 +90,6 @@ sp_selected_path_combine(void)
             continue;
         did = true;
 
-        NArtBpath *abp = NULL;
         SPCurve *c = sp_shape_get_curve(SP_SHAPE(item));
         if (first == NULL) {  // this is the topmost path
             first = item;
@@ -290,6 +291,31 @@ sp_selected_path_to_curves0(gboolean interactive, guint32 /*text_grouping_policy
     selection->clear();
     GSList *items = g_slist_copy(selected);
 
+    did = sp_item_list_to_curves(items, &selected, &to_select);
+
+    g_slist_free (items);
+    selection->setReprList(to_select);
+    selection->addList(selected);
+    g_slist_free (to_select);
+    g_slist_free (selected);
+
+    if (interactive) {
+        desktop->clearWaitingCursor();
+        if (did) {
+            sp_document_done(sp_desktop_document(desktop), SP_VERB_OBJECT_TO_CURVE, 
+                             _("Object to path"));
+        } else {
+            sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No objects</b> to convert to path in the selection."));
+            return;
+        }
+    }
+}
+
+static bool
+sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_select)
+{
+    bool did = false;
+    
     for (;
          items != NULL;
          items = items->next) {
@@ -305,20 +331,37 @@ sp_selected_path_to_curves0(gboolean interactive, guint32 /*text_grouping_policy
             Inkscape::XML::Node *repr = box3d_convert_to_group(SP_BOX3D(item));
             
             if (repr) {
-                to_select = g_slist_prepend (to_select, repr);
+                *to_select = g_slist_prepend (*to_select, repr);
                 did = true;
-                selected = g_slist_remove (selected, item);
+                *selected = g_slist_remove (*selected, item);
             }
 
             continue;
         }
+        
+        if (SP_IS_GROUP(item)) {
+            sp_lpe_item_remove_path_effect(SP_LPE_ITEM(item), true);
+            GSList *item_list = sp_item_group_item_list(SP_GROUP(item));
+            
+            GSList *item_to_select = NULL;
+            GSList *item_selected = NULL;
+            
+            if (sp_item_list_to_curves(item_list, &item_selected, &item_to_select))
+                did = true;
+
+            g_slist_free(item_list);
+            g_slist_free(item_to_select);
+            g_slist_free(item_selected);
+
+            continue;
+        }
 
         Inkscape::XML::Node *repr = sp_selected_item_to_curved_repr(item, 0);
         if (!repr)
             continue;
 
         did = true;
-        selected = g_slist_remove (selected, item);
+        *selected = g_slist_remove (*selected, item);
 
         // remember the position of the item
         gint pos = SP_OBJECT_REPR(item)->position();
@@ -339,26 +382,11 @@ sp_selected_path_to_curves0(gboolean interactive, guint32 /*text_grouping_policy
 
         /* Buglet: We don't re-add the (new version of the) object to the selection of any other
          * desktops where it was previously selected. */
-        to_select = g_slist_prepend (to_select, repr);
+        *to_select = g_slist_prepend (*to_select, repr);
         Inkscape::GC::release(repr);
     }
-
-    g_slist_free (items);
-    selection->setReprList(to_select);
-    selection->addList(selected);
-    g_slist_free (to_select);
-    g_slist_free (selected);
-
-    if (interactive) {
-        desktop->clearWaitingCursor();
-        if (did) {
-            sp_document_done(sp_desktop_document(desktop), SP_VERB_OBJECT_TO_CURVE, 
-                             _("Object to path"));
-        } else {
-            sp_desktop_message_stack(desktop)->flash(Inkscape::ERROR_MESSAGE, _("<b>No objects</b> to convert to path in the selection."));
-            return;
-        }
-    }
+    
+    return did;
 }
 
 Inkscape::XML::Node *
@@ -450,7 +478,7 @@ sp_selected_path_reverse()
         SPCurve *rcurve = sp_curve_reverse(sp_path_get_curve_reference(path));
 
         gchar *str = sp_svg_write_path(SP_CURVE_BPATH(rcurve));
-        if ( sp_shape_has_path_effect(SP_SHAPE(path)) ) {
+        if ( sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(path)) ) {
             SP_OBJECT_REPR(path)->setAttribute("inkscape:original-d", str);
         } else {
             SP_OBJECT_REPR(path)->setAttribute("d", str);
index 81c4bc490b5765a51ae23b9a979e43f080ceb8a9..0ae2c8dc594add56bd40eba48604cd13869aef15 100644 (file)
@@ -891,14 +891,8 @@ void sp_selection_paste_livepatheffect()
 
 void sp_selection_remove_livepatheffect_impl(SPItem *item)
 {
-    if ( item && SP_IS_SHAPE(item) ) {
-        sp_shape_remove_path_effect(SP_SHAPE(item));
-   } else if (item && SP_IS_GROUP (item)) {
-        for (SPObject *child = sp_object_first_child(SP_OBJECT(item)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
-            if (!SP_IS_ITEM (child))
-                continue;
-            sp_selection_remove_livepatheffect_impl (SP_ITEM(child));
-        }
+    if ( item && SP_IS_LPE_ITEM(item) ) {
+        sp_lpe_item_remove_path_effect(SP_LPE_ITEM(item), false);
     }
 }
 
@@ -1626,9 +1620,8 @@ void sp_selection_next_patheffect_param(SPDesktop * dt)
     if ( selection && !selection->isEmpty() ) {
         SPItem *item = selection->singleItem();
         if ( item && SP_IS_SHAPE(item)) {
-            SPShape *shape = SP_SHAPE(item);
-            if (sp_shape_has_path_effect(shape)) {
-                sp_shape_edit_next_param_oncanvas(shape, dt);
+            if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(item))) {
+                sp_lpe_item_edit_next_param_oncanvas(SP_LPE_ITEM(item), dt);
             } else {
                 dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("The selection has no applied path effect."));
             }
index 8bf3f7479f9d2b512140a30b6860e3a07706f49e..9b982d75848883d01f467d4e1b7f9e30b9569b0a 100644 (file)
@@ -76,7 +76,7 @@ static void sp_genericellipse_update(SPObject *object, SPCtx *ctx, guint flags);
 static void sp_genericellipse_snappoints(SPItem const *item, SnapPointsIter p);
 
 static void sp_genericellipse_set_shape(SPShape *shape);
-static void sp_genericellipse_update_patheffect (SPShape *shape, bool write);
+static void sp_genericellipse_update_patheffect (SPLPEItem *lpeitem, bool write);
 
 static Inkscape::XML::Node *sp_genericellipse_write(SPObject *object, Inkscape::XML::Node *repr,
                                                     guint flags);
@@ -111,6 +111,7 @@ static void sp_genericellipse_class_init(SPGenericEllipseClass *klass)
 {
     SPObjectClass *sp_object_class = (SPObjectClass *) klass;
     SPItemClass *item_class = (SPItemClass *) klass;
+    SPLPEItemClass *lpe_item_class = (SPLPEItemClass *) klass;
     SPShapeClass *shape_class = (SPShapeClass *) klass;
 
     ge_parent_class = (SPShapeClass*) g_type_class_ref(SP_TYPE_SHAPE);
@@ -121,7 +122,7 @@ static void sp_genericellipse_class_init(SPGenericEllipseClass *klass)
     item_class->snappoints = sp_genericellipse_snappoints;
 
     shape_class->set_shape = sp_genericellipse_set_shape;
-    shape_class->update_patheffect = sp_genericellipse_update_patheffect;
+    lpe_item_class->update_patheffect = sp_genericellipse_update_patheffect;
 }
 
 static void
@@ -158,8 +159,9 @@ sp_genericellipse_update(SPObject *object, SPCtx *ctx, guint flags)
 }
 
 static void
-sp_genericellipse_update_patheffect(SPShape *shape, bool write)
+sp_genericellipse_update_patheffect(SPLPEItem *lpeitem, bool write)
 {
+    SPShape *shape = (SPShape *) lpeitem;
     sp_genericellipse_set_shape(shape);
 
     if (write) {
@@ -274,7 +276,7 @@ static void sp_genericellipse_set_shape(SPShape *shape)
     SPCurve *c = sp_curve_new_from_bpath(nr_artpath_affine(bpath, aff));
     g_assert(c != NULL);
 
-    sp_shape_perform_path_effect(c, SP_SHAPE (ellipse));
+    sp_lpe_item_perform_path_effect(SP_LPE_ITEM (ellipse), c);
     sp_shape_set_curve_insync((SPShape *) ellipse, c, TRUE);
     sp_curve_unref(c);
 }
index d0a1d9111710a4edb88402c1f10d3f65165eb559..cd74f88b8f36a41794b7e81d51168a467f7e3112 100644 (file)
@@ -65,7 +65,9 @@ static NRArenaItem *sp_group_show (SPItem *item, NRArena *arena, unsigned int ke
 static void sp_group_hide (SPItem * item, unsigned int key);
 static void sp_group_snappoints (SPItem const *item, SnapPointsIter p);
 
-static SPItemClass * parent_class;
+static void sp_group_update_patheffect(SPLPEItem *lpeitem, bool write);
+
+static SPLPEItemClass * parent_class;
 
 GType
 sp_group_get_type (void)
@@ -84,7 +86,7 @@ sp_group_get_type (void)
                        (GInstanceInitFunc) sp_group_init,
                        NULL,   /* value_table */
                };
-               group_type = g_type_register_static (SP_TYPE_ITEM, "SPGroup", &group_info, (GTypeFlags)0);
+               group_type = g_type_register_static (SP_TYPE_LPE_ITEM, "SPGroup", &group_info, (GTypeFlags)0);
        }
        return group_type;
 }
@@ -95,12 +97,14 @@ sp_group_class_init (SPGroupClass *klass)
        GObjectClass * object_class;
        SPObjectClass * sp_object_class;
        SPItemClass * item_class;
+       SPLPEItemClass * lpe_item_class;
 
        object_class = (GObjectClass *) klass;
        sp_object_class = (SPObjectClass *) klass;
        item_class = (SPItemClass *) klass;
+       lpe_item_class = (SPLPEItemClass *) klass;
 
-       parent_class = (SPItemClass *)g_type_class_ref (SP_TYPE_ITEM);
+       parent_class = (SPLPEItemClass *)g_type_class_ref (SP_TYPE_LPE_ITEM);
 
        object_class->dispose = sp_group_dispose;
 
@@ -121,6 +125,8 @@ sp_group_class_init (SPGroupClass *klass)
        item_class->show = sp_group_show;
        item_class->hide = sp_group_hide;
        item_class->snappoints = sp_group_snappoints;
+       
+       lpe_item_class->update_patheffect = sp_group_update_patheffect;
 }
 
 static void
@@ -289,16 +295,16 @@ sp_group_set_transform(SPItem *item, NR::Matrix const &xform)
 }
 
 static void sp_group_set(SPObject *object, unsigned key, char const *value) {
-       SPGroup *group=SP_GROUP(object);
+       SPGroup *group = SP_GROUP(object);
 
        switch (key) {
-               case SP_ATTR_INKSCAPE_GROUPMODE: {
+               case SP_ATTR_INKSCAPE_GROUPMODE:
                        if ( value && !strcmp(value, "layer") ) {
                                group->setLayerMode(SPGroup::LAYER);
                        } else {
                                group->setLayerMode(SPGroup::GROUP);
                        }
-               } break;
+                   break;
                default: {
                        if (((SPObjectClass *) (parent_class))->set) {
                                (* ((SPObjectClass *) (parent_class))->set)(object, key, value);
@@ -361,6 +367,8 @@ sp_item_group_ungroup (SPGroup *group, GSList **children, bool do_done)
       }
   }
 
+    sp_lpe_item_remove_path_effect(SP_LPE_ITEM(group), false);
+
        /* Step 1 - generate lists of children objects */
        GSList *items = NULL;
        GSList *objects = NULL;
@@ -796,6 +804,25 @@ void CGroup::onOrderChanged (Inkscape::XML::Node *child, Inkscape::XML::Node *,
     _group->requestModified(SP_OBJECT_MODIFIED_FLAG);
 }
 
+static void
+sp_group_update_patheffect (SPLPEItem *lpeitem, bool write)
+{
+#ifdef GROUP_VERBOSE
+    g_message("sp_group_update_patheffect: %p\n", lpeitem);
+#endif
+    g_return_if_fail (lpeitem != NULL);
+    g_return_if_fail (SP_IS_GROUP (lpeitem));
+
+    GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem));
+    for ( GSList const *iter = item_list; iter; iter = iter->next ) {
+        SPObject *subitem = static_cast<SPObject *>(iter->data);
+        if (SP_IS_LPE_ITEM(subitem)) {
+            sp_lpe_item_update_patheffect(SP_LPE_ITEM(subitem), true);
+        }
+    }
+}
+
+
 /*
   Local Variables:
   mode:c++
index a677d08d7f124498383386e3b998675d97fe8b2c..5af7a7b946f248570c80e20752e94389783a8274 100644 (file)
@@ -14,7 +14,7 @@
  */
 
 #include <map>
-#include "sp-item.h"
+#include "sp-lpe-item.h"
 
 #define SP_TYPE_GROUP            (sp_group_get_type ())
 #define SP_GROUP(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), SP_TYPE_GROUP, SPGroup))
@@ -26,7 +26,7 @@ class CGroup;
 
 namespace NR{ struct translate; }
 
-struct SPGroup : public SPItem {
+struct SPGroup : public SPLPEItem {
        enum LayerMode { GROUP, LAYER };
 
        LayerMode _layer_mode;
@@ -48,13 +48,13 @@ struct SPGroup : public SPItem {
        void translateChildItems(NR::translate const &tr);
 
     CGroup *group;
-
+    
 private:
        void _updateLayerMode(unsigned int display_key=0);
 };
 
 struct SPGroupClass {
-       SPItemClass parent_class;
+       SPLPEItemClass parent_class;
 };
 
 /*
index fc966aff47c08f02fac16d8aa64f031f7a6fef5c..263671d476e911b026e2ef458efb35138e788704 100644 (file)
@@ -1291,18 +1291,18 @@ sp_item_adjust_paint_recursive (SPItem *item, NR::Matrix advertized_transform, N
 void
 sp_item_adjust_livepatheffect (SPItem *item, NR::Matrix const &postmul, bool set)
 {
-    if ( !SP_IS_SHAPE(item) )
+    if ( !SP_IS_LPE_ITEM(item) )
         return;
 
-    SPShape *shape = SP_SHAPE (item);
-    if ( sp_shape_has_path_effect(shape) ) {
-        LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(shape);
+    SPLPEItem *lpeitem = SP_LPE_ITEM (item);
+    if ( sp_lpe_item_has_path_effect(lpeitem) ) {
+        LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);
         LivePathEffectObject *new_lpeobj = lpeobj->fork_private_if_necessary();
         if (new_lpeobj != lpeobj) {
-            sp_shape_set_path_effect(shape, new_lpeobj);
+            sp_lpe_item_set_path_effect(lpeitem, new_lpeobj);
         }
 
-        Inkscape::LivePathEffect::Effect * effect = sp_shape_get_livepatheffect(shape);
+        Inkscape::LivePathEffect::Effect * effect = sp_lpe_item_get_livepatheffect(lpeitem);
         if (effect) {
             effect->transform_multiply (to_2geom(postmul), set);
         }
index 7dbe51c265c954703bfadc54ccb9fac64df29d9b..99670882abab2b86ba788d8e9aab1bae8954dc3e 100644 (file)
@@ -59,7 +59,7 @@ static gchar * sp_path_description(SPItem *item);
 static void sp_path_convert_to_guides(SPItem *item);
 
 static void sp_path_update(SPObject *object, SPCtx *ctx, guint flags);
-static void sp_path_update_patheffect(SPShape *shape, bool write);
+static void sp_path_update_patheffect(SPLPEItem *lpeitem, bool write);
 
 static SPShapeClass *parent_class;
 
@@ -98,7 +98,7 @@ sp_path_class_init(SPPathClass * klass)
     GObjectClass *gobject_class = (GObjectClass *) klass;
     SPObjectClass *sp_object_class = (SPObjectClass *) klass;
     SPItemClass *item_class = (SPItemClass *) klass;
-    SPShapeClass *shape_class = (SPShapeClass *) klass;
+    SPLPEItemClass *lpe_item_class = (SPLPEItemClass *) klass;
 
     parent_class = (SPShapeClass *)g_type_class_peek_parent(klass);
 
@@ -114,7 +114,7 @@ sp_path_class_init(SPPathClass * klass)
     item_class->set_transform = sp_path_set_transform;
     item_class->convert_to_guides = sp_path_convert_to_guides;
 
-    shape_class->update_patheffect = sp_path_update_patheffect;
+    lpe_item_class->update_patheffect = sp_path_update_patheffect;
 }
 
 
@@ -136,7 +136,7 @@ static gchar *
 sp_path_description(SPItem * item)
 {
     int count = sp_nodes_in_path(SP_PATH(item));
-    if (SP_SHAPE(item)->path_effect_href) {
+    if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(item))) {
         return g_strdup_printf(ngettext("<b>Path</b> (%i node, path effect)",
                                         "<b>Path</b> (%i nodes, path effect)",count), count);
     } else {
@@ -264,7 +264,7 @@ sp_path_set(SPObject *object, unsigned int key, gchar const *value)
                 object->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
             break;
        case SP_ATTR_D:
-            if (!((SPShape *) path)->path_effect_href) {
+            if (!sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(path))) {
                 if (value) {
                     NArtBpath *bpath = sp_svg_read_path(value);
                     SPCurve *curve = sp_curve_new_from_bpath(bpath);
@@ -410,12 +410,13 @@ sp_path_set_transform(SPItem *item, NR::Matrix const &xform)
 }
 
 static void
-sp_path_update_patheffect(SPShape *shape, bool write)
+sp_path_update_patheffect(SPLPEItem *lpeitem, bool write)
 {
-    SPPath *path = (SPPath *) shape;
+    SPShape *shape = (SPShape *) lpeitem;
+    SPPath *path = (SPPath *) lpeitem;
     if (path->original_curve) {
         SPCurve *curve = sp_curve_copy (path->original_curve);
-        sp_shape_perform_path_effect(curve, shape);
+        sp_lpe_item_perform_path_effect(SP_LPE_ITEM(shape), curve);
         sp_shape_set_curve(shape, curve, TRUE);
         sp_curve_unref(curve);
 
index 12929e89cd74d65980c70ea5c02a578e3819176f..1556226f15e300cd76f29580274ca537bab33577 100644 (file)
@@ -18,7 +18,6 @@
 # include "config.h"
 #endif
 
-
 #include <libnr/n-art-bpath.h>
 #include <libnr/nr-matrix-fns.h>
 #include <libnr/nr-matrix-ops.h>
@@ -38,9 +37,7 @@
 #include "prefs-utils.h"
 #include "attributes.h"
 
-#include "live_effects/effect.h"
 #include "live_effects/lpeobject.h"
-#include "live_effects/lpeobject-reference.h"
 #include "uri.h"
 #include "extract-uri.h"
 #include "uri-references.h"
@@ -71,10 +68,7 @@ static void sp_shape_snappoints (SPItem const *item, SnapPointsIter p);
 
 static void sp_shape_update_marker_view (SPShape *shape, NRArenaItem *ai);
 
-static void lpeobject_ref_changed(SPObject *old_ref, SPObject *ref, SPShape *shape);
-static void lpeobject_ref_modified(SPObject *href, guint flags, SPShape *shape);
-
-static SPItemClass *parent_class;
+static SPLPEItemClass *parent_class;
 
 /**
  * Registers the SPShape class with Gdk and returns its type number.
@@ -94,7 +88,7 @@ sp_shape_get_type (void)
                        (GInstanceInitFunc) sp_shape_init,
                        NULL,   /* value_table */
                };
-               type = g_type_register_static (SP_TYPE_ITEM, "SPShape", &info, (GTypeFlags)0);
+               type = g_type_register_static (SP_TYPE_LPE_ITEM, "SPShape", &info, (GTypeFlags)0);
        }
        return type;
 }
@@ -109,14 +103,13 @@ sp_shape_class_init (SPShapeClass *klass)
     GObjectClass *gobject_class;
        SPObjectClass *sp_object_class;
        SPItemClass * item_class;
-       SPPathClass * path_class;
+    SPLPEItemClass * lpe_item_class;
 
     gobject_class = (GObjectClass *) klass;
        sp_object_class = (SPObjectClass *) klass;
        item_class = (SPItemClass *) klass;
-       path_class = (SPPathClass *) klass;
 
-       parent_class = (SPItemClass *)g_type_class_peek_parent (klass);
+       parent_class = (SPLPEItemClass *)g_type_class_peek_parent (klass);
 
     gobject_class->finalize = sp_shape_finalize;
 
@@ -132,9 +125,9 @@ sp_shape_class_init (SPShapeClass *klass)
        item_class->show = sp_shape_show;
        item_class->hide = sp_shape_hide;
     item_class->snappoints = sp_shape_snappoints;
+    lpe_item_class->update_patheffect = NULL;
 
     klass->set_shape = NULL;
-    klass->update_patheffect = NULL;
 }
 
 /**
@@ -143,10 +136,6 @@ sp_shape_class_init (SPShapeClass *klass)
 static void
 sp_shape_init (SPShape *shape)
 {
-    shape->path_effect_href = NULL;
-    shape->path_effect_ref  = new Inkscape::LivePathEffect::LPEObjectReference(SP_OBJECT(shape));
-       new (&shape->lpe_modified_connection) sigc::connection();
-
     for ( int i = 0 ; i < SP_MARKER_LOC_QTY ; i++ ) {
         new (&shape->release_connect[i]) sigc::connection();
         new (&shape->modified_connect[i]) sigc::connection();
@@ -180,10 +169,6 @@ sp_shape_finalize (GObject *object)
 static void
 sp_shape_build (SPObject *object, SPDocument *document, Inkscape::XML::Node *repr)
 {
-    SP_SHAPE(object)->path_effect_ref->changedSignal().connect(sigc::bind(sigc::ptr_fun(lpeobject_ref_changed), SP_SHAPE(object)));
-
-    sp_object_read_attr(object, "inkscape:path-effect");
     if (((SPObjectClass *) (parent_class))->build) {
        (*((SPObjectClass *) (parent_class))->build) (object, document, repr);
     }
@@ -222,14 +207,6 @@ sp_shape_release (SPObject *object)
        if (shape->curve) {
                shape->curve = sp_curve_unref (shape->curve);
        }
-
-    if (shape->path_effect_href) {
-        g_free(shape->path_effect_href);
-    }
-    shape->path_effect_ref->detach();
-
-    shape->lpe_modified_connection.disconnect();
-    shape->lpe_modified_connection.~connection();
     
        if (((SPObjectClass *) parent_class)->release) {
          ((SPObjectClass *) parent_class)->release (object);
@@ -241,52 +218,14 @@ sp_shape_release (SPObject *object)
 static void
 sp_shape_set(SPObject *object, unsigned int key, gchar const *value)
 {
-    SPShape *shape = (SPShape *) object;
-
-    switch (key) {
-        case SP_ATTR_INKSCAPE_PATH_EFFECT:
-            if ( value && shape->path_effect_href && ( strcmp(value, shape->path_effect_href) == 0 ) ) {
-                /* No change, do nothing. */
-            } else {
-                if (shape->path_effect_href) {
-                    g_free(shape->path_effect_href);
-                    shape->path_effect_href = NULL;
-                }
-                if (value) {
-                    shape->path_effect_href = g_strdup(value);
-
-                    // Now do the attaching, which emits the changed signal.
-                    try {
-                        shape->path_effect_ref->attach(Inkscape::URI(value));
-                    } catch (Inkscape::BadURIException &e) {
-                        g_warning("%s", e.what());
-                        shape->path_effect_ref->detach();
-                    }
-                } else {
-                    // Detach, which emits the changed signal.
-                    shape->path_effect_ref->detach();
-                }
-            }
-            break;
-        default:
-            if (((SPObjectClass *) parent_class)->set) {
-                ((SPObjectClass *) parent_class)->set(object, key, value);
-            }
-            break;
+    if (((SPObjectClass *) parent_class)->set) {
+        ((SPObjectClass *) parent_class)->set(object, key, value);
     }
 }
 
 static Inkscape::XML::Node *
 sp_shape_write(SPObject *object, Inkscape::XML::Node *repr, guint flags)
 {
-    SPShape *shape = (SPShape *) object;
-
-    if ( shape->path_effect_href ) {
-        repr->setAttribute("inkscape:path-effect", shape->path_effect_href);
-    } else {
-        repr->setAttribute("inkscape:path-effect", NULL);
-    }
-
     if (((SPObjectClass *)(parent_class))->write) {
         ((SPObjectClass *)(parent_class))->write(object, repr, flags);
     }
@@ -1146,122 +1085,6 @@ static void sp_shape_snappoints(SPItem const *item, SnapPointsIter p)
     }
 }
 
-
-LivePathEffectObject *
-sp_shape_get_livepatheffectobject(SPShape *shape) {
-    if (!shape) return NULL;
-
-    if (sp_shape_has_path_effect(shape)) {
-        return shape->path_effect_ref->lpeobject;
-    } else {
-        return NULL;
-    }
-}
-
-Inkscape::LivePathEffect::Effect *
-sp_shape_get_livepatheffect(SPShape *shape) {
-    if (!shape) return NULL;
-
-    LivePathEffectObject * lpeobj = sp_shape_get_livepatheffectobject(shape);
-    if (lpeobj)
-        return lpeobj->lpe;
-    else
-        return NULL;
-}
-
-/**
- * Calls any registered handlers for the update_patheffect action
- */
-void
-sp_shape_update_patheffect (SPShape *shape, bool write)
-{
-#ifdef SHAPE_VERBOSE
-    g_message("sp_shape_update_patheffect: %p\n", shape);
-#endif
-    g_return_if_fail (shape != NULL);
-    g_return_if_fail (SP_IS_SHAPE (shape));
-
-    if (SP_SHAPE_CLASS (G_OBJECT_GET_CLASS (shape))->update_patheffect) {
-        SP_SHAPE_CLASS (G_OBJECT_GET_CLASS (shape))->update_patheffect (shape, write);
-    }
-}
-
-void sp_shape_perform_path_effect(SPCurve *curve, SPShape *shape) {
-    if (!shape) return;
-    if (!curve) return;
-
-    LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(shape);
-    if (lpeobj && lpeobj->lpe) {
-        lpeobj->lpe->doEffect(curve);
-    }
-}
-
-/**
- * Gets called when (re)attached to another lpeobject.
- */
-static void
-lpeobject_ref_changed(SPObject *old_ref, SPObject *ref, SPShape *shape)
-{
-    if (old_ref) {
-        sp_signal_disconnect_by_data(old_ref, shape);
-    }
-    if ( IS_LIVEPATHEFFECT(ref) && ref != shape )
-    {
-        shape->lpe_modified_connection.disconnect();
-        shape->lpe_modified_connection = ref->connectModified(sigc::bind(sigc::ptr_fun(&lpeobject_ref_modified), shape));
-        lpeobject_ref_modified(ref, 0, shape);
-    }
-}
-
-/**
- * Gets called when lpeobject repr contents change: i.e. parameter change.
- */
-static void
-lpeobject_ref_modified(SPObject */*href*/, guint /*flags*/, SPShape *shape)
-{
-    sp_shape_update_patheffect (shape, true);
-}
-
-void sp_shape_set_path_effect(SPShape *shape, gchar *value)
-{
-    if (!value) {
-        sp_shape_remove_path_effect(shape);
-    } else {
-        SP_OBJECT_REPR(shape)->setAttribute("inkscape:path-effect", value);
-    }
-}
-
-void sp_shape_set_path_effect(SPShape *shape, LivePathEffectObject * new_lpeobj)
-{
-    const gchar * repr_id = SP_OBJECT_REPR(new_lpeobj)->attribute("id");
-    gchar *hrefstr = g_strdup_printf("#%s", repr_id);
-    sp_shape_set_path_effect(shape, hrefstr);
-    g_free(hrefstr);
-}
-
-void sp_shape_remove_path_effect(SPShape *shape)
-{
-    Inkscape::XML::Node *repr = SP_OBJECT_REPR(shape);
-    repr->setAttribute("inkscape:path-effect", NULL);
-    if (SP_IS_PATH(shape)) {
-        repr->setAttribute("d", repr->attribute("inkscape:original-d"));
-        repr->setAttribute("inkscape:original-d", NULL);
-    }
-}
-
-bool sp_shape_has_path_effect(SPShape *shape)
-{
-    return (shape->path_effect_href != NULL);
-}
-
-void sp_shape_edit_next_param_oncanvas(SPShape *shape, SPDesktop *dt)
-{
-    LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(shape);
-    if (lpeobj && lpeobj->lpe) {
-        lpeobj->lpe->editNextParamOncanvas(SP_ITEM(shape), dt);
-    }
-}
-
 /*
   Local Variables:
   mode:c++
index ce5407ad6926a342dbe8ee5cfd1e9c758cf5bdab..cc25d2e88f9cf3d4d3a0fdd20d8137fe1fa4b260 100644 (file)
@@ -15,7 +15,7 @@
  */
 
 #include "display/display-forward.h"
-#include "sp-item.h"
+#include "sp-lpe-item.h"
 #include "sp-marker-loc.h"
 
 #include <sigc++/connection.h>
 #define SP_SHAPE_WRITE_PATH (1 << 2)
 
 struct SPDesktop;
-struct LivePathEffectObject;
-namespace Inkscape{ 
-namespace LivePathEffect{
-    class LPEObjectReference;
-    class Effect;
-};
-};
 
-
-struct SPShape : public SPItem {
+struct SPShape : public SPLPEItem {
     SPCurve *curve;
 
       SPObject *marker[SP_MARKER_LOC_QTY];
       sigc::connection release_connect [SP_MARKER_LOC_QTY];
       sigc::connection modified_connect [SP_MARKER_LOC_QTY];
-
-    gchar *path_effect_href;
-    Inkscape::LivePathEffect::LPEObjectReference *path_effect_ref;
-    sigc::connection lpe_modified_connection;
 };
 
 struct SPShapeClass {
-       SPItemClass item_class;
+       SPLPEItemClass item_class;
 
        /* Build bpath from extra shape attributes */
        void (* set_shape) (SPShape *shape);
-
-    void (* update_patheffect) (SPShape *shape, bool write);
 };
 
 GType sp_shape_get_type (void);
@@ -79,16 +65,4 @@ int sp_shape_number_of_markers (SPShape* Shape, int type);
 NR::Matrix sp_shape_marker_get_transform(SPShape const *shape, NArtBpath const *bp);
 bool sp_shape_marker_required(SPShape const *shape, int const m, NArtBpath *bp);
 
-LivePathEffectObject * sp_shape_get_livepatheffectobject(SPShape *shape);
-Inkscape::LivePathEffect::Effect * sp_shape_get_livepatheffect(SPShape *shape);
-void sp_shape_update_patheffect (SPShape *shape, bool write);
-void sp_shape_perform_path_effect(SPCurve *curve, SPShape *shape);
-
-void sp_shape_set_path_effect(SPShape *shape, gchar *value);
-void sp_shape_set_path_effect(SPShape *shape, LivePathEffectObject * new_lpeobj);
-void sp_shape_remove_path_effect(SPShape *shape);
-bool sp_shape_has_path_effect(SPShape *shape);
-
-void sp_shape_edit_next_param_oncanvas(SPShape *shape, SPDesktop *dt);
-
 #endif
index 3e8ce49973afa41e2b830f018b8e1cff40d73b41..45dc6d2e3de9a93c4098b13602b65e75f2ad2728 100644 (file)
@@ -39,7 +39,7 @@ static gchar * sp_spiral_description (SPItem * item);
 static void sp_spiral_snappoints(SPItem const *item, SnapPointsIter p);
 
 static void sp_spiral_set_shape (SPShape *shape);
-static void sp_spiral_update_patheffect (SPShape *shape, bool write);
+static void sp_spiral_update_patheffect (SPLPEItem *lpeitem, bool write);
 
 static NR::Point sp_spiral_get_tangent (SPSpiral const *spiral, gdouble t);
 
@@ -80,11 +80,13 @@ sp_spiral_class_init (SPSpiralClass *klass)
        GObjectClass * gobject_class;
        SPObjectClass * sp_object_class;
        SPItemClass * item_class;
+       SPLPEItemClass * lpe_item_class;
        SPShapeClass *shape_class;
 
        gobject_class = (GObjectClass *) klass;
        sp_object_class = (SPObjectClass *) klass;
        item_class = (SPItemClass *) klass;
+       lpe_item_class = (SPLPEItemClass *) klass;
        shape_class = (SPShapeClass *) klass;
 
        parent_class = (SPShapeClass *)g_type_class_ref (SP_TYPE_SHAPE);
@@ -97,8 +99,9 @@ sp_spiral_class_init (SPSpiralClass *klass)
        item_class->description = sp_spiral_description;
        item_class->snappoints = sp_spiral_snappoints;
 
+    lpe_item_class->update_patheffect = sp_spiral_update_patheffect;
+
     shape_class->set_shape = sp_spiral_set_shape;
-    shape_class->update_patheffect = sp_spiral_update_patheffect;
 }
 
 /**
@@ -297,8 +300,9 @@ sp_spiral_update (SPObject *object, SPCtx *ctx, guint flags)
 }
 
 static void
-sp_spiral_update_patheffect(SPShape *shape, bool write)
+sp_spiral_update_patheffect(SPLPEItem *lpeitem, bool write)
 {
+    SPShape *shape = (SPShape *) lpeitem;
     sp_spiral_set_shape(shape);
 
     if (write) {
@@ -463,7 +467,7 @@ sp_spiral_set_shape (SPShape *shape)
                sp_spiral_fit_and_draw (spiral, c, (1.0 - t)/(SAMPLE_SIZE - 1.0),
                                        darray, hat1, hat2, &t);
 
-    sp_shape_perform_path_effect(c, SP_SHAPE (spiral));
+    sp_lpe_item_perform_path_effect(SP_LPE_ITEM (spiral), c);
     sp_shape_set_curve_insync ((SPShape *) spiral, c, TRUE);
     sp_curve_unref (c);
 }
index a04af838f4115b2a41b03c0fb8d9feefc5aacbe1..2aeb0cfc0c65b1198ebb458397fd2a7bd9530c7e 100644 (file)
@@ -42,7 +42,7 @@ static gchar * sp_star_description (SPItem * item);
 static void sp_star_snappoints(SPItem const *item, SnapPointsIter p);
 
 static void sp_star_set_shape (SPShape *shape);
-static void sp_star_update_patheffect (SPShape *shape, bool write);
+static void sp_star_update_patheffect (SPLPEItem *lpeitem, bool write);
 
 static SPShapeClass *parent_class;
 
@@ -73,13 +73,13 @@ sp_star_class_init (SPStarClass *klass)
        GObjectClass * gobject_class;
        SPObjectClass * sp_object_class;
        SPItemClass * item_class;
-       SPPathClass * path_class;
+       SPLPEItemClass * lpe_item_class;
        SPShapeClass * shape_class;
 
        gobject_class = (GObjectClass *) klass;
        sp_object_class = (SPObjectClass *) klass;
        item_class = (SPItemClass *) klass;
-       path_class = (SPPathClass *) klass;
+       lpe_item_class = (SPLPEItemClass *) klass;
        shape_class = (SPShapeClass *) klass;
 
        parent_class = (SPShapeClass *)g_type_class_ref (SP_TYPE_SHAPE);
@@ -92,8 +92,9 @@ sp_star_class_init (SPStarClass *klass)
        item_class->description = sp_star_description;
        item_class->snappoints = sp_star_snappoints;
 
+    lpe_item_class->update_patheffect = sp_star_update_patheffect;
+
        shape_class->set_shape = sp_star_set_shape;
-    shape_class->update_patheffect = sp_star_update_patheffect;
 }
 
 static void
@@ -276,8 +277,9 @@ sp_star_update (SPObject *object, SPCtx *ctx, guint flags)
 }
 
 static void
-sp_star_update_patheffect(SPShape *shape, bool write)
+sp_star_update_patheffect(SPLPEItem *lpeitem, bool write)
 {
+    SPShape *shape = (SPShape *) lpeitem;
     sp_star_set_shape(shape);
 
     if (write) {
@@ -501,7 +503,7 @@ sp_star_set_shape (SPShape *shape)
                }
 
     sp_curve_closepath (c);
-    sp_shape_perform_path_effect(c, SP_SHAPE (star));
+    sp_lpe_item_perform_path_effect(SP_LPE_ITEM (star), c);
     sp_shape_set_curve_insync (SP_SHAPE (star), c, TRUE);
     sp_curve_unref (c);
 }
index d2ec3d3c0f4c80e23c2b78be9a78c0ab94c92b1c..f76694f25b456b1f2d45dc14e95ee533d1c2273c 100644 (file)
@@ -476,7 +476,7 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi
                 if (newrepr) {
                     newrepr->setAttribute("d", str);
                 } else {
-                    if (SP_IS_SHAPE(item) && SP_SHAPE(item)->path_effect_href) {
+                    if (SP_IS_LPE_ITEM(item) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(item))) {
                         SP_OBJECT_REPR(item)->setAttribute("inkscape:original-d", str);
                     } else {
                         SP_OBJECT_REPR(item)->setAttribute("d", str);
index 081657cf02552e7b3dfddc547f34f569f7456c3f..842f10d521db01666d5a00f4b879c2da511ddce1 100644 (file)
@@ -556,9 +556,12 @@ void ClipboardManagerImpl::_copyUsedDefs(SPItem *item)
                 _copyNode(SP_OBJECT_REPR(SP_OBJECT(shape->marker[i])), _doc, _defs);
             }
         }
-        // Also copy live effects if applicable
-        if (sp_shape_has_path_effect(shape)) {
-            _copyNode(SP_OBJECT_REPR(SP_OBJECT(sp_shape_get_livepatheffectobject(shape))), _doc, _defs);
+    }
+    // For lpe items, copy liveeffect if applicable
+    if (SP_IS_LPE_ITEM(item)) {
+        SPLPEItem *lpeitem = SP_LPE_ITEM (item);
+        if (sp_lpe_item_has_path_effect(lpeitem)) {
+            _copyNode(SP_OBJECT_REPR(SP_OBJECT(sp_lpe_item_get_livepatheffectobject(lpeitem))), _doc, _defs);
         }
     }
     // For 3D boxes, copy perspectives
@@ -887,31 +890,14 @@ void ClipboardManagerImpl::_applyPathEffect(SPItem *item, gchar const *effect)
 {
     if ( item == NULL ) return;
     
-    if (SP_IS_SHAPE(item))
+    if (SP_IS_LPE_ITEM(item))
     {
-        SPShape *shape = SP_SHAPE(item);
+        SPLPEItem *lpeitem = SP_LPE_ITEM(item);
         SPObject *obj = sp_uri_reference_resolve(_clipboardSPDoc, effect);
         if (!obj) return;
         // if the effect is not used by anyone, we might as well take it
         LivePathEffectObject *lpeobj = LIVEPATHEFFECT(obj)->fork_private_if_necessary(1);
-        sp_shape_set_path_effect(shape, lpeobj);
-
-        // set inkscape:original-d for paths. the other shapes don't need this
-        if (SP_IS_PATH(item)) {
-            Inkscape::XML::Node *pathrepr = SP_OBJECT_REPR(item);
-            if (!pathrepr->attribute("inkscape:original-d")) {
-                pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d"));
-            }
-        }
-    }
-    else if (SP_IS_GROUP(item))
-    {
-        for (SPObject *child = sp_object_first_child(SP_OBJECT(item)) ;
-            child != NULL ; child = SP_OBJECT_NEXT(child))
-        {
-            if (!SP_IS_ITEM(child)) continue;
-            _applyPathEffect(SP_ITEM(child), effect);
-        }
+        sp_lpe_item_set_path_effect(lpeitem, lpeobj);
     }
 }
 
index 29ec03a8ca6294ed7cd6278b6e5d98adda534e32..2394adc6f03fc973cf0cf5ae983ec956b0c413e5 100644 (file)
@@ -3,6 +3,8 @@
  *
  * Authors:
  *   Johan Engelen <j.b.c.engelen@utwente.nl>
+ *   Steren Giannini <steren.giannini@gmail.com>
+ *   Bastien Bouclet <bgkweb@gmail.com>
  *
  * Copyright (C) 2007 Author
  *
@@ -18,6 +20,7 @@
 #include "verbs.h"
 #include "selection.h"
 #include "sp-shape.h"
+#include "sp-item-group.h"
 #include "sp-path.h"
 #include "live_effects/effect.h"
 #include "live_effects/lpeobject.h"
@@ -150,9 +153,9 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
     if ( sel && !sel->isEmpty() ) {
         SPItem *item = sel->singleItem();
         if ( item ) {
-            if ( SP_IS_SHAPE(item) ) {
-                SPShape *shape = SP_SHAPE(item);
-                LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(shape);
+            if ( SP_IS_LPE_ITEM(item) ) {
+                SPLPEItem *lpeitem = SP_LPE_ITEM(item);
+                LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(lpeitem);
                 set_sensitize_all(true);
                 if (lpeobj) {
                     if (lpeobj->lpe) {
@@ -164,8 +167,10 @@ LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
                     showText(_("No effect applied"));
                     button_remove.set_sensitive(false);
                 }
-            } else {
-                showText(_("Item is not a shape or path"));
+            }
+              else
+            {
+                showText(_("Item is not compound by paths"));
                 set_sensitize_all(false);
             }
         } else {
@@ -218,12 +223,13 @@ LivePathEffectEditor::onApply()
     Inkscape::Selection *sel = _getSelection();
     if ( sel && !sel->isEmpty() ) {
         SPItem *item = sel->singleItem();
-        if ( item && SP_IS_SHAPE(item) ) {
+        if ( item && SP_IS_LPE_ITEM(item) ) {
             SPDocument *doc = current_desktop->doc();
 
             const Util::EnumData<LivePathEffect::EffectType>* data = combo_effecttype.get_active_data();
             if (!data) return;
 
+            // Path effect definition
             Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
             Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect");
             repr->setAttribute("effect", data->key.c_str() );
@@ -233,18 +239,10 @@ LivePathEffectEditor::onApply()
             Inkscape::GC::release(repr);
 
             gchar *href = g_strdup_printf("#%s", repr_id);
-            sp_shape_set_path_effect(SP_SHAPE(item), href);
+            sp_lpe_item_set_path_effect(SP_LPE_ITEM(item), href);
             g_free(href);
 
-            // make sure there is an original-d for paths!!!
-            if ( SP_IS_PATH(item) ) {
-                Inkscape::XML::Node *pathrepr = SP_OBJECT_REPR(item);
-                if ( ! pathrepr->attribute("inkscape:original-d") ) {
-                    pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d"));
-                }
-            }
-
-            LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(SP_SHAPE(item));
+            LivePathEffectObject *lpeobj = sp_lpe_item_get_livepatheffectobject(SP_LPE_ITEM(item));
             if (lpeobj && lpeobj->lpe) {
                 lpeobj->lpe->resetDefaults(item);
             }
@@ -263,8 +261,8 @@ LivePathEffectEditor::onRemove()
     Inkscape::Selection *sel = _getSelection();
     if ( sel && !sel->isEmpty() ) {
         SPItem *item = sel->singleItem();
-        if ( item && SP_IS_SHAPE(item) ) {
-            sp_shape_remove_path_effect(SP_SHAPE(item));
+        if ( item && SP_IS_LPE_ITEM(item) ) {
+            sp_lpe_item_remove_path_effect(SP_LPE_ITEM(item), false);
             showText(_("No effect applied"));
             button_remove.set_sensitive(false);
             sp_document_done ( sp_desktop_document (current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, 
@@ -273,8 +271,6 @@ LivePathEffectEditor::onRemove()
     }
 }
 
-
-
 } // namespace Dialog
 } // namespace UI
 } // namespace Inkscape
index 76bdc7d07acbba61cdac7d69b57103fa60412f80..f550b5dc57d2c2639879d48c094e579733b21c7e 100644 (file)
@@ -993,9 +993,8 @@ sp_node_toolbox_sel_changed (Inkscape::Selection *selection, GObject *tbl)
     {
     GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "nodes_lpeedit" ) );
     SPItem *item = selection->singleItem();
-    if (item && SP_IS_SHAPE(item)) {
-       LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(SP_SHAPE(item));
-       if (lpeobj) {
+    if (item && SP_IS_LPE_ITEM(item)) {
+       if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(item))) {
            gtk_action_set_sensitive(w, TRUE);
        } else {
            gtk_action_set_sensitive(w, FALSE);