~ubuntu-branches/ubuntu/precise/inkscape/precise-updates

« back to all changes in this revision

Viewing changes to src/sp-object.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alex Valavanis
  • Date: 2010-09-12 19:44:58 UTC
  • mfrom: (1.1.12 upstream) (45.1.3 maverick)
  • Revision ID: james.westby@ubuntu.com-20100912194458-4sjwmbl7dlsrk5dc
Tags: 0.48.0-1ubuntu1
* Merge with Debian unstable (LP: #628048, LP: #401567, LP: #456248, 
  LP: #463602, LP: #591986)
* debian/control: 
  - Ubuntu maintainers
  - Promote python-lxml, python-numpy, python-uniconvertor to Recommends.
  - Demote pstoedit to Suggests (universe package).
  - Suggests ttf-dejavu instead of ttf-bitstream-vera (LP: #513319)
* debian/rules:
  - Run intltool-update on build (Ubuntu-specific).
  - Add translation domain to .desktop files (Ubuntu-specific).
* debian/dirs:
  - Add usr/share/pixmaps.  Allow inkscape.xpm installation
* drop 50-poppler-API.dpatch (now upstream)
* drop 51-paste-in-unwritable-directory.dpatch (now upstream) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#include "helper/sp-marshal.h"
39
39
#include "xml/node-event-vector.h"
40
40
#include "attributes.h"
 
41
#include "color-profile-fns.h"
41
42
#include "document.h"
42
43
#include "style.h"
43
44
#include "sp-object-repr.h"
53
54
#include "debug/demangle.h"
54
55
#include "util/share.h"
55
56
#include "util/format.h"
 
57
#include "util/longest-common-suffix.h"
56
58
 
57
 
#include "algorithms/longest-common-suffix.h"
58
59
using std::memcpy;
59
60
using std::strchr;
60
61
using std::strcmp;
112
113
    sp_object_repr_order_changed
113
114
};
114
115
 
 
116
// A friend class used to set internal members on SPObject so as to not expose settors in SPObject's public API
 
117
class SPObjectImpl
 
118
{
 
119
public:
 
120
 
 
121
/**
 
122
 * Null's the id member of an SPObject without attempting to free prior contents.
 
123
 */
 
124
    static void setIdNull( SPObject* obj ) {
 
125
        if (obj) {
 
126
            obj->id = 0;
 
127
        }
 
128
    }
 
129
 
 
130
/**
 
131
 * Sets the id member of an object, freeing any prior content.
 
132
 */
 
133
    static void setId( SPObject* obj, gchar const* id ) {
 
134
        if (obj && (id != obj->id) ) {
 
135
            if (obj->id) {
 
136
                g_free(obj->id);
 
137
                obj->id = 0;
 
138
            }
 
139
            if (id) {
 
140
                obj->id = g_strdup(id);
 
141
            }
 
142
        }
 
143
    }
 
144
};
 
145
 
 
146
 
115
147
static GObjectClass *parent_class;
116
148
 
117
149
/**
177
209
    object->children = object->_last_child = NULL;
178
210
    object->parent = object->next = NULL;
179
211
    object->repr = NULL;
180
 
    object->id = NULL;
 
212
    SPObjectImpl::setIdNull(object);
181
213
 
182
214
    object->_collection_policy = SPObject::COLLECT_WITH_PARENT;
183
215
 
188
220
    object->_successor = NULL;
189
221
 
190
222
    // FIXME: now we create style for all objects, but per SVG, only the following can have style attribute:
191
 
    // vg, g, defs, desc, title, symbol, use, image, switch, path, rect, circle, ellipse, line, polyline, 
192
 
    // polygon, text, tspan, tref, textPath, altGlyph, glyphRef, marker, linearGradient, radialGradient, 
 
223
    // vg, g, defs, desc, title, symbol, use, image, switch, path, rect, circle, ellipse, line, polyline,
 
224
    // polygon, text, tspan, tref, textPath, altGlyph, glyphRef, marker, linearGradient, radialGradient,
193
225
    // stop, pattern, clipPath, mask, filter, feImage, a, font, glyph, missing-glyph, foreignObject
194
226
    object->style = sp_style_new_from_object(object);
195
227
 
259
291
 
260
292
}
261
293
 
 
294
gchar const* SPObject::getId() const {
 
295
    return id;
 
296
}
 
297
 
262
298
/**
263
299
 * Increase reference count of object, with possible debugging.
264
300
 *
504
540
 
505
541
 
506
542
/** Queues the object for orphan collection */
507
 
void
508
 
SPObject::requestOrphanCollection() {
 
543
void SPObject::requestOrphanCollection() {
509
544
    g_return_if_fail(document != NULL);
510
545
 
511
546
    // do not remove style or script elements (Bug #276244)
512
 
    if (SP_IS_STYLE_ELEM(this))
513
 
        return;
514
 
    if (SP_IS_SCRIPT(this))
515
 
        return;
516
 
 
517
 
    document->queueForOrphanCollection(this);
518
 
 
519
 
    /** \todo
520
 
     * This is a temporary hack added to make fill&stroke rebuild its
521
 
     * gradient list when the defs are vacuumed.  gradient-vector.cpp
522
 
     * listens to the modified signal on defs, and now we give it that
523
 
     * signal.  Mental says that this should be made automatic by
524
 
     * merging SPObjectGroup with SPObject; SPObjectGroup would issue
525
 
     * this signal automatically. Or maybe just derive SPDefs from
526
 
     * SPObjectGroup?
527
 
     */
528
 
 
529
 
    this->requestModified(SP_OBJECT_CHILD_MODIFIED_FLAG);
 
547
    if (SP_IS_STYLE_ELEM(this)) {
 
548
        // leave it
 
549
    } else if (SP_IS_SCRIPT(this)) {
 
550
        // leave it
 
551
    } else if (SP_IS_PAINT_SERVER(this) && static_cast<SPPaintServer*>(this)->isSwatch() ) {
 
552
        // leave it
 
553
    } else if (IS_COLORPROFILE(this)) {
 
554
        // leave it
 
555
    } else {
 
556
        document->queueForOrphanCollection(this);
 
557
 
 
558
        /** \todo
 
559
         * This is a temporary hack added to make fill&stroke rebuild its
 
560
         * gradient list when the defs are vacuumed.  gradient-vector.cpp
 
561
         * listens to the modified signal on defs, and now we give it that
 
562
         * signal.  Mental says that this should be made automatic by
 
563
         * merging SPObjectGroup with SPObject; SPObjectGroup would issue
 
564
         * this signal automatically. Or maybe just derive SPDefs from
 
565
         * SPObjectGroup?
 
566
         */
 
567
 
 
568
        this->requestModified(SP_OBJECT_CHILD_MODIFIED_FLAG);
 
569
    }
530
570
}
531
571
 
532
572
/** Sends the delete signal to all children of this object recursively */
808
848
    }
809
849
}
810
850
 
