From 479624e2b6a81aa0998f3014b7df74bbb406f1eb Mon Sep 17 00:00:00 2001 From: asv Date: Thu, 26 Jan 2006 09:18:14 +0000 Subject: [PATCH] Synchronization algorithm between tree structures of SUIT_DataObjects and OB_ListItems is implemented (instanciated template methods defined in SUIT_TreeSync.h). --- src/ObjBrowser/OB_Browser.cxx | 257 ++++++++++++++++++++++++--------- src/ObjBrowser/OB_Browser.h | 9 +- src/ObjBrowser/OB_ListItem.cxx | 65 +++++---- src/ObjBrowser/OB_ListItem.h | 6 +- 4 files changed, 233 insertions(+), 104 deletions(-) diff --git a/src/ObjBrowser/OB_Browser.cxx b/src/ObjBrowser/OB_Browser.cxx index 66656c9cd..7ad1e6d44 100755 --- a/src/ObjBrowser/OB_Browser.cxx +++ b/src/ObjBrowser/OB_Browser.cxx @@ -22,6 +22,8 @@ #include "OB_ListItem.h" #include "OB_ListView.h" +#include + #include #include #include @@ -29,8 +31,9 @@ #include #include #include +#include -#include +#include /*! 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& ) const; + void children( const ItemPtr&, QValueList& ) 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( 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& 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& ch ) const +{ + for( QListViewItem* item = p->firstChild(); item; item = item->nextSibling() ) + { + ItemPtr p = dynamic_cast( item ); + if( p ) + ch.append( p ); + } +} + +ItemPtr OB_BrowserSync::parent( const ItemPtr& p ) const +{ + return p ? dynamic_cast( 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 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( st ); + exist.insert( ob_item->dataObject(), ob_item ); + } - for ( QPtrListIterator 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( 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( 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( 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( 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( 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(); } + diff --git a/src/ObjBrowser/OB_Browser.h b/src/ObjBrowser/OB_Browser.h index c3b05ff2e..a6e3cd421 100755 --- a/src/ObjBrowser/OB_Browser.h +++ b/src/ObjBrowser/OB_Browser.h @@ -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; diff --git a/src/ObjBrowser/OB_ListItem.cxx b/src/ObjBrowser/OB_ListItem.cxx index b2ced5c7b..49ad75741 100755 --- a/src/ObjBrowser/OB_ListItem.cxx +++ b/src/ObjBrowser/OB_ListItem.cxx @@ -34,7 +34,7 @@ using namespace std; */ template -ListItemF::ListItemF( T& theT, SUIT_DataObject* obj ) : +ListItemF::ListItemF( T* theT, SUIT_DataObject* obj ) : myT( theT ), myObject( obj ) { @@ -61,7 +61,7 @@ void ListItemF::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 void ListItemF::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 void ListItemF::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::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::update() */ OB_ListItem::OB_ListItem( SUIT_DataObject* obj, QListView* parent ) -: ListItemF( *this, obj ), +: ListItemF( this, obj ), QListViewItem(parent) { - update(); + update(); } OB_ListItem::OB_ListItem( SUIT_DataObject* obj, QListViewItem* parent ) -: ListItemF( *this, obj), +: ListItemF( this, obj ), QListViewItem(parent) { - update(); + update(); } OB_ListItem::OB_ListItem( SUIT_DataObject* obj, QListView* parent, QListViewItem* after ) -: ListItemF( *this, obj), +: ListItemF( this, obj), QListViewItem(parent, after ) { - update(); + update(); } OB_ListItem::OB_ListItem( SUIT_DataObject* obj, QListViewItem* parent, QListViewItem* after ) -: ListItemF( *this,obj), +: ListItemF( 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( *this, obj), +: ListItemF( this, obj), QCheckListItem( parent, "", type ) { - update(); + update(); } OB_CheckListItem::OB_CheckListItem( SUIT_DataObject* obj, QListViewItem* parent, Type type ) -: ListItemF( *this, obj), +: ListItemF( this, obj), QCheckListItem( parent, "", type ) { - update(); + update(); } OB_CheckListItem::OB_CheckListItem( SUIT_DataObject* obj, QListView* parent, QListViewItem* after, Type type ) -: ListItemF( *this, obj), +: ListItemF( 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( *this, obj), +: ListItemF( this, obj), #if defined(QT_VERSION) && QT_VERSION >= 0x030101 QCheckListItem( parent, after, "", type ) #else QCheckListItem( parent, "", type ) #endif { - update(); + update(); } OB_CheckListItem::~OB_CheckListItem() diff --git a/src/ObjBrowser/OB_ListItem.h b/src/ObjBrowser/OB_ListItem.h index 6b06cd842..112c3c8c9 100755 --- a/src/ObjBrowser/OB_ListItem.h +++ b/src/ObjBrowser/OB_ListItem.h @@ -33,7 +33,7 @@ class SUIT_DataObject; template 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; }; /* -- 2.39.2