X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fdocument-subset.cpp;h=5fcf1641cf80d26052816317ed244686e845bcd6;hb=5e230ff5b88fa5522aeaf72d6222c38e4470557d;hp=08638b9f3fd517d9aaf00c56ad9e4a9a176dc336;hpb=a8f1a69ef0da383f9b413c3043a74084e23b75c2;p=inkscape.git diff --git a/src/document-subset.cpp b/src/document-subset.cpp index 08638b9f3..5fcf1641c 100644 --- a/src/document-subset.cpp +++ b/src/document-subset.cpp @@ -15,6 +15,7 @@ #include #include +#include #include "util/list.h" #include "util/reverse-list.h" @@ -35,9 +36,10 @@ struct DocumentSubset::Relations : public GC::Managed, SPObject *parent; Siblings children; - gulong release_connection; + sigc::connection release_connection; + sigc::connection position_changed_connection; - Record() : parent(NULL), release_connection(0) {} + Record() : parent(NULL) {} unsigned childIndex(SPObject *obj) { Siblings::iterator found; @@ -55,17 +57,31 @@ struct DocumentSubset::Relations : public GC::Managed, } else { Siblings::const_iterator first=children.begin(); Siblings::const_iterator last=children.end() - 1; + while ( first != last ) { - Siblings::const_iterator mid=first + ( last - first + 1 ) / 2; - int pos=sp_object_compare_position(*mid, obj); + Siblings::const_iterator mid = first + ( last - first + 1 ) / 2; + int pos = sp_object_compare_position(*mid, obj); if ( pos < 0 ) { first = mid; } else if ( pos > 0 ) { - last = mid; + if ( last == mid ) { + last = mid - 1; // already at the top limit + } else { + last = mid; + } } else { g_assert_not_reached(); } } + + if ( first == last ) { + // compare to the single possiblity left + int pos = sp_object_compare_position(*last, obj); + if ( pos < 0 ) { + last++; + } + } + return last - children.begin(); } } @@ -140,14 +156,20 @@ struct DocumentSubset::Relations : public GC::Managed, void addOne(SPObject *obj); void remove(SPObject *obj, bool subtree); void reorder(SPObject *obj); + void clear(); private: Record &_doAdd(SPObject *obj) { sp_object_ref(obj); Record &record=records[obj]; record.release_connection - = g_signal_connect(obj, "release", - (GCallback)&Relations::_release_object, this); + = obj->connectRelease( + sigc::mem_fun(this, &Relations::_release_object) + ); + record.position_changed_connection + = obj->connectPositionChanged( + sigc::mem_fun(this, &Relations::reorder) + ); return record; } @@ -157,11 +179,20 @@ private: void _doRemove(SPObject *obj) { Record &record=records[obj]; - if (record.release_connection) { - g_signal_handler_disconnect(obj, record.release_connection); - record.release_connection = 0; - } + record.release_connection.disconnect(); + record.position_changed_connection.disconnect(); records.erase(obj); + + if ( record.parent == NULL ) { + Record &root = records[NULL]; + for ( Siblings::iterator it = root.children.begin(); it != root.children.end(); ++it ) { + if ( *it == obj ) { + root.children.erase( it ); + break; + } + } + } + removed_signal.emit(obj); sp_object_unref(obj); } @@ -179,22 +210,21 @@ private: } } - static void _release_object(SPObject *obj, void *relations_p) { - Relations &relations=*static_cast(relations_p); - if (relations.get(obj)) { - relations.remove(obj, true); + void _release_object(SPObject *obj) { + if (get(obj)) { + remove(obj, true); } } }; -DocumentSubset::DocumentSubset(SPDocument *document) -: _document(document), _relations(new DocumentSubset::Relations()) +DocumentSubset::DocumentSubset() +: _relations(new DocumentSubset::Relations()) { } void DocumentSubset::Relations::addOne(SPObject *obj) { g_return_if_fail( obj != NULL ); - g_return_if_fail( get(obj) != NULL ); + g_return_if_fail( get(obj) == NULL ); Record &record=_doAdd(obj); @@ -270,6 +300,16 @@ void DocumentSubset::Relations::remove(SPObject *obj, bool subtree) { changed_signal.emit(); } +void DocumentSubset::Relations::clear() { + Record &root=records[NULL]; + + while (!root.children.empty()) { + _doRemoveSubtree(root.children.front()); + } + + changed_signal.emit(); +} + void DocumentSubset::Relations::reorder(SPObject *obj) { SPObject::ParentIterator parent=obj; @@ -309,6 +349,10 @@ void DocumentSubset::_remove(SPObject *obj, bool subtree) { _relations->remove(obj, subtree); } +void DocumentSubset::_clear() { + _relations->clear(); +} + bool DocumentSubset::includes(SPObject *obj) const { return _relations->get(obj); }