summaryrefslogtreecommitdiffstats
path: root/src/document.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/document.cpp')
-rw-r--r--src/document.cpp124
1 files changed, 79 insertions, 45 deletions
diff --git a/src/document.cpp b/src/document.cpp
index e56adee68..dc7ed254c 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -92,23 +92,24 @@ SPDocument::SPDocument() :
keepalive(FALSE),
virgin(TRUE),
modified_since_save(FALSE),
- rdoc(0),
- rroot(0),
- root(0),
+ rdoc(NULL),
+ rroot(NULL),
+ root(NULL),
style_cascade(cr_cascade_new(NULL, NULL, NULL)),
- uri(0),
- base(0),
- name(0),
- priv(0), // reset in ctor
+ uri(NULL),
+ base(NULL),
+ name(NULL),
+ priv(NULL), // reset in ctor
actionkey(),
modified_id(0),
rerouting_handler_id(0),
- profileManager(0), // deferred until after other initialization
+ profileManager(NULL), // deferred until after other initialization
router(new Avoid::Router(Avoid::PolyLineRouting|Avoid::OrthogonalRouting)),
- _collection_queue(0),
+ _collection_queue(NULL),
oldSignalsConnected(false),
current_persp3d(NULL),
- current_persp3d_impl(NULL)
+ current_persp3d_impl(NULL),
+ _parent_document(NULL)
{
// Penalise libavoid for choosing paths with needless extra segments.
// This results in much better looking orthogonal connector paths.
@@ -123,7 +124,7 @@ SPDocument::SPDocument() :
p->resources = g_hash_table_new(g_str_hash, g_str_equal);
- p->sensitive = FALSE;
+ p->sensitive = false;
p->partial = NULL;
p->history_size = 0;
p->undo = NULL;
@@ -140,6 +141,8 @@ SPDocument::SPDocument() :
}
SPDocument::~SPDocument() {
+ priv->destroySignal.emit();
+
// kill/unhook this first
if ( profileManager ) {
delete profileManager;
@@ -229,6 +232,11 @@ SPDocument::~SPDocument() {
//delete this->_whiteboard_session_manager;
}
+sigc::connection SPDocument::connectDestroy(sigc::signal<void>::slot_type slot)
+{
+ return priv->destroySignal.connect(slot);
+}
+
SPDefs *SPDocument::getDefs()
{
if (!root) {
@@ -314,7 +322,8 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc,
gchar const *uri,
gchar const *base,
gchar const *name,
- unsigned int keepalive)
+ unsigned int keepalive,
+ SPDocument *parent)
{
SPDocument *document = new SPDocument();
@@ -325,6 +334,10 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc,
document->rdoc = rdoc;
document->rroot = rroot;
+ if (parent) {
+ document->_parent_document = parent;
+ parent->_child_documents.push_back(document);
+ }
if (document->uri){
g_free(document->uri);
@@ -375,16 +388,6 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc,
rroot->setAttribute("inkscape:version", Inkscape::version_string);
/* fixme: Again, I moved these here to allow version determining in ::build (Lauris) */
- /* Quick hack 2 - get default image size into document */
- if (!rroot->attribute("width")) rroot->setAttribute("width", "100%");
- if (!rroot->attribute("height")) rroot->setAttribute("height", "100%");
- /* End of quick hack 2 */
-
- /* Quick hack 3 - Set uri attributes */
-// if (uri) { // this is done in do_change_uri()
-// rroot->setAttribute("sodipodi:docname", uri);
-// }
- /* End of quick hack 3 */
/* Eliminate obsolete sodipodi:docbase, for privacy reasons */
rroot->setAttribute("sodipodi:docbase", NULL);
@@ -470,13 +473,45 @@ SPDocument *SPDocument::createDoc(Inkscape::XML::Document *rdoc,
}
/**
+ * Fetches a document and attaches it to the current document as a child href
+ */
+SPDocument *SPDocument::createChildDoc(std::string const &uri)
+{
+ SPDocument *parent = this;
+ SPDocument *document = NULL;
+
+ while(parent != NULL && parent->getURI() != NULL && document == NULL) {
+ // Check myself and any parents int he chain
+ if(uri == parent->getURI()) {
+ document = parent;
+ break;
+ }
+ // Then check children of those.
+ boost::ptr_list<SPDocument>::iterator iter;
+ for (iter = parent->_child_documents.begin();
+ iter != parent->_child_documents.end(); ++iter) {
+ if(uri == iter->getURI()) {
+ document = &*iter;
+ break;
+ }
+ }
+ parent = parent->_parent_document;
+ }
+
+ // Load a fresh document from the svg source.
+ if(!document) {
+ const char *path = uri.c_str();
+ document = createNewDoc(path, false, false, this);
+ }
+ return document;
+}
+/**
* Fetches document from URI, or creates new, if NULL; public document
* appears in document list.
*/
-SPDocument *SPDocument::createNewDoc(gchar const *uri, unsigned int keepalive, bool make_new)
+SPDocument *SPDocument::createNewDoc(gchar const *uri, unsigned int keepalive, bool make_new, SPDocument *parent)
{
- SPDocument *doc;
- Inkscape::XML::Document *rdoc;
+ Inkscape::XML::Document *rdoc = NULL;
gchar *base = NULL;
gchar *name = NULL;
@@ -518,7 +553,7 @@ SPDocument *SPDocument::createNewDoc(gchar const *uri, unsigned int keepalive, b
//# These should be set by now
g_assert(name);
- doc = createDoc(rdoc, uri, base, name, keepalive);
+ SPDocument *doc = createDoc(rdoc, uri, base, name, keepalive, parent);
g_free(base);
g_free(name);
@@ -528,7 +563,7 @@ SPDocument *SPDocument::createNewDoc(gchar const *uri, unsigned int keepalive, b
SPDocument *SPDocument::createNewDocFromMem(gchar const *buffer, gint length, unsigned int keepalive)
{
- SPDocument *doc = 0;
+ SPDocument *doc = NULL;
Inkscape::XML::Document *rdoc = sp_repr_read_mem(buffer, length, SP_SVG_NS_URI);
if ( rdoc ) {
@@ -539,7 +574,7 @@ SPDocument *SPDocument::createNewDocFromMem(gchar const *buffer, gint length, un
// TODO fixme: destroy document
} else {
Glib::ustring name = Glib::ustring::compose( _("Memory document %1"), ++doc_mem_count );
- doc = createDoc(rdoc, NULL, NULL, name.c_str(), keepalive);
+ doc = createDoc(rdoc, NULL, NULL, name.c_str(), keepalive, NULL);
}
}
@@ -602,6 +637,7 @@ void SPDocument::setWidth(const Inkscape::Util::Quantity &width)
root->updateRepr();
}
+
Inkscape::Util::Quantity SPDocument::getHeight() const
{
g_return_val_if_fail(this->priv != NULL, Inkscape::Util::Quantity(0.0, unit_table.getUnit("")));
@@ -725,7 +761,7 @@ void SPDocument::setBase( gchar const* base )
{
if (this->base) {
g_free(this->base);
- this->base = 0;
+ this->base = NULL;
}
if (base) {
this->base = g_strdup(base);
@@ -734,9 +770,9 @@ void SPDocument::setBase( gchar const* base )
void SPDocument::do_change_uri(gchar const *const filename, bool const rebase)
{
- gchar *new_base = 0;
- gchar *new_name = 0;
- gchar *new_uri = 0;
+ gchar *new_base = NULL;
+ gchar *new_name = NULL;
+ gchar *new_uri = NULL;
if (filename) {
#ifndef WIN32
@@ -1097,12 +1133,11 @@ static gint
sp_document_idle_handler(gpointer data)
{
SPDocument *doc = static_cast<SPDocument *>(data);
- if (doc->_updateDocument()) {
+ bool status = !doc->_updateDocument(); // method TRUE if it does NOT need further modification, so invert
+ if (!status) {
doc->modified_id = 0;
- return false;
- } else {
- return true;
}
+ return status;
}
/**
@@ -1514,15 +1549,14 @@ void SPDocument::importDefs(SPDocument *source)
// Prevent duplicates of solid swatches by checking if equivalent swatch already exists
if (src && SP_IS_GRADIENT(src)) {
SPGradient *gr = SP_GRADIENT(src);
- if (gr->isSolid() || gr->getVector()->isSolid()) {
- for (SPObject *trg = this->getDefs()->firstChild() ; trg ; trg = trg->getNext()) {
- if (trg && SP_IS_GRADIENT(trg) && src != trg) {
- if (gr->isEquivalent(SP_GRADIENT(trg))) {
- // Change object references to the existing equivalent gradient
- change_def_references(src, trg);
- duplicate = true;
- break;
- }
+ for (SPObject *trg = this->getDefs()->firstChild() ; trg ; trg = trg->getNext()) {
+ if (trg && SP_IS_GRADIENT(trg) && src != trg) {
+ if (gr->isEquivalent(SP_GRADIENT(trg)) &&
+ gr->isAligned(SP_GRADIENT(trg))) {
+ // Change object references to the existing equivalent gradient
+ change_def_references(src, trg);
+ duplicate = true;
+ break;
}
}
}