Code

Store cached icons to disk between runs, and invalidate/purge as needed.
[inkscape.git] / src / document-subset.cpp
index ba6e416cd49a09c08157be7a6c4625c384eb165d..e71b9bad5bd6af2919f10d936106b419a1cb4f19 100644 (file)
@@ -3,6 +3,7 @@
  *                            of nodes
  *
  * Copyright 2006  MenTaLguY  <mental@rydia.net>
+ *   Abhishek Sharma
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
@@ -36,10 +37,10 @@ struct DocumentSubset::Relations : public GC::Managed<GC::ATOMIC>,
         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;
@@ -57,17 +58,31 @@ struct DocumentSubset::Relations : public GC::Managed<GC::ATOMIC>,
             } 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();
             }
         }
@@ -126,7 +141,12 @@ struct DocumentSubset::Relations : public GC::Managed<GC::ATOMIC>,
         for ( Map::iterator iter=records.begin()
             ; iter != records.end() ; ++iter )
         {
-            sp_object_unref((*iter).first);
+            if ((*iter).first) {
+                sp_object_unref((*iter).first);
+                Record &record=(*iter).second;
+                record.release_connection.disconnect();
+                record.position_changed_connection.disconnect();
+            }
         }
     }
 
@@ -149,8 +169,9 @@ private:
         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)
@@ -164,10 +185,18 @@ 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;
+
+        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;
+                }
+            }
         }
+
+        record.release_connection.disconnect();
         record.position_changed_connection.disconnect();
         records.erase(obj);
         removed_signal.emit(obj);
@@ -187,10 +216,9 @@ private:
         }
     }
 
-    static void _release_object(SPObject *obj, void *relations_p) {
-        Relations &relations=*static_cast<Relations *>(relations_p);
-        if (relations.get(obj)) {
-            relations.remove(obj, true);
+    void _release_object(SPObject *obj) {
+        if (get(obj)) {
+            remove(obj, true);
         }
     }
 };
@@ -202,7 +230,7 @@ DocumentSubset::DocumentSubset()
 
 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);
 
@@ -274,7 +302,7 @@ void DocumentSubset::Relations::remove(SPObject *obj, bool subtree) {
         /* remove obj's record */
         _doRemove(obj);
     }
-    
+
     changed_signal.emit();
 }
 
@@ -381,4 +409,4 @@ DocumentSubset::connectRemoved(sigc::slot<void, SPObject *> slot) const {
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :