Code

switch SPStyle to using SPFilterReference for filters; sp_style_new now requires...
authorbuliabyak <buliabyak@users.sourceforge.net>
Wed, 27 Jun 2007 05:41:53 +0000 (05:41 +0000)
committerbuliabyak <buliabyak@users.sourceforge.net>
Wed, 27 Jun 2007 05:41:53 +0000 (05:41 +0000)
22 files changed:
src/desktop-style.cpp
src/dialogs/fill-style.cpp
src/dialogs/object-properties.cpp
src/dialogs/stroke-style.cpp
src/dialogs/text-edit.cpp
src/display/nr-arena-group.cpp
src/display/nr-arena-image.cpp
src/display/nr-arena-shape.cpp
src/filter-chemistry.cpp
src/selection-chemistry.cpp
src/sp-filter-reference.h
src/sp-item.cpp
src/style.cpp
src/style.h
src/text-editing.cpp
src/ui/dialog/fill-and-stroke.cpp
src/ui/widget/selected-style.cpp
src/ui/widget/style-swatch.cpp
src/uri-references.cpp
src/uri-references.h
src/widgets/dash-selector.cpp
src/widgets/toolbox.cpp

index 5685dc4d6502208c853848a1e6dbff5d5b1c525f..c6344da5cc54e4e9f485f1fb52a1c17975f5eb4c 100644 (file)
@@ -26,6 +26,7 @@
 #include "sp-use.h"
 #include "sp-feblend.h"
 #include "sp-filter.h"
+#include "sp-filter-reference.h"
 #include "sp-gaussian-blur.h"
 #include "sp-flowtext.h"
 #include "sp-flowregion.h"
@@ -351,7 +352,7 @@ sp_desktop_get_font_size_tool(SPDesktop *desktop)
 
     double ret = 12;
     if (style_str) {
-        SPStyle *style = sp_style_new();
+        SPStyle *style = sp_style_new(SP_ACTIVE_DOCUMENT);
         sp_style_merge_from_style_string(style, style_str);
         ret = style->font_size.computed;
         sp_style_unref(style);
@@ -1029,12 +1030,12 @@ objects_query_blend (GSList *objects, SPStyle *style_res)
         items++;
 
         //if object has a filter
-        if (style->filter.set && style->filter.filter) {
+        if (style->filter.set && style->filter.href->getObject()) {
             int blurcount = 0;
             int blendcount = 0;
 
             // determine whether filter is simple (blend and/or blur) or complex
-            for(SPObject *primitive_obj = style->filter.filter->children;
+            for(SPObject *primitive_obj = style->filter.href->getObject()->children;
                 primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj);
                 primitive_obj = primitive_obj->next) {
                 SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(primitive_obj);
@@ -1050,7 +1051,7 @@ objects_query_blend (GSList *objects, SPStyle *style_res)
 
             // simple filter
             if(blurcount == 1 || blendcount == 1) {
-                for(SPObject *primitive_obj = style->filter.filter->children;
+                for(SPObject *primitive_obj = style->filter.href->getObject()->children;
                     primitive_obj && SP_IS_FILTER_PRIMITIVE(primitive_obj);
                     primitive_obj = primitive_obj->next) {
                     if(SP_IS_FEBLEND(primitive_obj)) {
@@ -1117,9 +1118,9 @@ objects_query_blur (GSList *objects, SPStyle *style_res)
         items ++;
 
         //if object has a filter
-        if (style->filter.set && style->filter.filter) {
+        if (style->filter.set && style->filter.href->getObject()) {
             //cycle through filter primitives
-            SPObject *primitive_obj = style->filter.filter->children;
+            SPObject *primitive_obj = style->filter.href->getObject()->children;
             while (primitive_obj) {
                 if (SP_IS_FILTER_PRIMITIVE(primitive_obj)) {
                     SPFilterPrimitive *primitive = SP_FILTER_PRIMITIVE(primitive_obj);
index 086838727a83566fcd3ab94c40b6adafff8c70f8..7ff5ebc96d7f9542c5089da53fdbe444dac05476 100644 (file)
@@ -185,7 +185,7 @@ sp_fill_style_widget_update (SPWidget *spw)
     SPPaintSelector *psel = SP_PAINT_SELECTOR (g_object_get_data (G_OBJECT (spw), "paint-selector"));
 
     // create temporary style
-    SPStyle *query = sp_style_new ();
+    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
     // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
     int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FILL); 
 
@@ -430,7 +430,7 @@ sp_fill_style_widget_paint_changed ( SPPaintSelector *psel,
                 if (!vector) {
                     /* No vector in paint selector should mean that we just changed mode */
 
-                    SPStyle *query = sp_style_new ();
+                    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
                     int result = objects_query_fillstroke ((GSList *) items, query, true); 
                     guint32 common_rgb = 0;
                     if (result == QUERY_STYLE_MULTIPLE_SAME) {
index 7aa33fc5b9f72d0ea3aab33dcfd947cc1905f641..126deff3834967a3ffea298331b3ce40d333af30 100644 (file)
@@ -304,7 +304,7 @@ sp_fillstroke_selection_changed ( Inkscape::Application *inkscape,
     GtkAdjustment *a = GTK_ADJUSTMENT(gtk_object_get_data(GTK_OBJECT(dlg), "master_opacity_adjustment"));
 
     // create temporary style
-    SPStyle *query = sp_style_new ();
+    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
     // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
     int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_MASTEROPACITY);
 
index ed1082e26ef0d3b365fd082247bdf48cbf6661d0..fd43d374c9dd1a044dfb6a1be32a02e55a2cacf1 100644 (file)
@@ -200,7 +200,7 @@ sp_stroke_style_paint_update (SPWidget *spw)
     SPPaintSelector *psel = SP_PAINT_SELECTOR(gtk_object_get_data(GTK_OBJECT(spw), "paint-selector"));
 
     // create temporary style
-    SPStyle *query = sp_style_new ();
+    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
     // query into it
     int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKE); 
 
@@ -386,7 +386,7 @@ sp_stroke_style_paint_changed(SPPaintSelector *psel, SPWidget *spw)
                 if (!vector) {
                     /* No vector in paint selector should mean that we just changed mode */
 
-                    SPStyle *query = sp_style_new ();
+                    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
                     int result = objects_query_fillstroke ((GSList *) items, query, false); 
                     guint32 common_rgb = 0;
                     if (result == QUERY_STYLE_MULTIPLE_SAME) {
@@ -1417,7 +1417,7 @@ sp_stroke_style_line_update(SPWidget *spw, Inkscape::Selection *sel)
     GtkWidget *dsel = GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(spw), "dash"));
 
     // create temporary style
-    SPStyle *query = sp_style_new ();
+    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
     // query into it
     int result_sw = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEWIDTH); 
     int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT); 
index b2302372144f7e62814d5cb3ab00ef590295ae2f..5a59fd2e52f7677329f32bdf866c43133f82d285 100644 (file)
@@ -734,7 +734,7 @@ sp_text_edit_dialog_read_selection ( GtkWidget *dlg,
     if (dostyle) {
 
         // create temporary style
-        SPStyle *query = sp_style_new ();
+        SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
         // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
         int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); 
         int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); 
index da3a240a64558a98bd41c242693d829d37cface8..3f08f42f4393bd5d8cb8e23be6a0082fe3372719 100644 (file)
@@ -18,6 +18,7 @@
 #include "display/nr-filter-types.h"
 #include "style.h"
 #include "sp-filter.h"
+#include "sp-filter-reference.h"
 #include "sp-gaussian-blur.h"
 #include "sp-feblend.h"
 #include "display/nr-filter-blend.h"
@@ -195,12 +196,12 @@ void nr_arena_group_set_style (NRArenaGroup *group, SPStyle *style)
     group->style = style;
 
     //if group has a filter
-    if (style->filter.set && style->filter.filter) {
+    if (style->filter.set && style->filter.href->getObject()) {
         if (!group->filter) {
-            int primitives = sp_filter_primitive_count(style->filter.filter);
+            int primitives = sp_filter_primitive_count(style->filter.href->getObject());
             group->filter = new NR::Filter(primitives);
         }
-        sp_filter_build_renderer(style->filter.filter, group->filter);
+        sp_filter_build_renderer(style->filter.href->getObject(), group->filter);
     } else {
         //no filter set for this group
         delete group->filter;
index 5f22dc5cd5010c0ffd53e2e5ea1339faaf30d45a..87cc94e1b72e115af6193805d34c45d8172e2860 100644 (file)
@@ -23,6 +23,7 @@
 #include <livarot/Path.h>
 #include <livarot/Shape.h>
 #include "sp-filter.h"
+#include "sp-filter-reference.h"
 #include "sp-gaussian-blur.h"
 #include "sp-feblend.h"
 #include "display/nr-filter-blend.h"
@@ -368,12 +369,12 @@ void nr_arena_image_set_style (NRArenaImage *image, SPStyle *style)
     image->style = style;
 
     //if image has a filter
-    if (style->filter.set && style->filter.filter) {
+    if (style->filter.set && style->filter.href->getObject()) {
         if (!image->filter) {
-            int primitives = sp_filter_primitive_count(style->filter.filter);
+            int primitives = sp_filter_primitive_count(style->filter.href->getObject());
             image->filter = new NR::Filter(primitives);
         }
-        sp_filter_build_renderer(style->filter.filter, image->filter);
+        sp_filter_build_renderer(style->filter.href->getObject(), image->filter);
     } else {
         //no filter set for this image
         delete image->filter;
index c09bdb9dd9e1a405937d9a5f6edcb8a946c7640e..0e7dd27985614581aa397c02251d3549958e7302 100644 (file)
@@ -31,6 +31,7 @@
 #include "inkscape-cairo.h"
 
 #include "sp-filter.h"
+#include "sp-filter-reference.h"
 #include "display/nr-filter.h"
 
 #include <cairo.h>
@@ -1359,12 +1360,12 @@ nr_arena_shape_set_style(NRArenaShape *shape, SPStyle *style)
     shape->setMitreLimit(style->stroke_miterlimit.value);
 
     //if shape has a filter
-    if (style->filter.set && style->filter.filter) {
+    if (style->filter.set && style->filter.href->getObject()) {
         if (!shape->filter) {
-            int primitives = sp_filter_primitive_count(style->filter.filter);
+            int primitives = sp_filter_primitive_count(style->filter.href->getObject());
             shape->filter = new NR::Filter(primitives);
         }
-        sp_filter_build_renderer(style->filter.filter, shape->filter);
+        sp_filter_build_renderer(style->filter.href->getObject(), shape->filter);
     } else {
         //no filter set for this shape
         delete shape->filter;
index d3a02852eed3b2f5ecbbf12d23bae703dd2bf2e2..5515d0a049d69cca18b7174c8b9f6ecf63f94504 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "sp-feblend.h"
 #include "sp-filter.h"
+#include "sp-filter-reference.h"
 #include "sp-gaussian-blur.h"
 #include "svg/css-ostringstream.h"
 
@@ -40,7 +41,7 @@ count_filter_hrefs(SPObject *o, SPFilter *filter)
     SPStyle *style = SP_OBJECT_STYLE(o);
     if (style
         && style->filter.set
-        && style->filter.filter == filter)
+        && style->filter.href->getObject() == filter)
     {
         i ++;
     }
@@ -304,13 +305,13 @@ modify_filter_gaussian_blur_from_item(SPDocument *document, SPItem *item,
         //return new_filter_gaussian_blur_from_item(document, item, radius);
     }
 
-    SPFilter *filter = SP_FILTER(item->style->filter.filter);
+    SPFilter *filter = SP_FILTER(item->style->filter.href->getObject());
     Inkscape::XML::Document *xml_doc = sp_document_repr_doc(document);
 
     // If there are more users for this filter, duplicate it
     if (SP_OBJECT_HREFCOUNT(filter) > count_filter_hrefs(item, filter)) {
         Inkscape::XML::Node *repr;
-        repr = SP_OBJECT_REPR(item->style->filter.filter)->duplicate(xml_doc);
+        repr = SP_OBJECT_REPR(item->style->filter.href->getObject())->duplicate(xml_doc);
         SPDefs *defs = (SPDefs *) SP_DOCUMENT_DEFS(document);
         SP_OBJECT_REPR(defs)->appendChild(repr);
 
@@ -337,7 +338,7 @@ modify_filter_gaussian_blur_from_item(SPDocument *document, SPItem *item,
     }
 
     // Set the filter effects area
-    Inkscape::XML::Node *repr = SP_OBJECT_REPR(item->style->filter.filter);
+    Inkscape::XML::Node *repr = SP_OBJECT_REPR(item->style->filter.href->getObject());
     set_filter_area(repr, radius, expansion, i2d.expansionX(),
                     i2d.expansionY(), width, height);
 
@@ -390,9 +391,9 @@ void remove_filter (SPObject *item, bool recursive)
  * be handled gracefully */
 void remove_filter_gaussian_blur (SPObject *item)
 {
-    if (item->style && item->style->filter.set && item->style->filter.filter) {
+    if (item->style && item->style->filter.set && item->style->filter.href->getObject()) {
         // Search for the first blur primitive and remove it. (if found)
-        Inkscape::XML::Node *repr = SP_OBJECT_REPR(item->style->filter.filter);
+        Inkscape::XML::Node *repr = SP_OBJECT_REPR(item->style->filter.href->getObject());
         Inkscape::XML::Node *primitive = repr->firstChild();
         while (primitive) {
             if (strcmp("svg:feGaussianBlur", primitive->name()) == 0) {
index ed8d6379e4aaae48dd74060d3f0a0cf6b029abd3..27c04f1ddd4e9f10b9015edb930873335b852f63 100644 (file)
@@ -73,6 +73,7 @@
 #include "sp-item.h"
 #include "unit-constants.h"
 #include "xml/simple-document.h"
+#include "sp-filter-reference.h"
 
 using NR::X;
 using NR::Y;
@@ -952,8 +953,8 @@ void sp_copy_stuff_used_by_item (GSList **defs_clip, SPItem *item, const GSList
         }
     }
 
-    if (style->filter.filter) {
-        SPObject *filter = style->filter.filter;
+    if (style->filter.href->getObject()) {
+        SPObject *filter = style->filter.href->getObject();
         if (SP_IS_FILTER(filter)) {
             sp_copy_single (defs_clip, filter, xml_doc);
         }
@@ -1082,7 +1083,7 @@ void sp_selection_copy()
     sp_selection_copy_impl (items, &clipboard, &defs_clipboard, &style_clipboard, clipboard_document);
 
     if (tools_isactive (desktop, TOOLS_TEXT)) { // take style from cursor/text selection, overwriting the style just set by copy_impl
-        SPStyle *const query = sp_style_new();
+        SPStyle *const query = sp_style_new(SP_ACTIVE_DOCUMENT);
         if (sp_desktop_query_style_all (desktop, query)) {
             SPCSSAttr *css = sp_css_attr_from_style (query, SP_STYLE_FLAG_ALWAYS);
             if (css != NULL) {
index 226e033bb9dc330c67b59b9b03ae808c6e736539..216ff1d6f7a8bc10c57be0ac948a262209222edc 100644 (file)
@@ -8,6 +8,7 @@ class SPObject;
 class SPFilterReference : public Inkscape::URIReference {
 public:
     SPFilterReference(SPObject *obj) : URIReference(obj) {}
+    SPFilterReference(SPDocument *doc) : URIReference(doc) {}
 
     SPFilter *getObject() const {
         return (SPFilter *)URIReference::getObject();
index fbcc7b4a895b006c0538c9b5e917425a3d6596d9..7c1a464479684a86e8f4e50feae2520891e62fa7 100644 (file)
@@ -50,6 +50,7 @@
 #include "prefs-utils.h"
 #include "conn-avoid-ref.h"
 #include "conditions.h"
+#include "sp-filter-reference.h"
 
 #include "libnr/nr-matrix-div.h"
 #include "libnr/nr-matrix-fns.h"
@@ -1200,7 +1201,7 @@ sp_item_write_transform(SPItem *item, Inkscape::XML::Node *repr, NR::Matrix cons
              !preserve && // user did not chose to preserve all transforms
              !item->clip_ref->getObject() && // the object does not have a clippath
              !item->mask_ref->getObject() && // the object does not have a mask
-             !(!transform.is_translation() && SP_OBJECT_STYLE(item) && SP_OBJECT_STYLE(item)->filter.filter
+         !(!transform.is_translation() && SP_OBJECT_STYLE(item) && SP_OBJECT_STYLE(item)->filter.href->getObject()
              // the object does not have a filter, or the transform is translation (which is supposed to not affect filters)
         ) {
         transform_attr = ((SPItemClass *) G_OBJECT_GET_CLASS(item))->set_transform(item, transform);
index e15c54636adf10b496766cfd5eebe0431e27ff93..46b544382a751c3ad8335747e4dd9ac96ea42dbd 100644 (file)
@@ -31,6 +31,7 @@
 #include "document.h"
 #include "extract-uri.h"
 #include "uri-references.h"
+#include "uri.h"
 #include "sp-paint-server.h"
 #include "streq.h"
 #include "strneq.h"
@@ -39,6 +40,9 @@
 #include "xml/repr.h"
 #include "unit-constants.h"
 #include "isnan.h"
+#include "macros.h"
+
+#include "sp-filter-reference.h"
 
 #include <sigc++/functors/ptr_fun.h>
 #include <sigc++/adaptors/bind.h>
@@ -386,14 +390,44 @@ sp_style_object_release(SPObject *object, SPStyle *style)
     style->object = NULL;
 }
 
+/**
+ * Emit style modified signal on style's object if the filter changed.
+ */
+static void
+sp_style_filter_ref_modified(SPObject *obj, guint flags, SPStyle *style)
+{
+    SPFilter *filter=static_cast<SPFilter *>(obj);
+    if (style->filter.href->getObject() == filter)
+    {
+        if (style->object) {
+            style->object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
+        }
+    }
+}
 
+/**
+ * Gets called when the filter is (re)attached to the style
+ */
+static void
+sp_style_filter_ref_changed(SPObject *old_ref, SPObject *ref, SPStyle *style)
+{
+    if (old_ref) {
+        sp_signal_disconnect_by_data(old_ref, style);
+    }
+    if ( SP_IS_FILTER(ref))
+    {
+        ref->connectModified(sigc::bind(sigc::ptr_fun(&sp_style_filter_ref_modified), style));
+    }
+
+    sp_style_filter_ref_modified(ref, 0, style);
+}
 
 
 /**
  * Returns a new SPStyle object with settings as per sp_style_clear().
  */
 SPStyle *
-sp_style_new()
+sp_style_new(SPDocument *document)
 {
     SPStyle *const style = g_new0(SPStyle, 1);
 
@@ -402,13 +436,17 @@ sp_style_new()
     style->text = sp_text_style_new();
     style->text_private = TRUE;
 
+    if (document) {
+        style->filter.href = new SPFilterReference(document);
+        style->filter.href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_filter_ref_changed), style));
+    }
+
     sp_style_clear(style);
 
     style->cloned = false;
 
     style->fill_hreffed = false;
     style->stroke_hreffed = false;
-    style->filter_hreffed = false;
 
     new (&style->release_connection) sigc::connection();
 
@@ -418,9 +456,6 @@ sp_style_new()
     new (&style->stroke_release_connection) sigc::connection();
     new (&style->stroke_modified_connection) sigc::connection();
 
-    new (&style->filter_release_connection) sigc::connection();
-    new (&style->filter_modified_connection) sigc::connection();
-
     return style;
 }
 
@@ -434,7 +469,7 @@ sp_style_new_from_object(SPObject *object)
     g_return_val_if_fail(object != NULL, NULL);
     g_return_val_if_fail(SP_IS_OBJECT(object), NULL);
 
-    SPStyle *style = sp_style_new();
+    SPStyle *style = sp_style_new(SP_OBJECT_DOCUMENT(object));
     style->object = object;
     style->release_connection = object->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_style_object_release), style));
 
@@ -487,10 +522,6 @@ sp_style_unref(SPStyle *style)
         style->stroke_release_connection.~connection();
         style->stroke_modified_connection.disconnect();
         style->stroke_modified_connection.~connection();
-        style->filter_modified_connection.disconnect();
-        style->filter_modified_connection.~connection();
-        style->filter_release_connection.disconnect();
-        style->filter_release_connection.~connection();
         g_free(style->stroke_dash.dash);
         g_free(style);
     }
@@ -699,7 +730,7 @@ sp_style_read(SPStyle *style, SPObject *object, Inkscape::XML::Node *repr)
     } else {
         if (sp_repr_parent(repr)) {
             /// \todo fixme: This is not the prettiest thing (Lauris)
-            SPStyle *parent = sp_style_new();
+            SPStyle *parent = sp_style_new(NULL);
             sp_style_read(parent, NULL, sp_repr_parent(repr));
             sp_style_merge_from_parent(style, parent);
             sp_style_unref(parent);
@@ -2061,38 +2092,6 @@ sp_style_paint_server_modified(SPObject *obj, guint flags, SPStyle *style)
     }
 }
 
-
-
-/**
- * Disconnects from filter.
- */
-static void
-sp_style_filter_release(SPObject *obj, SPStyle *style)
-{
-    SPFilter *filter=static_cast<SPFilter *>(obj);
-    if (style->filter.filter == filter)
-    {
-        sp_style_filter_clear(style);
-    }
-}
-
-
-/**
- * Emit style modified signal on style's object if the filter changed.
- */
-static void
-sp_style_filter_modified(SPObject *obj, guint flags, SPStyle *style)
-{
-    SPFilter *filter=static_cast<SPFilter *>(obj);
-    if (style->filter.filter == filter)
-    {
-        if (style->object) {
-            style->object->requestModified(SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_STYLE_MODIFIED_FLAG);
-        }
-    }
-}
-
-
 /**
  *
  */
@@ -2162,20 +2161,15 @@ sp_style_merge_ifilter(SPStyle *style, SPIFilter const *parent)
     sp_style_filter_clear(style);
     style->filter.set = parent->set;
     style->filter.inherit = parent->inherit;
-    style->filter.filter = parent->filter;
-    style->filter.uri = parent->uri;
-    if (style->filter.filter) {
-        if (style->object && !style->cloned) { // href filter for style of non-clones only
-            sp_object_href(SP_OBJECT(style->filter.filter), style);
-            style->filter_hreffed = true;
-        }
-        if (style->object || style->cloned) { // connect to signals for style of real objects or clones (this excludes temp styles)
-            SPObject *filter = style->filter.filter;
-            style->filter_release_connection
-                = filter->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_style_filter_release), style));
-            style->filter_modified_connection
-                = filter->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_style_filter_modified), style));
-        }
+
+    if (style->filter.href && style->filter.href->getObject())
+       style->filter.href->detach();
+
+    try {
+        style->filter.href->attach(*parent->href->getURI());
+    } catch (Inkscape::BadURIException &e) {
+        g_warning("%s", e.what());
+        style->filter.href->detach();
     }
 }
 
@@ -2574,10 +2568,6 @@ sp_style_clear(SPStyle *style)
         style->marker[i].set = FALSE;
     }
 
-    style->filter.set = FALSE;
-    style->filter.uri = NULL;
-    style->filter.filter = NULL;
-
     style->enable_background.value = SP_CSS_BACKGROUND_ACCUMULATE;
     style->enable_background.set = false;
     style->enable_background.inherit = false;
@@ -3162,49 +3152,46 @@ sp_style_read_ifilter(gchar const *str, SPStyle * style, SPDocument *document)
     if (streq(str, "inherit")) {
         f->set = TRUE;
         f->inherit = TRUE;
-        f->filter = NULL;
+        if (f->href && f->href->getObject())
+            f->href->detach(); //f->filter = NULL;
     } else if(streq(str, "none")) {
         f->set = TRUE;
         f->inherit = FALSE;
-        f->filter = NULL;
+        if (f->href && f->href->getObject())
+           f->href->detach(); //f->filter = NULL;
     } else if (strneq(str, "url", 3)) {
-        f->uri = extract_uri(str);
-        if(f->uri == NULL || f->uri[0] == '\0') {
+        char *uri = extract_uri(str);
+        if(uri == NULL || uri[0] == '\0') {
             g_warning("Specified filter url is empty");
             f->set = TRUE;
             f->inherit = FALSE;
-            f->filter = NULL;
             return;
         }
         f->set = TRUE;
         f->inherit = FALSE;
-        f->filter = NULL;
-        if (document) {
-            SPObject *obj = sp_uri_reference_resolve(document, str);
-            if (SP_IS_FILTER(obj)) {
-                f->filter = SP_FILTER(obj);
-                if (style->object && !style->cloned) {
-                    sp_object_href(obj, style);
-                    style->filter_hreffed = true;
-                }
-                if (style->object || style->cloned) { // connect to signals for style of real objects or clones (this excludes temp styles)
-                    SPObject *filter = style->filter.filter;
-                    style->filter_release_connection
-                        = filter->connectRelease(sigc::bind<1>(sigc::ptr_fun(&sp_style_filter_release), style));
-                    style->filter_modified_connection
-                        = filter->connectModified(sigc::bind<2>(sigc::ptr_fun(&sp_style_filter_modified), style));
-                }
-            } else {
-                g_warning("Element '%s' not found or is not a filter", f->uri);
-            }
+        if (f->href && f->href->getObject())
+            f->href->detach();
+
+        // it may be that this style has not yet created its SPFilterReference;
+        // now that we have a document, we can create it here
+        if (!f->href) {
+            f->href = new SPFilterReference(document);
+            f->href->changedSignal().connect(sigc::bind(sigc::ptr_fun(sp_style_filter_ref_changed), style));
+        }
+
+        try {
+            f->href->attach(Inkscape::URI(uri));
+        } catch (Inkscape::BadURIException &e) {
+            g_warning("%s", e.what());
+            f->href->detach();
         }
 
     } else {
         /* We shouldn't reach this if SVG input is well-formed */
         f->set = FALSE;
         f->inherit = FALSE;
-        f->filter = NULL;
-        f->uri = NULL;
+        if (f->href && f->href->getObject())
+            f->href->detach(); 
     }
 }
 
@@ -3686,8 +3673,8 @@ sp_style_write_ifilter(gchar *p, gint const len, gchar const *key,
     {
         if (val->inherit) {
             return g_snprintf(p, len, "%s:inherit;", key);
-        } else if (val->uri) {
-            return g_snprintf(p, len, "%s:url(%s);", key, val->uri);
+        } else if (val->href->getURI()) {
+            return g_snprintf(p, len, "%s:url(%s);", key, val->href->getURI()->toString());
         }
     }
 
@@ -3735,15 +3722,8 @@ sp_style_paint_clear(SPStyle *style, SPIPaint *paint)
 static void
 sp_style_filter_clear(SPStyle *style)
 {
-
-    if (style->filter_hreffed) {
-        sp_object_hunref(SP_OBJECT(style->filter.filter), style);
-        style->filter_hreffed = false;
-    }
-    style->filter_release_connection.disconnect();
-    style->filter_modified_connection.disconnect();
-
-    style->filter.filter = NULL;
+    if (style->filter.href && style->filter.href->getObject())
+        style->filter.href->detach(); 
 }
 
 
index 544bde55778251ae3c9bf978c7cbd67ae3b5757a..df2ba127f6b374ccdb401fb4155afcfe10a0ffd4 100644 (file)
@@ -169,12 +169,13 @@ struct SPIPaint {
     } value;
 };
 
+struct SPFilterReference;
+
 /// Filter type internal to SPStyle
 struct SPIFilter {
     unsigned set : 1;
     unsigned inherit : 1;
-    SPFilter *filter;
-    gchar *uri;
+    SPFilterReference *href;
 };
 
 enum {
@@ -351,7 +352,6 @@ struct SPStyle {
     /// style has hreffed its fill/stroke paintservers, needs to release.
     bool fill_hreffed; 
     bool stroke_hreffed; 
-    bool filter_hreffed; 
 
     sigc::connection release_connection;
 
@@ -360,12 +360,9 @@ struct SPStyle {
 
     sigc::connection stroke_release_connection;
     sigc::connection stroke_modified_connection;
-
-    sigc::connection filter_release_connection;
-    sigc::connection filter_modified_connection;
 };
 
-SPStyle *sp_style_new();
+SPStyle *sp_style_new(SPDocument *document);
 
 SPStyle *sp_style_new_from_object(SPObject *object);
 
index b84361324338c62735017ba15f2407bd624e9d60..233ac8d3fe764f98cefb2ff1808541a31c2bc8f7 100644 (file)
@@ -1103,7 +1103,7 @@ as opposed to sp_style_merge_from_style_string which merges its parameter
 underneath the existing styles (ie ignoring already set properties). */
 static void overwrite_style_with_string(SPObject *item, gchar const *style_string)
 {
-    SPStyle *new_style = sp_style_new();
+    SPStyle *new_style = sp_style_new(SP_OBJECT_DOCUMENT(item));
     sp_style_merge_from_style_string(new_style, style_string);
     gchar const *item_style_string = SP_OBJECT_REPR(item)->attribute("style");
     if (item_style_string && *item_style_string)
@@ -1128,7 +1128,7 @@ static bool objects_have_equal_style(SPObject const *parent, SPObject const *chi
     gchar *parent_style = sp_style_write_string(parent->style, SP_STYLE_FLAG_ALWAYS);
     // we have to write parent_style then read it again, because some properties format their values
     // differently depending on whether they're set or not (*cough*dash-offset*cough*)
-    SPStyle *parent_spstyle = sp_style_new();
+    SPStyle *parent_spstyle = sp_style_new(SP_OBJECT_DOCUMENT(parent));
     sp_style_merge_from_style_string(parent_spstyle, parent_style);
     g_free(parent_style);
     parent_style = sp_style_write_string(parent_spstyle, SP_STYLE_FLAG_ALWAYS);
@@ -1144,7 +1144,7 @@ static bool objects_have_equal_style(SPObject const *parent, SPObject const *chi
         }
         child = SP_OBJECT_PARENT(child);
     }
-    SPStyle *child_spstyle = sp_style_new();
+    SPStyle *child_spstyle = sp_style_new(SP_OBJECT_DOCUMENT(parent));
     sp_style_merge_from_style_string(child_spstyle, child_style_construction.c_str());
     gchar *child_style = sp_style_write_string(child_spstyle, SP_STYLE_FLAG_ALWAYS);
     sp_style_unref(child_spstyle);
index 2967cf15164b782987cfd687961b250c44ae03c2..fdcfc763631f2cddd86d1bfadee7302889f1f0f3 100644 (file)
@@ -239,7 +239,7 @@ FillAndStroke::selectionChanged(Inkscape::Application *inkscape,
     _blocked = true;
 
     // create temporary style
-    SPStyle *query = sp_style_new ();
+    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
     // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
     int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_MASTEROPACITY);
 
index 2c5da4380130dbfeb411552ebfa534990f717c29..fcd56ad441333185317f9b4999230e5bc45d22d7 100644 (file)
@@ -863,7 +863,7 @@ SelectedStyle::update()
         return;
 
     // create temporary style
-    SPStyle *query = sp_style_new ();
+    SPStyle *query = sp_style_new (sp_desktop_document(_desktop));
 
     for (int i = SS_FILL; i <= SS_STROKE; i++) {
         Gtk::EventBox *place = (i == SS_FILL)? &_fill_place : &_stroke_place;
index 705083a8f9afa2784671dc53797939722812f76e..cad07fbd6ed3435cb6b87e2e31baf3a50152357c 100644 (file)
@@ -262,7 +262,7 @@ StyleSwatch::setStyle(SPCSSAttr *css)
     sp_repr_css_merge(_css, css);
 
     gchar const *css_string = sp_repr_css_write_string (_css);
-    SPStyle *temp_spstyle = sp_style_new();
+    SPStyle *temp_spstyle = sp_style_new(SP_ACTIVE_DOCUMENT);
     if (css_string)
         sp_style_merge_from_style_string (temp_spstyle, css_string);
 
index 6b2a8401fdeb9d78799af866b5423fbad5e6ed5e..8e14c9336522197fb9a63fa2b1992f9655b0838c 100644 (file)
@@ -24,19 +24,32 @@ static gchar *uri_to_id(SPDocument *document, const gchar *uri);
 namespace Inkscape {
 
 URIReference::URIReference(SPObject *owner)
-: _owner(owner), _obj(NULL), _uri(NULL)
+       : _owner(owner), _owner_document(NULL), _obj(NULL), _uri(NULL)
 {
        g_assert(_owner != NULL);
        /* FIXME !!! attach to owner's destroy signal to clean up in case */
 }
 
+URIReference::URIReference(SPDocument *owner_document)
+       : _owner_document(owner_document), _owner(NULL), _obj(NULL), _uri(NULL)
+{
+       g_assert(_owner_document != NULL);
+}
+
 URIReference::~URIReference() {
        detach();
 }
 
 void URIReference::attach(const URI &uri) throw(BadURIException)
 {
-       SPDocument *document = SP_OBJECT_DOCUMENT(_owner);
+       SPDocument *document;
+  if (_owner) {
+    document = SP_OBJECT_DOCUMENT(_owner);
+       } else if (_owner_document) {
+    document = _owner_document;
+       } else {
+    g_assert_not_reached();
+       }
        gchar const *fragment = uri.getFragment();
        if ( !uri.isRelative() || uri.getQuery() || !fragment ) {
                throw UnsupportedURIException();
index 38f346987933ba810e50b6093f9dc5166b550414..89cdff82743870ecba567b53709a9a271554a210 100644 (file)
@@ -41,6 +41,7 @@ public:
         *              is holding a reference to the target object.
         */
        URIReference(SPObject *owner);
+       URIReference(SPDocument *owner_document);
 
        /**
         * Destructor.  Calls shutdown() if the reference has not been
@@ -118,6 +119,7 @@ protected:
 
 private:
        SPObject *_owner;
+       SPDocument *_owner_document;
        sigc::connection _connection;
        sigc::connection _release_connection;
        SPObject *_obj;
index 78303c60b8335a4080922da8054b23002468c0fe..474ab90f9f95069411e96948a02fd5d5b705298f 100644 (file)
@@ -139,7 +139,7 @@ sp_dash_selector_new (Inkscape::XML::Node *drepr)
 
                if (ndashes > 0) {
                        int pos = 0;
-                       SPStyle *style = sp_style_new ();
+                       SPStyle *style = sp_style_new (NULL);
                        dashes = g_new (double *, ndashes + 1);
                        for (Inkscape::XML::Node *dr = drepr->firstChild(); dr; dr = dr->next()) {
                                if (!strcmp (dr->name(), "dash")) {
index c15337e0db4772de6ae4da82c9749f725c76d576..aa5165d15ef6bdabad3b57ef130a923cc3c310d7 100644 (file)
@@ -3156,7 +3156,7 @@ void
 sp_text_toolbox_selection_changed (Inkscape::Selection *selection, GObject *tbl)
 {
     SPStyle *query =
-        sp_style_new ();
+        sp_style_new (SP_ACTIVE_DOCUMENT);
 
     int result_family =
         sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY);
@@ -3350,7 +3350,7 @@ sp_text_toolbox_family_changed (GtkTreeSelection    *selection,
     gtk_entry_set_text (GTK_ENTRY (entry), family);
 
     SPStyle *query =
-        sp_style_new ();
+        sp_style_new (SP_ACTIVE_DOCUMENT);
 
     int result_numbers =
         sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
@@ -3443,7 +3443,7 @@ sp_text_toolbox_anchoring_toggled (GtkRadioButton   *button,
     }
 
     SPStyle *query =
-        sp_style_new ();
+        sp_style_new (SP_ACTIVE_DOCUMENT);
     int result_numbers =
         sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
 
@@ -3491,7 +3491,7 @@ sp_text_toolbox_style_toggled (GtkToggleButton  *button,
     }
 
     SPStyle *query =
-        sp_style_new ();
+        sp_style_new (SP_ACTIVE_DOCUMENT);
     int result_numbers =
         sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
 
@@ -3540,7 +3540,7 @@ sp_text_toolbox_orientation_toggled (GtkRadioButton  *button,
     }
 
     SPStyle *query =
-        sp_style_new ();
+        sp_style_new (SP_ACTIVE_DOCUMENT);
     int result_numbers =
         sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);
 
@@ -3636,7 +3636,7 @@ sp_text_toolbox_size_changed  (GtkComboBox *cbox,
     free (text);
 
     SPStyle *query =
-        sp_style_new ();
+        sp_style_new (SP_ACTIVE_DOCUMENT);
     int result_numbers =
         sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS);