5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
1 |
/** \file
|
2 |
* Base class for live path effect items
|
|
3 |
*/
|
|
4 |
/*
|
|
5 |
* Authors:
|
|
6 |
* Johan Engelen <j.b.c.engelen@ewi.utwente.nl>
|
|
7 |
* Bastien Bouclet <bgkweb@gmail.com>
|
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
8 |
* Abhishek Sharma
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
9 |
*
|
10 |
* Copyright (C) 2008 authors
|
|
11 |
*
|
|
12 |
* Released under GNU GPL, read the file 'COPYING' for more information
|
|
13 |
*/
|
|
14 |
||
15 |
#ifdef HAVE_CONFIG_H
|
|
16 |
# include "config.h"
|
|
17 |
#endif
|
|
18 |
||
19 |
#include "live_effects/effect.h" |
|
6801
by cilix42
Hide canvas text, too, when lpe-path-length is invisible |
20 |
#include "live_effects/lpe-path_length.h" |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
21 |
#include "live_effects/lpeobject.h" |
22 |
#include "live_effects/lpeobject-reference.h" |
|
23 |
||
24 |
#include "sp-path.h" |
|
25 |
#include "sp-item-group.h" |
|
5503
by pjrm
fix a couple of g++-4.3 compile errors. |
26 |
#include "streq.h" |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
27 |
#include "macros.h" |
28 |
#include "attributes.h" |
|
29 |
#include "sp-lpe-item.h" |
|
30 |
#include "xml/repr.h" |
|
31 |
#include "uri.h" |
|
5938
by johanengelen
put exception catch block around all doEffect calls. (so in SP_LPE_ITEM) |
32 |
#include "message-stack.h" |
33 |
#include "inkscape.h" |
|
34 |
#include "desktop.h" |
|
6456
by cilix42
Update helperpaths live also when any of the item's LPEs is modified |
35 |
#include "shape-editor.h" |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
36 |
|
5766
by johanengelen
LPE STACKING! |
37 |
#include <algorithm> |
38 |
||
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
39 |
/* LPEItem base class */
|
40 |
||
41 |
static void sp_lpe_item_class_init(SPLPEItemClass *klass); |
|
42 |
static void sp_lpe_item_init(SPLPEItem *lpe_item); |
|
43 |
static void sp_lpe_item_finalize(GObject *object); |
|
44 |
||
8422
by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily. |
45 |
static void sp_lpe_item_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr); |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
46 |
static void sp_lpe_item_release(SPObject *object); |
47 |
static void sp_lpe_item_set(SPObject *object, unsigned int key, gchar const *value); |
|
48 |
static void sp_lpe_item_update(SPObject *object, SPCtx *ctx, guint flags); |
|
49 |
static void sp_lpe_item_modified (SPObject *object, unsigned int flags); |
|
5884
by mental
plumb XML::Documents in everywhere |
50 |
static Inkscape::XML::Node *sp_lpe_item_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags); |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
51 |
|
52 |
static void sp_lpe_item_child_added (SPObject * object, Inkscape::XML::Node * child, Inkscape::XML::Node * ref); |
|
53 |
static void sp_lpe_item_remove_child (SPObject * object, Inkscape::XML::Node * child); |
|
54 |
||
5766
by johanengelen
LPE STACKING! |
55 |
static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); |
56 |
||
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
57 |
static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); |
58 |
||
59 |
static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); |
|
60 |
static void sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem); |
|
5766
by johanengelen
LPE STACKING! |
61 |
typedef std::list<std::string> HRefList; |
62 |
static std::string patheffectlist_write_svg(PathEffectList const & list); |
|
63 |
static std::string hreflist_write_svg(HRefList const & list); |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
64 |
|
65 |
static SPItemClass *parent_class; |
|
66 |
||
67 |
GType
|
|
68 |
sp_lpe_item_get_type() |
|
69 |
{
|
|
70 |
static GType lpe_item_type = 0; |
|
71 |
||
72 |
if (!lpe_item_type) { |
|
73 |
GTypeInfo lpe_item_info = { |
|
74 |
sizeof(SPLPEItemClass), |
|
75 |
NULL, NULL, |
|
76 |
(GClassInitFunc) sp_lpe_item_class_init, |
|
77 |
NULL, NULL, |
|
78 |
sizeof(SPLPEItem), |
|
79 |
16, |
|
80 |
(GInstanceInitFunc) sp_lpe_item_init, |
|
81 |
NULL, /* value_table */ |
|
82 |
};
|
|
83 |
lpe_item_type = g_type_register_static(SP_TYPE_ITEM, "SPLPEItem", &lpe_item_info, (GTypeFlags)0); |
|
84 |
}
|
|
85 |
return lpe_item_type; |
|
86 |
}
|
|
87 |
||
88 |
static void |
|
89 |
sp_lpe_item_class_init(SPLPEItemClass *klass) |
|
5766
by johanengelen
LPE STACKING! |
90 |
{
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
91 |
GObjectClass *gobject_class; |
92 |
SPObjectClass *sp_object_class; |
|
93 |
||
94 |
gobject_class = (GObjectClass *) klass; |
|
95 |
sp_object_class = (SPObjectClass *) klass; |
|
96 |
parent_class = (SPItemClass *)g_type_class_peek_parent (klass); |
|
97 |
||
98 |
gobject_class->finalize = sp_lpe_item_finalize; |
|
99 |
||
100 |
sp_object_class->build = sp_lpe_item_build; |
|
101 |
sp_object_class->release = sp_lpe_item_release; |
|
102 |
sp_object_class->set = sp_lpe_item_set; |
|
103 |
sp_object_class->update = sp_lpe_item_update; |
|
104 |
sp_object_class->modified = sp_lpe_item_modified; |
|
105 |
sp_object_class->write = sp_lpe_item_write; |
|
106 |
sp_object_class->child_added = sp_lpe_item_child_added; |
|
107 |
sp_object_class->remove_child = sp_lpe_item_remove_child; |
|
5766
by johanengelen
LPE STACKING! |
108 |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
109 |
klass->update_patheffect = NULL; |
110 |
}
|
|
111 |
||
112 |
static void |
|
113 |
sp_lpe_item_init(SPLPEItem *lpeitem) |
|
114 |
{
|
|
5766
by johanengelen
LPE STACKING! |
115 |
lpeitem->path_effects_enabled = 1; |
116 |
||
117 |
lpeitem->path_effect_list = new PathEffectList(); |
|
118 |
lpeitem->current_path_effect = NULL; |
|
119 |
||
8839
by johanengelen
work on the lpe group undo bug. it's not solved, but i think LPE code does everything correct now. I think now it's the interplay between undo-system and LPE that bugs. |
120 |
lpeitem->lpe_modified_connection_list = new std::list<sigc::connection>(); |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
121 |
}
|
122 |
||
123 |
static void |
|
124 |
sp_lpe_item_finalize(GObject *object) |
|
125 |
{
|
|
126 |
if (((GObjectClass *) (parent_class))->finalize) { |
|
127 |
(* ((GObjectClass *) (parent_class))->finalize)(object); |
|
128 |
}
|
|
129 |
}
|
|
130 |
||
131 |
/**
|
|
132 |
* Reads the Inkscape::XML::Node, and initializes SPLPEItem variables. For this to get called,
|
|
133 |
* our name must be associated with a repr via "sp_object_type_register". Best done through
|
|
134 |
* sp-object-repr.cpp's repr_name_entries array.
|
|
135 |
*/
|
|
136 |
static void |
|
8422
by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily. |
137 |
sp_lpe_item_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr) |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
138 |
{
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
139 |
object->readAttr( "inkscape:path-effect" ); |
5766
by johanengelen
LPE STACKING! |
140 |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
141 |
if (((SPObjectClass *) parent_class)->build) { |
142 |
((SPObjectClass *) parent_class)->build(object, document, repr); |
|
143 |
}
|
|
144 |
}
|
|
145 |
||
146 |
/**
|
|
147 |
* Drops any allocated memory.
|
|
148 |
*/
|
|
149 |
static void |
|
150 |
sp_lpe_item_release(SPObject *object) |
|
151 |
{
|
|
6358
by buliabyak
fix crash when simplifying an lpe path: deleting the list didn't release the references, and it didn't work in _finalize anyway |
152 |
SPLPEItem *lpeitem = (SPLPEItem *) object; |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
153 |
|
8839
by johanengelen
work on the lpe group undo bug. it's not solved, but i think LPE code does everything correct now. I think now it's the interplay between undo-system and LPE that bugs. |
154 |
// disconnect all modified listeners:
|
155 |
for (std::list<sigc::connection>::iterator mod_it = lpeitem->lpe_modified_connection_list->begin(); |
|
156 |
mod_it != lpeitem->lpe_modified_connection_list->end(); ++mod_it) |
|
157 |
{
|
|
158 |
mod_it->disconnect(); |
|
159 |
}
|
|
160 |
delete lpeitem->lpe_modified_connection_list; |
|
161 |
lpeitem->lpe_modified_connection_list = NULL; |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
162 |
|
6358
by buliabyak
fix crash when simplifying an lpe path: deleting the list didn't release the references, and it didn't work in _finalize anyway |
163 |
PathEffectList::iterator it = lpeitem->path_effect_list->begin(); |
164 |
while ( it != lpeitem->path_effect_list->end() ) { |
|
165 |
// unlink and delete all references in the list
|
|
166 |
(*it)->unlink(); |
|
167 |
delete *it; |
|
168 |
it = lpeitem->path_effect_list->erase(it); |
|
169 |
}
|
|
170 |
// delete the list itself
|
|
8839
by johanengelen
work on the lpe group undo bug. it's not solved, but i think LPE code does everything correct now. I think now it's the interplay between undo-system and LPE that bugs. |
171 |
delete lpeitem->path_effect_list; |
172 |
lpeitem->path_effect_list = NULL; |
|
6358
by buliabyak
fix crash when simplifying an lpe path: deleting the list didn't release the references, and it didn't work in _finalize anyway |
173 |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
174 |
if (((SPObjectClass *) parent_class)->release) |
175 |
((SPObjectClass *) parent_class)->release(object); |
|
176 |
}
|
|
177 |
||
178 |
/**
|
|
179 |
* Sets a specific value in the SPLPEItem.
|
|
180 |
*/
|
|
181 |
static void |
|
182 |
sp_lpe_item_set(SPObject *object, unsigned int key, gchar const *value) |
|
183 |
{
|
|
184 |
SPLPEItem *lpeitem = (SPLPEItem *) object; |
|
185 |
||
186 |
switch (key) { |
|
187 |
case SP_ATTR_INKSCAPE_PATH_EFFECT: |
|
5766
by johanengelen
LPE STACKING! |
188 |
{
|
189 |
lpeitem->current_path_effect = NULL; |
|
190 |
||
191 |
// Disable the path effects while populating the LPE list
|
|
192 |
sp_lpe_item_enable_path_effects(lpeitem, false); |
|
193 |
||
8839
by johanengelen
work on the lpe group undo bug. it's not solved, but i think LPE code does everything correct now. I think now it's the interplay between undo-system and LPE that bugs. |
194 |
// disconnect all modified listeners:
|
195 |
for ( std::list<sigc::connection>::iterator mod_it = lpeitem->lpe_modified_connection_list->begin(); |
|
196 |
mod_it != lpeitem->lpe_modified_connection_list->end(); |
|
197 |
++mod_it) |
|
198 |
{
|
|
199 |
mod_it->disconnect(); |
|
200 |
}
|
|
201 |
lpeitem->lpe_modified_connection_list->clear(); |
|
5766
by johanengelen
LPE STACKING! |
202 |
// Clear the path effect list
|
203 |
PathEffectList::iterator it = lpeitem->path_effect_list->begin(); |
|
204 |
while ( it != lpeitem->path_effect_list->end() ) |
|
205 |
{
|
|
206 |
(*it)->unlink(); |
|
207 |
delete *it; |
|
208 |
it = lpeitem->path_effect_list->erase(it); |
|
209 |
}
|
|
210 |
||
211 |
// Parse the contents of "value" to rebuild the path effect reference list
|
|
212 |
if ( value ) { |
|
213 |
std::istringstream iss(value); |
|
214 |
std::string href; |
|
215 |
while (std::getline(iss, href, ';')) |
|
216 |
{
|
|
8839
by johanengelen
work on the lpe group undo bug. it's not solved, but i think LPE code does everything correct now. I think now it's the interplay between undo-system and LPE that bugs. |
217 |
Inkscape::LivePathEffect::LPEObjectReference *path_effect_ref = new Inkscape::LivePathEffect::LPEObjectReference(object); |
5766
by johanengelen
LPE STACKING! |
218 |
try { |
219 |
path_effect_ref->link(href.c_str()); |
|
6873
by johanengelen
fix crash on entering invalid lpe name in xml |
220 |
} catch (Inkscape::BadURIException e) { |
6891
by Ted Gould
Merge from fe-moved |
221 |
g_warning("BadURIException when trying to find LPE: %s", e.what()); |
5766
by johanengelen
LPE STACKING! |
222 |
path_effect_ref->unlink(); |
223 |
delete path_effect_ref; |
|
224 |
path_effect_ref = NULL; |
|
225 |
}
|
|
226 |
||
6891
by Ted Gould
Merge from fe-moved |
227 |
lpeitem->path_effect_list->push_back(path_effect_ref); |
8839
by johanengelen
work on the lpe group undo bug. it's not solved, but i think LPE code does everything correct now. I think now it's the interplay between undo-system and LPE that bugs. |
228 |
if ( path_effect_ref->lpeobject && path_effect_ref->lpeobject->get_lpe() ) { |
229 |
// connect modified-listener
|
|
230 |
lpeitem->lpe_modified_connection_list->push_back( |
|
231 |
path_effect_ref->lpeobject->connectModified(sigc::bind(sigc::ptr_fun(&lpeobject_ref_modified), lpeitem)) ); |
|
232 |
} else { |
|
6891
by Ted Gould
Merge from fe-moved |
233 |
// something has gone wrong in finding the right patheffect.
|
234 |
g_warning("Unknown LPE type specified, LPE stack effectively disabled"); |
|
235 |
// keep the effect in the lpestack, so the whole stack is effectively disabled but maintained
|
|
5766
by johanengelen
LPE STACKING! |
236 |
}
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
237 |
}
|
238 |
}
|
|
5766
by johanengelen
LPE STACKING! |
239 |
|
240 |
sp_lpe_item_enable_path_effects(lpeitem, true); |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
241 |
}
|
242 |
break; |
|
243 |
default: |
|
244 |
if (((SPObjectClass *) parent_class)->set) { |
|
245 |
((SPObjectClass *) parent_class)->set(object, key, value); |
|
246 |
}
|
|
247 |
break; |
|
248 |
}
|
|
249 |
}
|
|
250 |
||
251 |
/**
|
|
252 |
* Receives update notifications.
|
|
253 |
*/
|
|
254 |
static void |
|
255 |
sp_lpe_item_update(SPObject *object, SPCtx *ctx, guint flags) |
|
256 |
{
|
|
257 |
if (((SPObjectClass *) parent_class)->update) { |
|
258 |
((SPObjectClass *) parent_class)->update(object, ctx, flags); |
|
259 |
}
|
|
6456
by cilix42
Update helperpaths live also when any of the item's LPEs is modified |
260 |
|
261 |
// update the helperpaths of all LPEs applied to the item
|
|
8846.1.1
by Krzysztof Kosiński
First GSoC node tool commit to Bazaar |
262 |
// TODO: re-add for the new node tool
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
263 |
}
|
264 |
||
265 |
/**
|
|
266 |
* Sets modified flag for all sub-item views.
|
|
267 |
*/
|
|
268 |
static void |
|
269 |
sp_lpe_item_modified (SPObject *object, unsigned int flags) |
|
270 |
{
|
|
5766
by johanengelen
LPE STACKING! |
271 |
if (SP_IS_GROUP(object) && (flags & SP_OBJECT_MODIFIED_FLAG) && (flags & SP_OBJECT_USER_MODIFIED_FLAG_B)) { |
272 |
sp_lpe_item_update_patheffect(SP_LPE_ITEM(object), true, true); |
|
273 |
}
|
|
274 |
||
275 |
if (((SPObjectClass *) (parent_class))->modified) { |
|
276 |
(* ((SPObjectClass *) (parent_class))->modified) (object, flags); |
|
277 |
}
|
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
278 |
}
|
279 |
||
280 |
/**
|
|
281 |
* Writes its settings to an incoming repr object, if any.
|
|
282 |
*/
|
|
283 |
static Inkscape::XML::Node * |
|
5884
by mental
plumb XML::Documents in everywhere |
284 |
sp_lpe_item_write(SPObject *object, Inkscape::XML::Document *xml_doc, Inkscape::XML::Node *repr, guint flags) |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
285 |
{
|
286 |
SPLPEItem *lpeitem = (SPLPEItem *) object; |
|
287 |
||
8540
by johanengelen
fix bug #377958: don't write inkscape:path-effect to plain svg |
288 |
if (flags & SP_OBJECT_WRITE_EXT) { |
289 |
if ( sp_lpe_item_has_path_effect(lpeitem) ) { |
|
290 |
std::string href = patheffectlist_write_svg(*lpeitem->path_effect_list); |
|
291 |
repr->setAttribute("inkscape:path-effect", href.c_str()); |
|
292 |
} else { |
|
293 |
repr->setAttribute("inkscape:path-effect", NULL); |
|
294 |
}
|
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
295 |
}
|
296 |
||
297 |
if (((SPObjectClass *)(parent_class))->write) { |
|
5884
by mental
plumb XML::Documents in everywhere |
298 |
((SPObjectClass *)(parent_class))->write(object, xml_doc, repr, flags); |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
299 |
}
|
300 |
||
301 |
return repr; |
|
302 |
}
|
|
303 |
||
6891
by Ted Gould
Merge from fe-moved |
304 |
/**
|
305 |
* returns true when LPE was successful.
|
|
306 |
*/
|
|
307 |
bool sp_lpe_item_perform_path_effect(SPLPEItem *lpeitem, SPCurve *curve) { |
|
308 |
if (!lpeitem) return false; |
|
309 |
if (!curve) return false; |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
310 |
|
5766
by johanengelen
LPE STACKING! |
311 |
if (sp_lpe_item_has_path_effect(lpeitem) && sp_lpe_item_path_effects_enabled(lpeitem)) { |
312 |
for (PathEffectList::iterator it = lpeitem->path_effect_list->begin(); it != lpeitem->path_effect_list->end(); ++it) |
|
313 |
{
|
|
314 |
LivePathEffectObject *lpeobj = (*it)->lpeobject; |
|
5792
by johanengelen
fix crash, report warnings instead. trying to find real cause for this (crash on copying path with lpestack). |
315 |
if (!lpeobj) { |
6885
by Ted Gould
From trunk |
316 |
/** \todo Investigate the cause of this.
|
317 |
* For example, this happens when copy pasting an object with LPE applied. Probably because the object is pasted while the effect is not yet pasted to defs, and cannot be found.
|
|
318 |
*/
|
|
5792
by johanengelen
fix crash, report warnings instead. trying to find real cause for this (crash on copying path with lpestack). |
319 |
g_warning("sp_lpe_item_perform_path_effect - NULL lpeobj in list!"); |
6891
by Ted Gould
Merge from fe-moved |
320 |
return false; |
5792
by johanengelen
fix crash, report warnings instead. trying to find real cause for this (crash on copying path with lpestack). |
321 |
}
|
6884
by Ted Gould
Merging from trunk |
322 |
Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); |
323 |
if (!lpe) { |
|
6885
by Ted Gould
From trunk |
324 |
/** \todo Investigate the cause of this.
|
325 |
* Not sure, but I think this can happen when an unknown effect type is specified...
|
|
326 |
*/
|
|
6891
by Ted Gould
Merge from fe-moved |
327 |
g_warning("sp_lpe_item_perform_path_effect - lpeobj with invalid lpe in the stack!"); |
328 |
return false; |
|
5792
by johanengelen
fix crash, report warnings instead. trying to find real cause for this (crash on copying path with lpestack). |
329 |
}
|
5766
by johanengelen
LPE STACKING! |
330 |
|
5902
by cilix42
Infrastructure in class LivePathEffect::Effect to put Inkscape into 'wait for parameter path' mode; make LPEMirrorReflect use this to let the user specify the mirroring line |
331 |
if (lpe->isVisible()) { |
6644
by cilix42
Rename acceptsNumParams() -> acceptsNumClicks() because it makes more sense |
332 |
if (lpe->acceptsNumClicks() > 0 && !lpe->isReady()) { |
5902
by cilix42
Infrastructure in class LivePathEffect::Effect to put Inkscape into 'wait for parameter path' mode; make LPEMirrorReflect use this to let the user specify the mirroring line |
333 |
// if the effect expects mouse input before being applied and the input is not finished
|
334 |
// yet, we don't alter the path
|
|
6891
by Ted Gould
Merge from fe-moved |
335 |
return false; |
5902
by cilix42
Infrastructure in class LivePathEffect::Effect to put Inkscape into 'wait for parameter path' mode; make LPEMirrorReflect use this to let the user specify the mirroring line |
336 |
}
|
337 |
||
5766
by johanengelen
LPE STACKING! |
338 |
// Groups have their doBeforeEffect called elsewhere
|
339 |
if (!SP_IS_GROUP(lpeitem)) { |
|
5902
by cilix42
Infrastructure in class LivePathEffect::Effect to put Inkscape into 'wait for parameter path' mode; make LPEMirrorReflect use this to let the user specify the mirroring line |
340 |
lpe->doBeforeEffect(lpeitem); |
5766
by johanengelen
LPE STACKING! |
341 |
}
|
342 |
||
5938
by johanengelen
put exception catch block around all doEffect calls. (so in SP_LPE_ITEM) |
343 |
try { |
344 |
lpe->doEffect(curve); |
|
345 |
}
|
|
346 |
catch (std::exception & e) { |
|
347 |
g_warning("Exception during LPE %s execution. \n %s", lpe->getName().c_str(), e.what()); |
|
6885
by Ted Gould
From trunk |
348 |
if (SP_ACTIVE_DESKTOP && SP_ACTIVE_DESKTOP->messageStack()) { |
349 |
SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, |
|
350 |
_("An exception occurred during execution of the Path Effect.") ); |
|
351 |
}
|
|
6891
by Ted Gould
Merge from fe-moved |
352 |
return false; |
5938
by johanengelen
put exception catch block around all doEffect calls. (so in SP_LPE_ITEM) |
353 |
}
|
5766
by johanengelen
LPE STACKING! |
354 |
}
|
5711
by cilix42
Add checkbox for LPEs to temporarily disable them on canvas (but keep them applied to the object) |
355 |
}
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
356 |
}
|
6891
by Ted Gould
Merge from fe-moved |
357 |
|
358 |
return true; |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
359 |
}
|
360 |
||
361 |
/**
|
|
362 |
* Calls any registered handlers for the update_patheffect action
|
|
363 |
*/
|
|
364 |
void
|
|
5766
by johanengelen
LPE STACKING! |
365 |
sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write) |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
366 |
{
|
367 |
#ifdef SHAPE_VERBOSE
|
|
368 |
g_message("sp_lpe_item_update_patheffect: %p\n", lpeitem); |
|
369 |
#endif
|
|
370 |
g_return_if_fail (lpeitem != NULL); |
|
371 |
g_return_if_fail (SP_IS_LPE_ITEM (lpeitem)); |
|
372 |
||
5769
by bgk
Stacked LPEs should now use the right bounding box |
373 |
if (!sp_lpe_item_path_effects_enabled(lpeitem)) |
374 |
return; |
|
375 |
||
6801
by cilix42
Hide canvas text, too, when lpe-path-length is invisible |
376 |
// TODO: hack! this will be removed when path length measuring is reimplemented in a better way
|
377 |
PathEffectList lpelist = sp_lpe_item_get_effect_list(lpeitem); |
|
378 |
std::list<Inkscape::LivePathEffect::LPEObjectReference *>::iterator i; |
|
379 |
for (i = lpelist.begin(); i != lpelist.end(); ++i) { |
|
6885
by Ted Gould
From trunk |
380 |
if ((*i)->lpeobject) { |
381 |
Inkscape::LivePathEffect::Effect *lpe = (*i)->lpeobject->get_lpe(); |
|
382 |
if (dynamic_cast<Inkscape::LivePathEffect::LPEPathLength *>(lpe)) { |
|
383 |
if (!lpe->isVisible()) { |
|
384 |
// we manually disable text for LPEPathLength
|
|
8846.1.1
by Krzysztof Kosiński
First GSoC node tool commit to Bazaar |
385 |
// use static_cast, because we already checked for the right type above
|
386 |
static_cast<Inkscape::LivePathEffect::LPEPathLength *>(lpe)->hideCanvasText(); |
|
6885
by Ted Gould
From trunk |
387 |
}
|
6801
by cilix42
Hide canvas text, too, when lpe-path-length is invisible |
388 |
}
|
389 |
}
|
|
390 |
}
|
|
391 |
||
5766
by johanengelen
LPE STACKING! |
392 |
SPLPEItem *top; |
393 |
||
394 |
if (wholetree) { |
|
395 |
SPObject *prev_parent = lpeitem; |
|
396 |
SPObject *parent = prev_parent->parent; |
|
397 |
while (parent && SP_IS_LPE_ITEM(parent) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(parent))) { |
|
398 |
prev_parent = parent; |
|
399 |
parent = prev_parent->parent; |
|
400 |
}
|
|
401 |
top = SP_LPE_ITEM(prev_parent); |
|
402 |
}
|
|
403 |
else { |
|
404 |
top = lpeitem; |
|
405 |
}
|
|
406 |
||
407 |
if (SP_LPE_ITEM_CLASS (G_OBJECT_GET_CLASS (top))->update_patheffect) { |
|
408 |
SP_LPE_ITEM_CLASS (G_OBJECT_GET_CLASS (top))->update_patheffect (top, write); |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
409 |
}
|
410 |
}
|
|
411 |
||
412 |
/**
|
|
8839
by johanengelen
work on the lpe group undo bug. it's not solved, but i think LPE code does everything correct now. I think now it's the interplay between undo-system and LPE that bugs. |
413 |
* Gets called when any of the lpestack's lpeobject repr contents change: i.e. parameter change in any of the stacked LPEs
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
414 |
*/
|
415 |
static void |
|
416 |
lpeobject_ref_modified(SPObject */*href*/, guint /*flags*/, SPLPEItem *lpeitem) |
|
417 |
{
|
|
8839
by johanengelen
work on the lpe group undo bug. it's not solved, but i think LPE code does everything correct now. I think now it's the interplay between undo-system and LPE that bugs. |
418 |
#ifdef SHAPE_VERBOSE
|
419 |
g_message("lpeobject_ref_modified"); |
|
420 |
#endif
|
|
5766
by johanengelen
LPE STACKING! |
421 |
sp_lpe_item_update_patheffect (lpeitem, true, true); |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
422 |
}
|
423 |
||
424 |
static void |
|
425 |
sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem) |
|
426 |
{
|
|
427 |
if (SP_IS_GROUP(lpeitem)) { |
|
428 |
GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); |
|
429 |
for ( GSList const *iter = item_list; iter; iter = iter->next ) { |
|
430 |
SPObject *subitem = static_cast<SPObject *>(iter->data); |
|
431 |
if (SP_IS_LPE_ITEM(subitem)) { |
|
432 |
sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(subitem)); |
|
433 |
}
|
|
434 |
}
|
|
435 |
}
|
|
436 |
else if (SP_IS_PATH(lpeitem)) { |
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
437 |
Inkscape::XML::Node *pathrepr = lpeitem->getRepr(); |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
438 |
if ( !pathrepr->attribute("inkscape:original-d") ) { |
439 |
pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d")); |
|
440 |
}
|
|
441 |
}
|
|
442 |
}
|
|
443 |
||
444 |
static void |
|
445 |
sp_lpe_item_cleanup_original_path_recursive(SPLPEItem *lpeitem) |
|
446 |
{
|
|
447 |
if (SP_IS_GROUP(lpeitem)) { |
|
448 |
GSList const *item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); |
|
449 |
for ( GSList const *iter = item_list; iter; iter = iter->next ) { |
|
450 |
SPObject *subitem = static_cast<SPObject *>(iter->data); |
|
451 |
if (SP_IS_LPE_ITEM(subitem)) { |
|
452 |
sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(subitem)); |
|
453 |
}
|
|
454 |
}
|
|
455 |
}
|
|
456 |
else if (SP_IS_PATH(lpeitem)) { |
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
457 |
Inkscape::XML::Node *repr = lpeitem->getRepr(); |
5766
by johanengelen
LPE STACKING! |
458 |
if (!sp_lpe_item_has_path_effect_recursive(lpeitem) |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
459 |
&& repr->attribute("inkscape:original-d")) { |
460 |
repr->setAttribute("d", repr->attribute("inkscape:original-d")); |
|
461 |
repr->setAttribute("inkscape:original-d", NULL); |
|
462 |
}
|
|
463 |
else { |
|
5766
by johanengelen
LPE STACKING! |
464 |
sp_lpe_item_update_patheffect(lpeitem, true, true); |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
465 |
}
|
466 |
}
|
|
467 |
}
|
|
468 |
||
5766
by johanengelen
LPE STACKING! |
469 |
void sp_lpe_item_add_path_effect(SPLPEItem *lpeitem, gchar *value, bool reset) |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
470 |
{
|
5766
by johanengelen
LPE STACKING! |
471 |
if (value) { |
472 |
// Apply the path effects here because in the casse of a group, lpe->resetDefaults
|
|
473 |
// needs that all the subitems have their effects applied
|
|
474 |
sp_lpe_item_update_patheffect(lpeitem, false, true); |
|
475 |
||
476 |
// Disable the path effects while preparing the new lpe
|
|
477 |
sp_lpe_item_enable_path_effects(lpeitem, false); |
|
478 |
||
479 |
// Add the new reference to the list of LPE references
|
|
480 |
HRefList hreflist; |
|
481 |
for (PathEffectList::const_iterator it = lpeitem->path_effect_list->begin(); it != lpeitem->path_effect_list->end(); ++it) |
|
482 |
{
|
|
483 |
hreflist.push_back( std::string((*it)->lpeobject_href) ); |
|
5683
by bgk
Fix LPE for groups bounding box calculation by using the SPItem->getBounds method. |
484 |
}
|
5766
by johanengelen
LPE STACKING! |
485 |
hreflist.push_back( std::string(value) ); |
486 |
std::string hrefs = hreflist_write_svg(hreflist); |
|
487 |
||
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
488 |
lpeitem->getRepr()->setAttribute("inkscape:path-effect", hrefs.c_str()); |
5766
by johanengelen
LPE STACKING! |
489 |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
490 |
// make sure there is an original-d for paths!!!
|
491 |
sp_lpe_item_create_original_path_recursive(lpeitem); |
|
5766
by johanengelen
LPE STACKING! |
492 |
|
493 |
LivePathEffectObject *lpeobj = lpeitem->path_effect_list->back()->lpeobject; |
|
6884
by Ted Gould
Merging from trunk |
494 |
if (lpeobj && lpeobj->get_lpe()) { |
495 |
Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); |
|
5766
by johanengelen
LPE STACKING! |
496 |
// Ask the path effect to reset itself if it doesn't have parameters yet
|
497 |
if (reset) { |
|
498 |
// has to be called when all the subitems have their lpes applied
|
|
5902
by cilix42
Infrastructure in class LivePathEffect::Effect to put Inkscape into 'wait for parameter path' mode; make LPEMirrorReflect use this to let the user specify the mirroring line |
499 |
lpe->resetDefaults(lpeitem); |
500 |
}
|
|
501 |
||
5905
by cilix42
whitespace |
502 |
// perform this once when the effect is applied
|
5902
by cilix42
Infrastructure in class LivePathEffect::Effect to put Inkscape into 'wait for parameter path' mode; make LPEMirrorReflect use this to let the user specify the mirroring line |
503 |
lpe->doOnApply(SP_LPE_ITEM(lpeitem)); |
504 |
||
6643
by cilix42
Remove done_pathparam_set and friends because it currently isn't used any more anyway; reimplement its intended functionality by using isReady() |
505 |
// indicate that all necessary preparations are done and the effect can be performed
|
506 |
lpe->setReady(); |
|
5766
by johanengelen
LPE STACKING! |
507 |
}
|
508 |
||
509 |
//Enable the path effects now that everything is ready to apply the new path effect
|
|
510 |
sp_lpe_item_enable_path_effects(lpeitem, true); |
|
511 |
||
512 |
// Apply the path effect
|
|
513 |
sp_lpe_item_update_patheffect(lpeitem, true, true); |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
514 |
}
|
515 |
}
|
|
516 |
||
5766
by johanengelen
LPE STACKING! |
517 |
void sp_lpe_item_add_path_effect(SPLPEItem *lpeitem, LivePathEffectObject * new_lpeobj) |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
518 |
{
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
519 |
const gchar * repr_id = new_lpeobj->getRepr()->attribute("id"); |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
520 |
gchar *hrefstr = g_strdup_printf("#%s", repr_id); |
5766
by johanengelen
LPE STACKING! |
521 |
sp_lpe_item_add_path_effect(lpeitem, hrefstr, false); |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
522 |
g_free(hrefstr); |
523 |
}
|
|
524 |
||
5766
by johanengelen
LPE STACKING! |
525 |
void sp_lpe_item_remove_current_path_effect(SPLPEItem *lpeitem, bool keep_paths) |
526 |
{
|
|
527 |
Inkscape::LivePathEffect::LPEObjectReference* lperef = sp_lpe_item_get_current_lpereference(lpeitem); |
|
528 |
if (!lperef) |
|
529 |
return; |
|
530 |
||
531 |
PathEffectList new_list = *lpeitem->path_effect_list; |
|
532 |
new_list.remove(lperef); //current lpe ref is always our 'own' pointer from the path_effect_list |
|
533 |
std::string r = patheffectlist_write_svg(new_list); |
|
534 |
||
8722
by scislac
Fix for 419577 by Johan |
535 |
if (!r.empty()) { |
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
536 |
lpeitem->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); |
8722
by scislac
Fix for 419577 by Johan |
537 |
} else { |
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
538 |
lpeitem->getRepr()->setAttribute("inkscape:path-effect", NULL); |
8722
by scislac
Fix for 419577 by Johan |
539 |
}
|
5766
by johanengelen
LPE STACKING! |
540 |
|
541 |
if (!keep_paths) { |
|
542 |
sp_lpe_item_cleanup_original_path_recursive(lpeitem); |
|
543 |
}
|
|
544 |
}
|
|
545 |
||
546 |
void sp_lpe_item_remove_all_path_effects(SPLPEItem *lpeitem, bool keep_paths) |
|
547 |
{
|
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
548 |
lpeitem->getRepr()->setAttribute("inkscape:path-effect", NULL); |
5766
by johanengelen
LPE STACKING! |
549 |
|
550 |
if (!keep_paths) { |
|
551 |
sp_lpe_item_cleanup_original_path_recursive(lpeitem); |
|
552 |
}
|
|
553 |
}
|
|
554 |
||
555 |
void sp_lpe_item_down_current_path_effect(SPLPEItem *lpeitem) |
|
556 |
{
|
|
557 |
Inkscape::LivePathEffect::LPEObjectReference* lperef = sp_lpe_item_get_current_lpereference(lpeitem); |
|
558 |
if (!lperef) |
|
559 |
return; |
|
560 |
||
561 |
PathEffectList new_list = *lpeitem->path_effect_list; |
|
562 |
PathEffectList::iterator cur_it = find( new_list.begin(), new_list.end(), lperef ); |
|
563 |
if (cur_it != new_list.end()) { |
|
564 |
PathEffectList::iterator down_it = cur_it; |
|
565 |
down_it++; |
|
566 |
if (down_it != new_list.end()) { // perhaps current effect is already last effect |
|
567 |
std::iter_swap(cur_it, down_it); |
|
568 |
}
|
|
569 |
}
|
|
570 |
std::string r = patheffectlist_write_svg(new_list); |
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
571 |
lpeitem->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); |
5766
by johanengelen
LPE STACKING! |
572 |
|
573 |
sp_lpe_item_cleanup_original_path_recursive(lpeitem); |
|
574 |
}
|
|
575 |
||
576 |
void sp_lpe_item_up_current_path_effect(SPLPEItem *lpeitem) |
|
577 |
{
|
|
578 |
Inkscape::LivePathEffect::LPEObjectReference* lperef = sp_lpe_item_get_current_lpereference(lpeitem); |
|
579 |
if (!lperef) |
|
580 |
return; |
|
581 |
||
582 |
PathEffectList new_list = *lpeitem->path_effect_list; |
|
583 |
PathEffectList::iterator cur_it = find( new_list.begin(), new_list.end(), lperef ); |
|
584 |
if (cur_it != new_list.end() && cur_it != new_list.begin()) { |
|
585 |
PathEffectList::iterator up_it = cur_it; |
|
586 |
up_it--; |
|
587 |
std::iter_swap(cur_it, up_it); |
|
588 |
}
|
|
589 |
std::string r = patheffectlist_write_svg(new_list); |
|
590 |
||
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
591 |
lpeitem->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); |
5766
by johanengelen
LPE STACKING! |
592 |
|
593 |
sp_lpe_item_cleanup_original_path_recursive(lpeitem); |
|
594 |
}
|
|
595 |
||
8520
by buliabyak
fix rendering of testcase errorhandling-nosuchlpe.svg: make sure shapes do not calculate the curve if they have a broken lpe, instead reading it directly from d= and issuing a warning |
596 |
/** used for shapes so they can see if they should also disable shape calculation and read from d= */
|
597 |
bool sp_lpe_item_has_broken_path_effect(SPLPEItem *lpeitem) |
|
598 |
{
|
|
599 |
if (lpeitem->path_effect_list->empty()) |
|
600 |
return false; |
|
601 |
||
602 |
// go through the list; if some are unknown or invalid, return true
|
|
603 |
PathEffectList effect_list = sp_lpe_item_get_effect_list(lpeitem); |
|
604 |
for (PathEffectList::iterator it = effect_list.begin(); it != effect_list.end(); it++) |
|
605 |
{
|
|
606 |
LivePathEffectObject *lpeobj = (*it)->lpeobject; |
|
607 |
if (!lpeobj || !lpeobj->get_lpe()) |
|
608 |
return true; |
|
609 |
}
|
|
610 |
||
611 |
return false; |
|
612 |
}
|
|
613 |
||
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
614 |
|
615 |
bool sp_lpe_item_has_path_effect(SPLPEItem *lpeitem) |
|
616 |
{
|
|
7566
by buliabyak
sp_lpe_item_has_path_effect now returns false if one of the effects in the stack is invalid or unsupported, in which case LPE stack is disabled |
617 |
if (lpeitem->path_effect_list->empty()) |
618 |
return false; |
|
619 |
||
620 |
// go through the list; if some are unknown or invalid, we are not an LPE item!
|
|
621 |
PathEffectList effect_list = sp_lpe_item_get_effect_list(lpeitem); |
|
622 |
for (PathEffectList::iterator it = effect_list.begin(); it != effect_list.end(); it++) |
|
623 |
{
|
|
624 |
LivePathEffectObject *lpeobj = (*it)->lpeobject; |
|
625 |
if (!lpeobj || !lpeobj->get_lpe()) |
|
626 |
return false; |
|
627 |
}
|
|
628 |
||
629 |
return true; |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
630 |
}
|
631 |
||
632 |
bool sp_lpe_item_has_path_effect_recursive(SPLPEItem *lpeitem) |
|
633 |
{
|
|
634 |
SPObject *parent = lpeitem->parent; |
|
635 |
if (parent && SP_IS_LPE_ITEM(parent)) { |
|
636 |
return sp_lpe_item_has_path_effect(lpeitem) || sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(parent)); |
|
637 |
}
|
|
638 |
else { |
|
639 |
return sp_lpe_item_has_path_effect(lpeitem); |
|
640 |
}
|
|
641 |
}
|
|
642 |
||
6322
by cilix42
New LPE FreehandShape derived from PatternAlongPath (for the shapes in pen/pencil context); don't apply shapes each time the selection changes; new functions to test for specific LPE type and if a path can accept a new shape |
643 |
Inkscape::LivePathEffect::Effect* |
644 |
sp_lpe_item_has_path_effect_of_type(SPLPEItem *lpeitem, int type) |
|
645 |
{
|
|
646 |
std::list<Inkscape::LivePathEffect::LPEObjectReference *>::iterator i; |
|
647 |
for (i = lpeitem->path_effect_list->begin(); i != lpeitem->path_effect_list->end(); ++i) { |
|
6884
by Ted Gould
Merging from trunk |
648 |
Inkscape::LivePathEffect::Effect* lpe = (*i)->lpeobject->get_lpe(); |
649 |
if (lpe && (lpe->effectType() == type)) { |
|
650 |
return lpe; |
|
6322
by cilix42
New LPE FreehandShape derived from PatternAlongPath (for the shapes in pen/pencil context); don't apply shapes each time the selection changes; new functions to test for specific LPE type and if a path can accept a new shape |
651 |
}
|
652 |
}
|
|
653 |
return NULL; |
|
654 |
}
|
|
655 |
||
656 |
/* Return false if the item is not a path or already has a shape applied */
|
|
657 |
bool sp_lpe_item_can_accept_freehand_shape(SPLPEItem *lpeitem) |
|
658 |
{
|
|
659 |
if (!SP_IS_PATH(lpeitem)) |
|
660 |
return false; |
|
661 |
||
662 |
if (sp_lpe_item_has_path_effect_of_type(lpeitem, Inkscape::LivePathEffect::FREEHAND_SHAPE)) |
|
663 |
return false; |
|
664 |
||
665 |
return true; |
|
666 |
}
|
|
667 |
||
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
668 |
void sp_lpe_item_edit_next_param_oncanvas(SPLPEItem *lpeitem, SPDesktop *dt) |
669 |
{
|
|
5766
by johanengelen
LPE STACKING! |
670 |
Inkscape::LivePathEffect::LPEObjectReference *lperef = sp_lpe_item_get_current_lpereference(lpeitem); |
6884
by Ted Gould
Merging from trunk |
671 |
if (lperef && lperef->lpeobject && lperef->lpeobject->get_lpe()) { |
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
672 |
lperef->lpeobject->get_lpe()->editNextParamOncanvas(lpeitem, dt); |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
673 |
}
|
674 |
}
|
|
675 |
||
676 |
static void |
|
677 |
sp_lpe_item_child_added (SPObject *object, Inkscape::XML::Node *child, Inkscape::XML::Node *ref) |
|
678 |
{
|
|
679 |
if (((SPObjectClass *) (parent_class))->child_added) |
|
680 |
(* ((SPObjectClass *) (parent_class))->child_added) (object, child, ref); |
|
5766
by johanengelen
LPE STACKING! |
681 |
|
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
682 |
if (SP_IS_LPE_ITEM(object) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(object))) { |
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
683 |
SPObject *ochild = object->get_child_by_repr(child); |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
684 |
if ( ochild && SP_IS_LPE_ITEM(ochild) ) { |
685 |
sp_lpe_item_create_original_path_recursive(SP_LPE_ITEM(ochild)); |
|
686 |
}
|
|
687 |
}
|
|
688 |
}
|
|
689 |
||
690 |
static void |
|
691 |
sp_lpe_item_remove_child (SPObject * object, Inkscape::XML::Node * child) |
|
692 |
{
|
|
693 |
if (SP_IS_LPE_ITEM(object) && sp_lpe_item_has_path_effect_recursive(SP_LPE_ITEM(object))) { |
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
694 |
SPObject *ochild = object->get_child_by_repr(child); |
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
695 |
if ( ochild && SP_IS_LPE_ITEM(ochild) ) { |
696 |
sp_lpe_item_cleanup_original_path_recursive(SP_LPE_ITEM(ochild)); |
|
697 |
}
|
|
698 |
}
|
|
699 |
||
700 |
if (((SPObjectClass *) (parent_class))->remove_child) |
|
701 |
(* ((SPObjectClass *) (parent_class))->remove_child) (object, child); |
|
702 |
}
|
|
703 |
||
5766
by johanengelen
LPE STACKING! |
704 |
static std::string patheffectlist_write_svg(PathEffectList const & list) |
705 |
{
|
|
706 |
HRefList hreflist; |
|
707 |
for (PathEffectList::const_iterator it = list.begin(); it != list.end(); ++it) |
|
708 |
{
|
|
709 |
hreflist.push_back( std::string((*it)->lpeobject_href) ); |
|
710 |
}
|
|
711 |
return hreflist_write_svg(hreflist); |
|
712 |
}
|
|
713 |
||
714 |
/**
|
|
715 |
* THE function that should be used to generate any patheffectlist string.
|
|
716 |
* one of the methods to change the effect list:
|
|
717 |
* - create temporary href list
|
|
718 |
* - populate the templist with the effects from the old list that you want to have and their order
|
|
719 |
* - call this function with temp list as param
|
|
720 |
*/
|
|
721 |
static std::string hreflist_write_svg(HRefList const & list) |
|
722 |
{
|
|
723 |
std::string r; |
|
724 |
bool semicolon_first = false; |
|
725 |
for (HRefList::const_iterator it = list.begin(); it != list.end(); ++it) |
|
726 |
{
|
|
727 |
if (semicolon_first) { |
|
728 |
r += ';'; |
|
729 |
}
|
|
730 |
semicolon_first = true; |
|
731 |
||
732 |
r += (*it); |
|
733 |
}
|
|
734 |
return r; |
|
735 |
}
|
|
736 |
||
737 |
// Return a copy of the effect list
|
|
738 |
PathEffectList sp_lpe_item_get_effect_list(SPLPEItem *lpeitem) |
|
739 |
{
|
|
740 |
return *lpeitem->path_effect_list; |
|
741 |
}
|
|
742 |
||
743 |
Inkscape::LivePathEffect::LPEObjectReference* sp_lpe_item_get_current_lpereference(SPLPEItem *lpeitem) |
|
744 |
{
|
|
8839
by johanengelen
work on the lpe group undo bug. it's not solved, but i think LPE code does everything correct now. I think now it's the interplay between undo-system and LPE that bugs. |
745 |
if (!lpeitem->current_path_effect && !lpeitem->path_effect_list->empty()) { |
5766
by johanengelen
LPE STACKING! |
746 |
sp_lpe_item_set_current_path_effect(lpeitem, lpeitem->path_effect_list->back()); |
8839
by johanengelen
work on the lpe group undo bug. it's not solved, but i think LPE code does everything correct now. I think now it's the interplay between undo-system and LPE that bugs. |
747 |
}
|
5766
by johanengelen
LPE STACKING! |
748 |
|
749 |
return lpeitem->current_path_effect; |
|
750 |
}
|
|
751 |
||
752 |
Inkscape::LivePathEffect::Effect* sp_lpe_item_get_current_lpe(SPLPEItem *lpeitem) |
|
753 |
{
|
|
754 |
Inkscape::LivePathEffect::LPEObjectReference* lperef = sp_lpe_item_get_current_lpereference(lpeitem); |
|
755 |
||
756 |
if (lperef && lperef->lpeobject) |
|
6884
by Ted Gould
Merging from trunk |
757 |
return lperef->lpeobject->get_lpe(); |
5766
by johanengelen
LPE STACKING! |
758 |
else
|
759 |
return NULL; |
|
760 |
}
|
|
761 |
||
762 |
bool sp_lpe_item_set_current_path_effect(SPLPEItem *lpeitem, Inkscape::LivePathEffect::LPEObjectReference* lperef) |
|
763 |
{
|
|
764 |
for (PathEffectList::iterator it = lpeitem->path_effect_list->begin(); it != lpeitem->path_effect_list->end(); it++) { |
|
765 |
if ((*it)->lpeobject_repr == lperef->lpeobject_repr) { |
|
766 |
lpeitem->current_path_effect = (*it); // current_path_effect should always be a pointer from the path_effect_list ! |
|
767 |
return true; |
|
768 |
}
|
|
769 |
}
|
|
770 |
||
771 |
return false; |
|
772 |
}
|
|
773 |
||
9012.1.407
by Johan Engelen
fix bug when forking LPE stack |
774 |
/**
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
775 |
* Writes a new "inkscape:path-effect" string to xml, where the old_lpeobjects are substituted by the new ones.
|
9012.1.407
by Johan Engelen
fix bug when forking LPE stack |
776 |
* Note that this method messes up the item's \c PathEffectList.
|
777 |
*/
|
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
778 |
void SPLPEItem::replacePathEffects( std::vector<LivePathEffectObject const *> const old_lpeobjs, |
779 |
std::vector<LivePathEffectObject const *> const new_lpeobjs ) |
|
5766
by johanengelen
LPE STACKING! |
780 |
{
|
781 |
HRefList hreflist; |
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
782 |
for (PathEffectList::const_iterator it = this->path_effect_list->begin(); it != this->path_effect_list->end(); ++it) |
5766
by johanengelen
LPE STACKING! |
783 |
{
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
784 |
LivePathEffectObject const * current_lpeobj = (*it)->lpeobject; |
785 |
std::vector<LivePathEffectObject const *>::const_iterator found_it(std::find(old_lpeobjs.begin(), old_lpeobjs.end(), current_lpeobj)); |
|
786 |
if ( found_it != old_lpeobjs.end() ) { |
|
787 |
std::vector<LivePathEffectObject const *>::difference_type found_index = std::distance (old_lpeobjs.begin(), found_it); |
|
788 |
const gchar * repr_id = new_lpeobjs[found_index]->getRepr()->attribute("id"); |
|
5766
by johanengelen
LPE STACKING! |
789 |
gchar *hrefstr = g_strdup_printf("#%s", repr_id); |
790 |
hreflist.push_back( std::string(hrefstr) ); |
|
791 |
g_free(hrefstr); |
|
792 |
}
|
|
793 |
else { |
|
794 |
hreflist.push_back( std::string((*it)->lpeobject_href) ); |
|
795 |
}
|
|
796 |
}
|
|
797 |
std::string r = hreflist_write_svg(hreflist); |
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
798 |
this->getRepr()->setAttribute("inkscape:path-effect", r.c_str()); |
5766
by johanengelen
LPE STACKING! |
799 |
}
|
800 |
||
9012.1.419
by Johan Engelen
better fix for lpe stack forking |
801 |
/**
|
802 |
* Check all effects in the stack if they are used by other items, and fork them if so.
|
|
803 |
* It is not recommended to fork the effects by yourself calling LivePathEffectObject::fork_private_if_necessary,
|
|
804 |
* use this method instead.
|
|
805 |
* Returns true if one or more effects were forked; returns false if nothing was done.
|
|
806 |
*/
|
|
807 |
bool sp_lpe_item_fork_path_effects_if_necessary(SPLPEItem *lpeitem, unsigned int nr_of_allowed_users) |
|
808 |
{
|
|
809 |
bool forked = false; |
|
810 |
||
811 |
if ( sp_lpe_item_has_path_effect(lpeitem) ) { |
|
812 |
// If one of the path effects is used by 2 or more items, fork it
|
|
813 |
// so that each object has its own independent copy of the effect.
|
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
814 |
// Note: replacing path effects messes up the path effect list
|
815 |
||
816 |
// Clones of the LPEItem will increase the refcount of the lpeobjects.
|
|
817 |
// Therefore, nr_of_allowed_users should be increased with the number of clones (i.e. refs to the lpeitem)
|
|
818 |
nr_of_allowed_users += lpeitem->hrefcount; |
|
819 |
||
820 |
std::vector<LivePathEffectObject const *> old_lpeobjs, new_lpeobjs; |
|
821 |
PathEffectList effect_list = sp_lpe_item_get_effect_list(lpeitem); |
|
822 |
for (PathEffectList::iterator it = effect_list.begin(); it != effect_list.end(); it++) |
|
823 |
{
|
|
824 |
LivePathEffectObject *lpeobj = (*it)->lpeobject; |
|
825 |
if (lpeobj) { |
|
826 |
LivePathEffectObject *forked_lpeobj = lpeobj->fork_private_if_necessary(nr_of_allowed_users); |
|
827 |
if (forked_lpeobj != lpeobj) { |
|
828 |
forked = true; |
|
829 |
old_lpeobjs.push_back(lpeobj); |
|
830 |
new_lpeobjs.push_back(forked_lpeobj); |
|
9012.1.419
by Johan Engelen
better fix for lpe stack forking |
831 |
}
|
832 |
}
|
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
833 |
}
|
834 |
||
835 |
if (forked) { |
|
836 |
lpeitem->replacePathEffects(old_lpeobjs, new_lpeobjs); |
|
837 |
}
|
|
9012.1.419
by Johan Engelen
better fix for lpe stack forking |
838 |
}
|
839 |
||
840 |
return forked; |
|
841 |
}
|
|
842 |
||
5766
by johanengelen
LPE STACKING! |
843 |
// Enable or disable the path effects of the item.
|
844 |
// The counter allows nested calls
|
|
845 |
static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable) |
|
846 |
{
|
|
847 |
if (enable) { |
|
848 |
lpeitem->path_effects_enabled++; |
|
849 |
}
|
|
850 |
else { |
|
851 |
lpeitem->path_effects_enabled--; |
|
852 |
}
|
|
853 |
}
|
|
854 |
||
855 |
// Are the path effects enabled on this item ?
|
|
856 |
bool sp_lpe_item_path_effects_enabled(SPLPEItem *lpeitem) |
|
857 |
{
|
|
858 |
return lpeitem->path_effects_enabled > 0; |
|
859 |
}
|
|
860 |
||
5227
by pjrm
svn propset svn:eol-style native *.[ch] *.cpp (including buildtool.cpp, packaging/macosx/native-gtk/*, src/dom/**). |
861 |
/*
|
862 |
Local Variables:
|
|
863 |
mode:c++
|
|
864 |
c-file-style:"stroustrup"
|
|
865 |
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
|
|
866 |
indent-tabs-mode:nil
|
|
867 |
fill-column:99
|
|
868 |
End:
|
|
869 |
*/
|
|
9020
by JazzyNico
Code refactoring and merging with trunk (revision 10599). |
870 |
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
|