]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
Synchronization algorithm between tree structures of SUIT_DataObjects and OB_ListItem...
authorasv <asv@opencascade.com>
Thu, 26 Jan 2006 09:18:14 +0000 (09:18 +0000)
committerasv <asv@opencascade.com>
Thu, 26 Jan 2006 09:18:14 +0000 (09:18 +0000)
src/ObjBrowser/OB_Browser.cxx
src/ObjBrowser/OB_Browser.h
src/ObjBrowser/OB_ListItem.cxx
src/ObjBrowser/OB_ListItem.h

index 66656c9cd96cf4573c09c92ee194b0fde180c90e..7ad1e6d44d2da5ac3cf1f86d9af1ea32a3cb9108 100755 (executable)
@@ -22,6 +22,8 @@
 #include "OB_ListItem.h"
 #include "OB_ListView.h"
 
+#include <SUIT_DataObjectIterator.h>
+
 #include <qcursor.h>
 #include <qlayout.h>
 #include <qtooltip.h>
@@ -29,8 +31,9 @@
 #include <qwmatrix.h>
 #include <qlistview.h>
 #include <qpopupmenu.h>
+#include <qdatetime.h>
 
-#include <time.h>
+#include <SUIT_TreeSync.h>
 
 /*!
     Class: OB_Browser::ToolTip
@@ -81,6 +84,138 @@ void OB_Browser::ToolTip::maybeTip( const QPoint& pos )
   tip( aRect, aText );
 }
 
+
+typedef SUIT_DataObject*   ObjPtr;
+typedef OB_ListItem*       ItemPtr;
+/*!
+    Class: OB_BrowserSync
+    Descr: Auxiliary class for synchronizing tree of SUIT_DataObjects and list view items
+*/
+
+class OB_BrowserSync
+{
+public:
+  OB_BrowserSync( OB_Browser* );
+  bool     isEqual( const ObjPtr&, const ItemPtr& ) const;
+  ObjPtr   nullSrc() const;
+  ItemPtr  nullTrg() const;
+  ItemPtr  createItem( const ObjPtr&, const ItemPtr&, const ItemPtr&, const bool ) const;
+  void     updateItem( const ItemPtr& ) const;
+  void     deleteItemWithChildren( const ItemPtr& ) const;
+  void     children( const ObjPtr&, QValueList<ObjPtr>& ) const;
+  void     children( const ItemPtr&, QValueList<ItemPtr>& ) const;
+  ItemPtr  parent( const ItemPtr& ) const;
+private:
+  bool     needUpdate( const ItemPtr& ) const;
+  OB_Browser*   myBrowser;
+};
+
+
+OB_BrowserSync::OB_BrowserSync( OB_Browser* ob )
+: myBrowser( ob )
+{
+}
+
+bool OB_BrowserSync::needUpdate( const ItemPtr& item ) const
+{
+  bool update = false;
+  if ( item ) {
+    SUIT_DataObject* obj = item->dataObject();
+    if ( obj ) {
+      // 1. check text
+      update = ( item->text( 0 ) != obj->name() );
+      if ( !update ) { 
+       // 2. check pixmap (compare serialNumber()-s)
+       QPixmap objPix = obj->icon();
+       const QPixmap* itemPix = item->pixmap( 0 );
+       update = (  objPix.isNull() && (  itemPix && !itemPix->isNull() ) ) || 
+                ( !objPix.isNull() && ( !itemPix ||  itemPix->isNull() ) ); 
+       if ( !update && !objPix.isNull() && itemPix && !itemPix->isNull() ) {
+         int aIconW = objPix.width();
+         if( aIconW > 20 ) {
+           QWMatrix aM;
+           double aScale = 20.0 / aIconW;
+           aM.scale( aScale, aScale );
+           objPix = objPix.xForm( aM );
+         }
+         update = ( objPix.serialNumber() != itemPix->serialNumber() );
+       }
+      }
+    }
+  }
+  return update;
+}
+
+void OB_BrowserSync::updateItem( const ItemPtr& p ) const
+{
+  if ( p && needUpdate( p ) ) { 
+    //    printf( "--- needUpdate for %s = true ---\n", p->text( 0 ).latin1() );
+    p->update();
+  }
+}
+
+ItemPtr OB_BrowserSync::createItem( const ObjPtr& src,
+                                   const ItemPtr& parent, const ItemPtr& after,
+                                   const bool asFirst ) const
+{
+  ItemPtr i = myBrowser ? dynamic_cast<ItemPtr>( myBrowser->createItem( src, parent, after, asFirst ) ) : 0;
+  if( i )
+    i->setOpen( src->isOpen() );
+  return i;
+}
+
+void OB_BrowserSync::deleteItemWithChildren( const ItemPtr& i ) const
+{
+  if( myBrowser && myBrowser->myItems.contains( i->dataObject() ) )
+  {
+    myBrowser->removeReferences( i );
+    delete i;
+  }
+}
+
+bool OB_BrowserSync::isEqual( const ObjPtr& p, const ItemPtr& q ) const
+{
+  return ( !p && !q ) || ( p && q && q->dataObject()==p );
+}
+
+ObjPtr OB_BrowserSync::nullSrc() const
+{
+  return 0;
+}
+
+ItemPtr OB_BrowserSync::nullTrg() const
+{
+  return 0;
+}
+
+void OB_BrowserSync::children( const ObjPtr& p, QValueList<ObjPtr>& ch ) const
+{
+  DataObjectList l;
+  if( p )
+  {
+    p->children( l );
+    ch.clear();
+    for( SUIT_DataObject* o = l.first(); o; o = l.next() )
+      ch.append( o );
+  }
+}
+
+void OB_BrowserSync::children( const ItemPtr& p, QValueList<ItemPtr>& ch ) const
+{
+  for( QListViewItem* item = p->firstChild(); item; item = item->nextSibling() )
+  {
+    ItemPtr p = dynamic_cast<ItemPtr>( item );
+    if( p )
+      ch.append( p );
+  }
+}
+
+ItemPtr OB_BrowserSync::parent( const ItemPtr& p ) const
+{
+  return p ? dynamic_cast<ItemPtr>( p->parent() ) : 0;
+}
+
+
 /*!
     Class: OB_Browser
     Descr: Hierarchical tree object browser.
@@ -514,6 +649,8 @@ void OB_Browser::setAppropriateColumn( const int id, const bool on )
 
 void OB_Browser::updateTree( SUIT_DataObject* obj, const bool autoOpen )
 {
+//  QTime t1 = QTime::currentTime();
+
   if ( !obj && !(obj = getRootObject()) )
     return;
 
@@ -536,6 +673,9 @@ void OB_Browser::updateTree( SUIT_DataObject* obj, const bool autoOpen )
 
   if ( selNum != numberOfSelected() )
     emit selectionChanged();
+
+//  QTime t2 = QTime::currentTime();
+//  qDebug( QString( "update tree time = %1 msecs" ).arg( t1.msecsTo( t2 ) ) );
 }
 
 void OB_Browser::replaceTree( SUIT_DataObject* src, SUIT_DataObject* trg )
@@ -578,84 +718,67 @@ void OB_Browser::replaceTree( SUIT_DataObject* src, SUIT_DataObject* trg )
     emit selectionChanged();
 }
 
-void OB_Browser::updateView( const SUIT_DataObject* theStartObj )
+void OB_Browser::updateView( SUIT_DataObject* startObj )
 {
   QListView* lv = listView();
   if ( !lv )
     return;
 
-  if ( !theStartObj || theStartObj->root() != getRootObject() )
+  if ( !startObj || startObj->root() != getRootObject() )
     return;
 
-  QListViewItem* after = 0;
-  QListViewItem* parent = 0;
-  QListViewItem* startItem = listViewItem( theStartObj );
-
-  if ( theStartObj->parent() )
-    parent = listViewItem( theStartObj->parent() );
-
-  QListViewItem* prv = 0;
-  QListViewItem* cur = parent ? parent->firstChild() : lv->firstChild();
-  while ( !after && cur )
+  if( startObj==myRoot )
   {
-    if ( cur == startItem )
-      after = prv;
-
-    prv = cur;
-    cur = cur->nextSibling();
-  }
+    DataObjectList ch;
+    myRoot->children( ch );
 
-  QPtrList<QListViewItem> delList;
-  if ( !startItem && theStartObj == getRootObject() )
-  {
-    for ( QListViewItem* item = lv->firstChild(); item; item = item->nextSibling() )
-      delList.append( item );
-  }
-  else
-    delList.append( startItem );
+    ItemMap exist;
+    QListViewItem* st = lv->firstChild();
+    for( ; st; st =  st->nextSibling() )
+    {
+      OB_ListItem* ob_item = dynamic_cast<OB_ListItem*>( st );
+      exist.insert( ob_item->dataObject(), ob_item );
+    }
 
-  for ( QPtrListIterator<QListViewItem> it( delList ); it.current(); ++it )
-  {
-    removeReferences( it.current() );
-    delete it.current();
-  }
+    SUIT_DataObject* local_root = ch.first();
+    for( ; local_root; local_root = ch.next() )
+    {
+      OB_BrowserSync sync( this );
+      OB_ListItem* local_item = dynamic_cast<OB_ListItem*>( listViewItem( local_root ) );
+      
+      //      QString srcName = ( local_root && !local_root->name().isNull() ) ? local_root->name() : "";
+      //      QString trgName = ( local_item && !local_item->text(0).isNull() ) ? local_item->text(0) : "";
+      //      printf( "--- OB_Browser::updateView() calls synchronize()_1: src = %s, trg = %s ---\n",  srcName.latin1(), trgName.latin1() );
+
+      synchronize<ObjPtr,ItemPtr,OB_BrowserSync>( local_root, local_item, sync );
+      exist[local_root] = 0;
+    }
 
-  // for myRoot object, if myShowRoot==false, then creating multiple top-level QListViewItem-s
-  // (which will correspond to myRoot's children = Modules).  
-  if ( rootIsDecorated() && theStartObj == myRoot )
-  {
-    DataObjectList lst;
-    theStartObj->children( lst );
-    DataObjectListIterator it ( lst );
-    // iterating backward to preserve the order of elements in the tree
-    for ( it.toLast(); it.current(); --it )
-      createTree( it.current(), 0, 0 );
+    ItemMap::const_iterator anIt = exist.begin(), aLast = exist.end();
+    for( ; anIt!=aLast; anIt++ )
+      if( anIt.data() )
+      {
+       removeReferences( anIt.data() );
+       OB_ListItem* item = dynamic_cast<OB_ListItem*>( anIt.data() );
+       if( item && myItems.contains( item->dataObject() ) )
+         delete anIt.data();
+      }
   }
   else
-    createTree( theStartObj, parent, after ? after : parent );
-}
-
-QListViewItem* OB_Browser::createTree( const SUIT_DataObject* obj,
-                                       QListViewItem* parent, QListViewItem* after )
-{
-  if ( !obj )
-    return 0;
-  
-  QListViewItem* item = createItem( obj, parent, after );
+  {
+    OB_BrowserSync sync( this );
+    OB_ListItem* startItem = dynamic_cast<OB_ListItem*>( listViewItem( startObj ) );
 
-  DataObjectList lst;
-  obj->children( lst );
-  for ( DataObjectListIterator it ( lst ); it.current(); ++it )
-    createTree( it.current(), item );
+    //    QString srcName = ( startObj && !startObj->name().isNull() ) ? startObj->name() : "";
+    //    QString trgName = ( startItem && !startItem->text(0).isNull() ) ? startItem->text(0) : "";
+    //    printf( "--- OB_Browser::updateView() calls synchronize()_2: src = %s, trg = %s ---\n",  srcName.latin1(), trgName.latin1() );
 
-  if ( item )
-    item->setOpen( obj->isOpen() );
-
-  return item;
+    synchronize<ObjPtr,ItemPtr,OB_BrowserSync>( startObj, startItem, sync );
+  }
 }
 
-QListViewItem* OB_Browser::createItem( const SUIT_DataObject* o,
-                                       QListViewItem* parent, QListViewItem* after )
+QListViewItem* OB_Browser::createItem( const SUIT_DataObject* o, QListViewItem* parent,
+                                      QListViewItem* after, const bool asFirstChild )
 {
   QListView* lv = listView();
 
@@ -686,7 +809,7 @@ QListViewItem* OB_Browser::createItem( const SUIT_DataObject* o,
         after = after->nextSibling();
     }
 
-    if ( after )
+    if ( after && !asFirstChild )
     {
       if ( type == -1 )
         item = new OB_ListItem( obj, parent, after );
@@ -711,7 +834,6 @@ QListViewItem* OB_Browser::createItem( const SUIT_DataObject* o,
 
   myItems.insert( obj, item );
   obj->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
-
   updateText( item );
 
   return item;
@@ -1099,7 +1221,7 @@ void OB_Browser::removeObject( SUIT_DataObject* obj, const bool autoUpd )
     return;
   }
 
-  if ( !autoUpd )
+  if( !autoUpd )
     return;
 
   if ( isAutoUpdate() )
@@ -1107,8 +1229,8 @@ void OB_Browser::removeObject( SUIT_DataObject* obj, const bool autoUpd )
     SUIT_DataObject* pObj = item && item->parent() ? dataObject( item->parent() ) : 0;
     updateTree( pObj, false );
   }
-  else
-    delete item;
+
+  delete item;
 }
 
 void OB_Browser::autoOpenBranches()
@@ -1149,3 +1271,4 @@ void OB_Browser::setModified()
 {
   myModifiedTime = clock();
 }
+
index c3b05ff2ee07f5db7c497002b1b723e45a6c47b3..a6e3cd42113231860df4d79739858decf157a98c 100755 (executable)
@@ -37,6 +37,7 @@
 class QToolTip;
 class OB_Filter;
 class OB_ListView;
+class OB_ListItem;
 
 class OB_EXPORT OB_Browser : public QFrame, public SUIT_PopupClient
 {
@@ -134,7 +135,7 @@ private slots:
 
 protected:
   void              adjustWidth( QListViewItem* );
-  virtual void      updateView( const SUIT_DataObject* theStartObj = 0 );
+  virtual void      updateView( SUIT_DataObject* = 0 );
   virtual void      updateText();
 
   virtual void      keyPressEvent( QKeyEvent* );
@@ -165,8 +166,8 @@ private:
   DataObjectKey     objectKey( QListViewItem* ) const;
   DataObjectKey     objectKey( SUIT_DataObject* ) const;
 
-  QListViewItem*    createTree( const SUIT_DataObject*, QListViewItem*, QListViewItem* = 0 );
-  QListViewItem*    createItem( const SUIT_DataObject*, QListViewItem*, QListViewItem* = 0 );
+  QListViewItem*    createTree( const SUIT_DataObject*, QListViewItem*, QListViewItem* = 0, const bool = false );
+  QListViewItem*    createItem( const SUIT_DataObject*, QListViewItem*, QListViewItem* = 0, const bool = false );
 
   SUIT_DataObject*  storeState( DataObjectMap&, DataObjectMap&,
                                 DataObjectKeyMap&, DataObjectKeyMap&, DataObjectKey& ) const;
@@ -174,6 +175,8 @@ private:
                                   const DataObjectKeyMap&, const DataObjectKeyMap&, const DataObjectKey& );
 
 private:
+  friend class OB_BrowserSync;
+
   OB_ListView*      myView;
   SUIT_DataObject*  myRoot;
   ItemMap           myItems;
index b2ced5c7bc77fbd83574f3ecc87ae88633a6ec3b..49ad75741da39d1611b64a3f09737cc5a0b8f47a 100755 (executable)
@@ -34,7 +34,7 @@ using namespace std;
 */
 
 template<class T>
