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/
19 #include "OB_Browser.h"
21 #include "OB_Filter.h"
22 #include "OB_ListItem.h"
23 #include "OB_ListView.h"
25 #include <SUIT_DataObjectIterator.h>
26 #include <SUIT_TreeSync.h>
33 #include <qlistview.h>
34 #include <qpopupmenu.h>
35 #include <qdatetime.h>
40 \class OB_Browser::ToolTip
41 Tool tip for OB_Browser.
44 class OB_Browser::ToolTip : public QToolTip
47 ToolTip( OB_Browser* b, QWidget* p = 0 );
50 void maybeTip( const QPoint& );
53 OB_Browser* myBrowser;
59 OB_Browser::ToolTip::ToolTip( OB_Browser* b, QWidget* p )
68 OB_Browser::ToolTip::~ToolTip()
73 It is called when there is a possibility that a tool tip
74 should be shown and must decide whether there is a tool tip for the point
75 in the widget that this QToolTip object relates to.
76 \param pos - point co-ordinates
78 void OB_Browser::ToolTip::maybeTip( const QPoint& pos )
80 if ( !parentWidget() || !myBrowser || !myBrowser->isShowToolTips() )
83 QListView* lv = myBrowser->listView();
85 QListViewItem* item = lv->itemAt( pos );
86 SUIT_DataObject* obj = myBrowser->dataObject( item );
90 QString aText = obj->toolTip();
92 if ( aText.isEmpty() )
95 QRect aRect = lv->itemRect( item );
101 typedef SUIT_DataObject* ObjPtr;
102 typedef OB_ListItem* ItemPtr;
105 \class OB_BrowserSync
106 Auxiliary class for synchronizing tree of SUIT_DataObjects and list view items
111 OB_BrowserSync( OB_Browser* );
112 bool isEqual( const ObjPtr&, const ItemPtr& ) const;
113 ObjPtr nullSrc() const;
114 ItemPtr nullTrg() const;
115 ItemPtr createItem( const ObjPtr&, const ItemPtr&, const ItemPtr&, const bool ) const;
116 void updateItem( const ItemPtr& ) const;
117 void deleteItemWithChildren( const ItemPtr& ) const;
118 void children( const ObjPtr&, QValueList<ObjPtr>& ) const;
119 void children( const ItemPtr&, QValueList<ItemPtr>& ) const;
120 ItemPtr parent( const ItemPtr& ) const;
122 bool needUpdate( const ItemPtr& ) const;
123 OB_Browser* myBrowser;
130 OB_BrowserSync::OB_BrowserSync( OB_Browser* ob )
136 \return true if item must be updated
137 \param item - item to be checked
139 bool OB_BrowserSync::needUpdate( const ItemPtr& item ) const
143 SUIT_DataObject* obj = item->dataObject();
146 update = ( item->text( 0 ) != obj->name() ) || myBrowser->needToUpdateTexts( item );
149 // 2. check pixmap (compare serialNumber()-s)
150 QPixmap objPix = obj->icon();
151 const QPixmap* itemPix = item->pixmap( 0 );
152 update = ( objPix.isNull() && ( itemPix && !itemPix->isNull() ) ) ||
153 ( !objPix.isNull() && ( !itemPix || itemPix->isNull() ) );
154 if ( !update && !objPix.isNull() && itemPix && !itemPix->isNull() ) {
155 int aIconW = objPix.width();
158 double aScale = 20.0 / aIconW;
159 aM.scale( aScale, aScale );
160 objPix = objPix.xForm( aM );
162 update = ( objPix.serialNumber() != itemPix->serialNumber() );
174 void OB_BrowserSync::updateItem( const ItemPtr& p ) const
176 if ( p && needUpdate( p ) ) {
177 // printf( "--- needUpdate for %s = true ---\n", p->text( 0 ).latin1() );
178 myBrowser->updateText( p );
184 Creates item by SUIT object
185 \param src - corresponding SUIT object
186 \param parent - parent for item
187 \param after - previous sibling for item
188 \param prepend - item must be added to start of children list
190 ItemPtr OB_BrowserSync::createItem( const ObjPtr& src,
191 const ItemPtr& parent, const ItemPtr& after,
192 const bool prepend ) const
194 ItemPtr i = myBrowser ? dynamic_cast<ItemPtr>( myBrowser->createItem( src, parent, after, prepend ) ) : 0;
196 i->setOpen( src->isOpen() );
201 Deletes object with all children
204 void OB_BrowserSync::deleteItemWithChildren( const ItemPtr& i ) const
206 if( myBrowser && myBrowser->myItems.contains( i->dataObject() ) )
208 myBrowser->removeReferences( i );
214 \return true if objects correspond each other at all
215 \param p - suit object
216 \param q - object browser item
218 bool OB_BrowserSync::isEqual( const ObjPtr& p, const ItemPtr& q ) const
220 bool isRoot = p==myBrowser->getRootObject() && !q,
221 isEq = p && q && q->dataObject()==p;
222 return isRoot || ( !p && !q ) || isEq;
226 \return null suit object
228 ObjPtr OB_BrowserSync::nullSrc() const
236 ItemPtr OB_BrowserSync::nullTrg() const
242 Fills list with children of SUIT object
243 \param p - SUIT object
244 \param ch - list to be filled
246 void OB_BrowserSync::children( const ObjPtr& p, QValueList<ObjPtr>& ch ) const
253 for( SUIT_DataObject* o = l.first(); o; o = l.next() )
259 Fills list with children of item
261 \param ch - list to be filled
263 void OB_BrowserSync::children( const ItemPtr& p, QValueList<ItemPtr>& ch ) const
265 for( QListViewItem* item = p ? p->firstChild() : myBrowser->listView()->firstChild(); item; item = item->nextSibling() )
267 ItemPtr p = dynamic_cast<ItemPtr>( item );
274 \return parent of item
277 ItemPtr OB_BrowserSync::parent( const ItemPtr& p ) const
279 return p ? dynamic_cast<ItemPtr>( p->parent() ) : 0;
286 OB_Browser::OB_Browser( QWidget* parent, SUIT_DataObject* root )
291 myAutoOpenLevel( 0 ),
292 myAutoUpdate( false ),
293 myAutoDelObjs( false ),
294 myRootDecorated( true )
296 myView = new OB_ListView( QtxListView::HeaderAuto, this );
297 myView->setAppropriate( myView->addColumn( "Data" ), false );
298 myView->setSorting( -1 );
299 myView->setRootIsDecorated( true );
300 myView->setSelectionMode( QListView::Extended );
301 myView->installEventFilter( this );
302 myView->viewport()->installEventFilter( this );
304 QVBoxLayout* main = new QVBoxLayout( this );
305 main->addWidget( myView );
307 myShowToolTips = true;
308 myTooltip = new ToolTip( this, myView->viewport() );
310 connect( myView, SIGNAL( dropped( QPtrList<QListViewItem>, QListViewItem*, int ) ),
311 this, SLOT( onDropped( QPtrList<QListViewItem>, QListViewItem*, int ) ) );
312 connect( myView, SIGNAL( selectionChanged() ), this, SIGNAL( selectionChanged() ) );
313 connect( myView, SIGNAL( doubleClicked( QListViewItem* ) ),
314 this, SLOT( onDoubleClicked( QListViewItem* ) ) );
316 setRootObject( root );
324 OB_Browser::~OB_Browser()
331 \return true if root is decorated by +
333 bool OB_Browser::rootIsDecorated() const
335 return myRootDecorated;
339 Sets state "root is recorated"
340 \param decor - new value of state
342 void OB_Browser::setRootIsDecorated( const bool decor )
344 if ( decor == rootIsDecorated() )
347 myRootDecorated = decor;
348 updateTree( 0, false );
352 \return number of levels to be auto opened on update tree
354 int OB_Browser::autoOpenLevel() const
356 return myAutoOpenLevel;
360 Changes number of levels to be auto opened on update tree
361 \param level - new number of levels
363 void OB_Browser::setAutoOpenLevel( const int level )
365 if ( myAutoOpenLevel == level )
368 myAutoOpenLevel = level;
374 \return state "are tooltips shown"
376 bool OB_Browser::isShowToolTips()
378 return myShowToolTips;
382 Sets new value of state "are tooltips shown"
383 \param theDisplay - new value
385 void OB_Browser::setShowToolTips( const bool theDisplay )
387 myShowToolTips = theDisplay;
391 \return true if object browser automatically updates tree after SUIT object removing
393 bool OB_Browser::isAutoUpdate() const
399 Sets new value of "auto update": whether object browser automatically updates tree after SUIT object removing
401 void OB_Browser::setAutoUpdate( const bool on )
407 \return true if object browser must delete old tree on setRootObject(), replaceTree()
408 \sa setRootObject(), replaceTree()
410 bool OB_Browser::isAutoDeleteObjects() const
412 return myAutoDelObjs;
416 Sets whether object browser must delete old tree on setRootObject(), replaceTree()
417 \sa setRootObject(), replaceTree()
419 void OB_Browser::setAutoDeleteObjects( const bool on )
425 \return root SUIT object of browser
427 SUIT_DataObject* OB_Browser::getRootObject() const
433 Sets new root SUIT object of browser
434 \param theRoot - new root object
436 void OB_Browser::setRootObject( SUIT_DataObject* theRoot )
438 DataObjectKey curKey;
439 DataObjectMap selObjs, openObjs;
440 DataObjectKeyMap selKeys, openKeys;
442 int selNum = numberOfSelected();
444 SUIT_DataObject* curObj = 0;
446 curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
448 removeConnections( myRoot );
449 if ( myRoot != theRoot && isAutoDeleteObjects() )
454 createConnections( myRoot );
457 updateView( myRoot );
458 else if ( listView() )
464 restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
470 if ( selNum != numberOfSelected() )
471 emit selectionChanged();
475 \return number of selected items
477 int OB_Browser::numberOfSelected() const
482 for ( QListViewItemIterator it( listView() ); it.current(); ++it )
483 if ( it.current()->isSelected() )
490 \return list of selected objects
492 DataObjectList OB_Browser::getSelected() const
500 Fills list with selected objects
502 void OB_Browser::getSelected( DataObjectList& theObjList ) const
509 for ( QListViewItemIterator it( listView() ); it.current(); ++it )
511 if ( it.current()->isSelected() )
513 SUIT_DataObject* obj = dataObject( it.current() );
515 theObjList.append( obj );
522 \param theObject - new selected object
523 \param append - if it is true, then other selected objects are left as selected,
524 otherwise only 'theObject' will be selected
526 void OB_Browser::setSelected( const SUIT_DataObject* theObject, const bool append )
529 lst.append( theObject );
530 setSelected( lst, append );
534 Sets selected objects
535 \param theObjLst - new selected objects
536 \param append - if it is true, then other selected objects are left as selected,
537 otherwise only 'theObjLst' will be selected
539 void OB_Browser::setSelected( const DataObjectList& theObjLst, const bool append )
541 QListView* lv = listView();
546 bool changed = false;
547 bool block = lv->signalsBlocked();
548 lv->blockSignals( true );
550 QMap<QListViewItem*, int> map;
551 for ( DataObjectListIterator itr( theObjLst ); itr.current(); ++itr )
552 map.insert( listViewItem( itr.current() ), 0 );
554 for ( QListViewItemIterator it( lv ); it.current(); ++it )
556 QListViewItem* item = it.current();
557 if ( map.contains( item ) && !lv->isSelected( item ) )
560 lv->setSelected( item, true );
562 if ( !append && !map.contains( item ) && lv->isSelected( item ) )
565 lv->setSelected( item, false );
569 lv->blockSignals( block );
574 QListViewItem* sel = 0;
575 QListViewItem* cur = lv->currentItem();
576 for ( QListViewItemIterator iter( lv ); iter.current() && !sel; ++iter, count++ )
578 if ( iter.current()->isSelected() && cur == iter.current() )
579 sel = iter.current();
582 for ( QListViewItemIterator itr( lv ); itr.current() && !sel; ++itr )
584 if ( itr.current()->isSelected() )
589 lv->setCurrentItem( sel );
591 if ( sel && count == 1 )
592 lv->ensureItemVisible( sel );
594 emit selectionChanged();
599 \return true if item corresponding to object is opened
600 \param theObject - object to be checked
602 bool OB_Browser::isOpen( SUIT_DataObject* theObject ) const
606 res = listView()->isOpen( listViewItem( theObject ) );
611 Sets opened state of item
612 \param theObject - object corresponding to item
613 \param theOpen - new opened state
615 void OB_Browser::setOpen( SUIT_DataObject* theObject, const bool theOpen )
618 listView()->setOpen( listViewItem( theObject ), theOpen );
622 \return SUIT object correspondint to item at position 'pos'
623 \param pos - position
625 SUIT_DataObject* OB_Browser::dataObjectAt( const QPoint& pos ) const
627 SUIT_DataObject* obj = 0;
629 QListView* lv = listView();
631 obj = dataObject( lv->itemAt( pos ) );
637 \return filter of list view
639 OB_Filter* OB_Browser::filter() const
641 return myView->filter();
645 Changes filter of list view
646 \param f - new filter
648 void OB_Browser::setFilter( OB_Filter* f )
650 myView->setFilter( f );
654 Adds new column to list view
655 \param label - title of column
656 \param id - id of column
657 \param width - width of column
659 int OB_Browser::addColumn( const QString& label, const int id, const int width )
661 return addColumn( QIconSet(), label, id, width );
665 Adds new column to list view
666 \param icon - icon of column
667 \param label - title of column
668 \param id - id of column
669 \param width - width of column
671 int OB_Browser::addColumn( const QIconSet& icon, const QString& label, const int id, const int width )
673 QListView* lv = listView();
680 while ( myColumnIds.contains( theId ) )
684 if ( myColumnIds.contains( theId ) )
685 return -1; // can not reuse id
689 sec = lv->addColumn( label, width );
691 sec = lv->addColumn( icon, label, width );
696 myColumnIds.insert( theId, sec );
704 \param id - id of column
706 void OB_Browser::removeColumn( const int id )
708 QListView* lv = listView();
709 if ( !lv || !myColumnIds.contains( id ) )
712 int sec = myColumnIds[id];
713 lv->removeColumn( sec );
715 // update map of column indeces
716 myColumnIds.remove( id );
717 for ( QMap<int, int>::iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
726 Sets title of first column (name column)
727 \param label - new title
729 void OB_Browser::setNameTitle( const QString& label )
731 setNameTitle( QIconSet(), label );
735 Sets title and icon of first column (name column)
736 \param icon - new icon
737 \param label - new title
739 void OB_Browser::setNameTitle( const QIconSet& icon, const QString& label )
741 QListView* lv = listView();
746 lv->setColumnText( 0, label );
748 lv->setColumnText( 0, icon, label );
753 \param id - column id
754 \param label - new column title
756 void OB_Browser::setColumnTitle( const int id, const QString& label )
758 setColumnTitle( id, QIconSet(), label );
762 Sets title and icon of column
763 \param id - column id
764 \param icon - new column icon
765 \param label - new column title
767 void OB_Browser::setColumnTitle( const int id, const QIconSet& icon, const QString& label )
769 QListView* lv = listView();
770 if ( !lv || !myColumnIds.contains( id ) )
774 lv->setColumnText( myColumnIds[id], label );
776 lv->setColumnText( myColumnIds[id], icon, label );
780 \return title of first column (name column)
782 QString OB_Browser::nameTitle() const
784 return myView->columnText( 0 );
788 \return title of first column (name column)
789 \param id - column id
791 QString OB_Browser::columnTitle( const int id ) const
794 if ( myColumnIds.contains( id ) )
795 txt = myView->columnText( myColumnIds[id] );
800 \return true if column is visible
801 \param id - column id
803 bool OB_Browser::isColumnVisible( const int id ) const
805 return myColumnIds.contains( id ) && myView->isShown( myColumnIds[id] );
809 Sets visibility of column
810 \param id - column id
811 \param on - new visibility state
813 void OB_Browser::setColumnShown( const int id, const bool on )
815 if ( !myColumnIds.contains( id ) )
818 myView->setShown( myColumnIds[id], on );
820 myView->setColumnWidthMode( myColumnIds[id], QListView::Manual );
824 Sets global width mode
825 \param mode - new width mode
827 void OB_Browser::setWidthMode( QListView::WidthMode mode )
829 for ( int i = 0, n = myView->columns(); i < n; i++ )
830 if( mode!=QListView::Maximum || myView->columnWidth( i )>0 )
831 myView->setColumnWidthMode( i, mode );
835 \return list of columns ids
837 QValueList<int> OB_Browser::columns() const
840 for ( QMap<int, int>::ConstIterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
841 lst.append( it.key() );
846 \return true if it is possible to show/hide column by popup
847 \param id - column id
849 bool OB_Browser::appropriateColumn( const int id ) const
852 if ( myColumnIds.contains( id ) )
853 res = myView->appropriate( myColumnIds[id] );
858 Sets "appropriate state": is it possible to show/hide column by popup
859 \param id - column id
860 \param on - new state
862 void OB_Browser::setAppropriateColumn( const int id, const bool on )
864 if ( !myColumnIds.contains( id ) )
867 myView->setAppropriate( myColumnIds[id], on );
872 \param obj - start object
873 \param autoOpen - to open automatically branches of autoOpenLevel()
876 void OB_Browser::updateTree( SUIT_DataObject* obj, const bool autoOpen )
878 // QTime t1 = QTime::currentTime();
880 if ( !obj && !(obj = getRootObject()) )
883 DataObjectKey curKey;
884 DataObjectMap selObjs, openObjs;
885 DataObjectKeyMap selKeys, openKeys;
887 int selNum = numberOfSelected();
889 SUIT_DataObject* curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
893 restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
900 if ( selNum != numberOfSelected() )
901 emit selectionChanged();
903 // QTime t2 = QTime::currentTime();
904 // qDebug( QString( "update tree time = %1 msecs" ).arg( t1.msecsTo( t2 ) ) );
908 Replaces part of tree starting at object 'src' by tree starting at object 'trg'
910 void OB_Browser::replaceTree( SUIT_DataObject* src, SUIT_DataObject* trg )
912 if ( !src || !trg || src == trg || src->root() != getRootObject() )
915 DataObjectKey curKey;
916 DataObjectMap selObjs, openObjs;
917 DataObjectKeyMap selKeys, openKeys;
919 int selNum = numberOfSelected();
921 SUIT_DataObject* curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
923 SUIT_DataObject* parent = src->parent();
924 int pos = parent ? parent->childPos( src ) : -1;
928 removeConnections( src );
929 if ( isAutoDeleteObjects() )
932 if ( parent && pos != -1 )
933 parent->insertChild( trg, pos );
935 trg->setParent( parent );
938 createConnections( trg );
940 restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
946 if ( selNum != numberOfSelected() )
947 emit selectionChanged();
952 \param startObj - start object
954 void OB_Browser::updateView( SUIT_DataObject* startObj )
956 QListView* lv = listView();
960 if ( !startObj || startObj->root() != getRootObject() )
963 //qDebug( "updateView:" );
966 if ( startObj == myRoot )
968 OB_BrowserSync sync( this );
969 synchronize<ObjPtr,ItemPtr,OB_BrowserSync>( myRoot, 0, sync );
973 OB_BrowserSync sync( this );
974 OB_ListItem* startItem = dynamic_cast<OB_ListItem*>( listViewItem( startObj ) );
975 synchronize<ObjPtr,ItemPtr,OB_BrowserSync>( startObj, startItem, sync );
980 Creates new list item
982 \param o - corresponding SUIT object
983 \param parent - parent item
984 \param after - item after that new item must be added
985 \param prepend - new item must be added as first
987 QListViewItem* OB_Browser::createItem( const SUIT_DataObject* o, QListViewItem* parent,
988 QListViewItem* after, const bool prepend )
990 QListView* lv = listView();
995 QListViewItem* item = 0;
996 SUIT_DataObject* obj = (SUIT_DataObject*)o;
1000 switch ( obj->checkType() )
1002 case SUIT_DataObject::CheckBox:
1003 type = QCheckListItem::CheckBox;
1005 case SUIT_DataObject::RadioButton:
1006 type = QCheckListItem::RadioButton;
1015 item = new OB_ListItem( obj, parent, after );
1017 item = new OB_CheckListItem( obj, parent, after, (QCheckListItem::Type)type );
1022 item = new OB_ListItem( obj, parent );
1024 item = new OB_CheckListItem( obj, parent, (QCheckListItem::Type)type );
1028 after = parent->firstChild();
1029 while ( after && after->nextSibling() )
1030 after = after->nextSibling();
1032 item = new OB_ListItem( obj, parent, after );
1034 item = new OB_CheckListItem( obj, parent, after, (QCheckListItem::Type)type );
1042 item = new OB_ListItem( obj, lv, after );
1044 item = new OB_CheckListItem( obj, lv, after, (QCheckListItem::Type)type );
1049 item = new OB_ListItem( obj, lv );
1051 item = new OB_CheckListItem( obj, lv, (QCheckListItem::Type)type );
1055 after = lv->firstChild();
1056 while ( after && after->nextSibling() )
1057 after = after->nextSibling();
1059 item = new OB_ListItem( obj, lv, after );
1061 item = new OB_CheckListItem( obj, lv, after, (QCheckListItem::Type)type );
1065 myItems.insert( obj, item );
1066 obj->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1073 Adjusts width by root item
1075 void OB_Browser::adjustWidth()
1080 listView()->setColumnWidth( 0, 0 );
1081 if ( listView()->firstChild() )
1082 adjustWidth( listView()->firstChild() );
1086 Adjusts width by item
1089 void OB_Browser::adjustWidth( QListViewItem* item )
1093 item->widthChanged( 0 );
1094 if ( item->isOpen() )
1095 adjustWidth( item->firstChild() );
1096 item = item->nextSibling();
1101 \return SUIT object corresponding to item
1104 SUIT_DataObject* OB_Browser::dataObject( const QListViewItem* item ) const
1106 SUIT_DataObject* obj = 0;
1108 if ( item && item->rtti() == OB_ListItem::RTTI() )
1109 obj = ((OB_ListItem*)item)->dataObject();
1110 else if ( item && item->rtti() == OB_CheckListItem::RTTI() )
1111 obj = ((OB_CheckListItem*)item)->dataObject();
1117 \return item corresponding to SUIT object
1118 \param obj - SUIT object
1120 QListViewItem* OB_Browser::listViewItem( const SUIT_DataObject* obj ) const
1122 QListViewItem* item = 0;
1124 if ( myItems.contains( (SUIT_DataObject*)obj ) )
1125 item = myItems[(SUIT_DataObject*)obj];
1131 \return list view of object browser
1133 QListView* OB_Browser::listView() const
1139 \remove all items referencing current (through data objects)
1141 void OB_Browser::removeReferences( QListViewItem* item )
1146 SUIT_DataObject* obj = dataObject( item );
1147 obj->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1148 myItems.remove( obj );
1150 QListViewItem* i = item->firstChild();
1153 removeReferences( i );
1154 i = i->nextSibling();
1159 Connects all children to SLOT onDestroyed
1161 void OB_Browser::createConnections( SUIT_DataObject* obj )
1166 DataObjectList childList;
1167 obj->children( childList, true );
1169 childList.prepend( obj );
1171 for ( DataObjectListIterator it( childList ); it.current(); ++it )
1172 it.current()->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1176 Disconnects all children from SLOT onDestroyed
1178 void OB_Browser::removeConnections( SUIT_DataObject* obj )
1183 DataObjectList childList;
1184 obj->children( childList, true );
1186 childList.prepend( obj );
1188 for ( DataObjectListIterator it( childList ); it.current(); ++it )
1189 it.current()->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1193 Stores states (opened, selected) of current tree items
1194 \return current item
1195 \param selObjs, selKeys - maps of selected objects
1196 \param openObjs, openKeys - maps of opened objects
1197 \param curKey - map of current objects
1199 SUIT_DataObject* OB_Browser::storeState( DataObjectMap& selObjs, DataObjectMap& openObjs,
1200 DataObjectKeyMap& selKeys, DataObjectKeyMap& openKeys,
1201 DataObjectKey& curKey ) const
1203 QListView* lv = listView();
1207 SUIT_DataObject* curObj = dataObject( lv->currentItem() );
1209 curKey = objectKey( curObj );
1211 for ( QListViewItemIterator it( lv ); it.current(); ++it )
1213 SUIT_DataObject* obj = dataObject( it.current() );
1217 selObjs.insert( obj, lv->isSelected( it.current() ) );
1218 openObjs.insert( obj, lv->isOpen( it.current() ) );
1219 if ( lv->isSelected( it.current() ) )
1220 selKeys.insert( objectKey( obj ), 0 );
1221 if ( lv->isOpen( it.current() ) )
1222 openKeys.insert( objectKey( obj ), 0 );
1229 Restores states (opened, selected) of current tree items
1230 \param selObjs, selKeys - maps of selected objects
1231 \param openObjs, openKeys - maps of opened objects
1232 \param curKey - map of current objects
1234 void OB_Browser::restoreState( const DataObjectMap& selObjs, const DataObjectMap& openObjs,
1235 const SUIT_DataObject* curObj, const DataObjectKeyMap& selKeys,
1236 const DataObjectKeyMap& openKeys, const DataObjectKey& curKey )
1238 QListView* lv = listView();
1242 bool block = lv->signalsBlocked();
1243 lv->blockSignals( true );
1245 QListViewItem* curItem = 0;
1246 for ( QListViewItemIterator it( lv ); it.current(); ++it )
1248 QListViewItem* item = it.current();
1249 SUIT_DataObject* obj = dataObject( item );
1254 DataObjectKey key = objectKey( obj );
1256 if ( selObjs.contains( obj ) )
1258 if ( selObjs[obj] && !lv->isSelected( item ) )
1259 lv->setSelected( item, true );
1261 else if ( !key.isNull() && selKeys.contains( key ) && !lv->isSelected( item ) )
1262 lv->setSelected( item, true );
1264 if ( openObjs.contains( obj ) )
1266 bool parentOpen = true;
1267 if( item && item->parent() )
1268 parentOpen = item->parent()->isOpen();
1270 if ( openObjs[obj] && parentOpen )
1271 lv->setOpen( item, true );
1273 else if ( !key.isNull() && openKeys.contains( key ) )
1275 bool parentOpen = true;
1276 if( item && item->parent() )
1277 parentOpen = item->parent()->isOpen();
1280 lv->setOpen( item, true );
1283 if ( !curItem && ( curObj == obj || ( !curKey.isNull() && curKey == key )) )
1288 lv->setCurrentItem( curItem );
1290 lv->blockSignals( block );
1294 Creates object key by tree item
1296 OB_Browser::DataObjectKey OB_Browser::objectKey( QListViewItem* i ) const
1298 return objectKey( dataObject( i ) );
1302 Creates object key by SUIT object
1304 OB_Browser::DataObjectKey OB_Browser::objectKey( SUIT_DataObject* obj ) const
1309 return DataObjectKey( obj->key() );
1313 Custom key press event handler, updates tree by F5
1315 void OB_Browser::keyPressEvent( QKeyEvent* e )
1317 if ( e->key() == Qt::Key_F5 )
1318 updateTree( 0, false );
1320 QFrame::keyPressEvent( e );
1324 SLOT: called if action "Expand all" is activated
1326 void OB_Browser::onExpand()
1328 DataObjectList selected;
1329 getSelected( selected );
1330 for ( DataObjectListIterator itr( selected ); itr.current(); ++itr )
1331 expand( listViewItem( itr.current() ) );
1335 SLOT: called if action "Show/hide column" is activated by popup
1337 void OB_Browser::onColumnVisible( int id )
1339 setColumnShown( id, !isColumnVisible( id ) );
1343 SLOT: called if SUIT object is destroyed
1345 void OB_Browser::onDestroyed( SUIT_DataObject* obj )
1347 removeObject( obj );
1351 SLOT: called on finish of drag-n-drop operation
1352 \param items - dragged items
1353 \param item - destination (item on that they were dropped)
1354 \param action - QDropEvent::Action
1356 void OB_Browser::onDropped( QPtrList<QListViewItem> items, QListViewItem* item, int action )
1358 SUIT_DataObject* obj = dataObject( item );
1363 for ( QPtrListIterator<QListViewItem> it( items ); it.current(); ++it )
1365 SUIT_DataObject* o = dataObject( it.current() );
1370 if ( !lst.isEmpty() )
1371 emit dropped( lst, obj, action );
1375 Updates texts of items
1377 void OB_Browser::updateText()
1379 if ( myColumnIds.isEmpty() )
1382 QListView* lv = listView();
1386 for ( QListViewItemIterator it( lv ); it.current(); ++it )
1388 SUIT_DataObject* obj = dataObject( it.current() );
1392 for( QMap<int, int>::iterator itr = myColumnIds.begin(); itr != myColumnIds.end(); ++itr )
1393 it.current()->setText( itr.data(), obj->text( itr.key() ) );
1398 \return true if item must be updated
1399 \param item - item to be checked
1401 bool OB_Browser::needToUpdateTexts( QListViewItem* item ) const
1403 SUIT_DataObject* obj = dataObject( item );
1407 for( QMap<int, int>::const_iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
1408 if( item->text( it.data() ) != obj->text( it.key() ) )
1414 Updates texts of item
1415 \param item - item to be updated
1417 void OB_Browser::updateText( QListViewItem* item )
1419 SUIT_DataObject* obj = dataObject( item );
1423 for( QMap<int, int>::iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
1424 item->setText( it.data(), obj->text( it.key() ) );
1430 bool OB_Browser::eventFilter( QObject* o, QEvent* e )
1432 if ( o == myView && e->type() == QEvent::ContextMenu )
1434 QContextMenuEvent* ce = (QContextMenuEvent*)e;
1435 if ( ce->reason() != QContextMenuEvent::Mouse )
1436 contextMenuRequest( ce );
1439 if ( o == myView->viewport() && e->type() == QEvent::MouseButtonRelease )
1441 QMouseEvent* me = (QMouseEvent*)e;
1442 if ( me->button() == RightButton )
1444 QContextMenuEvent ce( QContextMenuEvent::Mouse, me->pos(), me->globalPos(), me->state() );
1445 contextMenuRequest( &ce );
1450 return QFrame::eventFilter( o, e );
1454 Adds custom actions to popup
1455 \param menu - popup menu
1457 void OB_Browser::contextMenuPopup( QPopupMenu* menu )
1459 /* QValueList<int> cols;
1460 for ( QMap<int, int>::ConstIterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
1462 if ( appropriateColumn( it.key() ) )
1463 cols.append( it.key() );
1466 uint num = menu->count();
1467 menu->setCheckable( true );
1468 for ( QValueList<int>::const_iterator iter = cols.begin(); iter != cols.end(); ++iter )
1470 QString name = columnTitle( *iter );
1471 if ( name.isEmpty() )
1474 int id = menu->insertItem( name, this, SLOT( onColumnVisible( int ) ) );
1475 menu->setItemChecked( id, isColumnVisible( *iter ) );
1476 menu->setItemParameter( id, *iter );
1478 if ( menu->count() != num )
1479 menu->insertSeparator();*/
1481 DataObjectList selected;
1482 getSelected( selected );
1484 bool closed = false;
1485 for ( DataObjectListIterator itr( selected ); itr.current() && !closed; ++itr )
1486 closed = hasClosed( listViewItem( itr.current() ) );
1490 menu->insertItem( tr( "MEN_EXPAND_ALL" ), this, SLOT( onExpand() ) );
1491 menu->insertSeparator();
1496 Expands item with all it's children
1498 void OB_Browser::expand( QListViewItem* item )
1503 item->setOpen( true );
1504 for ( QListViewItem* child = item->firstChild(); child; child = child->nextSibling() )
1509 \return true if item or one of it's children isn't opened
1511 bool OB_Browser::hasClosed( QListViewItem* item ) const
1516 if ( item->childCount() && !item->isOpen() )
1520 for ( QListViewItem* child = item->firstChild(); child && !has; child = child->nextSibling() )
1521 has = hasClosed( child );
1528 \param obj - SUIT object to be removed
1529 \param autoUpd - auto tree updating
1531 void OB_Browser::removeObject( SUIT_DataObject* obj, const bool autoUpd )
1536 // Removing list view items from <myItems> recursively for all children.
1537 // Otherwise, "delete item" line will destroy all item's children,
1538 // and <myItems> will contain invalid pointers (see ~QListViewItem() description in Qt docs)
1539 DataObjectList childList;
1540 obj->children( childList, true );
1541 for ( DataObjectListIterator it( childList ); it.current(); ++it )
1543 it.current()->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1544 myItems.remove( it.current() );
1547 QListViewItem* item = listViewItem( obj );
1549 obj->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1550 myItems.remove( obj );
1552 if ( obj == myRoot )
1554 // remove all child list view items
1562 if ( isAutoUpdate() )
1564 SUIT_DataObject* pObj = item && item->parent() ? dataObject( item->parent() ) : 0;
1565 updateTree( pObj, false );
1572 Opens branches from 1 to autoOpenLevel()
1575 void OB_Browser::autoOpenBranches()
1577 int level = autoOpenLevel();
1578 QListView* lv = listView();
1579 if ( !lv || level < 1 )
1582 QListViewItem* item = lv->firstChild();
1585 openBranch( item, level );
1586 item = item->nextSibling();
1595 void OB_Browser::openBranch( QListViewItem* item, const int level )
1602 item->setOpen( true );
1603 openBranch( item->firstChild(), level - 1 );
1604 item = item->nextSibling();
1609 SLOT: called on double click on item, emits signal
1611 void OB_Browser::onDoubleClicked( QListViewItem* item )
1614 emit doubleClicked( dataObject( item ) );
1618 Stores time of last modification
1620 void OB_Browser::setModified()
1622 myModifiedTime = clock();