~inkscape.dev/inkscape/trunk

10697 by Jon A. Cruz
Fixing more broken and split doc comments.
1
/*
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
2
 * SPDocument manipulation
1 by mental
moving trunk for module inkscape
3
 *
4
 * Authors:
5
 *   Lauris Kaplinski <lauris@kaplinski.com>
6
 *   MenTaLguY <mental@rydia.net>
7
 *   bulia byak <buliabyak@users.sf.net>
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
8
 *   Jon A. Cruz <jon@joncruz.org>
9
 *   Abhishek Sharma
11782 by tavmjong-free
Add symbols dialog. See: http://wiki.inkscape.org/wiki/index.php/SymbolsDialog
10
 *   Tavmjong Bah <tavmjong@free.fr>
1 by mental
moving trunk for module inkscape
11
 *
12
 * Copyright (C) 2004-2005 MenTaLguY
13
 * Copyright (C) 1999-2002 Lauris Kaplinski
14
 * Copyright (C) 2000-2001 Ximian, Inc.
11782 by tavmjong-free
Add symbols dialog. See: http://wiki.inkscape.org/wiki/index.php/SymbolsDialog
15
 * Copyright (C) 2012 Tavmjong Bah
1 by mental
moving trunk for module inkscape
16
 *
17
 * Released under GNU GPL, read the file 'COPYING' for more information
18
 */
19
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
20
/** \class SPDocument
21
 * SPDocument serves as the container of both model trees (agnostic XML
1 by mental
moving trunk for module inkscape
22
 * and typed object tree), and implements all of the document-level
149 by rwst
bulk trailing spaces removal. consistency through MD5 of binary
23
 * functionality used by the program. Many document level operations, like
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
24
 * load, save, print, export and so on, use SPDocument as their basic datatype.
1 by mental
moving trunk for module inkscape
25
 *
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
26
 * SPDocument implements undo and redo stacks and an id-based object
1 by mental
moving trunk for module inkscape
27
 * dictionary.  Thanks to unique id attributes, the latter can be used to
28
 * map from the XML tree back to the object tree.
29
 *
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
30
 * SPDocument performs the basic operations needed for asynchronous
1 by mental
moving trunk for module inkscape
31
 * update notification (SPObject ::modified virtual method), and implements
32
 * the 'modified' signal, as well.
33
 */