-ListItemF<T>::ListItemF( T& theT, SUIT_DataObject* obj ) :
+ListItemF<T>::ListItemF( T* theT, SUIT_DataObject* obj ) :
 myT( theT ),
 myObject( obj )
 {
@@ -61,7 +61,7 @@ void ListItemF<T>::paintC( QPainter* p, QColorGroup& cg, int c, int w, int align
   }
 
   
-  p->fillRect( 0, 0, w, myT.height(), cg.brush( QColorGroup::Base ) );
+  p->fillRect( 0, 0, w, myT->height(), cg.brush( QColorGroup::Base ) );
   //int itemW = myT.width( p->fontMetrics(), myT.listView(), c );
     
   //myT.paintCell( p, colorGrp, c, itemW,  align );
@@ -71,18 +71,18 @@ template<class T>
 void ListItemF<T>::paintFoc( QPainter* p, QColorGroup& cg, const QRect& r )
 {
   QRect rect = r;
-  rect.setWidth( myT.width( p->fontMetrics(), myT.listView(), 0 ) );
+  rect.setWidth( myT->width( p->fontMetrics(), myT->listView(), 0 ) );
   //myT.paintFocus( p, cg, rect );
 }
 
 template<class T>
 void ListItemF<T>::setSel( bool s )
 {
-  QListView* lv = myT.listView();
+  QListView* lv = myT->listView();
   if ( s && lv && lv->inherits( "OB_ListView" ) )
   {
     OB_ListView* objlv = (OB_ListView*)lv;
-    s = s && objlv->isOk( &myT );
+    s = s && objlv->isOk( myT );
   }
 
   //myT.setSelected( s );
@@ -95,24 +95,27 @@ void ListItemF<T>::update()
   if ( !obj )
     return;
 
-  myT.setText( 0, obj->name() );
+  QString n = obj->name();
+  if( myT->text( 0 )!=n )
+    myT->setText( 0, n );
 
-  int aIconW = obj->icon().width();
-  if ( aIconW > 0 )
+  QPixmap p = obj->icon();
+  int aIconW = p.width();
+  if( aIconW > 0 )
   {
-    if ( aIconW > 20 )
+    if( aIconW > 20 )
     {
       QWMatrix aM;
       double aScale = 20.0 / aIconW;
       aM.scale( aScale, aScale );
-      myT.setPixmap( 0, obj->icon().xForm( aM ) );
+      myT->setPixmap( 0, p.xForm( aM ) );
     }
     else
-      myT.setPixmap( 0, obj->icon() );
+      myT->setPixmap( 0, p );
   }
 
-  myT.setDragEnabled( obj->isDragable() );
-  myT.setDropEnabled( true );
+  myT->setDragEnabled( obj->isDragable() );
+  myT->setDropEnabled( true );
 }
 
 /*!
@@ -121,31 +124,31 @@ void ListItemF<T>::update()
 */
 
 OB_ListItem::OB_ListItem( SUIT_DataObject* obj, QListView* parent )
-: ListItemF<QListViewItem>( *this, obj ),
+: ListItemF<QListViewItem>( this, obj ),
  QListViewItem(parent)
 {
-       update();
+  update();
 }
 
 OB_ListItem::OB_ListItem( SUIT_DataObject* obj, QListViewItem* parent )
-: ListItemF<QListViewItem>( *this, obj),
+: ListItemF<QListViewItem>( this, obj ),
  QListViewItem(parent)
 {
-       update();
+  update();
 }
 
 OB_ListItem::OB_ListItem( SUIT_DataObject* obj, QListView* parent, QListViewItem* after )
-: ListItemF<QListViewItem>( *this, obj),
+: ListItemF<QListViewItem>( this, obj),
 QListViewItem(parent, after )
 {
-       update();
+  update();
 }
 
 OB_ListItem::OB_ListItem( SUIT_DataObject* obj, QListViewItem* parent, QListViewItem* after )
-: ListItemF<QListViewItem>( *this,obj),
+: ListItemF<QListViewItem>( this,obj),
 QListViewItem(parent, after )
 {
-       update();
+  update();
 }
 
 OB_ListItem::~OB_ListItem()
@@ -154,8 +157,8 @@ OB_ListItem::~OB_ListItem()
 
 void OB_ListItem::setSelected( bool s )
 {
-       setSel( s );
-       QListViewItem::setSelected( s );
+  setSel( s );
+  QListViewItem::setSelected( s );
 }
 
 void OB_ListItem::paintFocus( QPainter* p, const QColorGroup& cg, const QRect& r )
@@ -209,39 +212,39 @@ void OB_ListItem::setText( int column, const QString& text )
 */
 
 OB_CheckListItem::OB_CheckListItem( SUIT_DataObject* obj, QListView* parent, Type type )
-: ListItemF<QCheckListItem>( *this, obj),
+: ListItemF<QCheckListItem>( this, obj),
 QCheckListItem( parent, "", type )
 {
-       update();
+  update();
 }
 
 OB_CheckListItem::OB_CheckListItem( SUIT_DataObject* obj, QListViewItem* parent, Type type )
-: ListItemF<QCheckListItem>( *this, obj),
+: ListItemF<QCheckListItem>( this, obj),
 QCheckListItem( parent, "", type )
 {
-       update();
+  update();
 }
 
 OB_CheckListItem::OB_CheckListItem( SUIT_DataObject* obj, QListView* parent, QListViewItem* after, Type type )
-: ListItemF<QCheckListItem>( *this, obj),
+: ListItemF<QCheckListItem>( this, obj),
 #if defined(QT_VERSION) && QT_VERSION >= 0x030101
  QCheckListItem( parent, after, "", type )
 #else
  QCheckListItem( parent, "", type )
 #endif
 {
-       update();
+  update();
 }
 
 OB_CheckListItem::OB_CheckListItem( SUIT_DataObject* obj, QListViewItem* parent, QListViewItem* after, Type type )
-: ListItemF<QCheckListItem>( *this, obj),
+: ListItemF<QCheckListItem>( this, obj),
 #if defined(QT_VERSION) && QT_VERSION >= 0x030101
  QCheckListItem( parent, after, "", type )
 #else
  QCheckListItem( parent, "", type )
 #endif
 {
-       update();
+  update();
 }
 
 OB_CheckListItem::~OB_CheckListItem()
index 6b06cd8424fdbfd81e77f8561ceb473a669ffabb..112c3c8c9ac0783b2abd5b73018ce4ef97591546 100755 (executable)
@@ -33,7 +33,7 @@ class SUIT_DataObject;
 template<class T> class ListItemF
 {
 public:
-       ListItemF(T&, SUIT_DataObject* );
+       ListItemF( T*, SUIT_DataObject* );
   /*ListItem( SUIT_DataObject*, QListView* );
   ListItem( SUIT_DataObject*, QListViewItem* );
   ListItem( SUIT_DataObject*, QListView*, QListViewItem* );
@@ -49,12 +49,12 @@ public:
   void            paintFoc( QPainter* p, QColorGroup& cg, const QRect& r );
   void            paintC( QPainter* p, QColorGroup& cg, int c, int w, int align );
 
-protected:
+//protected:
   void                     update();
 
 protected:
   SUIT_DataObject* myObject;
-  T& myT;
+  T myT;
 };
 
 /*