1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "OB_Browser.h"
21 #include "OB_Filter.h"
22 #include "OB_ListItem.h"
23 #include "OB_ListView.h"
24 #include "OB_FindDlg.h"
26 #include <SUIT_DataObjectIterator.h>
27 #include <SUIT_TreeSync.h>
34 #include <qlistview.h>
35 #include <qpopupmenu.h>
36 #include <qdatetime.h>
41 \class OB_Browser::ToolTip
42 Tool tip for OB_Browser.
45 class OB_Browser::ToolTip : public QToolTip
48 ToolTip( OB_Browser* b, QWidget* p = 0 );
51 void maybeTip( const QPoint& );
54 OB_Browser* myBrowser;
60 OB_Browser::ToolTip::ToolTip( OB_Browser* b, QWidget* p )
69 OB_Browser::ToolTip::~ToolTip()
74 It is called when there is a possibility that a tool tip
75 should be shown and must decide whether there is a tool tip for the point
76 in the widget that this QToolTip object relates to.
77 \param pos - point co-ordinates
79 void OB_Browser::ToolTip::maybeTip( const QPoint& pos )
81 if ( !parentWidget() || !myBrowser || !myBrowser->isShowToolTips() )
84 QListView* lv = myBrowser->listView();
86 QListViewItem* item = lv->itemAt( pos );
87 SUIT_DataObject* obj = myBrowser->dataObject( item );
91 QString aText = obj->toolTip();
93 if ( aText.isEmpty() )
96 QRect aRect = lv->itemRect( item );
102 typedef SUIT_DataObject* ObjPtr;
103 typedef OB_ListItem* ItemPtr;
106 \class OB_BrowserSync
107 Auxiliary class for synchronizing tree of SUIT_DataObjects and list view items
112 OB_BrowserSync( OB_Browser* );
113 bool isEqual( const ObjPtr&, const ItemPtr& ) const;
114 ObjPtr nullSrc() const;
115 ItemPtr nullTrg() const;
116 ItemPtr createItem( const ObjPtr&, const ItemPtr&, const ItemPtr&, const bool ) const;
117 void updateItem( const ObjPtr& , const ItemPtr& ) const;
118 void deleteItemWithChildren( const ItemPtr& ) const;
119 void children( const ObjPtr&, QValueList<ObjPtr>& ) const;
120 void children( const ItemPtr&, QValueList<ItemPtr>& ) const;
121 ItemPtr parent( const ItemPtr& ) const;
123 bool needUpdate( const ItemPtr& ) const;
124 OB_Browser* myBrowser;
131 OB_BrowserSync::OB_BrowserSync( OB_Browser* ob )
137 \return true if item must be updated
138 \param item - item to be checked
140 bool OB_BrowserSync::needUpdate( const ItemPtr& item ) const
144 SUIT_DataObject* obj = item->dataObject();
147 update = ( item->text( 0 ) != obj->name() ) || myBrowser->needToUpdateTexts( item );
150 // 2. check pixmap (compare serialNumber()-s)
151 QPixmap objPix = obj->icon();
152 const QPixmap* itemPix = item->pixmap( 0 );
153 update = ( objPix.isNull() && ( itemPix && !itemPix->isNull() ) ) ||
154 ( !objPix.isNull() && ( !itemPix || itemPix->isNull() ) );
155 if ( !update && !objPix.isNull() && itemPix && !itemPix->isNull() ) {
156 int aIconW = objPix.width();
159 double aScale = 20.0 / aIconW;
160 aM.scale( aScale, aScale );
161 objPix = objPix.xForm( aM );
163 update = ( objPix.serialNumber() != itemPix->serialNumber() );
175 void OB_BrowserSync::updateItem( const ObjPtr& o, const ItemPtr& p ) const
177 if ( p && needUpdate( p ) ) {
178 // printf( "--- needUpdate for %s = true ---\n", p->text( 0 ).latin1() );
179 myBrowser->updateText( p );
182 if( o && myBrowser->getUpdater() )
184 myBrowser->getUpdater()->update( o, p );
189 Creates item by SUIT object
190 \param src - corresponding SUIT object
191 \param parent - parent for item
192 \param after - previous sibling for item
193 \param prepend - item must be added to start of children list
195 ItemPtr OB_BrowserSync::createItem( const ObjPtr& src,
196 const ItemPtr& parent, const ItemPtr& after,
197 const bool prepend ) const
199 ItemPtr i = myBrowser ? dynamic_cast<ItemPtr>( myBrowser->createItem( src, parent, after, prepend ) ) : 0;
201 i->setOpen( src->isOpen() );
206 Deletes object with all children
209 void OB_BrowserSync::deleteItemWithChildren( const ItemPtr& i ) const
211 if( myBrowser && myBrowser->myItems.contains( i->dataObject() ) )
213 myBrowser->removeReferences( i );
219 \return true if objects correspond each other at all
220 \param p - suit object
221 \param q - object browser item
223 bool OB_BrowserSync::isEqual( const ObjPtr& p, const ItemPtr& q ) const
225 bool isRoot = p==myBrowser->getRootObject() && !q,
226 isEq = p && q && q->dataObject()==p;
227 return isRoot || ( !p && !q ) || isEq;
231 \return null suit object
233 ObjPtr OB_BrowserSync::nullSrc() const
241 ItemPtr OB_BrowserSync::nullTrg() const
247 Fills list with children of SUIT object
248 \param p - SUIT object
249 \param ch - list to be filled
251 void OB_BrowserSync::children( const ObjPtr& p, QValueList<ObjPtr>& ch ) const
258 for( SUIT_DataObject* o = l.first(); o; o = l.next() )
264 Fills list with children of item
266 \param ch - list to be filled
268 void OB_BrowserSync::children( const ItemPtr& p, QValueList<ItemPtr>& ch ) const
270 for( QListViewItem* item = p ? p->firstChild() : myBrowser->listView()->firstChild(); item; item = item->nextSibling() )
272 ItemPtr p = dynamic_cast<ItemPtr>( item );
279 \return parent of item
282 ItemPtr OB_BrowserSync::parent( const ItemPtr& p ) const
284 return p ? dynamic_cast<ItemPtr>( p->parent() ) : 0;
291 OB_Browser::OB_Browser( QWidget* parent, SUIT_DataObject* root )
297 myAutoOpenLevel( 0 ),
298 myAutoUpdate( false ),
299 myAutoDelObjs( false ),
300 myRootDecorated( true )
302 myView = new OB_ListView( QtxListView::HeaderAuto, this );
303 myView->setAppropriate( myView->addColumn( "Data" ), false );
304 myView->setSorting( -1 );
305 myView->setRootIsDecorated( true );
306 myView->setSelectionMode( QListView::Extended );
307 myView->installEventFilter( this );
308 myView->viewport()->installEventFilter( this );
310 myFindDlg = new OB_FindDlg( this );
313 QVBoxLayout* main = new QVBoxLayout( this );
314 main->addWidget( myView, 1 );
315 main->addWidget( myFindDlg, 0 );
317 myShowToolTips = true;
318 myTooltip = new ToolTip( this, myView->viewport() );
320 connect( myView, SIGNAL( dropped( QPtrList<QListViewItem>, QListViewItem*, int ) ),
321 this, SLOT( onDropped( QPtrList<QListViewItem>, QListViewItem*, int ) ) );
322 connect( myView, SIGNAL( selectionChanged() ), this, SIGNAL( selectionChanged() ) );
323 connect( myView, SIGNAL( doubleClicked( QListViewItem* ) ),
324 this, SLOT( onDoubleClicked( QListViewItem* ) ) );
326 setRootObject( root );
334 OB_Browser::~OB_Browser()
342 \return true if root is decorated by +
344 bool OB_Browser::rootIsDecorated() const
346 return myRootDecorated;
350 Sets state "root is recorated"
351 \param decor - new value of state
353 void OB_Browser::setRootIsDecorated( const bool decor )
355 if ( decor == rootIsDecorated() )
358 myRootDecorated = decor;
359 updateTree( 0, false );
363 \return number of levels to be auto opened on update tree
365 int OB_Browser::autoOpenLevel() const
367 return myAutoOpenLevel;
371 Changes number of levels to be auto opened on update tree
372 \param level - new number of levels
374 void OB_Browser::setAutoOpenLevel( const int level )
376 if ( myAutoOpenLevel == level )
379 myAutoOpenLevel = level;
383 Opens branches from 1 to \alevels. If parameter value negative then autoOpenLevel() value will be used.
386 void OB_Browser::openLevels( const int levels )
388 int level = levels < 0 ? autoOpenLevel() : levels;
389 QListView* lv = listView();
390 if ( !lv || level < 1 )
393 QListViewItem* item = lv->firstChild();
396 openBranch( item, level );
397 item = item->nextSibling();
402 \return state "are tooltips shown"
404 bool OB_Browser::isShowToolTips()
406 return myShowToolTips;
410 Sets new value of state "are tooltips shown"
411 \param theDisplay - new value
413 void OB_Browser::setShowToolTips( const bool theDisplay )
415 myShowToolTips = theDisplay;
419 \return true if object browser automatically updates tree after SUIT object removing
421 bool OB_Browser::isAutoUpdate() const
427 Sets new value of "auto update": whether object browser automatically updates tree after SUIT object removing
429 void OB_Browser::setAutoUpdate( const bool on )
435 \return true if object browser must delete old tree on setRootObject(), replaceTree()
436 \sa setRootObject(), replaceTree()
438 bool OB_Browser::isAutoDeleteObjects() const
440 return myAutoDelObjs;
444 Sets whether object browser must delete old tree on setRootObject(), replaceTree()
445 \sa setRootObject(), replaceTree()
447 void OB_Browser::setAutoDeleteObjects( const bool on )
453 \return updater of browser
455 OB_Updater* OB_Browser::getUpdater() const
461 \sets new updater of browser
463 void OB_Browser::setUpdater( OB_Updater* theUpdate )
467 myUpdater = theUpdate;
471 \return root SUIT object of browser
473 SUIT_DataObject* OB_Browser::getRootObject() const
479 Sets new root SUIT object of browser
480 \param theRoot - new root object
482 void OB_Browser::setRootObject( SUIT_DataObject* theRoot )
484 DataObjectKey curKey;
485 DataObjectMap selObjs, openObjs;
486 DataObjectKeyMap selKeys, openKeys;
488 int selNum = numberOfSelected();
490 SUIT_DataObject* curObj = 0;
492 curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
494 removeConnections( myRoot );
495 if ( myRoot != theRoot && isAutoDeleteObjects() )
500 createConnections( myRoot );
503 updateView( myRoot );
504 else if ( listView() )
510 restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
516 if ( selNum != numberOfSelected() )
517 emit selectionChanged();
521 \return number of selected items
523 int OB_Browser::numberOfSelected() const
528 for ( QListViewItemIterator it( listView() ); it.current(); ++it )
529 if ( it.current()->isSelected() )
536 \return list of selected objects
538 DataObjectList OB_Browser::getSelected() const
546 Fills list with selected objects
548 void OB_Browser::getSelected( DataObjectList& theObjList ) const
555 for ( QListViewItemIterator it( listView() ); it.current(); ++it )
557 if ( it.current()->isSelected() )
559 SUIT_DataObject* obj = dataObject( it.current() );
561 theObjList.append( obj );
568 \param theObject - new selected object
569 \param append - if it is true, then other selected objects are left as selected,
570 otherwise only 'theObject' will be selected
572 void OB_Browser::setSelected( const SUIT_DataObject* theObject, const bool append )
575 lst.append( theObject );
576 setSelected( lst, append );
580 Sets selected objects
581 \param theObjLst - new selected objects
582 \param append - if it is true, then other selected objects are left as selected,
583 otherwise only 'theObjLst' will be selected
585 void OB_Browser::setSelected( const DataObjectList& theObjLst, const bool append )
587 QListView* lv = listView();
592 bool changed = false;
593 bool block = lv->signalsBlocked();
594 lv->blockSignals( true );
596 QMap<QListViewItem*, int> map;
597 for ( DataObjectListIterator itr( theObjLst ); itr.current(); ++itr )
598 map.insert( listViewItem( itr.current() ), 0 );
600 for ( QListViewItemIterator it( lv ); it.current(); ++it )
602 QListViewItem* item = it.current();
603 if ( map.contains( item ) && !lv->isSelected( item ) )
606 lv->setSelected( item, true );
608 if ( !append && !map.contains( item ) && lv->isSelected( item ) )
611 lv->setSelected( item, false );
615 lv->blockSignals( block );
620 QListViewItem* sel = 0;
621 QListViewItem* cur = lv->currentItem();
622 for ( QListViewItemIterator iter( lv ); iter.current() && !sel; ++iter, count++ )
624 if ( iter.current()->isSelected() && cur == iter.current() )
625 sel = iter.current();
628 for ( QListViewItemIterator itr( lv ); itr.current() && !sel; ++itr )
630 if ( itr.current()->isSelected() )
635 lv->setCurrentItem( sel );
637 if ( sel && count == 1 )
638 lv->ensureItemVisible( sel );
640 emit selectionChanged();
645 \return true if item corresponding to object is opened
646 \param theObject - object to be checked
648 bool OB_Browser::isOpen( SUIT_DataObject* theObject ) const
652 res = listView()->isOpen( listViewItem( theObject ) );
657 Sets opened state of item
658 \param theObject - object corresponding to item
659 \param theOpen - new opened state
661 void OB_Browser::setOpen( SUIT_DataObject* theObject, const bool theOpen )
664 listView()->setOpen( listViewItem( theObject ), theOpen );
668 \return SUIT object correspondint to item at position 'pos'
669 \param pos - position
671 SUIT_DataObject* OB_Browser::dataObjectAt( const QPoint& pos ) const
673 SUIT_DataObject* obj = 0;
675 QListView* lv = listView();
677 obj = dataObject( lv->itemAt( pos ) );
683 \return filter of list view
685 OB_Filter* OB_Browser::filter() const
687 return myView->filter();
691 Changes filter of list view
692 \param f - new filter
694 void OB_Browser::setFilter( OB_Filter* f )
696 myView->setFilter( f );
700 Adds new column to list view
701 \param label - title of column
702 \param id - id of column
703 \param width - width of column
705 int OB_Browser::addColumn( const QString& label, const int id, const int width )
707 return addColumn( QIconSet(), label, id, width );
711 Adds new column to list view
712 \param icon - icon of column
713 \param label - title of column
714 \param id - id of column
715 \param width - width of column
717 int OB_Browser::addColumn( const QIconSet& icon, const QString& label, const int id, const int width )
719 QListView* lv = listView();
726 while ( myColumnIds.contains( theId ) )
730 if ( myColumnIds.contains( theId ) )
731 return -1; // can not reuse id
735 sec = lv->addColumn( label, width );
737 sec = lv->addColumn( icon, label, width );
742 myColumnIds.insert( theId, sec );
750 \param id - id of column
752 void OB_Browser::removeColumn( const int id )
754 QListView* lv = listView();
755 if ( !lv || !myColumnIds.contains( id ) )
758 int sec = myColumnIds[id];
759 lv->removeColumn( sec );
761 // update map of column indeces
762 myColumnIds.remove( id );
763 for ( QMap<int, int>::iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
772 Sets title of first column (name column)
773 \param label - new title
775 void OB_Browser::setNameTitle( const QString& label )
777 setNameTitle( QIconSet(), label );
781 Sets title and icon of first column (name column)
782 \param icon - new icon
783 \param label - new title
785 void OB_Browser::setNameTitle( const QIconSet& icon, const QString& label )
787 QListView* lv = listView();
792 lv->setColumnText( 0, label );
794 lv->setColumnText( 0, icon, label );
799 \param id - column id
800 \param label - new column title
802 void OB_Browser::setColumnTitle( const int id, const QString& label )
804 setColumnTitle( id, QIconSet(), label );
808 Sets title and icon of column
809 \param id - column id
810 \param icon - new column icon
811 \param label - new column title
813 void OB_Browser::setColumnTitle( const int id, const QIconSet& icon, const QString& label )
815 QListView* lv = listView();
816 if ( !lv || !myColumnIds.contains( id ) )
820 lv->setColumnText( myColumnIds[id], label );
822 lv->setColumnText( myColumnIds[id], icon, label );
826 \return title of first column (name column)
828 QString OB_Browser::nameTitle() const
830 return myView->columnText( 0 );
834 \return title of first column (name column)
835 \param id - column id
837 QString OB_Browser::columnTitle( const int id ) const
840 if ( myColumnIds.contains( id ) )
841 txt = myView->columnText( myColumnIds[id] );
846 \return true if column is visible
847 \param id - column id
849 bool OB_Browser::isColumnVisible( const int id ) const
851 return myColumnIds.contains( id ) && myView->isShown( myColumnIds[id] );
855 Sets visibility of column
856 \param id - column id
857 \param on - new visibility state
859 void OB_Browser::setColumnShown( const int id, const bool on )
861 if ( !myColumnIds.contains( id ) )
864 myView->setShown( myColumnIds[id], on );
866 myView->setColumnWidthMode( myColumnIds[id], QListView::Manual );
870 Sets global width mode
871 \param mode - new width mode
873 void OB_Browser::setWidthMode( QListView::WidthMode mode )
875 for ( int i = 0, n = myView->columns(); i < n; i++ )
876 if( mode!=QListView::Maximum || myView->columnWidth( i )>0 )
877 myView->setColumnWidthMode( i, mode );
881 \return list of columns ids
883 QValueList<int> OB_Browser::columns() const
886 for ( QMap<int, int>::ConstIterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
887 lst.append( it.key() );
892 \return true if it is possible to show/hide column by popup
893 \param id - column id
895 bool OB_Browser::appropriateColumn( const int id ) const
898 if ( myColumnIds.contains( id ) )
899 res = myView->appropriate( myColumnIds[id] );
904 Sets "appropriate state": is it possible to show/hide column by popup
905 \param id - column id
906 \param on - new state
908 void OB_Browser::setAppropriateColumn( const int id, const bool on )
910 if ( !myColumnIds.contains( id ) )
913 myView->setAppropriate( myColumnIds[id], on );
918 \param obj - start object
919 \param autoOpen - to open automatically branches of autoOpenLevel()
922 void OB_Browser::updateTree( SUIT_DataObject* obj, const bool autoOpen )
924 // QTime t1 = QTime::currentTime();
926 if ( !obj && !(obj = getRootObject()) )
929 DataObjectKey curKey;
930 DataObjectMap selObjs, openObjs;
931 DataObjectKeyMap selKeys, openKeys;
933 int selNum = numberOfSelected();
935 SUIT_DataObject* curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
939 restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
946 if ( selNum != numberOfSelected() )
947 emit selectionChanged();
949 // QTime t2 = QTime::currentTime();
950 // qDebug( QString( "update tree time = %1 msecs" ).arg( t1.msecsTo( t2 ) ) );
954 Replaces part of tree starting at object 'src' by tree starting at object 'trg'
956 void OB_Browser::replaceTree( SUIT_DataObject* src, SUIT_DataObject* trg )
958 if ( !src || !trg || src == trg || src->root() != getRootObject() )
961 DataObjectKey curKey;
962 DataObjectMap selObjs, openObjs;
963 DataObjectKeyMap selKeys, openKeys;
965 int selNum = numberOfSelected();
967 SUIT_DataObject* curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
969 SUIT_DataObject* parent = src->parent();
970 int pos = parent ? parent->childPos( src ) : -1;
974 removeConnections( src );
975 if ( isAutoDeleteObjects() )
978 if ( parent && pos != -1 )
979 parent->insertChild( trg, pos );
981 trg->setParent( parent );
984 createConnections( trg );
986 restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
990 if ( selNum != numberOfSelected() )
991 emit selectionChanged();
996 \param startObj - start object
998 void OB_Browser::updateView( SUIT_DataObject* startObj )
1000 QListView* lv = listView();
1004 if ( !startObj || startObj->root() != getRootObject() )
1007 //qDebug( "updateView:" );
1010 if ( startObj == myRoot )
1012 OB_BrowserSync sync( this );
1013 synchronize<ObjPtr,ItemPtr,OB_BrowserSync>( myRoot, 0, sync );
1017 OB_BrowserSync sync( this );
1018 OB_ListItem* startItem = dynamic_cast<OB_ListItem*>( listViewItem( startObj ) );
1019 synchronize<ObjPtr,ItemPtr,OB_BrowserSync>( startObj, startItem, sync );
1024 Creates new list item
1026 \param o - corresponding SUIT object
1027 \param parent - parent item
1028 \param after - item after that new item must be added
1029 \param prepend - new item must be added as first
1031 QListViewItem* OB_Browser::createItem( const SUIT_DataObject* o, QListViewItem* parent,
1032 QListViewItem* after, const bool prepend )
1034 QListView* lv = listView();
1039 QListViewItem* item = 0;
1040 SUIT_DataObject* obj = (SUIT_DataObject*)o;
1044 switch ( obj->checkType() )
1046 case SUIT_DataObject::CheckBox:
1047 type = QCheckListItem::CheckBox;
1049 case SUIT_DataObject::RadioButton:
1050 type = QCheckListItem::RadioButton;
1059 item = new OB_ListItem( obj, parent, after );
1061 item = new OB_CheckListItem( obj, parent, after, (QCheckListItem::Type)type );
1066 item = new OB_ListItem( obj, parent );
1068 item = new OB_CheckListItem( obj, parent, (QCheckListItem::Type)type );
1072 after = parent->firstChild();
1073 while ( after && after->nextSibling() )
1074 after = after->nextSibling();
1076 item = new OB_ListItem( obj, parent, after );
1078 item = new OB_CheckListItem( obj, parent, after, (QCheckListItem::Type)type );
1086 item = new OB_ListItem( obj, lv, after );
1088 item = new OB_CheckListItem( obj, lv, after, (QCheckListItem::Type)type );
1093 item = new OB_ListItem( obj, lv );
1095 item = new OB_CheckListItem( obj, lv, (QCheckListItem::Type)type );
1099 after = lv->firstChild();
1100 while ( after && after->nextSibling() )
1101 after = after->nextSibling();
1103 item = new OB_ListItem( obj, lv, after );
1105 item = new OB_CheckListItem( obj, lv, after, (QCheckListItem::Type)type );
1109 myItems.insert( obj, item );
1110 obj->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1117 Adjusts width by root item
1119 void OB_Browser::adjustWidth()
1124 listView()->setColumnWidth( 0, 0 );
1125 if ( listView()->firstChild() )
1126 adjustWidth( listView()->firstChild() );
1130 Adjusts width by item
1133 void OB_Browser::adjustWidth( QListViewItem* item )
1137 item->widthChanged( 0 );
1138 if ( item->isOpen() )
1139 adjustWidth( item->firstChild() );
1140 item = item->nextSibling();
1145 \return SUIT object corresponding to item
1148 SUIT_DataObject* OB_Browser::dataObject( const QListViewItem* item ) const
1150 SUIT_DataObject* obj = 0;
1152 if ( item && item->rtti() == OB_ListItem::RTTI() )
1153 obj = ((OB_ListItem*)item)->dataObject();
1154 else if ( item && item->rtti() == OB_CheckListItem::RTTI() )
1155 obj = ((OB_CheckListItem*)item)->dataObject();
1161 \return item corresponding to SUIT object
1162 \param obj - SUIT object
1164 QListViewItem* OB_Browser::listViewItem( const SUIT_DataObject* obj ) const
1166 QListViewItem* item = 0;
1168 if ( myItems.contains( (SUIT_DataObject*)obj ) )
1169 item = myItems[(SUIT_DataObject*)obj];
1175 \return list view of object browser
1177 QListView* OB_Browser::listView() const
1183 \remove all items referencing current (through data objects)
1185 void OB_Browser::removeReferences( QListViewItem* item )
1190 SUIT_DataObject* obj = dataObject( item );
1191 obj->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1192 myItems.remove( obj );
1194 QListViewItem* i = item->firstChild();
1197 removeReferences( i );
1198 i = i->nextSibling();
1203 Connects all children to SLOT onDestroyed
1205 void OB_Browser::createConnections( SUIT_DataObject* obj )
1210 DataObjectList childList;
1211 obj->children( childList, true );
1213 childList.prepend( obj );
1215 for ( DataObjectListIterator it( childList ); it.current(); ++it )
1216 it.current()->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1220 Disconnects all children from SLOT onDestroyed
1222 void OB_Browser::removeConnections( SUIT_DataObject* obj )
1227 DataObjectList childList;
1228 obj->children( childList, true );
1230 childList.prepend( obj );
1232 for ( DataObjectListIterator it( childList ); it.current(); ++it )
1233 it.current()->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1237 Stores states (opened, selected) of current tree items
1238 \return current item
1239 \param selObjs, selKeys - maps of selected objects
1240 \param openObjs, openKeys - maps of opened objects
1241 \param curKey - map of current objects
1243 SUIT_DataObject* OB_Browser::storeState( DataObjectMap& selObjs, DataObjectMap& openObjs,
1244 DataObjectKeyMap& selKeys, DataObjectKeyMap& openKeys,
1245 DataObjectKey& curKey ) const
1247 QListView* lv = listView();
1251 SUIT_DataObject* curObj = dataObject( lv->currentItem() );
1253 curKey = objectKey( curObj );
1255 for ( QListViewItemIterator it( lv ); it.current(); ++it )
1257 SUIT_DataObject* obj = dataObject( it.current() );
1261 selObjs.insert( obj, lv->isSelected( it.current() ) );
1262 openObjs.insert( obj, lv->isOpen( it.current() ) );
1263 if ( lv->isSelected( it.current() ) )
1264 selKeys.insert( objectKey( obj ), 0 );
1265 if ( lv->isOpen( it.current() ) )
1266 openKeys.insert( objectKey( obj ), 0 );
1273 Restores states (opened, selected) of current tree items
1274 \param selObjs, selKeys - maps of selected objects
1275 \param openObjs, openKeys - maps of opened objects
1276 \param curKey - map of current objects
1278 void OB_Browser::restoreState( const DataObjectMap& selObjs, const DataObjectMap& openObjs,
1279 const SUIT_DataObject* curObj, const DataObjectKeyMap& selKeys,
1280 const DataObjectKeyMap& openKeys, const DataObjectKey& curKey )
1282 QListView* lv = listView();
1286 bool block = lv->signalsBlocked();
1287 lv->blockSignals( true );
1289 QListViewItem* curItem = 0;
1290 for ( QListViewItemIterator it( lv ); it.current(); ++it )
1292 QListViewItem* item = it.current();
1293 SUIT_DataObject* obj = dataObject( item );
1298 DataObjectKey key = objectKey( obj );
1300 if ( selObjs.contains( obj ) )
1302 if ( selObjs[obj] && !lv->isSelected( item ) )
1303 lv->setSelected( item, true );
1305 else if ( !key.isNull() && selKeys.contains( key ) && !lv->isSelected( item ) )
1306 lv->setSelected( item, true );
1308 if ( openObjs.contains( obj ) )
1310 bool parentOpen = true;
1311 if( item && item->parent() )
1312 parentOpen = item->parent()->isOpen();
1314 if ( openObjs[obj] && parentOpen )
1315 lv->setOpen( item, true );
1317 else if ( !key.isNull() && openKeys.contains( key ) )
1319 bool parentOpen = true;
1320 if( item && item->parent() )
1321 parentOpen = item->parent()->isOpen();
1324 lv->setOpen( item, true );
1327 if ( !curItem && ( curObj == obj || ( !curKey.isNull() && curKey == key )) )
1332 lv->setCurrentItem( curItem );
1334 lv->blockSignals( block );
1338 Creates object key by tree item
1340 OB_Browser::DataObjectKey OB_Browser::objectKey( QListViewItem* i ) const
1342 return objectKey( dataObject( i ) );
1346 Creates object key by SUIT object
1348 OB_Browser::DataObjectKey OB_Browser::objectKey( SUIT_DataObject* obj ) const
1353 return DataObjectKey( obj->key() );
1357 Custom key press event handler, updates tree by F5
1359 void OB_Browser::keyPressEvent( QKeyEvent* e )
1361 if ( e->key() == Qt::Key_F5 )
1362 updateTree( 0, false );
1364 QFrame::keyPressEvent( e );
1368 SLOT: called if action "Expand all" is activated
1370 void OB_Browser::onExpand()
1372 DataObjectList selected;
1373 getSelected( selected );
1374 for ( DataObjectListIterator itr( selected ); itr.current(); ++itr )
1375 expand( listViewItem( itr.current() ) );
1379 SLOT: called if action "Show/hide column" is activated by popup
1381 void OB_Browser::onColumnVisible( int id )
1383 setColumnShown( id, !isColumnVisible( id ) );
1387 SLOT: called if SUIT object is destroyed
1389 void OB_Browser::onDestroyed( SUIT_DataObject* obj )
1391 removeObject( obj );
1395 SLOT: called on finish of drag-n-drop operation
1396 \param items - dragged items
1397 \param item - destination (item on that they were dropped)
1398 \param action - QDropEvent::Action
1400 void OB_Browser::onDropped( QPtrList<QListViewItem> items, QListViewItem* item, int action )
1402 SUIT_DataObject* obj = dataObject( item );
1407 for ( QPtrListIterator<QListViewItem> it( items ); it.current(); ++it )
1409 SUIT_DataObject* o = dataObject( it.current() );
1414 if ( !lst.isEmpty() )
1415 emit dropped( lst, obj, action );
1419 Updates texts of items
1421 void OB_Browser::updateText()
1423 if ( myColumnIds.isEmpty() )
1426 QListView* lv = listView();
1430 for ( QListViewItemIterator it( lv ); it.current(); ++it )
1432 SUIT_DataObject* obj = dataObject( it.current() );
1436 for( QMap<int, int>::iterator itr = myColumnIds.begin(); itr != myColumnIds.end(); ++itr )
1437 it.current()->setText( itr.data(), obj->text( itr.key() ) );
1442 \return true if item must be updated
1443 \param item - item to be checked
1445 bool OB_Browser::needToUpdateTexts( QListViewItem* item ) const
1447 SUIT_DataObject* obj = dataObject( item );
1451 for( QMap<int, int>::const_iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
1452 if( item->text( it.data() ) != obj->text( it.key() ) )
1458 Updates texts of item
1459 \param item - item to be updated
1461 void OB_Browser::updateText( QListViewItem* item )
1463 SUIT_DataObject* obj = dataObject( item );
1467 for( QMap<int, int>::iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
1468 item->setText( it.data(), obj->text( it.key() ) );
1474 bool OB_Browser::eventFilter( QObject* o, QEvent* e )
1476 if ( o == myView && e->type() == QEvent::ContextMenu )
1478 QContextMenuEvent* ce = (QContextMenuEvent*)e;
1479 if ( ce->reason() != QContextMenuEvent::Mouse )
1480 contextMenuRequest( ce );
1483 if ( o == myView->viewport() && e->type() == QEvent::MouseButtonRelease )
1485 QMouseEvent* me = (QMouseEvent*)e;
1486 if ( me->button() == RightButton )
1488 QContextMenuEvent ce( QContextMenuEvent::Mouse, me->pos(), me->globalPos(), me->state() );
1489 contextMenuRequest( &ce );
1494 return QFrame::eventFilter( o, e );
1498 Adds custom actions to popup
1499 \param menu - popup menu
1501 void OB_Browser::contextMenuPopup( QPopupMenu* menu )
1503 /* QValueList<int> cols;
1504 for ( QMap<int, int>::ConstIterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
1506 if ( appropriateColumn( it.key() ) )
1507 cols.append( it.key() );
1510 uint num = menu->count();
1511 menu->setCheckable( true );
1512 for ( QValueList<int>::const_iterator iter = cols.begin(); iter != cols.end(); ++iter )
1514 QString name = columnTitle( *iter );
1515 if ( name.isEmpty() )
1518 int id = menu->insertItem( name, this, SLOT( onColumnVisible( int ) ) );
1519 menu->setItemChecked( id, isColumnVisible( *iter ) );
1520 menu->setItemParameter( id, *iter );
1522 if ( menu->count() != num )
1523 menu->insertSeparator();*/
1525 DataObjectList selected;
1526 getSelected( selected );
1528 bool closed = false;
1529 for ( DataObjectListIterator itr( selected ); itr.current() && !closed; ++itr )
1530 closed = hasClosed( listViewItem( itr.current() ) );
1534 menu->insertItem( tr( "MEN_EXPAND_ALL" ), this, SLOT( onExpand() ) );
1535 menu->insertSeparator();
1540 Expands item with all it's children
1542 void OB_Browser::expand( QListViewItem* item )
1547 item->setOpen( true );
1548 for ( QListViewItem* child = item->firstChild(); child; child = child->nextSibling() )
1553 \return true if item or one of it's children isn't opened
1555 bool OB_Browser::hasClosed( QListViewItem* item ) const
1560 if ( item->childCount() && !item->isOpen() )
1564 for ( QListViewItem* child = item->firstChild(); child && !has; child = child->nextSibling() )
1565 has = hasClosed( child );
1572 \param obj - SUIT object to be removed
1573 \param autoUpd - auto tree updating
1575 void OB_Browser::removeObject( SUIT_DataObject* obj, const bool autoUpd )
1580 // Removing list view items from <myItems> recursively for all children.
1581 // Otherwise, "delete item" line will destroy all item's children,
1582 // and <myItems> will contain invalid pointers (see ~QListViewItem() description in Qt docs)
1583 DataObjectList childList;
1584 obj->children( childList, true );
1585 for ( DataObjectListIterator it( childList ); it.current(); ++it )
1587 it.current()->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1588 myItems.remove( it.current() );
1591 QListViewItem* item = listViewItem( obj );
1593 obj->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1594 myItems.remove( obj );
1596 if ( obj == myRoot )
1598 // remove all child list view items
1606 if ( isAutoUpdate() )
1608 SUIT_DataObject* pObj = item && item->parent() ? dataObject( item->parent() ) : 0;
1609 updateTree( pObj, false );
1616 Opens branches from 1 to autoOpenLevel()
1619 void OB_Browser::autoOpenBranches()
1629 void OB_Browser::openBranch( QListViewItem* item, const int level )
1636 item->setOpen( true );
1637 openBranch( item->firstChild(), level - 1 );
1638 item = item->nextSibling();
1643 SLOT: called on double click on item, emits signal
1645 void OB_Browser::onDoubleClicked( QListViewItem* item )
1648 emit doubleClicked( dataObject( item ) );
1652 Stores time of last modification
1654 void OB_Browser::setModified()
1656 myModifiedTime = clock();
1659 OB_ObjSearch* OB_Browser::getSearch() const
1661 return myFindDlg->getSearch();
1664 void OB_Browser::setSearch( OB_ObjSearch* s )
1666 myFindDlg->setSearch( s );
1669 void OB_Browser::enableSearch( const bool on )
1671 myFindDlg->setShown( on );