34
35
36
#define noSP_DOCUMENT_DEBUG_IDLE
37
#define noSP_DOCUMENT_DEBUG_UNDO
38
39
#ifdef HAVE_CONFIG_H
40
# include "config.h"
41
#endif
4629 by bryce
Applying fixes for gcc 4.3 build issues (closes LP: #169115)
42
#include <string>
43
#include <cstring>
10347.1.2 by Krzysztof Kosiński
Remove more of libnr
44
#include <2geom/transforms.h>
7337 by tweenk
Move files from the src/dialogs/ directory to the places where they
45
11142 by Alex Valavanis
eek-preview: Cairo drawing
46
#include "widgets/desktop-widget.h"
7337 by tweenk
Move files from the src/dialogs/ directory to the places where they
47
#include "desktop.h"
48
#include "dir-util.h"
10347.1.21 by Krzysztof Kosiński
Rewrite NRArenaItem hierarchy into C++
49
#include "display/drawing-item.h"
7337 by tweenk
Move files from the src/dialogs/ directory to the places where they
50
#include "document-private.h"
10963 by Alex Valavanis
Header cleaning
51
#include "document-undo.h"
11153 by Kris
Clipboard code cleaning (patch for bug #964852 by Romain, see devmail thread "Some clipboard functions")
52
#include "id-clash.h"
13341.5.3 by Liam P. White
3. remove dead code, refactor existing code. Connect overlooked signals.
53
#include "inkscape.h"
7123 by tweenk
Improved version reporting. Add SVN revision and custom status to
54
#include "inkscape-version.h"
7337 by tweenk
Move files from the src/dialogs/ directory to the places where they
55
#include "libavoid/router.h"
56
#include "persp3d.h"
6885 by Ted Gould
From trunk
57
#include "preferences.h"
7337 by tweenk
Move files from the src/dialogs/ directory to the places where they
58
#include "profile-manager.h"
59
#include "rdf.h"
11608.1.91 by Markus Engel
Removed old SPObject factory.
60
#include "sp-factory.h"
602 by acspike
fix translation for fit page
61
#include "sp-item-group.h"
7337 by tweenk
Move files from the src/dialogs/ directory to the places where they
62
#include "sp-namedview.h"
11782 by tavmjong-free
Add symbols dialog. See: http://wiki.inkscape.org/wiki/index.php/SymbolsDialog
63
#include "sp-symbol.h"
4224 by cilix42
Fundamentally reworked version of the 3D box tool (among many other things, this fixes bugs #168900 and #168868). See mailing list for details. Sorry for this single large commit but it was unfeasible to keep the history.
64
#include "transf_mat_3x4.h"
12380.1.54 by Matthew Petroff
Eliminate "unit-constants.h".
65
#include "util/units.h"
7337 by tweenk
Move files from the src/dialogs/ directory to the places where they
66
#include "xml/repr.h"
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
67
#include "xml/rebase-hrefs.h"
10986 by Alex Valavanis
More header cleanup/fwd declarations
68
#include "libcroco/cr-cascade.h"
4224 by cilix42
Fundamentally reworked version of the 3D box tool (among many other things, this fixes bugs #168900 and #168868). See mailing list for details. Sorry for this single large commit but it was unfeasible to keep the history.
69
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
70
using Inkscape::DocumentUndo;
12380.1.62 by Matthew Petroff
Switched to global UnitTable.
71
using Inkscape::Util::unit_table;
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
72
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
73
// Higher number means lower priority.
74
#define SP_DOCUMENT_UPDATE_PRIORITY (G_PRIORITY_HIGH_IDLE - 2)
75
76
// Should have a lower priority than SP_DOCUMENT_UPDATE_PRIORITY,
77
// since we want it to happen when there are no more updates.
78
#define SP_DOCUMENT_REROUTING_PRIORITY (G_PRIORITY_HIGH_IDLE - 1)
1 by mental
moving trunk for module inkscape
79
80
81
static gint sp_document_idle_handler(gpointer data);
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
82
static gint sp_document_rerouting_handler(gpointer data);
1 by mental
moving trunk for module inkscape
83
84
gboolean sp_document_resource_list_free(gpointer key, gpointer value, gpointer data);
85
86
static gint doc_count = 0;
12712 by JazzyNico
Fix for Bug #1022543 (Ctrl+C increments the documents count).
87
static gint doc_mem_count = 0;
1 by mental
moving trunk for module inkscape
88
2989 by mental
add document serial numbers
89
static unsigned long next_serial = 0;
90
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
91
SPDocument::SPDocument() :
5897 by joncruz
Fixed uninitialized variables, including modified-since-save.
92
    keepalive(FALSE),
93
    virgin(TRUE),
94
    modified_since_save(FALSE),
13104 by Johan B. C. Engelen
code cleanup
95
    rdoc(NULL),
96
    rroot(NULL),
97
    root(NULL),
5897 by joncruz
Fixed uninitialized variables, including modified-since-save.
98
    style_cascade(cr_cascade_new(NULL, NULL, NULL)),
13104 by Johan B. C. Engelen
code cleanup
99
    uri(NULL),
100
    base(NULL),
101
    name(NULL),
102
    priv(NULL), // reset in ctor
9662 by Jon A. Cruz
Safer fix for bug #579932 that won't leak memory.
103
    actionkey(),
5897 by joncruz
Fixed uninitialized variables, including modified-since-save.
104
    modified_id(0),
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
105
    rerouting_handler_id(0),
13104 by Johan B. C. Engelen
code cleanup
106
    profileManager(NULL), // deferred until after other initialization
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
107
    router(new Avoid::Router(Avoid::PolyLineRouting|Avoid::OrthogonalRouting)),
13104 by Johan B. C. Engelen
code cleanup
108
    _collection_queue(NULL),
8914 by Jon A. Cruz
Correcting initialization order in ctor.
109
    oldSignalsConnected(false),
11461 by Kris
various
110
    current_persp3d(NULL),
12971 by Martin Owens
Move sub-document reference creation code from uri-reference to document.cpp as createChildDoc(path)
111
    current_persp3d_impl(NULL),
112
    _parent_document(NULL)
5897 by joncruz
Fixed uninitialized variables, including modified-since-save.
113
{
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
114
    // Penalise libavoid for choosing paths with needless extra segments.
115
    // This results in much better looking orthogonal connector paths.
116
    router->setRoutingPenalty(Avoid::segmentPenalty);
144 by mjwybrow
* src/document.cpp, src/document.h, src/sp-conn-end-pair.cpp,
117
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
118
    SPDocumentPrivate *p = new SPDocumentPrivate();
1 by mental
moving trunk for module inkscape
119
2989 by mental
add document serial numbers
120
    p->serial = next_serial++;
121
1 by mental
moving trunk for module inkscape
122
    p->iddef = g_hash_table_new(g_direct_hash, g_direct_equal);
123
    p->reprdef = g_hash_table_new(g_direct_hash, g_direct_equal);
124
125
    p->resources = g_hash_table_new(g_str_hash, g_str_equal);
126
13104 by Johan B. C. Engelen
code cleanup
127
    p->sensitive = false;
1 by mental
moving trunk for module inkscape
128
    p->partial = NULL;
129
    p->history_size = 0;
130
    p->undo = NULL;
131
    p->redo = NULL;
2680 by mental
better way to deal with undo+id collisions
132
    p->seeking = false;
1 by mental
moving trunk for module inkscape
133
134
    priv = p;
1267 by dwyip
quick g_message UndoStackObserver for tracing calls to the undo system
135
3862 by joncruz
Adding profile manager and user-visible drop-down in CMS picker
136
    // Once things are set, hook in the manager
137
    profileManager = new Inkscape::ProfileManager(this);
138
1267 by dwyip
quick g_message UndoStackObserver for tracing calls to the undo system
139
    // XXX only for testing!
140
    priv->undoStackObservers.add(p->console_output_undo_observer);
1 by mental
moving trunk for module inkscape
141
}
142
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
143
SPDocument::~SPDocument() {
13094 by Jon A. Cruz
Adding destroy signal do document to allow proper cleanup.
144
    priv->destroySignal.emit();
145
3862 by joncruz
Adding profile manager and user-visible drop-down in CMS picker
146
    // kill/unhook this first
147
    if ( profileManager ) {
148
        delete profileManager;
149
        profileManager = 0;
150
    }
151
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
152
    if (router) {
153
        delete router;
154
        router = NULL;
155
    }
156
13341.5.2 by Liam P. White
2. connect signals
157
    if (oldSignalsConnected) {
158
        priv->selChangeConnection.disconnect();
159
        priv->desktopActivatedConnection.disconnect();
160
    } else {
161
        _selection_changed_connection.disconnect();
162
        _desktop_activated_connection.disconnect();
163
    }
164
1 by mental
moving trunk for module inkscape
165
    if (priv) {
166
        if (priv->partial) {
167
            sp_repr_free_log(priv->partial);
168
            priv->partial = NULL;
169
        }
170
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
171
        DocumentUndo::clearRedo(this);
172
        DocumentUndo::clearUndo(this);
1 by mental
moving trunk for module inkscape
173
174
        if (root) {
1447 by mental
sp_object_invoke_release -> SPObject::releaseReferences, plus the introduction of sigc++ signals for "release" and "modified" which will eventually replace their GObject signal counterparts
175
            root->releaseReferences();
635 by mental
use proper unref function on SPRoot to avoid appearance of leak
176
            sp_object_unref(root);
1 by mental
moving trunk for module inkscape
177
            root = NULL;
178
        }
179
180
        if (priv->iddef) g_hash_table_destroy(priv->iddef);
181
        if (priv->reprdef) g_hash_table_destroy(priv->reprdef);
182
183
        if (rdoc) Inkscape::GC::release(rdoc);
184
185
        /* Free resources */
186
        g_hash_table_foreach_remove(priv->resources, sp_document_resource_list_free, this);
187
        g_hash_table_destroy(priv->resources);
188
189
        delete priv;
190
        priv = NULL;
191
    }
192
193
    cr_cascade_unref(style_cascade);
194
    style_cascade = NULL;
195
196
    if (name) {
197
        g_free(name);
198
        name = NULL;
199
    }
200
    if (base) {
201
        g_free(base);
202
        base = NULL;
203
    }
204
    if (uri) {
205
        g_free(uri);
206
        uri = NULL;
207
    }
208
209
    if (modified_id) {
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
210
        g_source_remove(modified_id);
1 by mental
moving trunk for module inkscape
211
        modified_id = 0;
212
    }
213
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
214
    if (rerouting_handler_id) {
215
        g_source_remove(rerouting_handler_id);
216
        rerouting_handler_id = 0;
217
    }
218
1 by mental
moving trunk for module inkscape
219
    if (keepalive) {
13341.5.1 by Liam P. White
1. make it compile
220
        inkscape_unref(INKSCAPE);
1 by mental
moving trunk for module inkscape
221
        keepalive = FALSE;
222
    }
12611 by buliabyak
dying document needs to delete its perspective
223
224
    if (this->current_persp3d_impl) 
225
        delete this->current_persp3d_impl;
226
    this->current_persp3d_impl = NULL;
227
12625 by buliabyak
collectOrphans moved to the end of destructor to prevent leaking of uncollected stuff
228
    // This is at the end of the destructor, because preceding code adds new orphans to the queue
229
    collectOrphans();
230
4224 by cilix42
Fundamentally reworked version of the 3D box tool (among many other things, this fixes bugs #168900 and #168868). See mailing list for details. Sorry for this single large commit but it was unfeasible to keep the history.
231
}
232
13094 by Jon A. Cruz
Adding destroy signal do document to allow proper cleanup.
233
sigc::connection SPDocument::connectDestroy(sigc::signal<void>::slot_type slot)
234
{
235
    return priv->destroySignal.connect(slot);
236
}
237
10254 by Jon A. Cruz
Removed outdated/unsafe SP_DOCUMENT_DEFS macro and reduced usage of SP_ROOT() gtk type function/macro.
238
SPDefs *SPDocument::getDefs()
239
{
11588 by John Smith
Fix for 1030239 : Custom markers only added to the list in Stroke Style after reloading the file
240
    if (!root) {
241
        return NULL;
242
    }
10254 by Jon A. Cruz
Removed outdated/unsafe SP_DOCUMENT_DEFS macro and reduced usage of SP_ROOT() gtk type function/macro.
243
    return root->defs;
244
}
245
11461 by Kris
various
246
Persp3D *SPDocument::getCurrentPersp3D() {
8910 by Maximilian Albert
Refactoring of 3D box tool, mainly to avoid unnecessary creation of perspectives.
247
    // Check if current_persp3d is still valid
248
    std::vector<Persp3D*> plist;
249
    getPerspectivesInDefs(plist);
250
    for (unsigned int i = 0; i < plist.size(); ++i) {
251
        if (current_persp3d == plist[i])
252
            return current_persp3d;
253
    }
254
255
    // If not, return the first perspective in defs (which may be NULL of none exists)
256
    current_persp3d = persp3d_document_first_persp (this);
257
258
    return current_persp3d;
259
}
260
11461 by Kris
various
261
Persp3DImpl *SPDocument::getCurrentPersp3DImpl() {
8910 by Maximilian Albert
Refactoring of 3D box tool, mainly to avoid unnecessary creation of perspectives.
262
    return current_persp3d_impl;
263
}
264
11461 by Kris
various
265
void SPDocument::setCurrentPersp3D(Persp3D * const persp) {
8910 by Maximilian Albert
Refactoring of 3D box tool, mainly to avoid unnecessary creation of perspectives.
266
    current_persp3d = persp;
267
    //current_persp3d_impl = persp->perspective_impl;
268
}
269
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
270
void SPDocument::getPerspectivesInDefs(std::vector<Persp3D*> &list) const
271
{
10254 by Jon A. Cruz
Removed outdated/unsafe SP_DOCUMENT_DEFS macro and reduced usage of SP_ROOT() gtk type function/macro.
272
    for (SPObject *i = root->defs->firstChild(); i; i = i->getNext() ) {
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
273
        if (SP_IS_PERSP3D(i)) {
8910 by Maximilian Albert
Refactoring of 3D box tool, mainly to avoid unnecessary creation of perspectives.
274
            list.push_back(SP_PERSP3D(i));
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
275
        }
3445 by cilix42
Hold perspectives on document level rather than globally; this corrects the changes made in commit #15681
276
    }
8910 by Maximilian Albert
Refactoring of 3D box tool, mainly to avoid unnecessary creation of perspectives.
277
}
278
279
/**
8712 by scislac
Patch to fix 205667 by Petteri Aimonen
280
void SPDocument::initialize_current_persp3d()
281
{
282
    this->current_persp3d = persp3d_document_first_persp(this);
283
    if (!this->current_persp3d) {
284
        this->current_persp3d = persp3d_create_xml_element(this);
285
    }
286
}
8910 by Maximilian Albert
Refactoring of 3D box tool, mainly to avoid unnecessary creation of perspectives.
287
**/
8712 by scislac
Patch to fix 205667 by Petteri Aimonen
288
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
289
unsigned long SPDocument::serial() const {
2989 by mental
add document serial numbers
290
    return priv->serial;
291
}
292
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
293
void SPDocument::queueForOrphanCollection(SPObject *object) {
1 by mental
moving trunk for module inkscape
294
    g_return_if_fail(object != NULL);
10059 by Jon A. Cruz
Pass removing some outdated C-macro use.
295
    g_return_if_fail(object->document == this);
1 by mental
moving trunk for module inkscape
296
297
    sp_object_ref(object, NULL);
298
    _collection_queue = g_slist_prepend(_collection_queue, object);
299
}
300
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
301
void SPDocument::collectOrphans() {
1 by mental
moving trunk for module inkscape
302
    while (_collection_queue) {
303
        GSList *objects=_collection_queue;
304
        _collection_queue = NULL;
305
        for ( GSList *iter=objects ; iter ; iter = iter->next ) {
306
            SPObject *object=reinterpret_cast<SPObject *>(iter->data);
307
            object->collectOrphan();
308
            sp_object_unref(object, NULL);
309
        }
310
        g_slist_free(objects);
311
    }
312
}
313
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
314
void SPDocument::reset_key (void */*dummy*/)
1 by mental
moving trunk for module inkscape
315
{
9662 by Jon A. Cruz
Safer fix for bug #579932 that won't leak memory.
316
    actionkey.clear();
1 by mental
moving trunk for module inkscape
317
}
149 by rwst
bulk trailing spaces removal. consistency through MD5 of binary
318
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
319
SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc,
320
                                  gchar const *uri,
321
                                  gchar const *base,
322
                                  gchar const *name,
12970 by Martin Owens
Protect against infinate looping of new included hrefs
323
                                  unsigned int keepalive,
324
                                  SPDocument *parent)
1 by mental
moving trunk for module inkscape
325
{
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
326
    SPDocument *document = new SPDocument();
327
6885 by Ted Gould
From trunk
328
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
329
    Inkscape::XML::Node *rroot = rdoc->root();
1 by mental
moving trunk for module inkscape
330
331
    document->keepalive = keepalive;
332
333
    document->rdoc = rdoc;
334
    document->rroot = rroot;
12971 by Martin Owens
Move sub-document reference creation code from uri-reference to document.cpp as createChildDoc(path)
335
    if (parent) {
336
        document->_parent_document = parent;
337
        parent->_child_documents.push_back(document);
338
    }
1 by mental
moving trunk for module inkscape
339
10519 by Kris
Memory leaks fix / code cleanup
340
    if (document->uri){
341
        g_free(document->uri);
10521 by Jon A. Cruz
Added overload for getObjectById(). Added safety by zeroing out invalid points (prevents accidental use of stale pointers).
342
        document->uri = 0;
10519 by Kris
Memory leaks fix / code cleanup
343
    }
344
    if (document->base){
345
        g_free(document->base);
10521 by Jon A. Cruz
Added overload for getObjectById(). Added safety by zeroing out invalid points (prevents accidental use of stale pointers).
346
        document->base = 0;
10519 by Kris
Memory leaks fix / code cleanup
347
    }
348
    if (document->name){
349
        g_free(document->name);
10521 by Jon A. Cruz
Added overload for getObjectById(). Added safety by zeroing out invalid points (prevents accidental use of stale pointers).
350
        document->name = 0;
10519 by Kris
Memory leaks fix / code cleanup
351
    }
1 by mental
moving trunk for module inkscape
352
#ifndef WIN32
7653 by pjrm
functional noop: Change prepend_current_dir_if_relative to return the result rather than taking a pointer to where to put the result. (Clarifies that the existing value isn't used.)
353
    document->uri = prepend_current_dir_if_relative(uri);
1 by mental
moving trunk for module inkscape
354
#else
355
    // FIXME: it may be that prepend_current_dir_if_relative works OK on windows too, test!
356
    document->uri = uri? g_strdup(uri) : NULL;
357
#endif
358
359
    // base is simply the part of the path before filename; e.g. when running "inkscape ../file.svg" the base is "../"
360
    // which is why we use g_get_current_dir() in calculating the abs path above
361
    //This is NULL for a new document
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
362
    if (base) {
1 by mental
moving trunk for module inkscape
363
        document->base = g_strdup(base);
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
364
    } else {
1 by mental
moving trunk for module inkscape
365
        document->base = NULL;
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
366
    }
1 by mental
moving trunk for module inkscape
367
    document->name = g_strdup(name);
368
11608.1.91 by Markus Engel
Removed old SPObject factory.
369
    // Create SPRoot element
11608.1.124 by Markus Engel
Removed TypeInfo; adjusted Factory to meet code style conventions.
370
    const std::string typeString = NodeTraits::get_type_string(*rroot);
11608.1.94 by Markus Engel
Added prefPaths to contexts; modified SPFactory
371
    SPObject* rootObj = SPFactory::instance().createObject(typeString);
11608.1.91 by Markus Engel
Removed old SPObject factory.
372
    document->root = dynamic_cast<SPRoot*>(rootObj);
373
11608.1.94 by Markus Engel
Added prefPaths to contexts; modified SPFactory
374
    if (document->root == 0) {
11608.1.91 by Markus Engel
Removed old SPObject factory.
375
    	// Node is not a valid root element
376
    	delete rootObj;
377
378
    	// fixme: what to do here?
379
    	throw;
380
    }
381
382
    // Recursively build object tree
383
    document->root->invoke_build(document, rroot, false);
1 by mental
moving trunk for module inkscape
384
385
    /* fixme: Not sure about this, but lets assume ::build updates */
7123 by tweenk
Improved version reporting. Add SVN revision and custom status to
386
    rroot->setAttribute("inkscape:version", Inkscape::version_string);
1 by mental
moving trunk for module inkscape
387
    /* fixme: Again, I moved these here to allow version determining in ::build (Lauris) */
388
389
6246 by sasilver
Remove obsolete 'sodipodi:docbase' attribute when opening old Sodipodi/Inkscape files.
390
    /* Eliminate obsolete sodipodi:docbase, for privacy reasons */
391
    rroot->setAttribute("sodipodi:docbase", NULL);
8029 by joncruz
Removed sodipodi:version
392
5879 by sasilver
Remove any baseProfile attribute, as we don't respect it. (See bug 166958.)
393
    /* Eliminate any claim to adhere to a profile, as we don't try to */
394
    rroot->setAttribute("baseProfile", NULL);
395
1 by mental
moving trunk for module inkscape
396
    // creating namedview
10254 by Jon A. Cruz
Removed outdated/unsafe SP_DOCUMENT_DEFS macro and reduced usage of SP_ROOT() gtk type function/macro.
397
    if (!sp_item_group_get_child_by_name(document->root, NULL, "sodipodi:namedview")) {
1 by mental
moving trunk for module inkscape
398
        // if there's none in the document already,
399
        Inkscape::XML::Node *rnew = NULL;
8029 by joncruz
Removed sodipodi:version
400
6885 by Ted Gould
From trunk
401
        rnew = rdoc->createElement("sodipodi:namedview");
402
        //rnew->setAttribute("id", "base");
403
404
        // Add namedview data from the preferences
405
        // we can't use getAllEntries because this could produce non-SVG doubles
406
        Glib::ustring pagecolor = prefs->getString("/template/base/pagecolor");
407
        if (!pagecolor.empty()) {
408
            rnew->setAttribute("pagecolor", pagecolor.data());
409
        }
6991 by speleo3
fixed: getting pagecolor for bordercolor
410
        Glib::ustring bordercolor = prefs->getString("/template/base/bordercolor");
6885 by Ted Gould
From trunk
411
        if (!bordercolor.empty()) {
412
            rnew->setAttribute("bordercolor", bordercolor.data());
413
        }
414
        sp_repr_set_svg_double(rnew, "borderopacity",
415
            prefs->getDouble("/template/base/borderopacity", 1.0));
416
        sp_repr_set_svg_double(rnew, "objecttolerance",
417
            prefs->getDouble("/template/base/objecttolerance", 10.0));
418
        sp_repr_set_svg_double(rnew, "gridtolerance",
419
            prefs->getDouble("/template/base/gridtolerance", 10.0));
420
        sp_repr_set_svg_double(rnew, "guidetolerance",
421
            prefs->getDouble("/template/base/guidetolerance", 10.0));
422
        sp_repr_set_svg_double(rnew, "inkscape:pageopacity",
423
            prefs->getDouble("/template/base/inkscape:pageopacity", 0.0));
424
        sp_repr_set_int(rnew, "inkscape:pageshadow",
425
            prefs->getInt("/template/base/inkscape:pageshadow", 2));
426
        sp_repr_set_int(rnew, "inkscape:window-width",
427
            prefs->getInt("/template/base/inkscape:window-width", 640));
428
        sp_repr_set_int(rnew, "inkscape:window-height",
429
            prefs->getInt("/template/base/inkscape:window-height", 480));
8029 by joncruz
Removed sodipodi:version
430
1 by mental
moving trunk for module inkscape
431
        // insert into the document
432
        rroot->addChild(rnew, NULL);
433
        // clean up
434
        Inkscape::GC::release(rnew);
435
    }
436
10254 by Jon A. Cruz
Removed outdated/unsafe SP_DOCUMENT_DEFS macro and reduced usage of SP_ROOT() gtk type function/macro.
437
    // Defs
438
    if (!document->root->defs) {
439
        Inkscape::XML::Node *r = rdoc->createElement("svg:defs");
1 by mental
moving trunk for module inkscape
440
        rroot->addChild(r, NULL);
441
        Inkscape::GC::release(r);
10254 by Jon A. Cruz
Removed outdated/unsafe SP_DOCUMENT_DEFS macro and reduced usage of SP_ROOT() gtk type function/macro.
442
        g_assert(document->root->defs);
1 by mental
moving trunk for module inkscape
443
    }
444
445
    /* Default RDF */
446
    rdf_set_defaults( document );
447
448
    if (keepalive) {
13341.5.1 by Liam P. White
1. make it compile
449
        inkscape_ref(INKSCAPE);
1 by mental
moving trunk for module inkscape
450
    }
451
8910 by Maximilian Albert
Refactoring of 3D box tool, mainly to avoid unnecessary creation of perspectives.
452
    // Check if the document already has a perspective (e.g., when opening an existing
453
    // document). If not, create a new one and set it as the current perspective.
454
    document->setCurrentPersp3D(persp3d_document_first_persp(document));
455
    if (!document->getCurrentPersp3D()) {
456
        //document->setCurrentPersp3D(persp3d_create_xml_element (document));
457
        Persp3DImpl *persp_impl = new Persp3DImpl();
458
        document->setCurrentPersp3DImpl(persp_impl);
459
    }
4224 by cilix42
Fundamentally reworked version of the 3D box tool (among many other things, this fixes bugs #168900 and #168868). See mailing list for details. Sorry for this single large commit but it was unfeasible to keep the history.
460
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
461
    DocumentUndo::setUndoSensitive(document, true);
1 by mental
moving trunk for module inkscape
462
463
    // reset undo key when selection changes, so that same-key actions on different objects are not coalesced
13341.5.9 by Liam P. White
5. Refactoring of Application class: make copy/assignment operators private, disallow pointers to Application
464
    document->priv->selChangeConnection = INKSCAPE.signal_selection_changed.connect(
13341.5.2 by Liam P. White
2. connect signals
465
                sigc::hide(sigc::bind(
466
                sigc::ptr_fun(&DocumentUndo::resetKey), document)
13341.5.6 by Liam P. White
4. further refactor Application class; create proper singleton, encapsulate members, simplify signals
467
    ));
13341.5.9 by Liam P. White
5. Refactoring of Application class: make copy/assignment operators private, disallow pointers to Application
468
    document->priv->desktopActivatedConnection = INKSCAPE.signal_activate_desktop.connect(
13341.5.2 by Liam P. White
2. connect signals
469
                sigc::hide(sigc::bind(
470
                sigc::ptr_fun(&DocumentUndo::resetKey), document)
13341.5.6 by Liam P. White
4. further refactor Application class; create proper singleton, encapsulate members, simplify signals
471
    ));
9828 by Krzysztof Kosiński
Remove the failed and unused "new gui" stuff.
472
    document->oldSignalsConnected = true;
1 by mental
moving trunk for module inkscape
473
474
    return document;
475
}
476
477
/**
12971 by Martin Owens
Move sub-document reference creation code from uri-reference to document.cpp as createChildDoc(path)
478
 * Fetches a document and attaches it to the current document as a child href
479
 */
12979 by Martin Owens
Check file existance and clean up memory issues thanks to KK and Johan
480
SPDocument *SPDocument::createChildDoc(std::string const &uri)
12977 by Martin Owens
Move absolute path generator to URI and use std::strings
481
{
12971 by Martin Owens
Move sub-document reference creation code from uri-reference to document.cpp as createChildDoc(path)
482
    SPDocument *parent = this;
483
    SPDocument *document = NULL;
484
13004 by tavmjong-free
Prevent attempt to initialize/compare std::string with/to null pointer.
485
    while(parent != NULL && parent->getURI() != NULL && document == NULL) {
12971 by Martin Owens
Move sub-document reference creation code from uri-reference to document.cpp as createChildDoc(path)
486
        // Check myself and any parents int he chain
12979 by Martin Owens
Check file existance and clean up memory issues thanks to KK and Johan
487
        if(uri == parent->getURI()) {
12971 by Martin Owens
Move sub-document reference creation code from uri-reference to document.cpp as createChildDoc(path)
488
            document = parent;
489
            break;
490
        }
491
        // Then check children of those.
492
        boost::ptr_list<SPDocument>::iterator iter;
493
        for (iter = parent->_child_documents.begin();
12979 by Martin Owens
Check file existance and clean up memory issues thanks to KK and Johan
494
          iter != parent->_child_documents.end(); ++iter) {
495
            if(uri == iter->getURI()) {
12971 by Martin Owens
Move sub-document reference creation code from uri-reference to document.cpp as createChildDoc(path)
496
                document = &*iter;
497
                break;
498
            }
499
        }
500
        parent = parent->_parent_document;
501
    }
502
503
    // Load a fresh document from the svg source.
504
    if(!document) {
12979 by Martin Owens
Check file existance and clean up memory issues thanks to KK and Johan
505
        const char *path = uri.c_str();
12977 by Martin Owens
Move absolute path generator to URI and use std::strings
506
        document = createNewDoc(path, false, false, this);
12971 by Martin Owens
Move sub-document reference creation code from uri-reference to document.cpp as createChildDoc(path)
507
    }
508
    return document;
509
}
510
/**
149 by rwst
bulk trailing spaces removal. consistency through MD5 of binary
511
 * Fetches document from URI, or creates new, if NULL; public document
1 by mental
moving trunk for module inkscape
512
 * appears in document list.
513
 */
12970 by Martin Owens
Protect against infinate looping of new included hrefs
514
SPDocument *SPDocument::createNewDoc(gchar const *uri, unsigned int keepalive, bool make_new, SPDocument *parent)
1 by mental
moving trunk for module inkscape
515
{
13104 by Johan B. C. Engelen
code cleanup
516
    Inkscape::XML::Document *rdoc = NULL;
1 by mental
moving trunk for module inkscape
517
    gchar *base = NULL;
518
    gchar *name = NULL;
519
520
    if (uri) {
521
        Inkscape::XML::Node *rroot;
522
        gchar *s, *p;
523
        /* Try to fetch repr from file */
524
        rdoc = sp_repr_read_file(uri, SP_SVG_NS_URI);
525
        /* If file cannot be loaded, return NULL without warning */
526
        if (rdoc == NULL) return NULL;
2461 by mental
get rid of sp_repr_document_root and (commented) sp_repr_duplicate
527
        rroot = rdoc->root();
1 by mental
moving trunk for module inkscape
528
        /* If xml file is not svg, return NULL without warning */
529
        /* fixme: destroy document */
530
        if (strcmp(rroot->name(), "svg:svg") != 0) return NULL;
531
        s = g_strdup(uri);
532
        p = strrchr(s, '/');
533
        if (p) {
534
            name = g_strdup(p + 1);
535
            p[1] = '\0';
536
            base = g_strdup(s);
537
        } else {
538
            base = NULL;
539
            name = g_strdup(uri);
540
        }
12712 by JazzyNico
Fix for Bug #1022543 (Ctrl+C increments the documents count).
541
        if (make_new) {
542
            base = NULL;
543
            uri = NULL;
544
            name = g_strdup_printf(_("New document %d"), ++doc_count);
545
        }
1 by mental
moving trunk for module inkscape
546
        g_free(s);
547
    } else {
12712 by JazzyNico
Fix for Bug #1022543 (Ctrl+C increments the documents count).
548
        if (make_new) {
549
            name = g_strdup_printf(_("Memory document %d"), ++doc_mem_count);
550
        }
551
1 by mental
moving trunk for module inkscape
552
        rdoc = sp_repr_document_new("svg:svg");
553
    }
554
555
    //# These should be set by now
556
    g_assert(name);
557
13104 by Johan B. C. Engelen
code cleanup
558
    SPDocument *doc = createDoc(rdoc, uri, base, name, keepalive, parent);
1 by mental
moving trunk for module inkscape
559
560
    g_free(base);
561
    g_free(name);
562
563
    return doc;
564
}
565
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
566
SPDocument *SPDocument::createNewDocFromMem(gchar const *buffer, gint length, unsigned int keepalive)
1 by mental
moving trunk for module inkscape
567
{
13104 by Johan B. C. Engelen
code cleanup
568
    SPDocument *doc = NULL;
10523 by Jon A. Cruz
Refactored createnewDocFromMem() to be C++ instead of C, removing potential for memory leaks.
569
570
    Inkscape::XML::Document *rdoc = sp_repr_read_mem(buffer, length, SP_SVG_NS_URI);
571
    if ( rdoc ) {
572
        // Only continue to create a non-null doc if it could be loaded
573
        Inkscape::XML::Node *rroot = rdoc->root();
574
        if ( strcmp(rroot->name(), "svg:svg") != 0 ) {
575
            // If xml file is not svg, return NULL without warning
576
            // TODO fixme: destroy document
577
        } else {
12712 by JazzyNico
Fix for Bug #1022543 (Ctrl+C increments the documents count).
578
            Glib::ustring name = Glib::ustring::compose( _("Memory document %1"), ++doc_mem_count );
12970 by Martin Owens
Protect against infinate looping of new included hrefs
579
            doc = createDoc(rdoc, NULL, NULL, name.c_str(), keepalive, NULL);
10523 by Jon A. Cruz
Refactored createnewDocFromMem() to be C++ instead of C, removing potential for memory leaks.
580
        }
581
    }
582
1 by mental
moving trunk for module inkscape
583
    return doc;
584
}
585
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
586
SPDocument *SPDocument::doRef()
1 by mental
moving trunk for module inkscape
587
{
9546.1.1 by Abhishek Sharma Public
This is the first c++ification commit from me. It handles sp-line, sp-polyline, sp-item and marks the onset of document c++ification as well. Users can check performace increase with [/usr/bin/time -v inkscape_binary_with_commandline_options].
588
    Inkscape::GC::anchor(this);
589
    return this;
1 by mental
moving trunk for module inkscape
590
}
591
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
592
SPDocument *SPDocument::doUnref()
1 by mental
moving trunk for module inkscape
593
{
9546.1.1 by Abhishek Sharma Public
This is the first c++ification commit from me. It handles sp-line, sp-polyline, sp-item and marks the onset of document c++ification as well. Users can check performace increase with [/usr/bin/time -v inkscape_binary_with_commandline_options].
594
    Inkscape::GC::release(this);
1 by mental
moving trunk for module inkscape
595
    return NULL;
596
}
597
12717 by Johan B. C. Engelen
fix bug "some of the locale-based templates cause objects to be resized when default units are changed" #1236257
598
/// guaranteed not to return nullptr
13774 by tavmjong-free
Change getDefaultUnit() to getDisplayUnit() to better reflect value returned by function.
599
Inkscape::Util::Unit const* SPDocument::getDisplayUnit() const
12717 by Johan B. C. Engelen
fix bug "some of the locale-based templates cause objects to be resized when default units are changed" #1236257
600
{
601
    SPNamedView const* nv = sp_document_namedview(this, NULL);
13774 by tavmjong-free
Change getDefaultUnit() to getDisplayUnit() to better reflect value returned by function.
602
    return nv ? nv->getDisplayUnit() : unit_table.getUnit("px");
12717 by Johan B. C. Engelen
fix bug "some of the locale-based templates cause objects to be resized when default units are changed" #1236257
603
}
604
13751 by Johan B. C. Engelen
Units: make it absolutely clear that Document properties unit dropdown is for UI Display Units. Upon document load, calculate the units used for SVG values, if a viewbox is available. If not, default to "px" SVG units.
605
/// guaranteed not to return nullptr
606
// returns 'px' units as default, like legacy Inkscape
13843 by tavmjong-free
Add getDocumentScale() to return "real-world" to "user-unit" scale factor.
607
// THIS SHOULD NOT BE USED... INSTEAD USE DOCUMENT SCALE
13751 by Johan B. C. Engelen
Units: make it absolutely clear that Document properties unit dropdown is for UI Display Units. Upon document load, calculate the units used for SVG values, if a viewbox is available. If not, default to "px" SVG units.
608
Inkscape::Util::Unit const& SPDocument::getSVGUnit() const
609
{
610
    SPNamedView const* nv = sp_document_namedview(this, NULL);
611
    return nv ? nv->getSVGUnit() : *unit_table.getUnit("px");
612
}
613
13843 by tavmjong-free
Add getDocumentScale() to return "real-world" to "user-unit" scale factor.
614
/// Returns document scale as defined by width/height and viewBox (real world to user-units).
615
Geom::Scale SPDocument::getDocumentScale() const
616
{
617
    Geom::Scale scale;
618
    if( root->viewBox_set ) {
619
        double scale_x = 1.0;
620
        double scale_y = 1.0;
621
        if( root->viewBox.width() > 0.0 ) {
622
            scale_x = root->width.computed / root->viewBox.width();
623
        }
624
        if( root->viewBox.height() > 0.0 ) {
625
            scale_y = root->height.computed / root->viewBox.height();
626
        }
627
        scale = Geom::Scale(scale_x, scale_y);
628
    }
629
    // std::cout << "SPDocument::getDocumentScale():\n" << scale << std::endl;
630
    return scale;
631
}
632
13837 by tavmjong-free
Avoid calling root->updateRepr() twice when changing width and height.
633
// Avoid calling root->updateRepr() twice by combining setting width and height.
634
// (As done on every delete as clipboard calls this via fitToRect(). Also called in page-sizer.cpp)
635
void SPDocument::setWidthAndHeight(const Inkscape::Util::Quantity &width, const Inkscape::Util::Quantity &height, bool changeSize)
636
{
637
    Inkscape::Util::Unit const *old_width_units = unit_table.getUnit("px");
638
    if (root->width.unit)
639
        old_width_units = unit_table.getUnit(root->width.unit);
640
    gdouble old_width_converted = Inkscape::Util::Quantity::convert(root->width.value, old_width_units, width.unit);
641
642
    root->width.computed = width.value("px");
643
    root->width.value = width.quantity;
644
    root->width.unit = (SVGLength::Unit) width.unit->svgUnit();
645
646
    Inkscape::Util::Unit const *old_height_units = unit_table.getUnit("px");
647
    if (root->height.unit)
648
        old_height_units = unit_table.getUnit(root->height.unit);
649
    gdouble old_height_converted = Inkscape::Util::Quantity::convert(root->height.value, old_height_units, height.unit);
650
651
    root->height.computed = height.value("px");
652
    root->height.value = height.quantity;
653
    root->height.unit = (SVGLength::Unit) height.unit->svgUnit();
654
655
    if (root->viewBox_set && changeSize)
656
        root->viewBox.setMax(Geom::Point(
657
        root->viewBox.left() + (root->width.value /  old_width_converted ) * root->viewBox.width(),
658
        root->viewBox.top()  + (root->height.value / old_height_converted) * root->viewBox.height()));
659
    root->updateRepr();
660
}
661
12475.1.2 by Matthew Petroff
Added viewBox implement document unit support.
662
Inkscape::Util::Quantity SPDocument::getWidth() const
1 by mental
moving trunk for module inkscape
663
{
12679 by Johan B. C. Engelen
Units: stop newing Unit objects. pass around pointers to "undeletable" Unit objects in the UnitTable. I think we should move to using indexed units, and pass around the index of the unit in the unittable, or smth like that... ?
664
    g_return_val_if_fail(this->priv != NULL, Inkscape::Util::Quantity(0.0, unit_table.getUnit("")));
665
    g_return_val_if_fail(this->root != NULL, Inkscape::Util::Quantity(0.0, unit_table.getUnit("")));
1 by mental
moving trunk for module inkscape
666
12475.1.2 by Matthew Petroff
Added viewBox implement document unit support.
667
    gdouble result = root->width.value;
668
    SVGLength::Unit u = root->width.unit;
10254 by Jon A. Cruz
Removed outdated/unsafe SP_DOCUMENT_DEFS macro and reduced usage of SP_ROOT() gtk type function/macro.
669
    if (root->width.unit == SVGLength::PERCENT && root->viewBox_set) {
10582.1.5 by Krzysztof Kosinski
Remove all NRRect use.
670
        result = root->viewBox.width();
12577 by Matthew Petroff
Fix percentage document size handling.
671
        u = SVGLength::PX;
10254 by Jon A. Cruz
Removed outdated/unsafe SP_DOCUMENT_DEFS macro and reduced usage of SP_ROOT() gtk type function/macro.
672
    }
12475.1.2 by Matthew Petroff
Added viewBox implement document unit support.
673
    if (u == SVGLength::NONE) {
674
        u = SVGLength::PX;
675
    }
676
    return Inkscape::Util::Quantity(result, unit_table.getUnit(u));
1 by mental
moving trunk for module inkscape
677
}
678
13776 by apenner
avoid recalculating viewbox if it is not necessary. (Bug 1384915, comment 24)
679
void SPDocument::setWidth(const Inkscape::Util::Quantity &width, bool changeSize)
1 by mental
moving trunk for module inkscape
680
{
13632 by apenner
use double precision Quantity::convert for units conversion in viewBox, instead of single-precision SVGLength.computed.
681
    Inkscape::Util::Unit const *old_units = unit_table.getUnit("px");
682
    if (root->width.unit)
683
        old_units = unit_table.getUnit(root->width.unit);
684
    gdouble old_converted = Inkscape::Util::Quantity::convert(root->width.value, old_units, width.unit);
13758 by tavmjong-free
Move 'm' handling code from document.cpp to svg-length.cpp and units.cpp to match handling of 'ft'.
685
12577 by Matthew Petroff
Fix percentage document size handling.
686
    root->width.computed = width.value("px");
13758 by tavmjong-free
Move 'm' handling code from document.cpp to svg-length.cpp and units.cpp to match handling of 'ft'.
687
    root->width.value = width.quantity;
688
    root->width.unit = (SVGLength::Unit) width.unit->svgUnit();
1 by mental
moving trunk for module inkscape
689
13776 by apenner
avoid recalculating viewbox if it is not necessary. (Bug 1384915, comment 24)
690
    if (root->viewBox_set && changeSize)
13632 by apenner
use double precision Quantity::convert for units conversion in viewBox, instead of single-precision SVGLength.computed.
691
        root->viewBox.setMax(Geom::Point(root->viewBox.left() + (root->width.value / old_converted) * root->viewBox.width(), root->viewBox.bottom()));
12577 by Matthew Petroff
Fix percentage document size handling.
692
10059 by Jon A. Cruz
Pass removing some outdated C-macro use.
693
    root->updateRepr();
1 by mental
moving trunk for module inkscape
694
}
695
12971 by Martin Owens
Move sub-document reference creation code from uri-reference to document.cpp as createChildDoc(path)
696
12475.1.2 by Matthew Petroff
Added viewBox implement document unit support.
697
Inkscape::Util::Quantity SPDocument::getHeight() const
10582.1.5 by Krzysztof Kosinski
Remove all NRRect use.
698
{
12679 by Johan B. C. Engelen
Units: stop newing Unit objects. pass around pointers to "undeletable" Unit objects in the UnitTable. I think we should move to using indexed units, and pass around the index of the unit in the unittable, or smth like that... ?
699
    g_return_val_if_fail(this->priv != NULL, Inkscape::Util::Quantity(0.0, unit_table.getUnit("")));
700
    g_return_val_if_fail(this->root != NULL, Inkscape::Util::Quantity(0.0, unit_table.getUnit("")));
10582.1.5 by Krzysztof Kosinski
Remove all NRRect use.
701
12475.1.2 by Matthew Petroff
Added viewBox implement document unit support.
702
    gdouble result = root->height.value;
703
    SVGLength::Unit u = root->height.unit;
10582.1.5 by Krzysztof Kosinski
Remove all NRRect use.
704
    if (root->height.unit == SVGLength::PERCENT && root->viewBox_set) {
705
        result = root->viewBox.height();
12577 by Matthew Petroff
Fix percentage document size handling.
706
        u = SVGLength::PX;
10582.1.5 by Krzysztof Kosinski
Remove all NRRect use.
707
    }
12475.1.2 by Matthew Petroff
Added viewBox implement document unit support.
708
    if (u == SVGLength::NONE) {
709
        u = SVGLength::PX;
710
    }
711
    return Inkscape::Util::Quantity(result, unit_table.getUnit(u));
10582.1.5 by Krzysztof Kosinski
Remove all NRRect use.
712
}
713
13776 by apenner
avoid recalculating viewbox if it is not necessary. (Bug 1384915, comment 24)
714
void SPDocument::setHeight(const Inkscape::Util::Quantity &height, bool changeSize)
1 by mental
moving trunk for module inkscape
715
{
13632 by apenner
use double precision Quantity::convert for units conversion in viewBox, instead of single-precision SVGLength.computed.
716
    Inkscape::Util::Unit const *old_units = unit_table.getUnit("px");
717
    if (root->height.unit)
718
        old_units = unit_table.getUnit(root->height.unit);
719
    gdouble old_converted = Inkscape::Util::Quantity::convert(root->height.value, old_units, height.unit);
13758 by tavmjong-free
Move 'm' handling code from document.cpp to svg-length.cpp and units.cpp to match handling of 'ft'.
720
12577 by Matthew Petroff
Fix percentage document size handling.
721
    root->height.computed = height.value("px");
13758 by tavmjong-free
Move 'm' handling code from document.cpp to svg-length.cpp and units.cpp to match handling of 'ft'.
722
    root->height.value = height.quantity;
723
    root->height.unit = (SVGLength::Unit) height.unit->svgUnit();
1 by mental
moving trunk for module inkscape
724
13776 by apenner
avoid recalculating viewbox if it is not necessary. (Bug 1384915, comment 24)
725
    if (root->viewBox_set && changeSize)
13632 by apenner
use double precision Quantity::convert for units conversion in viewBox, instead of single-precision SVGLength.computed.
726
        root->viewBox.setMax(Geom::Point(root->viewBox.right(), root->viewBox.top() + (root->height.value / old_converted) * root->viewBox.height()));
12577 by Matthew Petroff
Fix percentage document size handling.
727
10059 by Jon A. Cruz
Pass removing some outdated C-macro use.
728
    root->updateRepr();
1 by mental
moving trunk for module inkscape
729
}
730
12475.1.2 by Matthew Petroff
Added viewBox implement document unit support.
731
void SPDocument::setViewBox(const Geom::Rect &viewBox)
732
{
733
    root->viewBox_set = true;
734
    root->viewBox = viewBox;
735
    root->updateRepr();
736
}
737
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
738
Geom::Point SPDocument::getDimensions() const
6891 by Ted Gould
Merge from fe-moved
739
{
12475.1.2 by Matthew Petroff
Added viewBox implement document unit support.
740
    return Geom::Point(getWidth().value("px"), getHeight().value("px"));
8952 by Josh Andler
Patch by Alex Leone to add margins to resize page options in Document Properties
741
}
742
12411 by Martin Owens
Small refactor of align and distribute to reduce complexity.
743
Geom::OptRect SPDocument::preferredBounds() const
744
{
745
    return Geom::OptRect( Geom::Point(0, 0), getDimensions() );
746
}
747
8952 by Josh Andler
Patch by Alex Leone to add margins to resize page options in Document Properties
748
/**
6840 by cilix42
Yet another NR ==> Geom change
749
 * Given a Geom::Rect that may, for example, correspond to the bbox of an object,
539 by acspike
Adding fit canvas verbs
750
 * this function fits the canvas to that rect by resizing the canvas
751
 * and translating the document root into position.
8952 by Josh Andler
Patch by Alex Leone to add margins to resize page options in Document Properties
752
 * \param rect fit document size to this
753
 * \param with_margins add margins to rect, by taking margins from this
754
 *        document's namedview (<sodipodi:namedview> "fit-margin-..."
755
 *        attributes, and "units")
539 by acspike
Adding fit canvas verbs
756
 */
8952 by Josh Andler
Patch by Alex Leone to add margins to resize page options in Document Properties
757
void SPDocument::fitToRect(Geom::Rect const &rect, bool with_margins)
539 by acspike
Adding fit canvas verbs
758
{
6839 by cilix42
Next roud of NR ==> Geom conversion
759
    double const w = rect.width();
760
    double const h = rect.height();
3032 by pjrm
noop: Change fitToRect to take NR::Rect instead of old NRRect. Update callers.
761
12475.1.2 by Matthew Petroff
Added viewBox implement document unit support.
762
    double const old_height = getHeight().value("px");
13590 by apenner
maintain page size units when resizing page to drawing (Bug 1310787)
763
    Inkscape::Util::Unit const *nv_units = unit_table.getUnit("px");
13715 by apenner
in rev 13590, use 'root->height.unit' instead of namedview 'units'.
764
    if (root->height.unit)
765
        nv_units = unit_table.getUnit(root->height.unit);
13590 by apenner
maintain page size units when resizing page to drawing (Bug 1310787)
766
    SPNamedView *nv = sp_document_namedview(this, NULL);
8952 by Josh Andler
Patch by Alex Leone to add margins to resize page options in Document Properties
767
    
768
    /* in px */
769
    double margin_top = 0.0;
770
    double margin_left = 0.0;
771
    double margin_right = 0.0;
772
    double margin_bottom = 0.0;
773
    
774
    if (with_margins && nv) {
9546.1.12 by Abhishek Sharma public
XML Privatisation Stuff after a long time
775
        if (nv != NULL) {
13590 by apenner
maintain page size units when resizing page to drawing (Bug 1310787)
776
            margin_top = nv->getMarginLength("fit-margin-top", nv_units, unit_table.getUnit("px"), w, h, false);
777
            margin_left = nv->getMarginLength("fit-margin-left", nv_units, unit_table.getUnit("px"), w, h, true);
778
            margin_right = nv->getMarginLength("fit-margin-right", nv_units, unit_table.getUnit("px"), w, h, true);
779
            margin_bottom = nv->getMarginLength("fit-margin-bottom", nv_units, unit_table.getUnit("px"), w, h, false);
780
            margin_top = Inkscape::Util::Quantity::convert(margin_top, nv_units, "px");
781
            margin_left = Inkscape::Util::Quantity::convert(margin_left, nv_units, "px");
782
            margin_right = Inkscape::Util::Quantity::convert(margin_right, nv_units, "px");
783
            margin_bottom = Inkscape::Util::Quantity::convert(margin_bottom, nv_units, "px");
8952 by Josh Andler
Patch by Alex Leone to add margins to resize page options in Document Properties
784
        }
785
    }
786
    
787
    Geom::Rect const rect_with_margins(
9298 by Krzysztof Kosiński
Revert the inverted coordinate system fix. 3D Boxes and guides
788
            rect.min() - Geom::Point(margin_left, margin_bottom),
789
            rect.max() + Geom::Point(margin_right, margin_top));
8952 by Josh Andler
Patch by Alex Leone to add margins to resize page options in Document Properties
790
    
13837 by tavmjong-free
Avoid calling root->updateRepr() twice when changing width and height.
791
    setWidthAndHeight(
792
        Inkscape::Util::Quantity(Inkscape::Util::Quantity::convert(rect_with_margins.width(),  "px", nv_units), nv_units),
793
        Inkscape::Util::Quantity(Inkscape::Util::Quantity::convert(rect_with_margins.height(), "px", nv_units), nv_units)
794
        );
3032 by pjrm
noop: Change fitToRect to take NR::Rect instead of old NRRect. Update callers.
795
9298 by Krzysztof Kosiński
Revert the inverted coordinate system fix. 3D Boxes and guides
796
    Geom::Translate const tr(
797
            Geom::Point(0, old_height - rect_with_margins.height())
10347.1.2 by Krzysztof Kosiński
Remove more of libnr
798
            - rect_with_margins.min());
10254 by Jon A. Cruz
Removed outdated/unsafe SP_DOCUMENT_DEFS macro and reduced usage of SP_ROOT() gtk type function/macro.
799
    root->translateChildItems(tr);
8952 by Josh Andler
Patch by Alex Leone to add margins to resize page options in Document Properties
800
5771 by sasilver
wrtlprnft's patch for bug 234834 - keeps guidelines in same position relative to objects when doing "Fit page to selection", and also keeps the objects in the same position on the screen
801
    if(nv) {
8952 by Josh Andler
Patch by Alex Leone to add margins to resize page options in Document Properties
802
        Geom::Translate tr2(-rect_with_margins.min());
5771 by sasilver
wrtlprnft's patch for bug 234834 - keeps guidelines in same position relative to objects when doing "Fit page to selection", and also keeps the objects in the same position on the screen
803
        nv->translateGuides(tr2);
10787 by Johan Engelen
when resizing page, move the origin of the grids too. This way all objects will stay aligned to the grids.
804
        nv->translateGrids(tr2);
5771 by sasilver
wrtlprnft's patch for bug 234834 - keeps guidelines in same position relative to objects when doing "Fit page to selection", and also keeps the objects in the same position on the screen
805
806
        // update the viewport so the drawing appears to stay where it was
9298 by Krzysztof Kosiński
Revert the inverted coordinate system fix. 3D Boxes and guides
807
        nv->scrollAllDesktops(-tr2[0], tr2[1], false);
5771 by sasilver
wrtlprnft's patch for bug 234834 - keeps guidelines in same position relative to objects when doing "Fit page to selection", and also keeps the objects in the same position on the screen
808
    }
539 by acspike
Adding fit canvas verbs
809
}
810
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
811
void SPDocument::setBase( gchar const* base )
1 by mental
moving trunk for module inkscape
812
{
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
813
    if (this->base) {
814
        g_free(this->base);
13104 by Johan B. C. Engelen
code cleanup
815
        this->base = NULL;
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
816
    }
817
    if (base) {
818
        this->base = g_strdup(base);
819
    }
820
}
1 by mental
moving trunk for module inkscape
821
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
822
void SPDocument::do_change_uri(gchar const *const filename, bool const rebase)
823
{
13104 by Johan B. C. Engelen
code cleanup
824
    gchar *new_base = NULL;
825
    gchar *new_name = NULL;
826
    gchar *new_uri = NULL;
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
827
    if (filename) {
1 by mental
moving trunk for module inkscape
828
829
#ifndef WIN32
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
830
        new_uri = prepend_current_dir_if_relative(filename);
1 by mental
moving trunk for module inkscape
831
#else
832
        // FIXME: it may be that prepend_current_dir_if_relative works OK on windows too, test!
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
833
        new_uri = g_strdup(filename);
1 by mental
moving trunk for module inkscape
834
#endif
835
7659 by pjrm
oops, fix a bug in that last commit (revealed by eps import; I don't think this bug occurred with skencil import).
836
        new_base = g_path_get_dirname(new_uri);
837
        new_name = g_path_get_basename(new_uri);
1 by mental
moving trunk for module inkscape
838
    } else {
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
839
        new_uri = g_strdup_printf(_("Unnamed document %d"), ++doc_count);
840
        new_base = NULL;
9546.1.3 by Abhishek Sharma Public
New Class SPDocumentUndo created which takes care of c++fying some non SPDocument based methods
841
        new_name = g_strdup(this->uri);
1 by mental
moving trunk for module inkscape
842
    }
843
844
    // Update saveable repr attributes.
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
845
    Inkscape::XML::Node *repr = getReprRoot();
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
846
847
    // Changing uri in the document repr must not be not undoable.
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
848
    bool const saved = DocumentUndo::getUndoSensitive(this);
849
    DocumentUndo::setUndoSensitive(this, false);
1 by mental
moving trunk for module inkscape
850
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
851
    if (rebase) {
9546.1.3 by Abhishek Sharma Public
New Class SPDocumentUndo created which takes care of c++fying some non SPDocument based methods
852
        Inkscape::XML::rebase_hrefs(this, new_base, true);
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
853
    }
854
11574 by apenner
do not allow sodipodi:docname to have a temporary filename (partial fix for Bug 243162)
855
    if (strncmp(new_name, "ink_ext_XXXXXX", 14))	// do not use temporary filenames
856
        repr->setAttribute("sodipodi:docname", new_name);
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
857
    DocumentUndo::setUndoSensitive(this, saved);
9546.1.3 by Abhishek Sharma Public
New Class SPDocumentUndo created which takes care of c++fying some non SPDocument based methods
858
859
860
    g_free(this->name);
861
    g_free(this->base);
862
    g_free(this->uri);
863
    this->name = new_name;
864
    this->base = new_base;
865
    this->uri = new_uri;
866
867
    this->priv->uri_set_signal.emit(this->uri);
1 by mental
moving trunk for module inkscape
868
}
869
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
870
/**
871
 * Sets base, name and uri members of \a document.  Doesn't update
872
 * any relative hrefs in the document: thus, this is primarily for
873
 * newly-created documents.
874
 *
875
 * \see sp_document_change_uri_and_hrefs
876
 */
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
877
void SPDocument::setUri(gchar const *filename)
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
878
{
9546.1.3 by Abhishek Sharma Public
New Class SPDocumentUndo created which takes care of c++fying some non SPDocument based methods
879
    do_change_uri(filename, false);
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
880
}
8029 by joncruz
Removed sodipodi:version
881
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
882
/**
883
 * Changes the base, name and uri members of \a document, and updates any
884
 * relative hrefs in the document to be relative to the new base.
885
 *
886
 * \see sp_document_set_uri
887
 */
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
888
void SPDocument::changeUriAndHrefs(gchar const *filename)
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
889
{
9546.1.3 by Abhishek Sharma Public
New Class SPDocumentUndo created which takes care of c++fying some non SPDocument based methods
890
    do_change_uri(filename, true);
7654 by pjrm
sp_document_change_uri_and_hrefs: New function.
891
}
892
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
893
void SPDocument::emitResizedSignal(gdouble width, gdouble height)
1 by mental
moving trunk for module inkscape
894
{
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
895
    this->priv->resized_signal.emit(width, height);
1 by mental
moving trunk for module inkscape
896
}
897
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
898
sigc::connection SPDocument::connectModified(SPDocument::ModifiedSignal::slot_type slot)
1 by mental
moving trunk for module inkscape
899
{
900
    return priv->modified_signal.connect(slot);
901
}
902
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
903
sigc::connection SPDocument::connectURISet(SPDocument::URISetSignal::slot_type slot)
1 by mental
moving trunk for module inkscape
904
{
905
    return priv->uri_set_signal.connect(slot);
906
}
907
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
908
sigc::connection SPDocument::connectResized(SPDocument::ResizedSignal::slot_type slot)
1 by mental
moving trunk for module inkscape
909
{
910
    return priv->resized_signal.connect(slot);
911
}
912
913
sigc::connection
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
914
SPDocument::connectReconstructionStart(SPDocument::ReconstructionStart::slot_type slot)
1 by mental
moving trunk for module inkscape
915
{
916
    return priv->_reconstruction_start_signal.connect(slot);
917
}
918
919
void
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
920
SPDocument::emitReconstructionStart(void)
1 by mental
moving trunk for module inkscape
921
{
922
    // printf("Starting Reconstruction\n");
923
    priv->_reconstruction_start_signal.emit();
924
    return;
925
}
926
927
sigc::connection
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
928
SPDocument::connectReconstructionFinish(SPDocument::ReconstructionFinish::slot_type  slot)
1 by mental
moving trunk for module inkscape
929
{
930
    return priv->_reconstruction_finish_signal.connect(slot);
931
}
932
933
void
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
934
SPDocument::emitReconstructionFinish(void)
1 by mental
moving trunk for module inkscape
935
{
936
    // printf("Finishing Reconstruction\n");
937
    priv->_reconstruction_finish_signal.emit();
8910 by Maximilian Albert
Refactoring of 3D box tool, mainly to avoid unnecessary creation of perspectives.
938
939
/**    
8712 by scislac
Patch to fix 205667 by Petteri Aimonen
940
    // Reference to the old persp3d object is invalid after reconstruction.
941
    initialize_current_persp3d();
942
    
1 by mental
moving trunk for module inkscape
943
    return;
8910 by Maximilian Albert
Refactoring of 3D box tool, mainly to avoid unnecessary creation of perspectives.
944
**/
1 by mental
moving trunk for module inkscape
945
}
946
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
947
sigc::connection SPDocument::connectCommit(SPDocument::CommitSignal::slot_type slot)
1458 by johncoswell
Forced redraw of canvas upon document commit to work around event starvation issue at high zoom levels
948
{
949
    return priv->commit_signal.connect(slot);
950
}
951
952
1 by mental
moving trunk for module inkscape
953
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
954
void SPDocument::_emitModified() {
1 by mental
moving trunk for module inkscape
955
    static guint const flags = SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_CHILD_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG;
956
    root->emitModified(0);
957
    priv->modified_signal.emit(flags);
958
}
959
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
960
void SPDocument::bindObjectToId(gchar const *id, SPObject *object) {
1 by mental
moving trunk for module inkscape
961
    GQuark idq = g_quark_from_string(id);
962
963
    if (object) {
964
        g_assert(g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)) == NULL);
965
        g_hash_table_insert(priv->iddef, GINT_TO_POINTER(idq), object);
966
    } else {
967
        g_assert(g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq)) != NULL);
968
        g_hash_table_remove(priv->iddef, GINT_TO_POINTER(idq));
969
    }
970
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
971
    SPDocumentPrivate::IDChangedSignalMap::iterator pos;
1 by mental
moving trunk for module inkscape
972
973
    pos = priv->id_changed_signals.find(idq);
974
    if ( pos != priv->id_changed_signals.end() ) {
975
        if (!(*pos).second.empty()) {
976
            (*pos).second.emit(object);
977
        } else { // discard unused signal
978
            priv->id_changed_signals.erase(pos);
979
        }
980
    }
981
}
982
983
void
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
984
SPDocument::addUndoObserver(Inkscape::UndoStackObserver& observer)
1 by mental
moving trunk for module inkscape
985
{
4838 by joncruz
Warning and whitespace cleanup
986
    this->priv->undoStackObservers.add(observer);
1 by mental
moving trunk for module inkscape
987
}
988
989
void
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
990
SPDocument::removeUndoObserver(Inkscape::UndoStackObserver& observer)
1 by mental
moving trunk for module inkscape
991
{
4838 by joncruz
Warning and whitespace cleanup
992
    this->priv->undoStackObservers.remove(observer);
1 by mental
moving trunk for module inkscape
993
}
994
10521 by Jon A. Cruz
Added overload for getObjectById(). Added safety by zeroing out invalid points (prevents accidental use of stale pointers).
995
SPObject *SPDocument::getObjectById(Glib::ustring const &id) const
996
{
12058 by Kris
revert my revision 12053 (Bug #1103248 )
997
    return getObjectById( id.c_str() );
10521 by Jon A. Cruz
Added overload for getObjectById(). Added safety by zeroing out invalid points (prevents accidental use of stale pointers).
998
}
999
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1000
SPObject *SPDocument::getObjectById(gchar const *id) const
1001
{
1 by mental
moving trunk for module inkscape
1002
    g_return_val_if_fail(id != NULL, NULL);
11673 by John Smith
Fix for 1051434 : occasional crash when selecting disjoint path with markers
1003
    if (!priv || !priv->iddef) {
1004
    	return NULL;
1005
    }
1 by mental
moving trunk for module inkscape
1006
1007
    GQuark idq = g_quark_from_string(id);
10114 by JazzyNico
D-Bus. Merging branch lp:~joakim-verona/inkscape/dbus-fixes (Bug #666986, Bug #707054 and Bug #707364).
1008
    gpointer rv = g_hash_table_lookup(priv->iddef, GINT_TO_POINTER(idq));
1009
    if(rv != NULL)
11052 by Kris
cppcheck
1010
    {
1011
        return static_cast<SPObject*>(rv);
1012
    }
10114 by JazzyNico
D-Bus. Merging branch lp:~joakim-verona/inkscape/dbus-fixes (Bug #666986, Bug #707054 and Bug #707364).
1013
    else
11052 by Kris
cppcheck
1014
    {
10114 by JazzyNico
D-Bus. Merging branch lp:~joakim-verona/inkscape/dbus-fixes (Bug #666986, Bug #707054 and Bug #707364).
1015
        return NULL;
11052 by Kris
cppcheck
1016
    }
1 by mental
moving trunk for module inkscape
1017
}
1018
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
1019
sigc::connection SPDocument::connectIdChanged(gchar const *id,
1020
                                              SPDocument::IDChangedSignal::slot_type slot)
1 by mental
moving trunk for module inkscape
1021
{
1022
    return priv->id_changed_signals[g_quark_from_string(id)].connect(slot);
1023
}
1024
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1025
void SPDocument::bindObjectToRepr(Inkscape::XML::Node *repr, SPObject *object)
1026
{
1 by mental
moving trunk for module inkscape
1027
    if (object) {
1028
        g_assert(g_hash_table_lookup(priv->reprdef, repr) == NULL);
1029
        g_hash_table_insert(priv->reprdef, repr, object);
1030
    } else {
1031
        g_assert(g_hash_table_lookup(priv->reprdef, repr) != NULL);
1032
        g_hash_table_remove(priv->reprdef, repr);
1033
    }
1034
}
1035
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1036
SPObject *SPDocument::getObjectByRepr(Inkscape::XML::Node *repr) const
1037
{
1 by mental
moving trunk for module inkscape
1038
    g_return_val_if_fail(repr != NULL, NULL);
11052 by Kris
cppcheck
1039
    return static_cast<SPObject*>(g_hash_table_lookup(priv->reprdef, repr));
1 by mental
moving trunk for module inkscape
1040
}
1041
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1042
Glib::ustring SPDocument::getLanguage() const
1043
{
556 by knutux
SVG 1.1 Conditional Processing Module rendering support (<switch> element, requiredReatures/requiredExtensions/systemLanguage attributes).
1044
    gchar const *document_language = rdf_get_work_entity(this, rdf_find_entity("language"));
1045
    if (document_language) {
1046
        while (isspace(*document_language))
1047
            document_language++;
1048
    }
1049
    if ( !document_language || 0 == *document_language) {
1050
        // retrieve system language
1051
        document_language = getenv("LC_ALL");
1052
        if ( NULL == document_language || *document_language == 0 ) {
1053
            document_language = getenv ("LC_MESSAGES");
1054
        }
1055
        if ( NULL == document_language || *document_language == 0 ) {
1056
            document_language = getenv ("LANG");
1057
        }
12809 by JazzyNico
Add command line support for EMF and WMF export, by David Mathog.
1058
        if ( NULL == document_language || *document_language == 0 ) {
1059
            document_language = getenv ("LANGUAGE");
1060
        }
1061
        
556 by knutux
SVG 1.1 Conditional Processing Module rendering support (<switch> element, requiredReatures/requiredExtensions/systemLanguage attributes).
1062
        if ( NULL != document_language ) {
7380 by tweenk
Patch from Lubomir Rintel: fixes for GCC 4.4
1063
            const char *pos = strchr(document_language, '_');
556 by knutux
SVG 1.1 Conditional Processing Module rendering support (<switch> element, requiredReatures/requiredExtensions/systemLanguage attributes).
1064
            if ( NULL != pos ) {
1065
                return Glib::ustring(document_language, pos - document_language);
1066
            }
1067
        }
1068
    }
1069
1070
    if ( NULL == document_language )
1071
        return Glib::ustring();
1072
    return document_language;
1073
}
1074
1 by mental
moving trunk for module inkscape
1075
/* Object modification root handler */
1076
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1077
void SPDocument::requestModified()
1 by mental
moving trunk for module inkscape
1078
{
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1079
    if (!modified_id) {
1080
        modified_id = g_idle_add_full(SP_DOCUMENT_UPDATE_PRIORITY, 
1081
                sp_document_idle_handler, this, NULL);
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
1082
    }
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1083
    if (!rerouting_handler_id) {
1084
        rerouting_handler_id = g_idle_add_full(SP_DOCUMENT_REROUTING_PRIORITY, 
1085
                sp_document_rerouting_handler, this, NULL);
1 by mental
moving trunk for module inkscape
1086
    }
1087
}
1088
10254 by Jon A. Cruz
Removed outdated/unsafe SP_DOCUMENT_DEFS macro and reduced usage of SP_ROOT() gtk type function/macro.
1089
void SPDocument::setupViewport(SPItemCtx *ctx)
1 by mental
moving trunk for module inkscape
1090
{
12222 by Alex Valavanis
Fix -Wcast-align issues with SPItemCtx
1091
    ctx->flags = 0;
6840 by cilix42
Yet another NR ==> Geom change
1092
    ctx->i2doc = Geom::identity();
10254 by Jon A. Cruz
Removed outdated/unsafe SP_DOCUMENT_DEFS macro and reduced usage of SP_ROOT() gtk type function/macro.
1093
    // Set up viewport in case svg has it defined as percentages
1094
    if (root->viewBox_set) { // if set, take from viewBox
10582.1.5 by Krzysztof Kosinski
Remove all NRRect use.
1095
        ctx->viewport = root->viewBox;
1 by mental
moving trunk for module inkscape
1096
    } else { // as a last resort, set size to A4
12475.1.9 by Matthew Petroff
Improve code readability.
1097
        ctx->viewport = Geom::Rect::from_xywh(0, 0, Inkscape::Util::Quantity::convert(210, "mm", "px"), Inkscape::Util::Quantity::convert(297, "mm", "px"));
1 by mental
moving trunk for module inkscape
1098
    }
6840 by cilix42
Yet another NR ==> Geom change
1099
    ctx->i2vp = Geom::identity();
1 by mental
moving trunk for module inkscape
1100
}
1101
1441 by bryce
marker refactoring work
1102
/**
4838 by joncruz
Warning and whitespace cleanup
1103
 * Tries to update the document state based on the modified and
1441 by bryce
marker refactoring work
1104
 * "update required" flags, and return true if the document has
1105
 * been brought fully up to date.
1106
 */
1107
bool
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
1108
SPDocument::_updateDocument()
1441 by bryce
marker refactoring work
1109
{
1110
    /* Process updates */
1111
    if (this->root->uflags || this->root->mflags) {
1112
        if (this->root->uflags) {
1113
            SPItemCtx ctx;
10254 by Jon A. Cruz
Removed outdated/unsafe SP_DOCUMENT_DEFS macro and reduced usage of SP_ROOT() gtk type function/macro.
1114
            setupViewport(&ctx);
1441 by bryce
marker refactoring work
1115
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1116
            bool saved = DocumentUndo::getUndoSensitive(this);
1117
            DocumentUndo::setUndoSensitive(this, false);
1441 by bryce
marker refactoring work
1118
1119
            this->root->updateDisplay((SPCtx *)&ctx, 0);
1120
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1121
            DocumentUndo::setUndoSensitive(this, saved);
1441 by bryce
marker refactoring work
1122
        }
1123
        this->_emitModified();
1124
    }
1125
1126
    return !(this->root->uflags || this->root->mflags);
1127
}
1128
1129
1130
/**
1131
 * Repeatedly works on getting the document updated, since sometimes
1132
 * it takes more than one pass to get the document updated.  But it
1133
 * usually should not take more than a few loops, and certainly never
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
1134
 * more than 32 iterations.  So we bail out if we hit 32 iterations,
1441 by bryce
marker refactoring work
1135
 * since this typically indicates we're stuck in an update loop.
1136
 */
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1137
gint SPDocument::ensureUpToDate()
1 by mental
moving trunk for module inkscape
1138
{
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
1139
    // Bring the document up-to-date, specifically via the following:
1140
    //   1a) Process all document updates.
1141
    //   1b) When completed, process connector routing changes.
1142
    //   2a) Process any updates resulting from connector reroutings.
1143
    int counter = 32;
1144
    for (unsigned int pass = 1; pass <= 2; ++pass) {
1145
        // Process document updates.
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1146
        while (!_updateDocument()) {
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
1147
            if (counter == 0) {
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1148
                g_warning("More than 32 iteration while updating document '%s'", uri);
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
1149
                break;
1150
            }
1151
            counter--;
1152
        }
1153
        if (counter == 0)
1154
        {
1441 by bryce
marker refactoring work
1155
            break;
1156
        }
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
1157
1158
        // After updates on the first pass we get libavoid to process all the 
1159
        // changed objects and provide new routings.  This may cause some objects
1160
            // to be modified, hence the second update pass.
1161
        if (pass == 1) {
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1162
            router->processTransaction();
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
1163
        }
1 by mental
moving trunk for module inkscape
1164
    }
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
1165
    
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1166
    if (modified_id) {
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1167
        // Remove handler
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1168
        g_source_remove(modified_id);
1169
        modified_id = 0;
1 by mental
moving trunk for module inkscape
1170
    }
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1171
    if (rerouting_handler_id) {
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1172
        // Remove handler
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1173
        g_source_remove(rerouting_handler_id);
1174
        rerouting_handler_id = 0;
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
1175
    }
1441 by bryce
marker refactoring work
1176
    return counter>0;
1 by mental
moving trunk for module inkscape
1177
}
1178
1441 by bryce
marker refactoring work
1179
/**
1180
 * An idle handler to update the document.  Returns true if
1181
 * the document needs further updates.
1182
 */
1 by mental
moving trunk for module inkscape
1183
static gint
1184
sp_document_idle_handler(gpointer data)
1185
{
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
1186
    SPDocument *doc = static_cast<SPDocument *>(data);
13145 by mathog
Fix gradient position on document import (bug #1283193)
1187
    bool status = !doc->_updateDocument(); // method TRUE if it does NOT need further modification, so invert
1188
    if (!status) {
1441 by bryce
marker refactoring work
1189
        doc->modified_id = 0;
1 by mental
moving trunk for module inkscape
1190
    }
13145 by mathog
Fix gradient position on document import (bug #1283193)
1191
    return status;
1 by mental
moving trunk for module inkscape
1192
}
1193
8855 by Arcadie M. Cracan
Merge GSoC2009 Connectors into trunk
1194
/**
1195
 * An idle handler to reroute connectors in the document.  
1196
 */
1197
static gint
1198
sp_document_rerouting_handler(gpointer data)
1199
{
1200
    // Process any queued movement actions and determine new routings for 
1201
    // object-avoiding connectors.  Callbacks will be used to update and 
1202
    // redraw affected connectors.
1203
    SPDocument *doc = static_cast<SPDocument *>(data);
1204
    doc->router->processTransaction();
1205
    
1206
    // We don't need to handle rerouting again until there are further 
1207
    // diagram updates.
1208
    doc->rerouting_handler_id = 0;
1209
    return false;
1210
}
1211
6839 by cilix42
Next roud of NR ==> Geom conversion
1212
static bool is_within(Geom::Rect const &area, Geom::Rect const &box)
1 by mental
moving trunk for module inkscape
1213
{
1214
    return area.contains(box);
1215
}
1216
6839 by cilix42
Next roud of NR ==> Geom conversion
1217
static bool overlaps(Geom::Rect const &area, Geom::Rect const &box)
1 by mental
moving trunk for module inkscape
1218
{
1219
    return area.intersects(box);
1220
}
1221
6839 by cilix42
Next roud of NR ==> Geom conversion
1222
static GSList *find_items_in_area(GSList *s, SPGroup *group, unsigned int dkey, Geom::Rect const &area,
1223
                                  bool (*test)(Geom::Rect const &, Geom::Rect const &), bool take_insensitive = false)
1 by mental
moving trunk for module inkscape
1224
{
1225
    g_return_val_if_fail(SP_IS_GROUP(group), s);
1226
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1227
    for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) {
1228
        if ( SP_IS_ITEM(o) ) {
1229
            if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER ) {
1230
                s = find_items_in_area(s, SP_GROUP(o), dkey, area, test);
1231
            } else {
1232
                SPItem *child = SP_ITEM(o);
10582.1.1 by Krzysztof Kosinski
Refactor SPItem bounding box methods: remove NRRect usage and make code
1233
                Geom::OptRect box = child->desktopVisualBounds();
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1234
                if ( box && test(area, *box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) {
1235
                    s = g_slist_append(s, child);
1236
                }
1 by mental
moving trunk for module inkscape
1237
            }
1238
        }
1239
    }
1240
1241
    return s;
1242
}
1243
1244
/**
1245
Returns true if an item is among the descendants of group (recursively).
1246
 */
11735 by Campbell Barton
code cleanup: add own includes to cpp files or make the functions static if they are not used elsewhere.
1247
static bool item_is_in_group(SPItem *item, SPGroup *group)
1 by mental
moving trunk for module inkscape
1248
{
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1249
    bool inGroup = false;
1250
    for ( SPObject *o = group->firstChild() ; o && !inGroup; o = o->getNext() ) {
1251
        if ( SP_IS_ITEM(o) ) {
1252
            if (SP_ITEM(o) == item) {
1253
                inGroup = true;
1254
            } else if ( SP_IS_GROUP(o) ) {
1255
                inGroup = item_is_in_group(item, SP_GROUP(o));
1256
            }
1257
        }
1 by mental
moving trunk for module inkscape
1258
    }
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1259
    return inGroup;
1 by mental
moving trunk for module inkscape
1260
}
1261
12916 by Kris
pass class variables by reference for performance
1262
SPItem *SPDocument::getItemFromListAtPointBottom(unsigned int dkey, SPGroup *group, GSList const *list,Geom::Point const &p, bool take_insensitive)
1 by mental
moving trunk for module inkscape
1263
{
1264
    g_return_val_if_fail(group, NULL);
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1265
    SPItem *bottomMost = 0;
1266
6885 by Ted Gould
From trunk
1267
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
1268
    gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0);
1 by mental
moving trunk for module inkscape
1269
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1270
    for ( SPObject *o = group->firstChild() ; o && !bottomMost; o = o->getNext() ) {
1271
        if ( SP_IS_ITEM(o) ) {
1272
            SPItem *item = SP_ITEM(o);
10347.1.21 by Krzysztof Kosiński
Rewrite NRArenaItem hierarchy into C++
1273
            Inkscape::DrawingItem *arenaitem = item->get_arenaitem(dkey);
1274
            if (arenaitem && arenaitem->pick(p, delta, 1) != NULL
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1275
                && (take_insensitive || item->isVisibleAndUnlocked(dkey))) {
1276
                if (g_slist_find((GSList *) list, item) != NULL) {
1277
                    bottomMost = item;
1278
                }
1279
            }
1280
1281
            if ( !bottomMost && SP_IS_GROUP(o) ) {
1282
                // return null if not found:
1283
                bottomMost = getItemFromListAtPointBottom(dkey, SP_GROUP(o), list, p, take_insensitive);
1284
            }
1285
        }
1 by mental
moving trunk for module inkscape
1286
    }
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1287
    return bottomMost;
1 by mental
moving trunk for module inkscape
1288
}
1289
1290
/**
1291
Returns the topmost (in z-order) item from the descendants of group (recursively) which
1292
is at the point p, or NULL if none. Honors into_groups on whether to recurse into
1293
non-layer groups or not. Honors take_insensitive on whether to return insensitive
1294
items. If upto != NULL, then if item upto is encountered (at any level), stops searching
1295
upwards in z-order and returns what it has found so far (i.e. the found item is
1296
guaranteed to be lower than upto).
1297
 */
12916 by Kris
pass class variables by reference for performance
1298
static SPItem *find_item_at_point(unsigned int dkey, SPGroup *group, Geom::Point const &p, gboolean into_groups, bool take_insensitive = false, SPItem *upto = NULL)
1 by mental
moving trunk for module inkscape
1299
{
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1300
    SPItem *seen = NULL;
1301
    SPItem *newseen = NULL;
6885 by Ted Gould
From trunk
1302
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
1303
    gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0);
1 by mental
moving trunk for module inkscape
1304
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1305
    for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) {
1306
        if (!SP_IS_ITEM(o)) {
1307
            continue;
1308
        }
1 by mental
moving trunk for module inkscape
1309
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1310
        if (upto && SP_ITEM(o) == upto) {
1 by mental
moving trunk for module inkscape
1311
            break;
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1312
        }
1 by mental
moving trunk for module inkscape
1313
4838 by joncruz
Warning and whitespace cleanup
1314
        if (SP_IS_GROUP(o) && (SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) {
1 by mental
moving trunk for module inkscape
1315
            // if nothing found yet, recurse into the group
1316
            newseen = find_item_at_point(dkey, SP_GROUP(o), p, into_groups, take_insensitive, upto);
1317
            if (newseen) {
1318
                seen = newseen;
1319
                newseen = NULL;
1320
            }
1321
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1322
            if (item_is_in_group(upto, SP_GROUP(o))) {
1 by mental
moving trunk for module inkscape
1323
                break;
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1324
            }
1 by mental
moving trunk for module inkscape
1325
        } else {
1326
            SPItem *child = SP_ITEM(o);
10347.1.21 by Krzysztof Kosiński
Rewrite NRArenaItem hierarchy into C++
1327
            Inkscape::DrawingItem *arenaitem = child->get_arenaitem(dkey);
1 by mental
moving trunk for module inkscape
1328
1329
            // seen remembers the last (topmost) of items pickable at this point
10347.1.21 by Krzysztof Kosiński
Rewrite NRArenaItem hierarchy into C++
1330
            if (arenaitem && arenaitem->pick(p, delta, 1) != NULL
1 by mental
moving trunk for module inkscape
1331
                && (take_insensitive || child->isVisibleAndUnlocked(dkey))) {
1332
                seen = child;
1333
            }
1334
        }
1335
    }
1336
    return seen;
1337
}
1338
1339
/**
1340
Returns the topmost non-layer group from the descendants of group which is at point
1341
p, or NULL if none. Recurses into layers but not into groups.
1342
 */
12916 by Kris
pass class variables by reference for performance
1343
static SPItem *find_group_at_point(unsigned int dkey, SPGroup *group, Geom::Point const &p)
1 by mental
moving trunk for module inkscape
1344
{
1345
    SPItem *seen = NULL;
6885 by Ted Gould
From trunk
1346
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
1347
    gdouble delta = prefs->getDouble("/options/cursortolerance/value", 1.0);
1 by mental
moving trunk for module inkscape
1348
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1349
    for ( SPObject *o = group->firstChild() ; o ; o = o->getNext() ) {
1350
        if (!SP_IS_ITEM(o)) {
1351
            continue;
1352
        }
1 by mental
moving trunk for module inkscape
1353
        if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) == SPGroup::LAYER) {
1354
            SPItem *newseen = find_group_at_point(dkey, SP_GROUP(o), p);
1355
            if (newseen) {
1356
                seen = newseen;
1357
            }
1358
        }
1359
        if (SP_IS_GROUP(o) && SP_GROUP(o)->effectiveLayerMode(dkey) != SPGroup::LAYER ) {
1360
            SPItem *child = SP_ITEM(o);
10347.1.21 by Krzysztof Kosiński
Rewrite NRArenaItem hierarchy into C++
1361
            Inkscape::DrawingItem *arenaitem = child->get_arenaitem(dkey);
1 by mental
moving trunk for module inkscape
1362
1363
            // seen remembers the last (topmost) of groups pickable at this point
10347.1.21 by Krzysztof Kosiński
Rewrite NRArenaItem hierarchy into C++
1364
            if (arenaitem && arenaitem->pick(p, delta, 1) != NULL) {
1 by mental
moving trunk for module inkscape
1365
                seen = child;
1366
            }
1367
        }
1368
    }
1369
    return seen;
1370
}
1371
1372
/*
1373
 * Return list of items, contained in box
1374
 *
1375
 * Assumes box is normalized (and g_asserts it!)
1376
 *
1377
 */
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1378
GSList *SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect const &box) const
1 by mental
moving trunk for module inkscape
1379
{
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1380
    g_return_val_if_fail(this->priv != NULL, NULL);
1 by mental
moving trunk for module inkscape
1381
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1382
    return find_items_in_area(NULL, SP_GROUP(this->root), dkey, box, is_within);
1 by mental
moving trunk for module inkscape
1383
}
1384
1385
/*
1386
 * Return list of items, that the parts of the item contained in box
1387
 *
1388
 * Assumes box is normalized (and g_asserts it!)
1389
 *
1390
 */
1391
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1392
GSList *SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box) const
1 by mental
moving trunk for module inkscape
1393
{
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1394
    g_return_val_if_fail(this->priv != NULL, NULL);
1 by mental
moving trunk for module inkscape
1395
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1396
    return find_items_in_area(NULL, SP_GROUP(this->root), dkey, box, overlaps);
1 by mental
moving trunk for module inkscape
1397
}
1398
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1399
GSList *SPDocument::getItemsAtPoints(unsigned const key, std::vector<Geom::Point> points) const
2864 by buliabyak
add method to select objects picked by a vector of points
1400
{
1401
    GSList *items = NULL;
6885 by Ted Gould
From trunk
1402
    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
2864 by buliabyak
add method to select objects picked by a vector of points
1403
4838 by joncruz
Warning and whitespace cleanup
1404
    // When picking along the path, we don't want small objects close together
1405
    // (such as hatching strokes) to obscure each other by their deltas,
2864 by buliabyak
add method to select objects picked by a vector of points
1406
    // so we temporarily set delta to a small value
6885 by Ted Gould
From trunk
1407
    gdouble saved_delta = prefs->getDouble("/options/cursortolerance/value", 1.0);
1408
    prefs->setDouble("/options/cursortolerance/value", 0.25);
2864 by buliabyak
add method to select objects picked by a vector of points
1409
1410
    for(unsigned int i = 0; i < points.size(); i++) {
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1411
        SPItem *item = getItemAtPoint(key, points[i],
6839 by cilix42
Next roud of NR ==> Geom conversion
1412
                                                 false, NULL);
2864 by buliabyak
add method to select objects picked by a vector of points
1413
        if (item && !g_slist_find(items, item))
1414
            items = g_slist_prepend (items, item);
1415
    }
1416
1417
    // and now we restore it back
6885 by Ted Gould
From trunk
1418
    prefs->setDouble("/options/cursortolerance/value", saved_delta);
2864 by buliabyak
add method to select objects picked by a vector of points
1419
1420
    return items;
1421
}
1422
12916 by Kris
pass class variables by reference for performance
1423
SPItem *SPDocument::getItemAtPoint( unsigned const key, Geom::Point const &p,
13341.1.190 by Liam P. White
Header cleanup: stop using Glib types where they aren't truly needed. Eases GThread deprecation errors.
1424
                                    bool const into_groups, SPItem *upto) const
1 by mental
moving trunk for module inkscape
1425
{
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1426
    g_return_val_if_fail(this->priv != NULL, NULL);
1 by mental
moving trunk for module inkscape
1427
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1428
    return find_item_at_point(key, SP_GROUP(this->root), p, into_groups, false, upto);
1 by mental
moving trunk for module inkscape
1429
}
1430
12916 by Kris
pass class variables by reference for performance
1431
SPItem *SPDocument::getGroupAtPoint(unsigned int key, Geom::Point const &p) const
1 by mental
moving trunk for module inkscape
1432
{
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1433
    g_return_val_if_fail(this->priv != NULL, NULL);
1 by mental
moving trunk for module inkscape
1434
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1435
    return find_group_at_point(key, SP_GROUP(this->root), p);
1 by mental
moving trunk for module inkscape
1436
}
1437
1438
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1439
// Resource management
1440
1441
bool SPDocument::addResource(gchar const *key, SPObject *object)
1442
{
1443
    g_return_val_if_fail(key != NULL, false);
1444
    g_return_val_if_fail(*key != '\0', false);
1445
    g_return_val_if_fail(object != NULL, false);
1446
    g_return_val_if_fail(SP_IS_OBJECT(object), false);
1447
1448
    bool result = false;
1449
1450
    if ( !object->cloned ) {
1451
        GSList *rlist = (GSList*)g_hash_table_lookup(priv->resources, key);
1452
        g_return_val_if_fail(!g_slist_find(rlist, object), false);
1453
        rlist = g_slist_prepend(rlist, object);
1454
        g_hash_table_insert(priv->resources, (gpointer) key, rlist);
1455
1456
        GQuark q = g_quark_from_string(key);
1457
        priv->resources_changed_signals[q].emit();
1458
1459
        result = true;
1460
    }
1461
1462
    return result;
1463
}
1464
1465
bool SPDocument::removeResource(gchar const *key, SPObject *object)
1466
{
1467
    g_return_val_if_fail(key != NULL, false);
1468
    g_return_val_if_fail(*key != '\0', false);
1469
    g_return_val_if_fail(object != NULL, false);
1470
    g_return_val_if_fail(SP_IS_OBJECT(object), false);
1471
1472
    bool result = false;
1473
1474
    if ( !object->cloned ) {
1475
        GSList *rlist = (GSList*)g_hash_table_lookup(priv->resources, key);
1476
        g_return_val_if_fail(rlist != NULL, false);
1477
        g_return_val_if_fail(g_slist_find(rlist, object), false);
1478
        rlist = g_slist_remove(rlist, object);
1479
        g_hash_table_insert(priv->resources, (gpointer) key, rlist);
1480
1481
        GQuark q = g_quark_from_string(key);
1482
        priv->resources_changed_signals[q].emit();
1483
1484
        result = true;
1485
    }
1486
1487
    return result;
1488
}
1489
1490
GSList const *SPDocument::getResourceList(gchar const *key) const
1491
{
1 by mental
moving trunk for module inkscape
1492
    g_return_val_if_fail(key != NULL, NULL);
1493
    g_return_val_if_fail(*key != '\0', NULL);
1494
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1495
    return (GSList*)g_hash_table_lookup(this->priv->resources, key);
1 by mental
moving trunk for module inkscape
1496
}
1497
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1498
sigc::connection SPDocument::connectResourcesChanged(gchar const *key,
1499
                                                     SPDocument::ResourcesChangedSignal::slot_type slot)
1 by mental
moving trunk for module inkscape
1500
{
1501
    GQuark q = g_quark_from_string(key);
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1502
    return this->priv->resources_changed_signals[q].connect(slot);
1 by mental
moving trunk for module inkscape
1503
}
1504
1505
/* Helpers */
1506
1507
gboolean
3962 by joncruz
Warning cleanup
1508
sp_document_resource_list_free(gpointer /*key*/, gpointer value, gpointer /*data*/)
1 by mental
moving trunk for module inkscape
1509
{
1510
    g_slist_free((GSList *) value);
1511
    return TRUE;
1512
}
1513
11735 by Campbell Barton
code cleanup: add own includes to cpp files or make the functions static if they are not used elsewhere.
1514
static unsigned int count_objects_recursive(SPObject *obj, unsigned int count)
1 by mental
moving trunk for module inkscape
1515
{
1516
    count++; // obj itself
1517
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1518
    for ( SPObject *i = obj->firstChild(); i; i = i->getNext() ) {
1 by mental
moving trunk for module inkscape
1519
        count = count_objects_recursive(i, count);
1520
    }
1521
1522
    return count;
1523
}
1524
11735 by Campbell Barton
code cleanup: add own includes to cpp files or make the functions static if they are not used elsewhere.
1525
static unsigned int objects_in_document(SPDocument *document)
1 by mental
moving trunk for module inkscape
1526
{
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1527
    return count_objects_recursive(document->getRoot(), 0);
1 by mental
moving trunk for module inkscape
1528
}
1529
11735 by Campbell Barton
code cleanup: add own includes to cpp files or make the functions static if they are not used elsewhere.
1530
static void vacuum_document_recursive(SPObject *obj)
1 by mental
moving trunk for module inkscape
1531
{
1532
    if (SP_IS_DEFS(obj)) {
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1533
        for ( SPObject *def = obj->firstChild(); def; def = def->getNext()) {
1534
            // fixme: some inkscape-internal nodes in the future might not be collectable
1 by mental
moving trunk for module inkscape
1535
            def->requestOrphanCollection();
1536
        }
1537
    } else {
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1538
        for ( SPObject *i = obj->firstChild(); i; i = i->getNext() ) {
1 by mental
moving trunk for module inkscape
1539
            vacuum_document_recursive(i);
1540
        }
1541
    }
1542
}
1543
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1544
unsigned int SPDocument::vacuumDocument()
1 by mental
moving trunk for module inkscape
1545
{
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1546
    unsigned int start = objects_in_document(this);
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1547
    unsigned int end = start;
1 by mental
moving trunk for module inkscape
1548
    unsigned int newend = start;
1549
1550
    unsigned int iterations = 0;
1551
1552
    do {
1553
        end = newend;
1554
9945.1.1 by Jon A. Cruz
Merge and cleanup of GSoC C++-ification project.
1555
        vacuum_document_recursive(root);
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1556
        this->collectOrphans();
1 by mental
moving trunk for module inkscape
1557
        iterations++;
1558
9546.1.2 by Abhishek Sharma Public
C++fied SPDocument added
1559
        newend = objects_in_document(this);
1 by mental
moving trunk for module inkscape
1560
1561
    } while (iterations < 100 && newend < end);
1562
1563
    return start - newend;
1564
}
1565
8422 by cilix42
Revert recent refactoring changes by johnce because they break the build, which cannot be fixed easily.
1566
bool SPDocument::isSeeking() const {
2680 by mental
better way to deal with undo+id collisions
1567
    return priv->seeking;
1568
}
1569
11054 by JazzyNico
UI. Fix for bug #294354 (Unsaved files should have an asterisk (*) in the titlebar).
1570
void SPDocument::setModifiedSinceSave(bool modified) {
1571
    this->modified_since_save = modified;
12071 by JazzyNico
Crash. Partial fix for Bug #1046068 (Inkscape (GTK+/Quartz) calls output extensions or crashes when quitting while clipboard not empty).
1572
    if (SP_ACTIVE_DESKTOP) {
1573
        Gtk::Window *parent = SP_ACTIVE_DESKTOP->getToplevel();
12716 by Johan B. C. Engelen
fix crash bug 1237676
1574
        if (parent) { // during load, SP_ACTIVE_DESKTOP may be !nullptr, but parent might still be nullptr
1575
            SPDesktopWidget *dtw = static_cast<SPDesktopWidget *>(parent->get_data("desktopwidget"));
1576
            dtw->updateTitle( this->getName() );
1577
        }
12071 by JazzyNico
Crash. Partial fix for Bug #1046068 (Inkscape (GTK+/Quartz) calls output extensions or crashes when quitting while clipboard not empty).
1578
    }
11054 by JazzyNico
UI. Fix for bug #294354 (Unsaved files should have an asterisk (*) in the titlebar).
1579
}
1 by mental
moving trunk for module inkscape
1580
11153 by Kris
Clipboard code cleaning (patch for bug #964852 by Romain, see devmail thread "Some clipboard functions")
1581
1582
/**
13417 by mathog
Fix for bugs 1318657 and 1298967
1583
 * Paste SVG defs from the document retrieved from the clipboard or imported document into the active document.
11153 by Kris
Clipboard code cleaning (patch for bug #964852 by Romain, see devmail thread "Some clipboard functions")
1584
 * @param clipdoc The document to paste.
1585
 * @pre @c clipdoc != NULL and pasting into the active document is possible.
1586
 */
1587
void SPDocument::importDefs(SPDocument *source)
1588
{
1589
    Inkscape::XML::Node *root = source->getReprRoot();
1590
    Inkscape::XML::Node *defs = sp_repr_lookup_name(root, "svg:defs", 1);
1591
    Inkscape::XML::Node *target_defs = this->getDefs()->getRepr();
1592
1593
    prevent_id_clashes(source, this);
13417 by mathog
Fix for bugs 1318657 and 1298967
1594
    
1595
    int stagger=0;
1596
1597
    /*  Note, "clipboard" throughout the comments means "the document that is either the clipboard
1598
        or an imported document", as importDefs is called in both contexts.
1599
        
1600
        The order of the records in the clipboard is unpredictable and there may be both
1601
        forward and backwards references to other records within it.  There may be definitions in
1602
        the clipboard that duplicate definitions in the present document OR that duplicate other
1603
        definitions in the clipboard.  (Inkscape will not have created these, but they may be read
1604
        in from other SVG sources.)
1605
         
1606
        There are 3 passes to clean this up:
1607
1608
        In the first find and mark definitions in the clipboard that are duplicates of those in the
1609
        present document.  Change the ID to "RESERVED_FOR_INKSCAPE_DUPLICATE_DEF_XXXXXXXXX".
1610
        (Inkscape will not reuse an ID, and the XXXXXXXXX keeps it from automatically creating new ones.)
1611
        References in the clipboard to the old clipboard name are converted to the name used
1612
        in the current document. 
1613
1614
        In the second find and mark definitions in the clipboard that are duplicates of earlier 
1615
        definitions in the clipbard.  Unfortunately this is O(n^2) and could be very slow for a large
1616
        SVG with thousands of definitions.  As before, references are adjusted to reflect the name
1617
        going forward.
1618
1619
        In the final cycle copy over those records not marked with that ID.
1620
1621
        If an SVG file uses the special ID it will cause problems!
1622
        
1623
        If this function is called because of the paste of a true clipboard the caller will have passed in a
1624
        COPY of the clipboard items.  That is good, because this routine modifies that document.  If the calling
1625
        behavior ever changes, so that the same document is passed in on multiple pastes, this routine will break
1626
        as in the following example:
1627
        1.  Paste clipboard containing B same as A into document containing A.  Result, B is dropped
1628
        and all references to it will point to A.
1629
        2.  Paste same clipboard into a new document.  It will not contain A, so there will be unsatisfied
1630
        references in that window.
1631
    */
1632
1633
    std::string DuplicateDefString = "RESERVED_FOR_INKSCAPE_DUPLICATE_DEF";
1634
    
1635
    /* First pass: remove duplicates in clipboard of definitions in document */
11153 by Kris
Clipboard code cleaning (patch for bug #964852 by Romain, see devmail thread "Some clipboard functions")
1636
    for (Inkscape::XML::Node *def = defs->firstChild() ; def ; def = def->next()) {
11677 by John Smith
Fix for 643150 : Auto-palette swatches duplicated on copy and paste
1637
13417 by mathog
Fix for bugs 1318657 and 1298967
1638
        /* If this  clipboard has been pasted into one document, and is now being pasted into another,
1639
        or pasted again into the same, it will already have been processed.  If we detect that then 
1640
        skip the rest of this pass. */
1641
1642
        Glib::ustring defid = def->attribute("id");
1643
        if( defid.find( DuplicateDefString ) != Glib::ustring::npos )break;
1644
11677 by John Smith
Fix for 643150 : Auto-palette swatches duplicated on copy and paste
1645
        SPObject *src = source->getObjectByRepr(def);
11782 by tavmjong-free
Add symbols dialog. See: http://wiki.inkscape.org/wiki/index.php/SymbolsDialog
1646
1647
        // Prevent duplicates of solid swatches by checking if equivalent swatch already exists
11677 by John Smith
Fix for 643150 : Auto-palette swatches duplicated on copy and paste
1648
        if (src && SP_IS_GRADIENT(src)) {
13417 by mathog
Fix for bugs 1318657 and 1298967
1649
            SPGradient *s_gr = SP_GRADIENT(src);
13047 by insaner
crash on cut n paste, or alt+scroll..
1650
            for (SPObject *trg = this->getDefs()->firstChild() ; trg ; trg = trg->getNext()) {
13417 by mathog
Fix for bugs 1318657 and 1298967
1651
                if (trg && (src != trg) && SP_IS_GRADIENT(trg)) {
1652
                    SPGradient *t_gr = SP_GRADIENT(trg);
1653
                    if (t_gr && s_gr->isEquivalent(t_gr)) {
1654
                         // Change object references to the existing equivalent gradient
1655
                         Glib::ustring newid = trg->getId();
1656
                         if(newid != defid){  // id could be the same if it is a second paste into the same document
1657
                             change_def_references(src, trg);
1658
                         }
1659
                         gchar *longid = g_strdup_printf("%s_%9.9d", DuplicateDefString.c_str(), stagger++);
1660
                         def->setAttribute("id", longid );
1661
                         g_free(longid);
1662
                         // do NOT break here, there could be more than 1 duplicate!
11677 by John Smith
Fix for 643150 : Auto-palette swatches duplicated on copy and paste
1663
                    }
1664
                }
1665
            }
1666
        }
13417 by mathog
Fix for bugs 1318657 and 1298967
1667
    }
1668
1669
    /* Second pass: remove duplicates in clipboard of earlier definitions in clipboard */
1670
    for (Inkscape::XML::Node *def = defs->firstChild() ; def ; def = def->next()) {
1671
        Glib::ustring defid = def->attribute("id");
1672
        if( defid.find( DuplicateDefString ) != Glib::ustring::npos )continue; // this one already handled
1673
        SPObject *src = source->getObjectByRepr(def);
1674
        if (src && SP_IS_GRADIENT(src)) {
1675
            SPGradient *s_gr = SP_GRADIENT(src);
1676
            for (Inkscape::XML::Node *laterDef = def->next() ; laterDef ; laterDef = laterDef->next()) {
1677
                SPObject *trg = source->getObjectByRepr(laterDef);
1678
                if(trg && (src != trg) && SP_IS_GRADIENT(trg)) {
1679
                     Glib::ustring newid = trg->getId();
1680
                     if( newid.find( DuplicateDefString ) != Glib::ustring::npos )continue; // this one already handled
1681
                     SPGradient *t_gr = SP_GRADIENT(trg);
1682
                     if (t_gr && s_gr->isEquivalent(t_gr)) {
1683
                         // Change object references to the existing equivalent gradient
1684
                         // two id's in the clipboard should never be the same, so always change references
1685
                         change_def_references(trg, src);
1686
                         gchar *longid = g_strdup_printf("%s_%9.9d", DuplicateDefString.c_str(), stagger++);
1687
                         laterDef->setAttribute("id", longid );
1688
                         g_free(longid);
1689
                         // do NOT break here, there could be more than 1 duplicate!
1690
                     }
1691
                }
1692
            }
1693
        }
1694
    }
1695
1696
    /* Final pass: copy over those parts which are not duplicates  */
1697
    for (Inkscape::XML::Node *def = defs->firstChild() ; def ; def = def->next()) {
1698
1699
        /* Ignore duplicate defs marked in the first pass */
1700
        Glib::ustring defid = def->attribute("id");
1701
        if( defid.find( DuplicateDefString ) != Glib::ustring::npos )continue;
1702
1703
        bool duplicate = false;
1704
        SPObject *src = source->getObjectByRepr(def);
11677 by John Smith
Fix for 643150 : Auto-palette swatches duplicated on copy and paste
1705
11782 by tavmjong-free
Add symbols dialog. See: http://wiki.inkscape.org/wiki/index.php/SymbolsDialog
1706
        // Prevent duplication of symbols... could be more clever.
1707
        // The tag "_inkscape_duplicate" is added to "id" by ClipboardManagerImpl::copySymbol(). 
1708
        // We assume that symbols are in defs section (not required by SVG spec).
1709
        if (src && SP_IS_SYMBOL(src)) {
1710
1711
            Glib::ustring id = src->getRepr()->attribute("id");
1712
            size_t pos = id.find( "_inkscape_duplicate" );
1713
            if( pos != Glib::ustring::npos ) {
1714
1715
                // This is our symbol, now get rid of tag
1716
                id.erase( pos ); 
1717
1718
                // Check that it really is a duplicate
1719
                for (SPObject *trg = this->getDefs()->firstChild() ; trg ; trg = trg->getNext()) {
1720
                    if( trg && SP_IS_SYMBOL(trg) && src != trg ) { 
1721
                        std::string id2 = trg->getRepr()->attribute("id");
1722
1723
                        if( !id.compare( id2 ) ) {
1724
                            duplicate = true;
1725
                            break;
1726
                        }
1727
                    }
1728
                }
1729
                if ( !duplicate ) {
1730
                    src->getRepr()->setAttribute("id", id.c_str() );
1731
                }
1732
            }
1733
        }
1734
11677 by John Smith
Fix for 643150 : Auto-palette swatches duplicated on copy and paste
1735
        if (!duplicate) {
1736
            Inkscape::XML::Node * dup = def->duplicate(this->getReprDoc());
1737
            target_defs->appendChild(dup);
1738
            Inkscape::GC::release(dup);
1739
        }
11153 by Kris
Clipboard code cleaning (patch for bug #964852 by Romain, see devmail thread "Some clipboard functions")
1740
    }
1741
}
1742
1 by mental
moving trunk for module inkscape
1743
/*
1744
  Local Variables:
1745
  mode:c++
1746
  c-file-style:"stroustrup"
1747
  c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
1748
  indent-tabs-mode:nil
1749
  fill-column:99
1750
  End:
1751
*/
9900 by Chris Morgan
Super duper mega (fun!) commit: replaced encoding=utf-8 with fileencoding=utf-8 in all 1074 Vim modelines.
1752
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :