1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : OB_Browser.cxx
24 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
26 #include "OB_Browser.h"
28 //#include "OB_Filter.h"
29 //#include "OB_ListItem.h"
30 //#include "OB_ListView.h"
32 #include <QtxTreeView.h>
33 #include <QtxSearchTool.h>
34 //#include <SUIT_DataObjectIterator.h>
38 #include <QItemSelection>
40 #include <QVBoxLayout>
41 #include <QAbstractItemModel>
42 #include <QAbstractItemDelegate>
43 #include <QHeaderView>
49 \class OB_Browser::ToolTip
50 Tool tip for OB_Browser.
53 //TODO: ToolTip commented - to be removed or revised
55 class OB_Browser::ToolTip : public QToolTip
58 ToolTip( OB_Browser* b, QWidget* p = 0 );
61 void maybeTip( const QPoint& );
64 OB_Browser* myBrowser;
71 OB_Browser::ToolTip::ToolTip( OB_Browser* b, QWidget* p )
81 OB_Browser::ToolTip::~ToolTip()
86 It is called when there is a possibility that a tool tip
87 should be shown and must decide whether there is a tool tip for the point
88 in the widget that this QToolTip object relates to.
89 \param pos - point co-ordinates
92 void OB_Browser::ToolTip::maybeTip( const QPoint& pos )
94 if ( !parentWidget() || !myBrowser || !myBrowser->isShowToolTips() )
97 QListView* lv = myBrowser->listView();
99 QListViewItem* item = lv->itemAt( pos );
100 SUIT_DataObject* obj = myBrowser->dataObject( item );
104 QString aText = obj->toolTip();
106 if ( aText.isEmpty() )
109 QRect aRect = lv->itemRect( item );
118 \brief Object browser widget which can be used to handle tree-like data model.
120 The class OB_Browser implements public API of an object browser widget
121 that can be used to display arbitrary application data in a hierarchical form.
122 It is based on Qt4 model/view architecture.
124 Object browser can be used with conjuction of any custom item model inherited
125 from QAbstractItemModel class (see Qt 4 reference manual).
127 The class provides a functionality get/modify selection, drag-n-drop of the
133 \param parent paren widget
134 \param model data model
136 OB_Browser::OB_Browser( QWidget* parent, QAbstractItemModel* model )
141 myView = new QtxTreeView( this ); // create tree view
142 myView->setRootIsDecorated( true ); // show root item
143 myView->setSelectionMode( QAbstractItemView::ExtendedSelection ); // enable extended selection mode
144 myView->setAllColumnsShowFocus( true ); // focus is shown in all columns
146 // enable drag-n-drop support
147 myView->setDragDropMode( QAbstractItemView::DragDrop ); // enable both drag and drop operations
148 myView->setDropIndicatorShown( true ); // show drag indicator on dragging
150 // set-up search tool
151 mySearchTool = new QtxSearchTool( this, myView ); // create search tool
152 mySearchTool->setFrameStyle( QFrame::NoFrame | QFrame::Plain ); // do not show frame
153 mySearchTool->setActivators( QtxSearchTool::StandardKey | QtxSearchTool::SlashKey ); // set activation mode
154 mySearchTool->setSearcher( new QtxTreeViewSearcher( myView ) ); // assign searcher (for tree view)
157 QVBoxLayout* main = new QVBoxLayout( this );
158 main->addWidget( myView );
159 main->addWidget( mySearchTool );
160 main->setMargin( 0 );
161 main->setSpacing( 3 );
163 // TODO: decide what to do with tooltip
164 //myShowToolTips = true;
165 //myTooltip = new ToolTip( this, myView->viewport() );
167 // TODO: drag-n-drop works differently - SUIT_TreeModel to be updated
168 // and QTreeView needs some setup
169 //connect( myView, SIGNAL( dropped( QPtrList<QListViewItem>, QListViewItem*, int ) ),
170 // this, SLOT( onDropped( QPtrList<QListViewItem>, QListViewItem*, int ) ) );
173 connect( myView, SIGNAL( selectionChanged() ),
174 this, SIGNAL( selectionChanged() ) );
180 OB_Browser::~OB_Browser()
187 \brief Get data model.
191 QAbstractItemModel* OB_Browser::model() const
193 return myView->model();
197 \brief Set data model.
198 \param model data model
201 void OB_Browser::setModel( QAbstractItemModel* model )
203 myView->setModel( model );
209 \brief Get current item delegate (items renderer).
210 \return currently used item delegate
211 \sa setItemDelegate()
213 QAbstractItemDelegate* OB_Browser::itemDelegate() const
215 return myView->itemDelegate();
219 \brief Set item delegate (items renderer).
220 \param d custom item delegate
223 void OB_Browser::setItemDelegate( QAbstractItemDelegate* d )
225 myView->setItemDelegate( d );
229 \brief Check if controls for expanding and collapsing top-level items are shown.
230 \return \c true if top-level items are decorated
231 \sa setRootIsDecorated()
233 bool OB_Browser::rootIsDecorated() const
235 return myView->rootIsDecorated();
239 \brief Show/hide controls for expanding and collapsing top-level items.
240 \param decor if \c true, top-level items are decorated
241 \sa rootIsDecorated()
243 void OB_Browser::setRootIsDecorated( const bool decor )
245 if ( decor != rootIsDecorated() )
246 myView->setRootIsDecorated( decor );
250 \brief Check if "Sorting" popup menu command for the header is enabled.
251 \return \c true if "Sorting" menu command is enabled
252 \sa setSortMenuEnabled()
254 bool OB_Browser::sortMenuEnabled() const
256 return myView->sortMenuEnabled();
260 \brief Enable/disable "Sorting" popup menu command for the header.
261 \param enableSortMenu if \c true, enable "Sorting" menu command
262 \sa sortMenuEnabled()
264 void OB_Browser::setSortMenuEnabled( const bool enabled )
266 if ( enabled != sortMenuEnabled() )
267 myView->setSortMenuEnabled( enabled );
271 \brief Get search tool widget.
272 \return search tool widget
273 \sa isSearchToolEnabled(), setSearchToolEnabled()
275 QtxSearchTool* OB_Browser::searchTool() const
281 \brief Check if search tool is enabled.
282 \return \c true if search tool is enabled
283 \sa setSearchToolEnabled(), searchTool()
285 bool OB_Browser::isSearchToolEnabled() const
287 return mySearchTool->isEnabled();
291 \brief Enable/disable search tool.
292 \param enable pass \c true to enable search tool
293 \sa isSearchToolEnabled(), searchTool()
295 void OB_Browser::setSearchToolEnabled( const bool enable )
297 if ( mySearchTool->isEnabled() == enable )
300 mySearchTool->setEnabled( enable );
301 if ( !mySearchTool->isEnabled() )
302 mySearchTool->hide();
306 \brief Get number of levels which should be automatically expanded
307 when updating the data tree.
308 \return number of levels to be auto-opened on tree updating
309 \sa setAutoOpenLevel()
311 int OB_Browser::autoOpenLevel() const
313 return myAutoOpenLevel;
317 \brief Set number of levels which should be automatically expanded
318 when updating the data tree.
319 \param levels number of levels to be auto-opened on tree updating
322 void OB_Browser::setAutoOpenLevel( const int levels )
324 if ( myAutoOpenLevel != levels )
325 myAutoOpenLevel = levels;
329 \brief Expand all branches to the specified number of levels.
331 If \a levels value is negative, then autoOpenLevel() value is used instead.
333 \param levels number of levels to be expanded
336 void OB_Browser::openLevels( const int levels )
338 myView->expandLevels( levels < 0 ? autoOpenLevel() : levels );
342 \return state "are tooltips shown"
345 bool OB_Browser::isShowToolTips()
347 return myShowToolTips;
351 Sets new value of state "are tooltips shown"
352 \param theDisplay - new value
355 void OB_Browser::setShowToolTips( const bool theDisplay )
357 myShowToolTips = theDisplay;
362 \brief Get number of selected items.
363 \return number of selected items
365 int OB_Browser::numberOfSelected() const
367 // we take selection by rows
368 return myView->selectionModel() ? myView->selectionModel()->selectedRows().count() : 0;
372 \brief Get all selected items.
373 \return unsorted list of selected indexes with no duplicates
375 QModelIndexList OB_Browser::selectedIndexes() const
377 // we take selection by rows
378 return myView->selectionModel() ? myView->selectionModel()->selectedRows() : QModelIndexList();
382 \brief Get selection containing information about selected ranges.
383 \return QItemSelection instance
385 const QItemSelection OB_Browser::selection() const
387 static QItemSelection emptySel;
388 QItemSelection sel = emptySel;
389 if ( myView->selectionModel() )
390 sel = myView->selectionModel()->selection();
395 \brief Select/deselect specified model index.
396 \param index model index to be selected/deselected
397 \param on if \c true, the index will be selected, otherwise - deselected
398 \param keepSelection if \c true (default) the previous selection is kept,
399 otherwise it is first cleared
401 void OB_Browser::select( const QModelIndex& index, const bool on, const bool keepSelection )
403 if ( myView->selectionModel() ) {
404 QItemSelectionModel::SelectionFlags f = on ? QItemSelectionModel::Select : QItemSelectionModel::Deselect;
405 f = f | QItemSelectionModel::Rows;
406 if ( !keepSelection )
407 f = f | QItemSelectionModel::Clear;
409 myView->selectionModel()->select( index, f );
414 \brief Select/deselect specified model indices.
415 \param indexes model indices to be selected/deselected
416 \param on if \c true, the indices will be selected, otherwise - deselected
417 \param keepSelection if \c true (default) the previous selection is kept,
418 otherwise it is first cleared
420 void OB_Browser::select( const QModelIndexList& indexes, const bool on, const bool keepSelection )
422 bool blocked = myView->signalsBlocked();
423 myView->blockSignals( true );
427 if ( !indexes.isEmpty() ) {
428 QItemSelection mysel;
429 // select by range if indexes are contiguous
430 QModelIndex first=indexes.at(0);
431 QModelIndex last=first;
432 if (indexes.size() > 1) {
433 for (int i = 1; i < indexes.size(); ++i)
436 if(idx.parent().internalId()==last.parent().internalId() && idx.row()==last.row()+1 && idx.column()==last.column())
438 // index is contiguous to last: extend the range
443 // index idx is not contiguous: create a new range
444 mysel.select(first,last);
450 mysel.select(first,last);
452 if ( myView->selectionModel() ) {
453 QItemSelectionModel::SelectionFlags f = on ? QItemSelectionModel::Select : QItemSelectionModel::Deselect;
454 f = f | QItemSelectionModel::Rows;
455 if ( !keepSelection )
456 f = f | QItemSelectionModel::Clear;
457 myView->selectionModel()->select( mysel, f );
460 else if ( !keepSelection )
462 myView->clearSelection();
465 myView->blockSignals( blocked );
466 emit( selectionChanged() );
470 \brief Check if specified model index is expanded or collapsed.
471 \param index model index
472 \return \c true if model index is expanded
475 bool OB_Browser::isOpen( const QModelIndex& index ) const
477 return index.isValid() && model() && model()->hasChildren( index ) && myView->isExpanded( index );
481 \brief Expand/collapse the specified model index.
482 \param index model index
483 \param open if \c true, the index will be expanded, otherwse - collapsed
486 void OB_Browser::setOpen( const QModelIndex& index, const bool open )
488 myView->setExpanded( index, open ); // hasChildren() ???
492 \brief Adjust first column width to its contents.
494 void OB_Browser::adjustWidth()
496 myView->resizeColumnToEncloseContents( 0 );
500 \brief Adjust first column width to its contents.
502 void OB_Browser::adjustFirstColumnWidth()
504 myView->resizeColumnToEncloseContents( 0 );
508 \brief Adjust all columns width to its contents except the first column.
510 void OB_Browser::adjustColumnsWidth()
512 for ( int aCol = 1; aCol < myView->header()->count(); aCol++ ) {
513 if ( myView->columnWidth( aCol ) > 0 )
514 myView->resizeColumnToEncloseContents( aCol );
519 \return SUIT object correspondint to item at position 'pos'
520 \param pos - position
522 /* TODO: removed - QTreeView::indexAt() should be used
523 SUIT_DataObject* OB_Browser::dataObjectAt( const QPoint& pos ) const
525 SUIT_DataObject* obj = 0;
527 QListView* lv = listView();
529 obj = dataObject( lv->itemAt( pos ) );
535 \return filter of list view
538 OB_Filter* OB_Browser::filter() const
540 return myView->filter();
544 Changes filter of list view
545 \param f - new filter
548 void OB_Browser::setFilter( OB_Filter* f )
550 myView->setFilter( f );
554 Sets global width mode
555 \param mode - new width mode
558 void OB_Browser::setWidthMode( QListView::WidthMode mode )
560 for ( int i = 0, n = myView->columns(); i < n; i++ )
561 if( mode!=QListView::Maximum || myView->columnWidth( i )>0 )
562 myView->setColumnWidthMode( i, mode );
567 \param obj - start object
568 \param autoOpen - to open automatically branches of autoOpenLevel()
572 void OB_Browser::updateTree( SUIT_DataObject* obj, const bool autoOpen )
574 // QTime t1 = QTime::currentTime();
576 if ( !obj && !(obj = getRootObject()) )
579 DataObjectKey curKey;
580 DataObjectMap selObjs, openObjs;
581 DataObjectKeyMap selKeys, openKeys;
583 int selNum = numberOfSelected();
585 SUIT_DataObject* curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
589 restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
596 if ( selNum != numberOfSelected() )
597 emit selectionChanged();
599 // QTime t2 = QTime::currentTime();
600 // qDebug( QString( "update tree time = %1 msecs" ).arg( t1.msecsTo( t2 ) ) );
604 Replaces part of tree starting at object 'src' by tree starting at object 'trg'
607 void OB_Browser::replaceTree( SUIT_DataObject* src, SUIT_DataObject* trg )
609 if ( !src || !trg || src == trg || src->root() != getRootObject() )
612 DataObjectKey curKey;
613 DataObjectMap selObjs, openObjs;
614 DataObjectKeyMap selKeys, openKeys;
616 int selNum = numberOfSelected();
618 SUIT_DataObject* curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
620 SUIT_DataObject* parent = src->parent();
621 int pos = parent ? parent->childPos( src ) : -1;
625 removeConnections( src );
626 if ( isAutoDeleteObjects() )
629 if ( parent && pos != -1 )
630 parent->insertChild( trg, pos );
632 trg->setParent( parent );
635 createConnections( trg );
637 restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
641 if ( selNum != numberOfSelected() )
642 emit selectionChanged();
646 Adjusts width by item
650 void OB_Browser::adjustWidth( QListViewItem* item )
654 item->widthChanged( 0 );
655 if ( item->isOpen() )
656 adjustWidth( item->firstChild() );
657 item = item->nextSibling();
663 \remove all items referencing current (through data objects)
666 void OB_Browser::removeReferences( QListViewItem* item )
671 SUIT_DataObject* obj = dataObject( item );
672 obj->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
673 myItems.remove( obj );
675 QListViewItem* i = item->firstChild();
678 removeReferences( i );
679 i = i->nextSibling();
684 Connects all children to SLOT onDestroyed
686 /* TODO: move to SUIT_TreeModel
687 void OB_Browser::createConnections( SUIT_DataObject* obj )
692 DataObjectList childList;
693 obj->children( childList, true );
695 childList.prepend( obj );
697 for ( DataObjectListIterator it( childList ); it.current(); ++it )
698 it.current()->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
702 Disconnects all children from SLOT onDestroyed
704 /* TODO: move to SUIT_TreeModel
705 void OB_Browser::removeConnections( SUIT_DataObject* obj )
710 DataObjectList childList;
711 obj->children( childList, true );
713 childList.prepend( obj );
715 for ( DataObjectListIterator it( childList ); it.current(); ++it )
716 it.current()->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
720 Stores states (opened, selected) of current tree items
722 \param selObjs, selKeys - maps of selected objects
723 \param openObjs, openKeys - maps of opened objects
724 \param curKey - map of current objects
726 /* TODO: to be revised
727 SUIT_DataObject* OB_Browser::storeState( DataObjectMap& selObjs, DataObjectMap& openObjs,
728 DataObjectKeyMap& selKeys, DataObjectKeyMap& openKeys,
729 DataObjectKey& curKey ) const
731 QListView* lv = listView();
735 SUIT_DataObject* curObj = dataObject( lv->currentItem() );
737 curKey = objectKey( curObj );
739 for ( QListViewItemIterator it( lv ); it.current(); ++it )
741 SUIT_DataObject* obj = dataObject( it.current() );
745 selObjs.insert( obj, lv->isSelected( it.current() ) );
746 openObjs.insert( obj, lv->isOpen( it.current() ) );
747 if ( lv->isSelected( it.current() ) )
748 selKeys.insert( objectKey( obj ), 0 );
749 if ( lv->isOpen( it.current() ) )
750 openKeys.insert( objectKey( obj ), 0 );
757 Restores states (opened, selected) of current tree items
758 \param selObjs, selKeys - maps of selected objects
759 \param openObjs, openKeys - maps of opened objects
760 \param curKey - map of current objects
762 /* TODO: to be revised
763 void OB_Browser::restoreState( const DataObjectMap& selObjs, const DataObjectMap& openObjs,
764 const SUIT_DataObject* curObj, const DataObjectKeyMap& selKeys,
765 const DataObjectKeyMap& openKeys, const DataObjectKey& curKey )
767 QListView* lv = listView();
771 bool block = lv->signalsBlocked();
772 lv->blockSignals( true );
774 QListViewItem* curItem = 0;
775 for ( QListViewItemIterator it( lv ); it.current(); ++it )
777 QListViewItem* item = it.current();
778 SUIT_DataObject* obj = dataObject( item );
783 DataObjectKey key = objectKey( obj );
785 if ( selObjs.contains( obj ) )
787 if ( selObjs[obj] && !lv->isSelected( item ) )
788 lv->setSelected( item, true );
790 else if ( !key.isNull() && selKeys.contains( key ) && !lv->isSelected( item ) )
791 lv->setSelected( item, true );
793 if ( openObjs.contains( obj ) )
795 bool parentOpen = true;
796 if( item && item->parent() )
797 parentOpen = item->parent()->isOpen();
799 if ( openObjs[obj] && parentOpen )
800 lv->setOpen( item, true );
802 else if ( !key.isNull() && openKeys.contains( key ) )
804 bool parentOpen = true;
805 if( item && item->parent() )
806 parentOpen = item->parent()->isOpen();
809 lv->setOpen( item, true );
812 if ( !curItem && ( curObj == obj || ( !curKey.isNull() && curKey == key )) )
817 lv->setCurrentItem( curItem );
819 lv->blockSignals( block );
823 Creates object key by tree item
825 /* TODO: move to SUIT_TreeModel
826 OB_Browser::DataObjectKey OB_Browser::objectKey( QListViewItem* i ) const
828 return objectKey( dataObject( i ) );
832 Creates object key by SUIT object
834 /* TODO: move to SUIT_TreeModel
835 OB_Browser::DataObjectKey OB_Browser::objectKey( SUIT_DataObject* obj ) const
840 return DataObjectKey( obj->key() );
845 \brief Get tree view widget.
846 \return tree view widget of the object browser
848 QtxTreeView* OB_Browser::treeView() const
854 \brief Process context menu request event.
855 \param e context menu event
857 void OB_Browser::contextMenuEvent( QContextMenuEvent* e )
859 QMenu* popup = new QMenu();
861 createPopupMenu( popup );
863 Qtx::simplifySeparators( popup );
865 if ( !popup->actions().isEmpty() )
866 popup->exec( e->globalPos() );
871 \brief Get the time of the latest updating.
872 \return latest updating time
874 unsigned long OB_Browser::getModifiedTime() const
876 return myModifiedTime;
880 \brief Update the time of the latest updating.
882 void OB_Browser::setModified()
884 myModifiedTime = clock();
888 \brief Called when "Expand all" popup menu command is activated.
890 Expands all selected items recursively.
892 void OB_Browser::onExpandAll()
894 QModelIndexList indexes = selectedIndexes();
897 foreach ( index, indexes ) {
898 myView->expandAll( index );
903 \brief Called when "Collapse all" popup menu command is activated.
905 Collapse all selected items recursively.
907 void OB_Browser::onCollapseAll()
909 QModelIndexList indexes = selectedIndexes();
912 foreach ( index, indexes ) {
913 myView->collapseAll( index );
918 SLOT: called if SUIT object is destroyed
920 /* TODO: moved to SUIT_TreeModel
921 void OB_Browser::onDestroyed( SUIT_DataObject* obj )
927 SLOT: called on finish of drag-n-drop operation
928 \param items - dragged items
929 \param item - destination (item on that they were dropped)
930 \param action - QDropEvent::Action
932 // TODO: drag-n-drop works differently - SUIT_TreeModel to be updated
933 // and QTreeView needs some setup
935 void OB_Browser::onDropped( QPtrList<QListViewItem> items, QListViewItem* item, int action )
937 SUIT_DataObject* obj = dataObject( item );
942 for ( QPtrListIterator<QListViewItem> it( items ); it.current(); ++it )
944 SUIT_DataObject* o = dataObject( it.current() );
949 if ( !lst.isEmpty() )
950 emit dropped( lst, obj, action );
954 Updates texts of items
956 /* TODO: to be removed
957 void OB_Browser::updateText()
959 if ( myColumnIds.isEmpty() )
962 QListView* lv = listView();
966 for ( QListViewItemIterator it( lv ); it.current(); ++it )
968 SUIT_DataObject* obj = dataObject( it.current() );
972 for( QMap<int, int>::iterator itr = myColumnIds.begin(); itr != myColumnIds.end(); ++itr )
973 it.current()->setText( itr.data(), obj->text( itr.key() ) );
978 \return true if item must be updated
979 \param item - item to be checked
981 /* TODO: to be revised
982 bool OB_Browser::needToUpdateTexts( QListViewItem* item ) const
984 SUIT_DataObject* obj = dataObject( item );
988 for( QMap<int, int>::const_iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
989 if( item->text( it.data() ) != obj->text( it.key() ) )
995 Updates texts of item
996 \param item - item to be updated
998 /* TODO: to be revised
999 void OB_Browser::updateText( QListViewItem* item )
1001 SUIT_DataObject* obj = dataObject( item );
1005 for( QMap<int, int>::iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
1006 item->setText( it.data(), obj->text( it.key() ) );
1011 \brief Add custom actions to the popup menu.
1012 \param menu popup menu
1014 void OB_Browser::createPopupMenu( QMenu* menu )
1016 menu->addSeparator();
1018 QModelIndexList indexes = selectedIndexes();
1020 bool closed = false, opened = false;
1022 for ( QModelIndexList::Iterator it = indexes.begin();
1023 it != indexes.end() && !closed; ++it ) {
1024 closed = hasCollased( *it );
1027 for ( QModelIndexList::Iterator it = indexes.begin();
1028 it != indexes.end() && !opened; ++it ) {
1029 opened = hasExpanded( *it );
1033 menu->addAction( tr( "MEN_EXPAND_ALL" ), this, SLOT( onExpandAll() ) );
1035 menu->addAction( tr( "MEN_COLLAPSE_ALL" ), this, SLOT( onCollapseAll() ) );
1037 if ( isSearchToolEnabled() ) {
1038 menu->addSeparator();
1039 menu->addAction( tr( "MEN_FIND" ), searchTool(), SLOT( find() ), QKeySequence(Qt::CTRL + Qt::Key_F) );
1040 menu->addSeparator();
1045 Expands item with all it's children
1047 /* TODO: to be revised
1048 void OB_Browser::expand( QListViewItem* item )
1053 item->setOpen( true );
1054 for ( QListViewItem* child = item->firstChild(); child; child = child->nextSibling() )
1059 \brief Check if model index is collapsed or has collapsed children.
1060 \return \c true if item or one of its children is collapsed
1062 bool OB_Browser::hasCollased( const QModelIndex& index ) const
1064 bool result = false;
1066 if ( index.isValid() && model() ) {
1067 bool hasChildren = model()->hasChildren( index );
1068 result = hasChildren && !myView->isExpanded( index );
1069 if ( !result && hasChildren ) {
1070 int rows = model()->rowCount( index );
1071 for ( int i = 0; i < rows && !result; i ++ ) {
1072 QModelIndex child = model()->index( i, 0, index );
1073 result = hasCollased( child );
1081 \brief Check if model index is expanded or has expanded children.
1082 \return \c true if item or one of its children is expanded
1084 bool OB_Browser::hasExpanded( const QModelIndex& index ) const
1086 bool result = false;
1088 if ( index.isValid() && model() ) {
1089 bool hasChildren = model()->hasChildren( index );
1090 result = hasChildren && myView->isExpanded( index );
1091 if ( !result && hasChildren ) {
1092 int rows = model()->rowCount( index );
1093 for ( int i = 0; i < rows && !result; i ++ ) {
1094 QModelIndex child = model()->index( i, 0, index );
1095 result = hasExpanded( child );
1104 \param obj - SUIT object to be removed
1105 \param autoUpd - auto tree updating
1107 /* TODO: moved to SUIT_TreeModel
1108 void OB_Browser::removeObject( SUIT_DataObject* obj, const bool autoUpd )
1113 // Removing list view items from <myItems> recursively for all children.
1114 // Otherwise, "delete item" line will destroy all item's children,
1115 // and <myItems> will contain invalid pointers (see ~QListViewItem() description in Qt docs)
1116 DataObjectList childList;
1117 obj->children( childList, true );
1118 for ( DataObjectListIterator it( childList ); it.current(); ++it )
1120 it.current()->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1121 myItems.remove( it.current() );
1124 QListViewItem* item = listViewItem( obj );
1126 obj->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1127 myItems.remove( obj );
1129 if ( obj == myRoot )
1131 // remove all child list view items
1139 if ( isAutoUpdate() )
1141 SUIT_DataObject* pObj = item && item->parent() ? dataObject( item->parent() ) : 0;
1142 updateTree( pObj, false );
1149 Opens branches from 1 to autoOpenLevel()
1152 /* TODO: to be revised
1153 void OB_Browser::autoOpenBranches()
1163 /* TODO: to be revised
1164 void OB_Browser::openBranch( QListViewItem* item, const int level )
1171 item->setOpen( true );
1172 openBranch( item->firstChild(), level - 1 );
1173 item = item->nextSibling();
1178 SLOT: called on double click on item, emits signal
1180 /* TODO: to be revised
1181 void OB_Browser::onDoubleClicked( QListViewItem* item )
1184 emit doubleClicked( dataObject( item ) );
1189 \fn void OB_Browser::selectionChanged();
1190 \brief Emitted when selection is changed in the Object Browser.