Code

e4def4301198d110e0f11ce0ae4e556e186ac23a
[inkscape.git] / src / live_effects / lpeobject-reference.cpp
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