811
 
void
812
 
sp_object_invoke_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr, unsigned int cloned)
 
851
void sp_object_invoke_build(SPObject *object, SPDocument *document, Inkscape::XML::Node *repr, unsigned int cloned)
813
852
{
814
853
    debug("id=%x, typename=%s", object, g_type_name_from_instance((GTypeInstance*)object));
815
854
 
820
859
 
821
860
    g_assert(object->document == NULL);
822
861
    g_assert(object->repr == NULL);
823
 
    g_assert(object->id == NULL);
 
862
    g_assert(object->getId() == NULL);
824
863
 
825
864
    /* Bookkeeping */
826
865
 
837
876
            /* If we are not cloned, and not seeking, force unique id */
838
877
            gchar const *id = object->repr->attribute("id");
839
878
            if (!document->isSeeking()) {
840
 
                gchar *realid = sp_object_get_unique_id(object, id);
841
 
                g_assert(realid != NULL);
 
879
                {
 
880
                    gchar *realid = sp_object_get_unique_id(object, id);
 
881
                    g_assert(realid != NULL);
842
882
 
843
 
                object->document->bindObjectToId(realid, object);
844
 
                object->id = realid;
 
883
                    object->document->bindObjectToId(realid, object);
 
884
                    SPObjectImpl::setId(object, realid);
 
885
                    g_free(realid);
 
886
                }
845
887
 
846
888
                /* Redefine ID, if required */
847
 
                if ((id == NULL) || (strcmp(id, realid) != 0)) {
848
 
                    object->repr->setAttribute("id", realid);
 
889
                if ((id == NULL) || (strcmp(id, object->getId()) != 0)) {
 
890
                    object->repr->setAttribute("id", object->getId());
849
891
                }
850
892
            } else if (id) {
851
893
                // bind if id, but no conflict -- otherwise, we can expect
852
894
                // a subsequent setting of the id attribute
853
895
                if (!object->document->getObjectById(id)) {
854
896
                    object->document->bindObjectToId(id, object);
855
 
                    object->id = g_strdup(id);
 
897
                    SPObjectImpl::setId(object, id);
856
898
                }
857
899
            }
858
900
        }
859
901
    } else {
860
 
        g_assert(object->id == NULL);
 
902
        g_assert(object->getId() == NULL);
861
903
    }
