diff options
| author | Ted Gould <ted@gould.cx> | 2009-12-21 16:37:12 +0000 |
|---|---|---|
| committer | Ted Gould <ted@gould.cx> | 2009-12-21 16:37:12 +0000 |
| commit | 752a8f90d3442cdaa4689ba6de4b911ca4fda514 (patch) | |
| tree | 5e0739ec9bd2ac9cbdd2a2343859f89e02dae181 /src/document.cpp | |
| parent | Merging in from trunk (diff) | |
| parent | Updating the READMEs to better handle OSX. (diff) | |
| download | inkscape-752a8f90d3442cdaa4689ba6de4b911ca4fda514.tar.gz inkscape-752a8f90d3442cdaa4689ba6de4b911ca4fda514.zip | |
Updating to current trunk
(bzr r8254.1.38)
Diffstat (limited to 'src/document.cpp')
| -rw-r--r-- | src/document.cpp | 98 |
1 files changed, 78 insertions, 20 deletions
diff --git a/src/document.cpp b/src/document.cpp index d406f3712..a3ad6f7be 100644 --- a/src/document.cpp +++ b/src/document.cpp @@ -63,10 +63,16 @@ #include "xml/repr.h" #include "xml/rebase-hrefs.h" -#define SP_DOCUMENT_UPDATE_PRIORITY (G_PRIORITY_HIGH_IDLE - 1) +// Higher number means lower priority. +#define SP_DOCUMENT_UPDATE_PRIORITY (G_PRIORITY_HIGH_IDLE - 2) + +// Should have a lower priority than SP_DOCUMENT_UPDATE_PRIORITY, +// since we want it to happen when there are no more updates. +#define SP_DOCUMENT_REROUTING_PRIORITY (G_PRIORITY_HIGH_IDLE - 1) static gint sp_document_idle_handler(gpointer data); +static gint sp_document_rerouting_handler(gpointer data); gboolean sp_document_resource_list_free(gpointer key, gpointer value, gpointer data); @@ -88,15 +94,17 @@ SPDocument::SPDocument() : priv(0), // reset in ctor actionkey(0), modified_id(0), + rerouting_handler_id(0), profileManager(0), // deferred until after other initialization - router(new Avoid::Router()), + router(new Avoid::Router(Avoid::PolyLineRouting|Avoid::OrthogonalRouting)), perspectives(0), current_persp3d(0), _collection_queue(0), oldSignalsConnected(false) { - // Don't use the Consolidate moves optimisation. - router->ConsolidateMoves = false; + // Penalise libavoid for choosing paths with needless extra segments. + // This results in much better looking orthogonal connector paths. + router->setRoutingPenalty(Avoid::segmentPenalty); SPDocumentPrivate *p = new SPDocumentPrivate(); @@ -132,6 +140,11 @@ SPDocument::~SPDocument() { profileManager = 0; } + if (router) { + delete router; + router = NULL; + } + if (priv) { if (priv->partial) { sp_repr_free_log(priv->partial); @@ -177,10 +190,15 @@ SPDocument::~SPDocument() { } if (modified_id) { - gtk_idle_remove(modified_id); + g_source_remove(modified_id); modified_id = 0; } + if (rerouting_handler_id) { + g_source_remove(rerouting_handler_id); + rerouting_handler_id = 0; + } + if (oldSignalsConnected) { g_signal_handlers_disconnect_by_func(G_OBJECT(INKSCAPE), reinterpret_cast<gpointer>(sp_document_reset_key), @@ -195,13 +213,7 @@ SPDocument::~SPDocument() { keepalive = FALSE; } - if (router) { - delete router; - router = NULL; - } - //delete this->_whiteboard_session_manager; - } void SPDocument::add_persp3d (Persp3D * const /*persp*/) @@ -852,7 +864,12 @@ void sp_document_request_modified(SPDocument *doc) { if (!doc->modified_id) { - doc->modified_id = gtk_idle_add_priority(SP_DOCUMENT_UPDATE_PRIORITY, sp_document_idle_handler, doc); + doc->modified_id = g_idle_add_full(SP_DOCUMENT_UPDATE_PRIORITY, + sp_document_idle_handler, doc, NULL); + } + if (!doc->rerouting_handler_id) { + doc->rerouting_handler_id = g_idle_add_full(SP_DOCUMENT_REROUTING_PRIORITY, + sp_document_rerouting_handler, doc, NULL); } } @@ -908,26 +925,49 @@ SPDocument::_updateDocument() * Repeatedly works on getting the document updated, since sometimes * it takes more than one pass to get the document updated. But it * usually should not take more than a few loops, and certainly never - * more than 64 iterations. So we bail out if we hit 64 iterations, + * more than 32 iterations. So we bail out if we hit 32 iterations, * since this typically indicates we're stuck in an update loop. */ gint sp_document_ensure_up_to_date(SPDocument *doc) { - int counter = 64; - while (!doc->_updateDocument()) { - if (counter == 0) { - g_warning("More than 64 iteration while updating document '%s'", doc->uri? doc->uri:"<unknown URI, probably clipboard>"); + // Bring the document up-to-date, specifically via the following: + // 1a) Process all document updates. + // 1b) When completed, process connector routing changes. + // 2a) Process any updates resulting from connector reroutings. + int counter = 32; + for (unsigned int pass = 1; pass <= 2; ++pass) { + // Process document updates. + while (!doc->_updateDocument()) { + if (counter == 0) { + g_warning("More than 32 iteration while updating document '%s'", doc->uri); + break; + } + counter--; + } + if (counter == 0) + { break; } - counter--; - } + // After updates on the first pass we get libavoid to process all the + // changed objects and provide new routings. This may cause some objects + // to be modified, hence the second update pass. + if (pass == 1) { + doc->router->processTransaction(); + } + } + if (doc->modified_id) { /* Remove handler */ - gtk_idle_remove(doc->modified_id); + g_source_remove(doc->modified_id); doc->modified_id = 0; } + if (doc->rerouting_handler_id) { + /* Remove handler */ + g_source_remove(doc->rerouting_handler_id); + doc->rerouting_handler_id = 0; + } return counter>0; } @@ -947,6 +987,24 @@ sp_document_idle_handler(gpointer data) } } +/** + * An idle handler to reroute connectors in the document. + */ +static gint +sp_document_rerouting_handler(gpointer data) +{ + // Process any queued movement actions and determine new routings for + // object-avoiding connectors. Callbacks will be used to update and + // redraw affected connectors. + SPDocument *doc = static_cast<SPDocument *>(data); + doc->router->processTransaction(); + + // We don't need to handle rerouting again until there are further + // diagram updates. + doc->rerouting_handler_id = 0; + return false; +} + static bool is_within(Geom::Rect const &area, Geom::Rect const &box) { return area.contains(box); |
