1 // Copyright (C) 2007-2008 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
22 // File : OB_Browser.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "OB_Browser.h"
27 //#include "OB_Filter.h"
28 //#include "OB_ListItem.h"
29 //#include "OB_ListView.h"
31 #include <QtxTreeView.h>
32 #include <QtxSearchTool.h>
33 //#include <SUIT_DataObjectIterator.h>
37 #include <QItemSelection>
39 #include <QVBoxLayout>
40 #include <QAbstractItemModel>
41 #include <QAbstractItemDelegate>
42 #include <QHeaderView>
48 \class OB_Browser::ToolTip
49 Tool tip for OB_Browser.
52 //TODO: ToolTip commented - to be removed or revised
54 class OB_Browser::ToolTip : public QToolTip
57 ToolTip( OB_Browser* b, QWidget* p = 0 );
60 void maybeTip( const QPoint& );
63 OB_Browser* myBrowser;
70 OB_Browser::ToolTip::ToolTip( OB_Browser* b, QWidget* p )
80 OB_Browser::ToolTip::~ToolTip()
85 It is called when there is a possibility that a tool tip
86 should be shown and must decide whether there is a tool tip for the point
87 in the widget that this QToolTip object relates to.
88 \param pos - point co-ordinates
91 void OB_Browser::ToolTip::maybeTip( const QPoint& pos )
93 if ( !parentWidget() || !myBrowser || !myBrowser->isShowToolTips() )
96 QListView* lv = myBrowser->listView();
98 QListViewItem* item = lv->itemAt( pos );
99 SUIT_DataObject* obj = myBrowser->dataObject( item );
103 QString aText = obj->toolTip();
105 if ( aText.isEmpty() )
108 QRect aRect = lv->itemRect( item );
117 \brief Object browser widget which can be used to handle tree-like data model.
119 The class OB_Browser implements public API of an object browser widget
120 that can be used to display arbitrary application data in a hierarchical form.
121 It is based on Qt4 model/view architecture.
123 Object browser can be used with conjuction of any custom item model inherited
124 from QAbstractItemModel class (see Qt 4 reference manual).
126 The class provides a functionality get/modify selection, drag-n-drop of the
132 \param parent paren widget
133 \param model data model
135 OB_Browser::OB_Browser( QWidget* parent, QAbstractItemModel* model )
139 myView = new QtxTreeView( this );
140 myView->setRootIsDecorated( true );
141 myView->setSelectionMode( QAbstractItemView::ExtendedSelection );
142 myView->setAllColumnsShowFocus( true );
144 mySearchTool = new QtxSearchTool( this, myView );
145 mySearchTool->setFrameStyle( QFrame::NoFrame | QFrame::Plain );
146 mySearchTool->setActivators( QtxSearchTool::StandardKey | QtxSearchTool::SlashKey );
147 mySearchTool->setSearcher( new QtxTreeViewSearcher( myView ) );
149 QVBoxLayout* main = new QVBoxLayout( this );
150 main->addWidget( myView );
151 main->addWidget( mySearchTool );
152 main->setMargin( 0 );
153 main->setSpacing( 3 );
155 // TODO: decide what to do with tooltip
156 //myShowToolTips = true;
157 //myTooltip = new ToolTip( this, myView->viewport() );
159 // TODO: drag-n-drop works differently - SUIT_TreeModel to be updated
160 // and QTreeView needs some setup
161 //connect( myView, SIGNAL( dropped( QPtrList<QListViewItem>, QListViewItem*, int ) ),
162 // this, SLOT( onDropped( QPtrList<QListViewItem>, QListViewItem*, int ) ) );
165 connect( myView, SIGNAL( selectionChanged() ),
166 this, SIGNAL( selectionChanged() ) );
173 OB_Browser::~OB_Browser()
180 \brief Get data model.
184 QAbstractItemModel* OB_Browser::model() const
186 return myView->model();
190 \brief Set data model.
191 \param model data model
194 void OB_Browser::setModel( QAbstractItemModel* model )
196 myView->setModel( model );
202 \brief Get current item delegate (items renderer).
203 \return currently used item delegate
204 \sa setItemDelegate()
206 QAbstractItemDelegate* OB_Browser::itemDelegate() const
208 return myView->itemDelegate();
212 \brief Set item delegate (items renderer).
213 \param d custom item delegate
216 void OB_Browser::setItemDelegate( QAbstractItemDelegate* d )
218 myView->setItemDelegate( d );
222 \brief Check if controls for expanding and collapsing top-level items are shown.
223 \return \c true if top-level items are decorated
224 \sa setRootIsDecorated()
226 bool OB_Browser::rootIsDecorated() const
228 return myView->rootIsDecorated();
232 \brief Show/hide controls for expanding and collapsing top-level items.
233 \param decor if \c true, top-level items are decorated
234 \sa rootIsDecorated()
236 void OB_Browser::setRootIsDecorated( const bool decor )
238 if ( decor != rootIsDecorated() )
239 myView->setRootIsDecorated( decor );
243 \brief Check if "Sorting" popup menu command for the header is enabled.
244 \return \c true if "Sorting" menu command is enabled
245 \sa setSortMenuEnabled()
247 bool OB_Browser::sortMenuEnabled() const
249 return myView->sortMenuEnabled();
253 \brief Enable/disable "Sorting" popup menu command for the header.
254 \param enableSortMenu if \c true, enable "Sorting" menu command
255 \sa sortMenuEnabled()
257 void OB_Browser::setSortMenuEnabled( const bool enabled )
259 if ( enabled != sortMenuEnabled() )
260 myView->setSortMenuEnabled( enabled );
264 \brief Get search tool widget.
265 \return search tool widget
266 \sa isSearchToolEnabled(), setSearchToolEnabled()
268 QtxSearchTool* OB_Browser::searchTool() const
274 \brief Check if search tool is enabled.
275 \return \c true if search tool is enabled
276 \sa setSearchToolEnabled(), searchTool()
278 bool OB_Browser::isSearchToolEnabled() const
280 return mySearchTool->isEnabled();
284 \brief Enable/disable search tool.
285 \param enable pass \c true to enable search tool
286 \sa isSearchToolEnabled(), searchTool()
288 void OB_Browser::setSearchToolEnabled( const bool enable )
290 if ( mySearchTool->isEnabled() == enable )
293 mySearchTool->setEnabled( enable );
294 if ( !mySearchTool->isEnabled() )
295 mySearchTool->hide();
299 \brief Get number of levels which should be automatically expanded
300 when updating the data tree.
301 \return number of levels to be auto-opened on tree updating
302 \sa setAutoOpenLevel()
304 int OB_Browser::autoOpenLevel() const
306 return myAutoOpenLevel;
310 \brief Set number of levels which should be automatically expanded
311 when updating the data tree.
312 \param levels number of levels to be auto-opened on tree updating
315 void OB_Browser::setAutoOpenLevel( const int levels )
317 if ( myAutoOpenLevel != levels )
318 myAutoOpenLevel = levels;
322 \brief Expand all branches to the specified number of levels.
324 If \a levels value is negative, then autoOpenLevel() value is used instead.
326 \param levels number of levels to be expanded
329 void OB_Browser::openLevels( const int levels )
331 myView->expandLevels( levels < 0 ? autoOpenLevel() : levels );
335 \return state "are tooltips shown"
338 bool OB_Browser::isShowToolTips()
340 return myShowToolTips;
344 Sets new value of state "are tooltips shown"
345 \param theDisplay - new value
348 void OB_Browser::setShowToolTips( const bool theDisplay )
350 myShowToolTips = theDisplay;
355 \brief Get number of selected items.
356 \return number of selected items
358 int OB_Browser::numberOfSelected() const
360 return myView->selectionModel() ? myView->selectionModel()->selectedIndexes().count() : 0;
364 \brief Get all selected items.
365 \return unsorted list of selected indexes with no duplicates
367 QModelIndexList OB_Browser::selectedIndexes() const
369 return myView->selectionModel() ? myView->selectionModel()->selectedIndexes() : QModelIndexList();
373 \brief Get selection containing information about selected ranges.
374 \return QItemSelection instance
376 const QItemSelection OB_Browser::selection() const
378 static QItemSelection emptySel;
379 QItemSelection sel = emptySel;
380 if ( myView->selectionModel() )
381 sel = myView->selectionModel()->selection();
386 \brief Select/deselect specified model index.
387 \param index model index to be selected/deselected
388 \param on if \c true, the index will be selected, otherwise - deselected
389 \param keepSelection if \c true (default) the previous selection is kept,
390 otherwise it is first cleared
392 void OB_Browser::select( const QModelIndex& index, const bool on, const bool keepSelection )
394 if ( myView->selectionModel() ) {
395 QItemSelectionModel::SelectionFlags f = on ? QItemSelectionModel::Select : QItemSelectionModel::Deselect;
396 f = f | QItemSelectionModel::Rows;
397 if ( !keepSelection )
398 f = f | QItemSelectionModel::Clear;
400 myView->selectionModel()->select( index, f );
405 \brief Select/deselect specified model indices.
406 \param indexes model indices to be selected/deselected
407 \param on if \c true, the indices will be selected, otherwise - deselected
408 \param keepSelection if \c true (default) the previous selection is kept,
409 otherwise it is first cleared
411 void OB_Browser::select( const QModelIndexList& indexes, const bool on, const bool keepSelection )
413 bool blocked = myView->signalsBlocked();
414 myView->blockSignals( true );
419 if ( !indexes.isEmpty() ) {
420 foreach( idx, indexes ) {
421 select( idx, on, first ? keepSelection : true );
425 else if ( !keepSelection ) {
426 myView->clearSelection();
429 myView->blockSignals( blocked );
430 emit( selectionChanged() );
434 \brief Check if specified model index is expanded or collapsed.
435 \param index model index
436 \return \c true if model index is expanded
439 bool OB_Browser::isOpen( const QModelIndex& index ) const
441 return index.isValid() && model() && model()->hasChildren( index ) && myView->isExpanded( index );
445 \brief Expand/collapse the specified model index.
446 \param index model index
447 \param open if \c true, the index will be expanded, otherwse - collapsed
450 void OB_Browser::setOpen( const QModelIndex& index, const bool open )
452 myView->setExpanded( index, open ); // hasChildren() ???
456 \brief Adjust first column width to its contents.
458 void OB_Browser::adjustWidth()
460 myView->resizeColumnToEncloseContents( 0 );
464 \brief Adjust first column width to its contents.
466 void OB_Browser::adjustFirstColumnWidth()
468 myView->resizeColumnToEncloseContents( 0 );
472 \brief Adjust all columns width to its contents except the first column.
474 void OB_Browser::adjustColumnsWidth()
476 for ( int aCol = 1; aCol < myView->header()->count(); aCol++ ) {
477 if ( myView->columnWidth( aCol ) > 0 )
478 myView->resizeColumnToEncloseContents( aCol );
483 \return SUIT object correspondint to item at position 'pos'
484 \param pos - position
486 /* TODO: removed - QTreeView::indexAt() should be used
487 SUIT_DataObject* OB_Browser::dataObjectAt( const QPoint& pos ) const
489 SUIT_DataObject* obj = 0;
491 QListView* lv = listView();
493 obj = dataObject( lv->itemAt( pos ) );
499 \return filter of list view
502 OB_Filter* OB_Browser::filter() const
504 return myView->filter();
508 Changes filter of list view
509 \param f - new filter
512 void OB_Browser::setFilter( OB_Filter* f )
514 myView->setFilter( f );
518 Sets global width mode
519 \param mode - new width mode
522 void OB_Browser::setWidthMode( QListView::WidthMode mode )
524 for ( int i = 0, n = myView->columns(); i < n; i++ )
525 if( mode!=QListView::Maximum || myView->columnWidth( i )>0 )
526 myView->setColumnWidthMode( i, mode );
531 \param obj - start object
532 \param autoOpen - to open automatically branches of autoOpenLevel()
536 void OB_Browser::updateTree( SUIT_DataObject* obj, const bool autoOpen )
538 // QTime t1 = QTime::currentTime();
540 if ( !obj && !(obj = getRootObject()) )
543 DataObjectKey curKey;
544 DataObjectMap selObjs, openObjs;
545 DataObjectKeyMap selKeys, openKeys;
547 int selNum = numberOfSelected();
549 SUIT_DataObject* curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
553 restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
560 if ( selNum != numberOfSelected() )
561 emit selectionChanged();
563 // QTime t2 = QTime::currentTime();
564 // qDebug( QString( "update tree time = %1 msecs" ).arg( t1.msecsTo( t2 ) ) );
568 Replaces part of tree starting at object 'src' by tree starting at object 'trg'
571 void OB_Browser::replaceTree( SUIT_DataObject* src, SUIT_DataObject* trg )
573 if ( !src || !trg || src == trg || src->root() != getRootObject() )
576 DataObjectKey curKey;
577 DataObjectMap selObjs, openObjs;
578 DataObjectKeyMap selKeys, openKeys;
580 int selNum = numberOfSelected();
582 SUIT_DataObject* curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
584 SUIT_DataObject* parent = src->parent();
585 int pos = parent ? parent->childPos( src ) : -1;
589 removeConnections( src );
590 if ( isAutoDeleteObjects() )
593 if ( parent && pos != -1 )
594 parent->insertChild( trg, pos );
596 trg->setParent( parent );
599 createConnections( trg );
601 restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
605 if ( selNum != numberOfSelected() )
606 emit selectionChanged();
610 Adjusts width by item
614 void OB_Browser::adjustWidth( QListViewItem* item )
618 item->widthChanged( 0 );
619 if ( item->isOpen() )
620 adjustWidth( item->firstChild() );
621 item = item->nextSibling();
627 \remove all items referencing current (through data objects)
630 void OB_Browser::removeReferences( QListViewItem* item )
635 SUIT_DataObject* obj = dataObject( item );
636 obj->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
637 myItems.remove( obj );
639 QListViewItem* i = item->firstChild();
642 removeReferences( i );
643 i = i->nextSibling();
648 Connects all children to SLOT onDestroyed
650 /* TODO: move to SUIT_TreeModel
651 void OB_Browser::createConnections( SUIT_DataObject* obj )
656 DataObjectList childList;
657 obj->children( childList, true );
659 childList.prepend( obj );
661 for ( DataObjectListIterator it( childList ); it.current(); ++it )
662 it.current()->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
666 Disconnects all children from SLOT onDestroyed
668 /* TODO: move to SUIT_TreeModel
669 void OB_Browser::removeConnections( SUIT_DataObject* obj )
674 DataObjectList childList;
675 obj->children( childList, true );
677 childList.prepend( obj );
679 for ( DataObjectListIterator it( childList ); it.current(); ++it )
680 it.current()->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
684 Stores states (opened, selected) of current tree items
686 \param selObjs, selKeys - maps of selected objects
687 \param openObjs, openKeys - maps of opened objects
688 \param curKey - map of current objects
690 /* TODO: to be revised
691 SUIT_DataObject* OB_Browser::storeState( DataObjectMap& selObjs, DataObjectMap& openObjs,
692 DataObjectKeyMap& selKeys, DataObjectKeyMap& openKeys,
693 DataObjectKey& curKey ) const
695 QListView* lv = listView();
699 SUIT_DataObject* curObj = dataObject( lv->currentItem() );
701 curKey = objectKey( curObj );
703 for ( QListViewItemIterator it( lv ); it.current(); ++it )
705 SUIT_DataObject* obj = dataObject( it.current() );
709 selObjs.insert( obj, lv->isSelected( it.current() ) );
710 openObjs.insert( obj, lv->isOpen( it.current() ) );
711 if ( lv->isSelected( it.current() ) )
712 selKeys.insert( objectKey( obj ), 0 );
713 if ( lv->isOpen( it.current() ) )
714 openKeys.insert( objectKey( obj ), 0 );
721 Restores 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 void OB_Browser::restoreState( const DataObjectMap& selObjs, const DataObjectMap& openObjs,
728 const SUIT_DataObject* curObj, const DataObjectKeyMap& selKeys,
729 const DataObjectKeyMap& openKeys, const DataObjectKey& curKey )
731 QListView* lv = listView();
735 bool block = lv->signalsBlocked();
736 lv->blockSignals( true );
738 QListViewItem* curItem = 0;
739 for ( QListViewItemIterator it( lv ); it.current(); ++it )
741 QListViewItem* item = it.current();
742 SUIT_DataObject* obj = dataObject( item );
747 DataObjectKey key = objectKey( obj );
749 if ( selObjs.contains( obj ) )
751 if ( selObjs[obj] && !lv->isSelected( item ) )
752 lv->setSelected( item, true );
754 else if ( !key.isNull() && selKeys.contains( key ) && !lv->isSelected( item ) )
755 lv->setSelected( item, true );
757 if ( openObjs.contains( obj ) )
759 bool parentOpen = true;
760 if( item && item->parent() )
761 parentOpen = item->parent()->isOpen();
763 if ( openObjs[obj] && parentOpen )
764 lv->setOpen( item, true );
766 else if ( !key.isNull() && openKeys.contains( key ) )
768 bool parentOpen = true;
769 if( item && item->parent() )
770 parentOpen = item->parent()->isOpen();
773 lv->setOpen( item, true );
776 if ( !curItem && ( curObj == obj || ( !curKey.isNull() && curKey == key )) )
781 lv->setCurrentItem( curItem );
783 lv->blockSignals( block );
787 Creates object key by tree item
789 /* TODO: move to SUIT_TreeModel
790 OB_Browser::DataObjectKey OB_Browser::objectKey( QListViewItem* i ) const
792 return objectKey( dataObject( i ) );
796 Creates object key by SUIT object
798 /* TODO: move to SUIT_TreeModel
799 OB_Browser::DataObjectKey OB_Browser::objectKey( SUIT_DataObject* obj ) const
804 return DataObjectKey( obj->key() );
809 \brief Get tree view widget.
810 \return tree view widget of the object browser
812 QtxTreeView* OB_Browser::treeView() const
818 \brief Process context menu request event.
819 \param e context menu event
821 void OB_Browser::contextMenuEvent( QContextMenuEvent* e )
823 QMenu* popup = new QMenu();
825 createPopupMenu( popup );
827 Qtx::simplifySeparators( popup );
829 if ( !popup->actions().isEmpty() )
830 popup->exec( e->globalPos() );
835 \brief Get the time of the latest updating.
836 \return latest updating time
838 unsigned long OB_Browser::getModifiedTime() const
840 return myModifiedTime;
844 \brief Update the time of the latest updating.
846 void OB_Browser::setModified()
848 myModifiedTime = clock();
852 \brief Called when "Expand all" popup menu command is activated.
854 Expands all selected items recursively.
856 void OB_Browser::onExpandAll()
858 QModelIndexList indexes = selectedIndexes();
861 foreach ( index, indexes ) {
862 myView->expandAll( index );
867 \brief Called when "Collapse all" popup menu command is activated.
869 Collapse all selected items recursively.
871 void OB_Browser::onCollapseAll()
873 QModelIndexList indexes = selectedIndexes();
876 foreach ( index, indexes ) {
877 myView->collapseAll( index );
882 SLOT: called if SUIT object is destroyed
884 /* TODO: moved to SUIT_TreeModel
885 void OB_Browser::onDestroyed( SUIT_DataObject* obj )
891 SLOT: called on finish of drag-n-drop operation
892 \param items - dragged items
893 \param item - destination (item on that they were dropped)
894 \param action - QDropEvent::Action
896 // TODO: drag-n-drop works differently - SUIT_TreeModel to be updated
897 // and QTreeView needs some setup
899 void OB_Browser::onDropped( QPtrList<QListViewItem> items, QListViewItem* item, int action )
901 SUIT_DataObject* obj = dataObject( item );
906 for ( QPtrListIterator<QListViewItem> it( items ); it.current(); ++it )
908 SUIT_DataObject* o = dataObject( it.current() );
913 if ( !lst.isEmpty() )
914 emit dropped( lst, obj, action );
918 Updates texts of items
920 /* TODO: to be removed
921 void OB_Browser::updateText()
923 if ( myColumnIds.isEmpty() )
926 QListView* lv = listView();
930 for ( QListViewItemIterator it( lv ); it.current(); ++it )
932 SUIT_DataObject* obj = dataObject( it.current() );
936 for( QMap<int, int>::iterator itr = myColumnIds.begin(); itr != myColumnIds.end(); ++itr )
937 it.current()->setText( itr.data(), obj->text( itr.key() ) );
942 \return true if item must be updated
943 \param item - item to be checked
945 /* TODO: to be revised
946 bool OB_Browser::needToUpdateTexts( QListViewItem* item ) const
948 SUIT_DataObject* obj = dataObject( item );
952 for( QMap<int, int>::const_iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
953 if( item->text( it.data() ) != obj->text( it.key() ) )
959 Updates texts of item
960 \param item - item to be updated
962 /* TODO: to be revised
963 void OB_Browser::updateText( QListViewItem* item )
965 SUIT_DataObject* obj = dataObject( item );
969 for( QMap<int, int>::iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
970 item->setText( it.data(), obj->text( it.key() ) );
975 \brief Add custom actions to the popup menu.
976 \param menu popup menu
978 void OB_Browser::createPopupMenu( QMenu* menu )
980 menu->addSeparator();
982 QModelIndexList indexes = selectedIndexes();
984 bool closed = false, opened = false;
986 for ( QModelIndexList::Iterator it = indexes.begin();
987 it != indexes.end() && !closed; ++it ) {
988 closed = hasCollased( *it );
991 for ( QModelIndexList::Iterator it = indexes.begin();
992 it != indexes.end() && !opened; ++it ) {
993 opened = hasExpanded( *it );
997 menu->addAction( tr( "MEN_EXPAND_ALL" ), this, SLOT( onExpandAll() ) );
999 menu->addAction( tr( "MEN_COLLAPSE_ALL" ), this, SLOT( onCollapseAll() ) );
1001 if ( isSearchToolEnabled() ) {
1002 menu->addSeparator();
1003 menu->addAction( tr( "MEN_FIND" ), searchTool(), SLOT( find() ), QKeySequence(Qt::CTRL + Qt::Key_F) );
1004 menu->addSeparator();
1009 Expands item with all it's children
1011 /* TODO: to be revised
1012 void OB_Browser::expand( QListViewItem* item )
1017 item->setOpen( true );
1018 for ( QListViewItem* child = item->firstChild(); child; child = child->nextSibling() )
1023 \brief Check if model index is collapsed or has collapsed children.
1024 \return \c true if item or one of its children is collapsed
1026 bool OB_Browser::hasCollased( const QModelIndex& index ) const
1028 bool result = false;
1030 if ( index.isValid() && model() ) {
1031 bool hasChildren = model()->hasChildren( index );
1032 result = hasChildren && !myView->isExpanded( index );
1033 if ( !result && hasChildren ) {
1034 int rows = model()->rowCount( index );
1035 for ( int i = 0; i < rows && !result; i ++ ) {
1036 QModelIndex child = model()->index( i, 0, index );
1037 result = hasCollased( child );
1045 \brief Check if model index is expanded or has expanded children.
1046 \return \c true if item or one of its children is expanded
1048 bool OB_Browser::hasExpanded( const QModelIndex& index ) const
1050 bool result = false;
1052 if ( index.isValid() && model() ) {
1053 bool hasChildren = model()->hasChildren( index );
1054 result = hasChildren && myView->isExpanded( index );
1055 if ( !result && hasChildren ) {
1056 int rows = model()->rowCount( index );
1057 for ( int i = 0; i < rows && !result; i ++ ) {
1058 QModelIndex child = model()->index( i, 0, index );
1059 result = hasExpanded( child );
1068 \param obj - SUIT object to be removed
1069 \param autoUpd - auto tree updating
1071 /* TODO: moved to SUIT_TreeModel
1072 void OB_Browser::removeObject( SUIT_DataObject* obj, const bool autoUpd )
1077 // Removing list view items from <myItems> recursively for all children.
1078 // Otherwise, "delete item" line will destroy all item's children,
1079 // and <myItems> will contain invalid pointers (see ~QListViewItem() description in Qt docs)
1080 DataObjectList childList;
1081 obj->children( childList, true );
1082 for ( DataObjectListIterator it( childList ); it.current(); ++it )
1084 it.current()->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1085 myItems.remove( it.current() );
1088 QListViewItem* item = listViewItem( obj );
1090 obj->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
1091 myItems.remove( obj );
1093 if ( obj == myRoot )
1095 // remove all child list view items
1103 if ( isAutoUpdate() )
1105 SUIT_DataObject* pObj = item && item->parent() ? dataObject( item->parent() ) : 0;
1106 updateTree( pObj, false );
1113 Opens branches from 1 to autoOpenLevel()
1116 /* TODO: to be revised
1117 void OB_Browser::autoOpenBranches()
1127 /* TODO: to be revised
1128 void OB_Browser::openBranch( QListViewItem* item, const int level )
1135 item->setOpen( true );
1136 openBranch( item->firstChild(), level - 1 );
1137 item = item->nextSibling();
1142 SLOT: called on double click on item, emits signal
1144 /* TODO: to be revised
1145 void OB_Browser::onDoubleClicked( QListViewItem* item )
1148 emit doubleClicked( dataObject( item ) );
1153 \fn void OB_Browser::selectionChanged();
1154 \brief Emitted when selection is changed in the Object Browser.