[Uml-devel] branches/KDE/3.5/kdesdk/umbrello/umbrello

Oliver Kellogg okellogg at users.sourceforge.net
Sun Aug 6 09:47:52 UTC 2006


SVN commit 570260 by okellogg:

Optimization for insertion of UMLClassifierListItem representatives in the list view:
The UMLListView::childObjectAdded() was calling parentItem->findUMLObject(child)
which did a traversal of the parentItem using firstChild()/nextSibling() which
in turn triggered ensureItemVisible() which in turn led to a lot of superfluous
re-sorting of the list view (cf. UMLListViewItem::compare().)
The new method UMLListViewItem::findChildObject() uses a separate map of
UMLClassifierListItems to avoid the firstChild()/nextSibling() traversal.


 M  +8 -10     umllistview.cpp  
 M  +27 -1     umllistviewitem.cpp  
 M  +32 -5     umllistviewitem.h  


--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umllistview.cpp #570259:570260
@@ -801,7 +801,7 @@
                                          convert_OT_LVT(parent->getBaseType()),
                                          parent);
     } else {
-        childItem = parentItem->findUMLObject(child);
+        childItem = parentItem->findChildObject(child);
     }
     if (childItem) {
         childItem->setText(text);
@@ -821,16 +821,12 @@
     UMLClassifier *parent = const_cast<UMLClassifier*>(dynamic_cast<const UMLClassifier*>(sender()));
     UMLListViewItem *item(0);
     UMLListViewItem *parentItem = findUMLObject(parent);
-    for( item = static_cast<UMLListViewItem*>(parentItem->firstChild());
-            item;
-            item = static_cast<UMLListViewItem*>(item->nextSibling()) )
-    {
-        if(item->getUMLObject() == obj)
-        {
-            delete item;
-            return;
-        }
+    if (parentItem == NULL) {
+        kdError() << "UMLListView::childObjectRemoved(" << obj->getName()
+                  << "): cannot find parent UMLListViewItem" << endl;
+        return;
     }
+    parentItem->deleteChildItem(obj);
 }
 
 void UMLListView::slotDiagramRenamed(Uml::IDType id) {
@@ -1376,6 +1372,8 @@
             // update list view
             newItem = move->deepCopy(newParent);
             delete move;
+            UMLClassifierListItem *cli = dynamic_cast<UMLClassifierListItem*>(srcObj);
+            newParent->addClassifierListItem(cli, newItem);
             // update model objects
             m_bCreatingChildObject = true;
             UMLClassifier *oldParentClassifier = dynamic_cast<UMLClassifier*>(srcObj->parent());
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umllistviewitem.cpp #570259:570260
@@ -69,6 +69,9 @@
         m_nId = Uml::id_None;
         updateFolder();
     } else {
+        UMLClassifierListItem *umlchild = dynamic_cast<UMLClassifierListItem*>(o);
+        if (umlchild)
+            parent->addClassifierListItem(umlchild, this);
         updateObject();
         m_nId = o->getID();
     }
@@ -143,6 +146,21 @@
     return m_Type;
 }
 
+void UMLListViewItem::addClassifierListItem(UMLClassifierListItem *child, UMLListViewItem *childItem) {
+    m_comap[child] = childItem;
+}
+
+void UMLListViewItem::deleteChildItem(UMLClassifierListItem *child) {
+    UMLListViewItem *childItem = findChildObject(child);
+    if (childItem == NULL) {
+        kdError() << "UMLListViewItem::deleteChildItem(" << child->getName()
+                  << "): child listview item not found" << endl;
+        return;
+    }
+    m_comap.remove(child);
+    delete childItem;
+}
+
 Uml::IDType UMLListViewItem::getID() const {
     if (m_pObject)
         return m_pObject->getID();
@@ -593,7 +611,7 @@
     if (ourParent != otherParent) {
         retval = (subItem ? 0 : alphaOrder);
 #ifdef DEBUG_LVITEM_INSERTION_ORDER
-        kdDebug() << dbgPfx << retval << " because (ourParent != otherParentL)" << endl;
+        kdDebug() << dbgPfx << retval << " because (ourParent != otherParent)" << endl;
 #endif
         return retval;
     }
@@ -659,6 +677,14 @@
     return NULL;
 }
 
+UMLListViewItem* UMLListViewItem::findChildObject(UMLClassifierListItem *cli) {
+    ChildObjectMap::iterator it = m_comap.find(cli);
+    if (it != m_comap.end()) {
+        return *it;
+    }
+    return NULL;
+}
+
 UMLListViewItem * UMLListViewItem::findItem(Uml::IDType id) {
     if (getID() == id)
         return this;
--- branches/KDE/3.5/kdesdk/umbrello/umbrello/umllistviewitem.h #570259:570260
@@ -1,8 +1,3 @@
-/*
- *  copyright (C) 2002-2004
- *  Umbrello UML Modeller Authors <uml-devel@ uml.sf.net>
- */
-
 /***************************************************************************
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
@@ -10,18 +5,23 @@
  *   the Free Software Foundation; either version 2 of the License, or     *
  *   (at your option) any later version.                                   *
  *                                                                         *
+ *   copyright (C) 2002-2006                                               *
+ *   Umbrello UML Modeller Authors <uml-devel@ uml.sf.net>                 *
+ *                                                                         *
  ***************************************************************************/
 
 #ifndef UMLLISTVIEWITEM_H
 #define UMLLISTVIEWITEM_H
 
 #include <qlistview.h>
+#include <qmap.h>
 #include <qdom.h>
 #include "umlnamespace.h"
 
 // forward declarations
 class UMLListView;
 class UMLObject;
+class UMLClassifierListItem;
 
 /**
  * Items used by the class @ref UMLListView.  This is needed as the type
@@ -182,6 +182,16 @@
     void cancelRename( int col );
 
     /**
+     * Adds the child listview item representing the given UMLClassifierListItem.
+     */
+    void addClassifierListItem(UMLClassifierListItem *child, UMLListViewItem *childItem);
+
+    /**
+     * Deletes the child listview item representing the given UMLClassifierListItem.
+     */
+    void deleteChildItem(UMLClassifierListItem *child);
+
+    /**
      * Overrides the default sorting to sort by item type.
      */
     virtual int compare(QListViewItem *other, int col, bool ascending) const;
@@ -209,6 +219,14 @@
     UMLListViewItem* findUMLObject(UMLObject *o);
 
     /**
+     * Find the UMLListViewItem that represents the given UMLClassifierListItem
+     * in the children of the current UMLListViewItem.  (Only makes sense if
+     * the current UMLListViewItem represents a UMLClassifier.)
+     * Return a pointer to the item or NULL if not found.
+     */
+    UMLListViewItem* findChildObject(UMLClassifierListItem *cli);
+
+    /**
      * Find the UMLListViewItem of the given ID in the tree rooted at
      * the current UMLListViewItem.
      * Return a pointer to the item or NULL if not found.
@@ -256,12 +274,21 @@
      */
     bool m_bCreating;
 
+    /**
+     * Auxiliary map of child UMLLisViewItems keyed by UMLClassifierListItem.
+     * Used by findChildObject() for efficiency instead of looping using
+     * firstChild()/nextSibling() because the latter incur enforceItemVisible()
+     * and thus expensive sorting.
+     */
+    typedef QMap<UMLClassifierListItem*, UMLListViewItem*> ChildObjectMap;
+
     Uml::ListView_Type m_Type;
     Uml::IDType m_nId;
     int m_nChildren;
     UMLObject * m_pObject;
     QString m_Label;
     QString m_FolderFile;
+    ChildObjectMap m_comap;
 };
 
 #endif




More information about the umbrello-devel mailing list