862
904
 
863
905
    /* Invoke derived methods, if any */
909
951
    this->repr = NULL;
910
952
}
911
953
 
 
954
 
 
955
SPObject *SPObject::getNext()
 
956
{
 
957
    return next;
 
958
}
 
959
 
 
960
SPObject *SPObject::getPrev()
 
961
{
 
962
    return sp_object_prev(this);
 
963
}
 
964
 
912
965
/**
913
966
 * Callback for child_added node event.
914
967
 */
982
1035
                    }
983
1036
                }
984
1037
 
985
 
                if (object->id) {
986
 
                    document->bindObjectToId(object->id, NULL);
987
 
                    g_free(object->id);
 
1038
                if (object->getId()) {
 
1039
                    document->bindObjectToId(object->getId(), NULL);
 
1040
                    SPObjectImpl::setId(object, 0);
988
1041
                }
989
1042
 
990
1043
                if (new_id) {
991
 
                    object->id = g_strdup((char const*)new_id);
992
 
                    document->bindObjectToId(object->id, object);
993
 
                } else {
994
 
                    object->id = NULL;
 
1044
                    SPObjectImpl::setId(object, new_id);
 
1045
                    document->bindObjectToId(object->getId(), object);
995
1046
                }
996
1047
 
997
1048
                g_free(object->_default_label);
1130
1181
            repr->setAttribute("inkscape:collect", NULL);
1131
1182
        }
1132
1183
    } else {
1133
 
        repr->setAttribute("id", object->id);
 
1184
        repr->setAttribute("id", object->getId());
1134
1185
 
1135
1186
        if (object->xml_space.set) {
1136
1187
            char const *xml_space;
1145
1196
        } else {
1146
1197
            repr->setAttribute("inkscape:collect", NULL);
1147
1198
        }
1148
 
 
 
1199
 
1149
1200
        SPStyle const *const obj_style = SP_OBJECT_STYLE(object);
1150
1201
        if (obj_style) {
1151
1202
            gchar *s = sp_style_write_string(obj_style, SP_STYLE_FLAG_IFSET);
1201
1252
    }
1202
1253
}
1203
1254
 
1204
 
/** Used both to create reprs in the original document, and to create 
 
1255
/** Used both to create reprs in the original document, and to create
1205
1256
 *  reprs in another document (e.g. a temporary document used when
1206
1257
 *  saving as "Plain SVG"
1207
1258
 */
1311
1362
    }
1312
1363
    catch(...)
1313
1364
    {
1314
 
        /** \todo 
 
1365
        /** \todo
1315
1366
        * in case of catching an exception we need to inform the user somehow that the document is corrupted
1316
1367
        * maybe by implementing an document flag documentOk
1317
1368
        * or by a modal error dialog
1323
1374
}
1324
1375
 
1325
1376
/**
1326
 
 * Request modified always bubbles *up* the tree, as opposed to 
1327
 
 * request display update, which trickles down and relies on the 
 
1377
 * Request modified always bubbles *up* the tree, as opposed to
 
1378
 * request display update, which trickles down and relies on the
1328
1379
 * flags set during this pass...
1329
1380
 */
1330
1381
void
1355
1406
    }
1356
1407
}
1357
1408
 
1358
 
/** 
 
1409
/**
1359
1410
 *  Emits the MODIFIED signal with the object's flags.
1360
 
 *  The object's mflags are the original set aside during the update pass for 
 
1411
 *  The object's mflags are the original set aside during the update pass for
1361
1412
 *  later delivery here.  Once emitModified() is called, those flags don't
1362
1413
 *  need to be stored any longer.
1363
1414
 */
1748
1799
    for (const SPObject *child = firstChild(); child; child = child->next)
1749
1800
    {
1750
1801
        Inkscape::XML::NodeType child_type = child->repr->type();
1751
 
        
 
1802
 
1752
1803
        if (child_type == Inkscape::XML::ELEMENT_NODE) {
1753
1804
            GString * new_text = child->textualContent();
1754
1805
            g_string_append(text, new_text->str);