a5392ef904730ebb03955717f02928c006af5324
1 /*\r
2 * The reference corresponding to the inkscape:live-effect attribute\r
3 *\r
4 * Copyright (C) 2007 Johan Engelen\r
5 *\r
6 * Released under GNU GPL, read the file 'COPYING' for more information.\r
7 */\r
8 \r
9 #include "enums.h"\r
10 #include "live_effects/lpeobject-reference.h"\r
11 #include "live_effects/lpeobject.h"\r
12 \r
13 #include "prefs-utils.h"\r
14 #include "uri.h"\r
15 \r
16 namespace Inkscape {\r
17 \r
18 namespace LivePathEffect {\r
19 \r
20 static void lpeobjectreference_href_changed(SPObject *old_ref, SPObject *ref, LPEObjectReference *lpeobjref);\r
21 static void lpeobjectreference_delete_self(SPObject *deleted, LPEObjectReference *lpeobjref);\r
22 static void lpeobjectreference_source_modified(SPObject *iSource, guint flags, LPEObjectReference *lpeobjref);\r
23 \r
24 LPEObjectReference::LPEObjectReference(SPObject* i_owner) : URIReference(i_owner)\r
25 {\r
26 owner=i_owner;\r
27 lpeobject_href = NULL;\r
28 lpeobject_repr = NULL;\r
29 lpeobject = NULL;\r
30 _changed_connection = changedSignal().connect(sigc::bind(sigc::ptr_fun(lpeobjectreference_href_changed), this)); // listening to myself, this should be virtual instead\r
31 \r
32 user_unlink = NULL;\r
33 }\r
34 \r
35 LPEObjectReference::~LPEObjectReference(void)\r
36 {\r
37 _changed_connection.disconnect(); // to do before unlinking\r
38 \r
39 quit_listening();\r
40 unlink();\r
41 }\r
42 \r
43 bool LPEObjectReference::_acceptObject(SPObject * const obj) const\r
44 {\r
45 if (IS_LIVEPATHEFFECT(obj)) {\r
46 SPObject * const owner = getOwner();\r
47 /* Refuse references to us or to an ancestor. */\r
48 for ( SPObject *iter = owner ; iter ; iter = SP_OBJECT_PARENT(iter) ) {\r
49 if ( iter == obj ) {\r
50 return false;\r
51 }\r
52 }\r
53 return true;\r
54 } else {\r
55 return false;\r
56 }\r
57 }\r
58 \r
59 void\r
60 LPEObjectReference::link(char *to)\r
61 {\r
62 if ( to == NULL ) {\r
63 quit_listening();\r
64 unlink();\r
65 } else {\r
66 if ( !lpeobject_href || ( strcmp(to, lpeobject_href) != 0 ) ) {\r
67 g_free(lpeobject_href);\r
68 lpeobject_href = g_strdup(to);\r
69 try {\r
70 attach(Inkscape::URI(to));\r
71 } catch (Inkscape::BadURIException &e) {\r
72 /* TODO: Proper error handling as per\r
73 * http://www.w3.org/TR/SVG11/implnote.html#ErrorProcessing.\r
74 */\r
75 g_warning("%s", e.what());\r
76 detach();\r
77 }\r
78 }\r
79 }\r
80 }\r
81 \r
82 void\r
83 LPEObjectReference::unlink(void)\r
84 {\r
85 g_free(lpeobject_href);\r
86 lpeobject_href = NULL;\r
87 detach();\r
88 }\r
89 \r
90 void\r
91 LPEObjectReference::start_listening(LivePathEffectObject* to)\r
92 {\r
93 if ( to == NULL ) {\r
94 return;\r
95 }\r
96 lpeobject = to;\r
97 lpeobject_repr = SP_OBJECT_REPR(to);\r
98 _delete_connection = to->connectDelete(sigc::bind(sigc::ptr_fun(&lpeobjectreference_delete_self), this));\r
99 _modified_connection = to->connectModified(sigc::bind<2>(sigc::ptr_fun(&lpeobjectreference_source_modified), this));\r
100 }\r
101 \r
102 void\r
103 LPEObjectReference::quit_listening(void)\r
104 {\r
105 if ( lpeobject == NULL ) {\r
106 return;\r
107 }\r
108 _modified_connection.disconnect();\r
109 _delete_connection.disconnect();\r
110 lpeobject_repr = NULL;\r
111 lpeobject = NULL;\r
112 }\r
113 \r
114 static void\r
115 lpeobjectreference_href_changed(SPObject */*old_ref*/, SPObject */*ref*/, LPEObjectReference *lpeobjref)\r
116 {\r
117 lpeobjref->quit_listening();\r
118 LivePathEffectObject *refobj = LIVEPATHEFFECT( lpeobjref->getObject() );\r
119 if ( refobj ) {\r
120 lpeobjref->start_listening(refobj);\r
121 }\r
122 \r
123 lpeobjref->owner->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);\r
124 }\r
125 \r
126 static void\r
127 lpeobjectreference_delete_self(SPObject */*deleted*/, LPEObjectReference *lpeobjref)\r
128 {\r
129 guint const mode = prefs_get_int_attribute("options.cloneorphans", "value", SP_CLONE_ORPHANS_UNLINK);\r
130 \r
131 if (mode == SP_CLONE_ORPHANS_UNLINK) {\r
132 // leave it be. just forget about the source\r
133 lpeobjref->quit_listening();\r
134 lpeobjref->unlink();\r
135 if (lpeobjref->user_unlink)\r
136 lpeobjref->user_unlink(lpeobjref->owner);\r
137 } else if (mode == SP_CLONE_ORPHANS_DELETE) {\r
138 lpeobjref->owner->deleteObject();\r
139 }\r
140 }\r
141 \r
142 static void\r
143 lpeobjectreference_source_modified(SPObject *iSource, guint flags, LPEObjectReference *lpeobjref)\r
144 {\r
145 lpeobjref->owner->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);\r
146 }\r
147 \r
148 }; //namespace LivePathEffect\r
149 \r
150 }; // namespace inkscape\r
151 \r
152 /*\r
153 Local Variables:\r
154 mode:c++\r
155 c-file-style:"stroustrup"\r
156 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
157 indent-tabs-mode:nil\r
158 fill-column:99\r
159 End:\r
160 */\r
161 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r