#include "OB_ListItem.h"
#include "OB_ListView.h"
+#include <SUIT_DataObjectIterator.h>
+
#include <qcursor.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <qwmatrix.h>
#include <qlistview.h>
#include <qpopupmenu.h>
+#include <qdatetime.h>
-#include <time.h>
+#include <SUIT_TreeSync.h>
/*!
Class: OB_Browser::ToolTip
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.
void OB_Browser::updateTree( SUIT_DataObject* obj, const bool autoOpen )
{
+// QTime t1 = QTime::currentTime();
+
if ( !obj && !(obj = getRootObject()) )
return;
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 )
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();
after = after->nextSibling();
}
- if ( after )
+ if ( after && !asFirstChild )
{
if ( type == -1 )
item = new OB_ListItem( obj, parent, after );
myItems.insert( obj, item );
obj->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
-
updateText( item );
return item;
return;
}
- if ( !autoUpd )
+ if( !autoUpd )
return;
if ( isAutoUpdate() )
SUIT_DataObject* pObj = item && item->parent() ? dataObject( item->parent() ) : 0;
updateTree( pObj, false );
}
- else
- delete item;
+
+ delete item;
}
void OB_Browser::autoOpenBranches()
{
myModifiedTime = clock();
}
+
*/
template<class T>
-ListItemF<T>::ListItemF( T& theT, SUIT_DataObject* obj ) :
+ListItemF<T>::ListItemF( T* theT, SUIT_DataObject* obj ) :
myT( theT ),
myObject( obj )
{
}
- 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 );
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 );
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 );
}
/*!
*/
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()
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 )
*/
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()