X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FObjBrowser%2FOB_Browser.cxx;h=20634584a989b34d4ddce24e9c68cd2d00dece44;hb=bc4c826e687da26b1f96703015aa87a5d60d2e89;hp=41232b9a29e95585995e49a6b2f7886b1f6d2530;hpb=f830c97c748d8f8a6a7eccc8e3a58e19066a1181;p=modules%2Fgui.git diff --git a/src/ObjBrowser/OB_Browser.cxx b/src/ObjBrowser/OB_Browser.cxx index 41232b9a2..20634584a 100755 --- a/src/ObjBrowser/OB_Browser.cxx +++ b/src/ObjBrowser/OB_Browser.cxx @@ -1,47 +1,57 @@ -// Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D -// +// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // + +// File : OB_Browser.cxx +// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com) + #include "OB_Browser.h" -#include "OB_Filter.h" -#include "OB_ListItem.h" -#include "OB_ListView.h" -#include "OB_FindDlg.h" +//#include "OB_Filter.h" +//#include "OB_ListItem.h" +//#include "OB_ListView.h" -#include -#include +#include +#include +//#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include + /*! \class OB_Browser::ToolTip Tool tip for OB_Browser. */ +//TODO: ToolTip commented - to be removed or revised +/* class OB_Browser::ToolTip : public QToolTip { public: @@ -53,33 +63,36 @@ public: private: OB_Browser* myBrowser; }; - +*/ /*! Constructor */ +/* OB_Browser::ToolTip::ToolTip( OB_Browser* b, QWidget* p ) : QToolTip( p ), myBrowser( b ) { } - +*/ /*! Destructor */ +/* OB_Browser::ToolTip::~ToolTip() { } - +*/ /*! It is called when there is a possibility that a tool tip should be shown and must decide whether there is a tool tip for the point in the widget that this QToolTip object relates to. \param pos - point co-ordinates */ +/* void OB_Browser::ToolTip::maybeTip( const QPoint& pos ) { if ( !parentWidget() || !myBrowser || !myBrowser->isShowToolTips() ) - return; + return; QListView* lv = myBrowser->listView(); @@ -97,270 +110,203 @@ void OB_Browser::ToolTip::maybeTip( const QPoint& pos ) tip( aRect, aText ); } +*/ -typedef SUIT_DataObject* ObjPtr; -typedef OB_ListItem* ItemPtr; - /*! - \class OB_BrowserSync - Auxiliary class for synchronizing tree of SUIT_DataObjects and list view items -*/ -class OB_BrowserSync -{ -public: - OB_BrowserSync( OB_Browser* ); - bool isEqual( const ObjPtr&, const ItemPtr& ) const; - ObjPtr nullSrc() const; - ItemPtr nullTrg() const; - ItemPtr createItem( const ObjPtr&, const ItemPtr&, const ItemPtr&, const bool ) const; - void updateItem( const ObjPtr& , const ItemPtr& ) const; - void deleteItemWithChildren( const ItemPtr& ) const; - void children( const ObjPtr&, QValueList& ) const; - void children( const ItemPtr&, QValueList& ) const; - ItemPtr parent( const ItemPtr& ) const; -private: - bool needUpdate( const ItemPtr& ) const; - OB_Browser* myBrowser; -}; + \class OB_Browser + \brief Object browser widget which can be used to handle tree-like data model. + The class OB_Browser implements public API of an object browser widget + that can be used to display arbitrary application data in a hierarchical form. + It is based on Qt4 model/view architecture. -/*! - Constructor -*/ -OB_BrowserSync::OB_BrowserSync( OB_Browser* ob ) -: myBrowser( ob ) -{ -} + Object browser can be used with conjuction of any custom item model inherited + from QAbstractItemModel class (see Qt 4 reference manual). -/*! - \return true if item must be updated - \param item - item to be checked + The class provides a functionality get/modify selection, drag-n-drop of the + objects, etc. */ -bool OB_BrowserSync::needUpdate( const ItemPtr& item ) const -{ - bool update = false; - if ( item ) { - SUIT_DataObject* obj = item->dataObject(); - if ( obj ) { - // 1. check text - update = ( item->text( 0 ) != obj->name() ) || myBrowser->needToUpdateTexts( item ); - - if ( !update ) { - // 2. check pixmap (compare serialNumber()-s) - QPixmap objPix = obj->icon(); - const QPixmap* itemPix = item->pixmap( 0 ); - update = ( objPix.isNull() && ( itemPix && !itemPix->isNull() ) ) || - ( !objPix.isNull() && ( !itemPix || itemPix->isNull() ) ); - if ( !update && !objPix.isNull() && itemPix && !itemPix->isNull() ) { - int aIconW = objPix.width(); - if( aIconW > 20 ) { - QWMatrix aM; - double aScale = 20.0 / aIconW; - aM.scale( aScale, aScale ); - objPix = objPix.xForm( aM ); - } - update = ( objPix.serialNumber() != itemPix->serialNumber() ); - } - } - } - } - return update; -} /*! - Updates item - \param p - item + \brief Constructor + \param parent paren widget + \param model data model */ -void OB_BrowserSync::updateItem( const ObjPtr& o, const ItemPtr& p ) const +OB_Browser::OB_Browser( QWidget* parent, QAbstractItemModel* model ) +: QWidget( parent ), + myAutoOpenLevel( 0 ) { - if ( p && needUpdate( p ) ) { - // printf( "--- needUpdate for %s = true ---\n", p->text( 0 ).latin1() ); - myBrowser->updateText( p ); - p->update(); - } - if( o && myBrowser->getUpdater() ) - { - myBrowser->getUpdater()->update( o, p ); - } + // set-up tree view + myView = new QtxTreeView( this ); // create tree view + myView->setRootIsDecorated( true ); // show root item + myView->setSelectionMode( QAbstractItemView::ExtendedSelection ); // enable extended selection mode + myView->setAllColumnsShowFocus( true ); // focus is shown in all columns + + // enable drag-n-drop support + myView->setDragDropMode( QAbstractItemView::DragDrop ); // enable both drag and drop operations + myView->setDropIndicatorShown( true ); // show drag indicator on dragging + + // set-up search tool + mySearchTool = new QtxSearchTool( this, myView ); // create search tool + mySearchTool->setFrameStyle( QFrame::NoFrame | QFrame::Plain ); // do not show frame + mySearchTool->setActivators( QtxSearchTool::StandardKey | QtxSearchTool::SlashKey ); // set activation mode + mySearchTool->setSearcher( new QtxTreeViewSearcher( myView ) ); // assign searcher (for tree view) + + // layout widgets + QVBoxLayout* main = new QVBoxLayout( this ); + main->addWidget( myView ); + main->addWidget( mySearchTool ); + main->setMargin( 0 ); + main->setSpacing( 3 ); + + // TODO: decide what to do with tooltip + //myShowToolTips = true; + //myTooltip = new ToolTip( this, myView->viewport() ); + + // TODO: drag-n-drop works differently - SUIT_TreeModel to be updated + // and QTreeView needs some setup + //connect( myView, SIGNAL( dropped( QPtrList, QListViewItem*, int ) ), + // this, SLOT( onDropped( QPtrList, QListViewItem*, int ) ) ); + setModel( model ); + + connect( myView, SIGNAL( selectionChanged() ), + this, SIGNAL( selectionChanged() ) ); } /*! - Creates item by SUIT object - \param src - corresponding SUIT object - \param parent - parent for item - \param after - previous sibling for item - \param prepend - item must be added to start of children list + \brief Destructor. */ -ItemPtr OB_BrowserSync::createItem( const ObjPtr& src, - const ItemPtr& parent, const ItemPtr& after, - const bool prepend ) const +OB_Browser::~OB_Browser() { - ItemPtr i = myBrowser ? dynamic_cast( myBrowser->createItem( src, parent, after, prepend ) ) : 0; - if( i ) - i->setOpen( src->isOpen() ); - return i; + //delete myTooltip; + //setUpdater( 0 ); } /*! - Deletes object with all children - \param i - item + \brief Get data model. + \return data model + \sa setModel() */ -void OB_BrowserSync::deleteItemWithChildren( const ItemPtr& i ) const +QAbstractItemModel* OB_Browser::model() const { - if( myBrowser && myBrowser->myItems.contains( i->dataObject() ) ) - { - myBrowser->removeReferences( i ); - delete i; - } + return myView->model(); } /*! - \return true if objects correspond each other at all - \param p - suit object - \param q - object browser item + \brief Set data model. + \param model data model + \sa model() */ -bool OB_BrowserSync::isEqual( const ObjPtr& p, const ItemPtr& q ) const +void OB_Browser::setModel( QAbstractItemModel* model ) { - bool isRoot = p==myBrowser->getRootObject() && !q, - isEq = p && q && q->dataObject()==p; - return isRoot || ( !p && !q ) || isEq; + myView->setModel( model ); + myView->update(); + setModified(); } /*! - \return null suit object + \brief Get current item delegate (items renderer). + \return currently used item delegate + \sa setItemDelegate() */ -ObjPtr OB_BrowserSync::nullSrc() const +QAbstractItemDelegate* OB_Browser::itemDelegate() const { - return 0; + return myView->itemDelegate(); } /*! - \return null item + \brief Set item delegate (items renderer). + \param d custom item delegate + \sa itemDelegate() */ -ItemPtr OB_BrowserSync::nullTrg() const +void OB_Browser::setItemDelegate( QAbstractItemDelegate* d ) { - return 0; + myView->setItemDelegate( d ); } /*! - Fills list with children of SUIT object - \param p - SUIT object - \param ch - list to be filled + \brief Check if controls for expanding and collapsing top-level items are shown. + \return \c true if top-level items are decorated + \sa setRootIsDecorated() */ -void OB_BrowserSync::children( const ObjPtr& p, QValueList& ch ) const +bool OB_Browser::rootIsDecorated() const { - DataObjectList l; - if( p ) - { - p->children( l ); - ch.clear(); - for( SUIT_DataObject* o = l.first(); o; o = l.next() ) - ch.append( o ); - } + return myView->rootIsDecorated(); } /*! - Fills list with children of item - \param p - item - \param ch - list to be filled + \brief Show/hide controls for expanding and collapsing top-level items. + \param decor if \c true, top-level items are decorated + \sa rootIsDecorated() */ -void OB_BrowserSync::children( const ItemPtr& p, QValueList& ch ) const +void OB_Browser::setRootIsDecorated( const bool decor ) { - for( QListViewItem* item = p ? p->firstChild() : myBrowser->listView()->firstChild(); item; item = item->nextSibling() ) - { - ItemPtr p = dynamic_cast( item ); - if( p ) - ch.append( p ); - } + if ( decor != rootIsDecorated() ) + myView->setRootIsDecorated( decor ); } -/*! - \return parent of item - \param p - item +/* + \brief Check if "Sorting" popup menu command for the header is enabled. + \return \c true if "Sorting" menu command is enabled + \sa setSortMenuEnabled() */ -ItemPtr OB_BrowserSync::parent( const ItemPtr& p ) const +bool OB_Browser::sortMenuEnabled() const { - return p ? dynamic_cast( p->parent() ) : 0; + return myView->sortMenuEnabled(); } - -/*! - Constructor +/* + \brief Enable/disable "Sorting" popup menu command for the header. + \param enableSortMenu if \c true, enable "Sorting" menu command + \sa sortMenuEnabled() */ -OB_Browser::OB_Browser( QWidget* parent, SUIT_DataObject* root ) -: QFrame( parent ), - -myRoot( 0 ), -myTooltip( 0 ), -myUpdater( 0 ), -myAutoOpenLevel( 0 ), -myAutoUpdate( false ), -myAutoDelObjs( false ), -myRootDecorated( true ) +void OB_Browser::setSortMenuEnabled( const bool enabled ) { - myView = new OB_ListView( QtxListView::HeaderAuto, this ); - myView->setAppropriate( myView->addColumn( "Data" ), false ); - myView->setSorting( -1 ); - myView->setRootIsDecorated( true ); - myView->setSelectionMode( QListView::Extended ); - myView->installEventFilter( this ); - myView->viewport()->installEventFilter( this ); - - myFindDlg = new OB_FindDlg( this ); - myFindDlg->hide(); - - QVBoxLayout* main = new QVBoxLayout( this ); - main->addWidget( myView, 1 ); - main->addWidget( myFindDlg, 0 ); - - myShowToolTips = true; - myTooltip = new ToolTip( this, myView->viewport() ); - - connect( myView, SIGNAL( dropped( QPtrList, QListViewItem*, int ) ), - this, SLOT( onDropped( QPtrList, QListViewItem*, int ) ) ); - connect( myView, SIGNAL( selectionChanged() ), this, SIGNAL( selectionChanged() ) ); - connect( myView, SIGNAL( doubleClicked( QListViewItem* ) ), - this, SLOT( onDoubleClicked( QListViewItem* ) ) ); - - setRootObject( root ); - - setModified(); + if ( enabled != sortMenuEnabled() ) + myView->setSortMenuEnabled( enabled ); } /*! - Destructor + \brief Get search tool widget. + \return search tool widget + \sa isSearchToolEnabled(), setSearchToolEnabled() */ -OB_Browser::~OB_Browser() +QtxSearchTool* OB_Browser::searchTool() const { - myItems.clear(); - delete myTooltip; - setUpdater( 0 ); + return mySearchTool; } /*! - \return true if root is decorated by + + \brief Check if search tool is enabled. + \return \c true if search tool is enabled + \sa setSearchToolEnabled(), searchTool() */ -bool OB_Browser::rootIsDecorated() const +bool OB_Browser::isSearchToolEnabled() const { - return myRootDecorated; + return mySearchTool->isEnabled(); } /*! - Sets state "root is recorated" - \param decor - new value of state + \brief Enable/disable search tool. + \param enable pass \c true to enable search tool + \sa isSearchToolEnabled(), searchTool() */ -void OB_Browser::setRootIsDecorated( const bool decor ) +void OB_Browser::setSearchToolEnabled( const bool enable ) { - if ( decor == rootIsDecorated() ) + if ( mySearchTool->isEnabled() == enable ) return; - myRootDecorated = decor; - updateTree( 0, false ); + mySearchTool->setEnabled( enable ); + if ( !mySearchTool->isEnabled() ) + mySearchTool->hide(); } /*! - \return number of levels to be auto opened on update tree + \brief Get number of levels which should be automatically expanded + when updating the data tree. + \return number of levels to be auto-opened on tree updating + \sa setAutoOpenLevel() */ int OB_Browser::autoOpenLevel() const { @@ -368,306 +314,212 @@ int OB_Browser::autoOpenLevel() const } /*! - Changes number of levels to be auto opened on update tree - \param level - new number of levels + \brief Set number of levels which should be automatically expanded + when updating the data tree. + \param levels number of levels to be auto-opened on tree updating + \sa autoOpenLevel() */ -void OB_Browser::setAutoOpenLevel( const int level ) +void OB_Browser::setAutoOpenLevel( const int levels ) { - if ( myAutoOpenLevel == level ) - return; - - myAutoOpenLevel = level; + if ( myAutoOpenLevel != levels ) + myAutoOpenLevel = levels; } /*! - Opens branches from 1 to \alevels. If parameter value negative then autoOpenLevel() value will be used. + \brief Expand all branches to the specified number of levels. + + If \a levels value is negative, then autoOpenLevel() value is used instead. + + \param levels number of levels to be expanded \sa autoOpenLevel() */ void OB_Browser::openLevels( const int levels ) { - int level = levels < 0 ? autoOpenLevel() : levels; - QListView* lv = listView(); - if ( !lv || level < 1 ) - return; - - QListViewItem* item = lv->firstChild(); - while ( item ) - { - openBranch( item, level ); - item = item->nextSibling(); - } + myView->expandLevels( levels < 0 ? autoOpenLevel() : levels ); } /*! \return state "are tooltips shown" */ +/* bool OB_Browser::isShowToolTips() { return myShowToolTips; } - +*/ /*! Sets new value of state "are tooltips shown" \param theDisplay - new value */ +/* void OB_Browser::setShowToolTips( const bool theDisplay ) { myShowToolTips = theDisplay; } - -/*! - \return true if object browser automatically updates tree after SUIT object removing */ -bool OB_Browser::isAutoUpdate() const -{ - return myAutoUpdate; -} /*! - Sets new value of "auto update": whether object browser automatically updates tree after SUIT object removing -*/ -void OB_Browser::setAutoUpdate( const bool on ) -{ - myAutoUpdate = on; -} - -/*! - \return true if object browser must delete old tree on setRootObject(), replaceTree() - \sa setRootObject(), replaceTree() -*/ -bool OB_Browser::isAutoDeleteObjects() const -{ - return myAutoDelObjs; -} - -/*! - Sets whether object browser must delete old tree on setRootObject(), replaceTree() - \sa setRootObject(), replaceTree() -*/ -void OB_Browser::setAutoDeleteObjects( const bool on ) -{ - myAutoDelObjs = on; -} - -/*! - \return updater of browser + \brief Get number of selected items. + \return number of selected items */ -OB_Updater* OB_Browser::getUpdater() const +int OB_Browser::numberOfSelected() const { - return myUpdater; + // we take selection by rows + return myView->selectionModel() ? myView->selectionModel()->selectedRows().count() : 0; } /*! - \sets new updater of browser + \brief Get all selected items. + \return unsorted list of selected indexes with no duplicates */ -void OB_Browser::setUpdater( OB_Updater* theUpdate ) +QModelIndexList OB_Browser::selectedIndexes() const { - if( myUpdater ) - delete myUpdater; - myUpdater = theUpdate; + // we take selection by rows + return myView->selectionModel() ? myView->selectionModel()->selectedRows() : QModelIndexList(); } /*! - \return root SUIT object of browser + \brief Get selection containing information about selected ranges. + \return QItemSelection instance */ -SUIT_DataObject* OB_Browser::getRootObject() const +const QItemSelection OB_Browser::selection() const { - return myRoot; + static QItemSelection emptySel; + QItemSelection sel = emptySel; + if ( myView->selectionModel() ) + sel = myView->selectionModel()->selection(); + return sel; } /*! - Sets new root SUIT object of browser - \param theRoot - new root object + \brief Select/deselect specified model index. + \param index model index to be selected/deselected + \param on if \c true, the index will be selected, otherwise - deselected + \param keepSelection if \c true (default) the previous selection is kept, + otherwise it is first cleared */ -void OB_Browser::setRootObject( SUIT_DataObject* theRoot ) +void OB_Browser::select( const QModelIndex& index, const bool on, const bool keepSelection ) { - DataObjectKey curKey; - DataObjectMap selObjs, openObjs; - DataObjectKeyMap selKeys, openKeys; - - int selNum = numberOfSelected(); - - SUIT_DataObject* curObj = 0; - if ( theRoot ) - curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey ); - - removeConnections( myRoot ); - if ( myRoot != theRoot && isAutoDeleteObjects() ) - delete myRoot; + if ( myView->selectionModel() ) { + QItemSelectionModel::SelectionFlags f = on ? QItemSelectionModel::Select : QItemSelectionModel::Deselect; + f = f | QItemSelectionModel::Rows; + if ( !keepSelection ) + f = f | QItemSelectionModel::Clear; - myRoot = theRoot; - - createConnections( myRoot ); - - if ( myRoot ) - updateView( myRoot ); - else if ( listView() ) - { - myItems.clear(); - listView()->clear(); + myView->selectionModel()->select( index, f ); } - - restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey ); - - autoOpenBranches(); - - setModified(); - - if ( selNum != numberOfSelected() ) - emit selectionChanged(); } /*! - \return number of selected items -*/ -int OB_Browser::numberOfSelected() const -{ - int count = 0; - if ( listView() ) + \brief Select/deselect specified model indices. + \param indexes model indices to be selected/deselected + \param on if \c true, the indices will be selected, otherwise - deselected + \param keepSelection if \c true (default) the previous selection is kept, + otherwise it is first cleared +*/ +void OB_Browser::select( const QModelIndexList& indexes, const bool on, const bool keepSelection ) +{ + bool blocked = myView->signalsBlocked(); + myView->blockSignals( true ); + + QModelIndex idx; + + if ( !indexes.isEmpty() ) { + QItemSelection mysel; + // select by range if indexes are contiguous + QModelIndex first=indexes.at(0); + QModelIndex last=first; + if (indexes.size() > 1) { + for (int i = 1; i < indexes.size(); ++i) + { + idx=indexes.at(i); + if(idx.parent().internalId()==last.parent().internalId() && idx.row()==last.row()+1 && idx.column()==last.column()) + { + // index is contiguous to last: extend the range + last=idx; + } + else + { + // index idx is not contiguous: create a new range + mysel.select(first,last); + first=idx; + last=idx; + } + } + } + mysel.select(first,last); + + if ( myView->selectionModel() ) { + QItemSelectionModel::SelectionFlags f = on ? QItemSelectionModel::Select : QItemSelectionModel::Deselect; + f = f | QItemSelectionModel::Rows; + if ( !keepSelection ) + f = f | QItemSelectionModel::Clear; + myView->selectionModel()->select( mysel, f ); + } + } + else if ( !keepSelection ) { - for ( QListViewItemIterator it( listView() ); it.current(); ++it ) - if ( it.current()->isSelected() ) - count++; + myView->clearSelection(); } - return count; -} -/*! - \return list of selected objects -*/ -DataObjectList OB_Browser::getSelected() const -{ - DataObjectList lst; - getSelected( lst ); - return lst; + myView->blockSignals( blocked ); + emit( selectionChanged() ); } /*! - Fills list with selected objects + \brief Check if specified model index is expanded or collapsed. + \param index model index + \return \c true if model index is expanded + \sa setOpen() */ -void OB_Browser::getSelected( DataObjectList& theObjList ) const +bool OB_Browser::isOpen( const QModelIndex& index ) const { - theObjList.clear(); - - if ( !listView() ) - return; - - for ( QListViewItemIterator it( listView() ); it.current(); ++it ) - { - if ( it.current()->isSelected() ) - { - SUIT_DataObject* obj = dataObject( it.current() ); - if ( obj ) - theObjList.append( obj ); - } - } + return index.isValid() && model() && model()->hasChildren( index ) && myView->isExpanded( index ); } /*! - Sets selected object - \param theObject - new selected object - \param append - if it is true, then other selected objects are left as selected, - otherwise only 'theObject' will be selected + \brief Expand/collapse the specified model index. + \param index model index + \param open if \c true, the index will be expanded, otherwse - collapsed + \sa isOpen() */ -void OB_Browser::setSelected( const SUIT_DataObject* theObject, const bool append ) +void OB_Browser::setOpen( const QModelIndex& index, const bool open ) { - DataObjectList lst; - lst.append( theObject ); - setSelected( lst, append ); + myView->setExpanded( index, open ); // hasChildren() ??? } /*! - Sets selected objects - \param theObjLst - new selected objects - \param append - if it is true, then other selected objects are left as selected, - otherwise only 'theObjLst' will be selected + \brief Adjust first column width to its contents. */ -void OB_Browser::setSelected( const DataObjectList& theObjLst, const bool append ) +void OB_Browser::adjustWidth() { - QListView* lv = listView(); - - if ( !lv ) - return; - - bool changed = false; - bool block = lv->signalsBlocked(); - lv->blockSignals( true ); - - QMap map; - for ( DataObjectListIterator itr( theObjLst ); itr.current(); ++itr ) - map.insert( listViewItem( itr.current() ), 0 ); - - for ( QListViewItemIterator it( lv ); it.current(); ++it ) - { - QListViewItem* item = it.current(); - if ( map.contains( item ) && !lv->isSelected( item ) ) - { - changed = true; - lv->setSelected( item, true ); - } - if ( !append && !map.contains( item ) && lv->isSelected( item ) ) - { - changed = true; - lv->setSelected( item, false ); - } - } - - lv->blockSignals( block ); - - if ( changed ) - { - int count = 0; - QListViewItem* sel = 0; - QListViewItem* cur = lv->currentItem(); - for ( QListViewItemIterator iter( lv ); iter.current() && !sel; ++iter, count++ ) - { - if ( iter.current()->isSelected() && cur == iter.current() ) - sel = iter.current(); - } - - for ( QListViewItemIterator itr( lv ); itr.current() && !sel; ++itr ) - { - if ( itr.current()->isSelected() ) - sel = itr.current(); - } - - if ( sel ) - lv->setCurrentItem( sel ); - - if ( sel && count == 1 ) - lv->ensureItemVisible( sel ); - - emit selectionChanged(); - } + myView->resizeColumnToEncloseContents( 0 ); } /*! - \return true if item corresponding to object is opened - \param theObject - object to be checked + \brief Adjust first column width to its contents. */ -bool OB_Browser::isOpen( SUIT_DataObject* theObject ) const +void OB_Browser::adjustFirstColumnWidth() { - bool res = false; - if ( listView() ) - res = listView()->isOpen( listViewItem( theObject ) ); - return res; + myView->resizeColumnToEncloseContents( 0 ); } /*! - Sets opened state of item - \param theObject - object corresponding to item - \param theOpen - new opened state + \brief Adjust all columns width to its contents except the first column. */ -void OB_Browser::setOpen( SUIT_DataObject* theObject, const bool theOpen ) +void OB_Browser::adjustColumnsWidth() { - if ( listView() ) - listView()->setOpen( listViewItem( theObject ), theOpen ); + for ( int aCol = 1; aCol < myView->header()->count(); aCol++ ) { + if ( myView->columnWidth( aCol ) > 0 ) + myView->resizeColumnToEncloseContents( aCol ); + } } /*! \return SUIT object correspondint to item at position 'pos' \param pos - position */ +/* TODO: removed - QTreeView::indexAt() should be used SUIT_DataObject* OB_Browser::dataObjectAt( const QPoint& pos ) const { SUIT_DataObject* obj = 0; @@ -678,247 +530,45 @@ SUIT_DataObject* OB_Browser::dataObjectAt( const QPoint& pos ) const return obj; } - +*/ /*! \return filter of list view */ +/* TODO: removed OB_Filter* OB_Browser::filter() const { return myView->filter(); } - +*/ /*! Changes filter of list view \param f - new filter */ +/* TODO: removed void OB_Browser::setFilter( OB_Filter* f ) { myView->setFilter( f ); } - -/*! - Adds new column to list view - \param label - title of column - \param id - id of column - \param width - width of column */ -int OB_Browser::addColumn( const QString& label, const int id, const int width ) -{ - return addColumn( QIconSet(), label, id, width ); -} - -/*! - Adds new column to list view - \param icon - icon of column - \param label - title of column - \param id - id of column - \param width - width of column -*/ -int OB_Browser::addColumn( const QIconSet& icon, const QString& label, const int id, const int width ) -{ - QListView* lv = listView(); - if ( !lv ) - return -1; - - int theId = id; - if ( theId < 0 ) - { - while ( myColumnIds.contains( theId ) ) - theId++; - } - - if ( myColumnIds.contains( theId ) ) - return -1; // can not reuse id - - int sec = -1; - if ( icon.isNull() ) - sec = lv->addColumn( label, width ); - else - sec = lv->addColumn( icon, label, width ); - - if ( sec == -1 ) - return -1; - - myColumnIds.insert( theId, sec ); - updateText(); - - return theId; -} - -/*! - Removes column - \param id - id of column -*/ -void OB_Browser::removeColumn( const int id ) -{ - QListView* lv = listView(); - if ( !lv || !myColumnIds.contains( id ) ) - return; - - int sec = myColumnIds[id]; - lv->removeColumn( sec ); - - // update map of column indeces - myColumnIds.remove( id ); - for ( QMap::iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it ) - { - if ( it.key() > id ) - it.data()--; - } - updateText(); -} - -/*! - Sets title of first column (name column) - \param label - new title -*/ -void OB_Browser::setNameTitle( const QString& label ) -{ - setNameTitle( QIconSet(), label ); -} - -/*! - Sets title and icon of first column (name column) - \param icon - new icon - \param label - new title -*/ -void OB_Browser::setNameTitle( const QIconSet& icon, const QString& label ) -{ - QListView* lv = listView(); - if ( !lv ) - return; - - if ( icon.isNull() ) - lv->setColumnText( 0, label ); - else - lv->setColumnText( 0, icon, label ); -} - -/*! - Sets title of column - \param id - column id - \param label - new column title -*/ -void OB_Browser::setColumnTitle( const int id, const QString& label ) -{ - setColumnTitle( id, QIconSet(), label ); -} - -/*! - Sets title and icon of column - \param id - column id - \param icon - new column icon - \param label - new column title -*/ -void OB_Browser::setColumnTitle( const int id, const QIconSet& icon, const QString& label ) -{ - QListView* lv = listView(); - if ( !lv || !myColumnIds.contains( id ) ) - return; - - if ( icon.isNull() ) - lv->setColumnText( myColumnIds[id], label ); - else - lv->setColumnText( myColumnIds[id], icon, label ); -} - -/*! - \return title of first column (name column) -*/ -QString OB_Browser::nameTitle() const -{ - return myView->columnText( 0 ); -} - -/*! - \return title of first column (name column) - \param id - column id -*/ -QString OB_Browser::columnTitle( const int id ) const -{ - QString txt; - if ( myColumnIds.contains( id ) ) - txt = myView->columnText( myColumnIds[id] ); - return txt; -} - -/*! - \return true if column is visible - \param id - column id -*/ -bool OB_Browser::isColumnVisible( const int id ) const -{ - return myColumnIds.contains( id ) && myView->isShown( myColumnIds[id] ); -} - -/*! - Sets visibility of column - \param id - column id - \param on - new visibility state -*/ -void OB_Browser::setColumnShown( const int id, const bool on ) -{ - if ( !myColumnIds.contains( id ) ) - return; - - myView->setShown( myColumnIds[id], on ); - if( !on ) - myView->setColumnWidthMode( myColumnIds[id], QListView::Manual ); -} - /*! Sets global width mode \param mode - new width mode */ +/* TODO: removed void OB_Browser::setWidthMode( QListView::WidthMode mode ) { for ( int i = 0, n = myView->columns(); i < n; i++ ) if( mode!=QListView::Maximum || myView->columnWidth( i )>0 ) myView->setColumnWidthMode( i, mode ); } - -/*! - \return list of columns ids -*/ -QValueList OB_Browser::columns() const -{ - QValueList lst; - for ( QMap::ConstIterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it ) - lst.append( it.key() ); - return lst; -} - -/*! - \return true if it is possible to show/hide column by popup - \param id - column id */ -bool OB_Browser::appropriateColumn( const int id ) const -{ - bool res = false; - if ( myColumnIds.contains( id ) ) - res = myView->appropriate( myColumnIds[id] ); - return res; -} - -/*! - Sets "appropriate state": is it possible to show/hide column by popup - \param id - column id - \param on - new state -*/ -void OB_Browser::setAppropriateColumn( const int id, const bool on ) -{ - if ( !myColumnIds.contains( id ) ) - return; - - myView->setAppropriate( myColumnIds[id], on ); -} - /*! Updates tree \param obj - start object \param autoOpen - to open automatically branches of autoOpenLevel() \sa autoOpenLevel() */ +/* TODO: removed void OB_Browser::updateTree( SUIT_DataObject* obj, const bool autoOpen ) { // QTime t1 = QTime::currentTime(); @@ -949,10 +599,11 @@ void OB_Browser::updateTree( SUIT_DataObject* obj, const bool autoOpen ) // QTime t2 = QTime::currentTime(); // qDebug( QString( "update tree time = %1 msecs" ).arg( t1.msecsTo( t2 ) ) ); } - +*/ /*! Replaces part of tree starting at object 'src' by tree starting at object 'trg' */ +/* TODO: removed void OB_Browser::replaceTree( SUIT_DataObject* src, SUIT_DataObject* trg ) { if ( !src || !trg || src == trg || src->root() != getRootObject() ) @@ -990,146 +641,12 @@ void OB_Browser::replaceTree( SUIT_DataObject* src, SUIT_DataObject* trg ) if ( selNum != numberOfSelected() ) emit selectionChanged(); } - -/*! - Updates view - \param startObj - start object -*/ -void OB_Browser::updateView( SUIT_DataObject* startObj ) -{ - QListView* lv = listView(); - if ( !lv ) - return; - - if ( !startObj || startObj->root() != getRootObject() ) - return; - - //qDebug( "updateView:" ); - //startObj->dump(); - - if ( startObj == myRoot ) - { - OB_BrowserSync sync( this ); - synchronize( myRoot, 0, sync ); - } - else - { - OB_BrowserSync sync( this ); - OB_ListItem* startItem = dynamic_cast( listViewItem( startObj ) ); - synchronize( startObj, startItem, sync ); - } -} - -/*! - Creates new list item - \return new item - \param o - corresponding SUIT object - \param parent - parent item - \param after - item after that new item must be added - \param prepend - new item must be added as first */ -QListViewItem* OB_Browser::createItem( const SUIT_DataObject* o, QListViewItem* parent, - QListViewItem* after, const bool prepend ) -{ - QListView* lv = listView(); - - if ( !lv || !o ) - return 0; - - QListViewItem* item = 0; - SUIT_DataObject* obj = (SUIT_DataObject*)o; - - int type = -1; - - switch ( obj->checkType() ) - { - case SUIT_DataObject::CheckBox: - type = QCheckListItem::CheckBox; - break; - case SUIT_DataObject::RadioButton: - type = QCheckListItem::RadioButton; - break; - } - - if ( parent ) - { - if ( after ) - { - if ( type == -1 ) - item = new OB_ListItem( obj, parent, after ); - else - item = new OB_CheckListItem( obj, parent, after, (QCheckListItem::Type)type ); - } - else if ( prepend ) - { - if ( type == -1 ) - item = new OB_ListItem( obj, parent ); - else - item = new OB_CheckListItem( obj, parent, (QCheckListItem::Type)type ); - } - else // append - { - after = parent->firstChild(); - while ( after && after->nextSibling() ) - after = after->nextSibling(); - if ( type == -1 ) - item = new OB_ListItem( obj, parent, after ); - else - item = new OB_CheckListItem( obj, parent, after, (QCheckListItem::Type)type ); - } - } - else - { - if ( after ) - { - if ( type == -1 ) - item = new OB_ListItem( obj, lv, after ); - else - item = new OB_CheckListItem( obj, lv, after, (QCheckListItem::Type)type ); - } - else if ( prepend ) - { - if ( type == -1 ) - item = new OB_ListItem( obj, lv ); - else - item = new OB_CheckListItem( obj, lv, (QCheckListItem::Type)type ); - } - else // append - { - after = lv->firstChild(); - while ( after && after->nextSibling() ) - after = after->nextSibling(); - if ( type == -1 ) - item = new OB_ListItem( obj, lv, after ); - else - item = new OB_CheckListItem( obj, lv, after, (QCheckListItem::Type)type ); - } - } - - myItems.insert( obj, item ); - obj->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) ); - updateText( item ); - - return item; -} - -/*! - Adjusts width by root item -*/ -void OB_Browser::adjustWidth() -{ - if ( !listView() ) - return; - - listView()->setColumnWidth( 0, 0 ); - if ( listView()->firstChild() ) - adjustWidth( listView()->firstChild() ); -} - /*! Adjusts width by item \param item */ +/* void OB_Browser::adjustWidth( QListViewItem* item ) { while ( item ) @@ -1140,48 +657,12 @@ void OB_Browser::adjustWidth( QListViewItem* item ) item = item->nextSibling(); } } - -/*! - \return SUIT object corresponding to item - \param item -*/ -SUIT_DataObject* OB_Browser::dataObject( const QListViewItem* item ) const -{ - SUIT_DataObject* obj = 0; - - if ( item && item->rtti() == OB_ListItem::RTTI() ) - obj = ((OB_ListItem*)item)->dataObject(); - else if ( item && item->rtti() == OB_CheckListItem::RTTI() ) - obj = ((OB_CheckListItem*)item)->dataObject(); - - return obj; -} - -/*! - \return item corresponding to SUIT object - \param obj - SUIT object */ -QListViewItem* OB_Browser::listViewItem( const SUIT_DataObject* obj ) const -{ - QListViewItem* item = 0; - - if ( myItems.contains( (SUIT_DataObject*)obj ) ) - item = myItems[(SUIT_DataObject*)obj]; - - return item; -} - -/*! - \return list view of object browser -*/ -QListView* OB_Browser::listView() const -{ - return myView; -} /*! \remove all items referencing current (through data objects) */ +/* TODO: void OB_Browser::removeReferences( QListViewItem* item ) { if ( !item ) @@ -1198,10 +679,11 @@ void OB_Browser::removeReferences( QListViewItem* item ) i = i->nextSibling(); } } - +*/ /*! Connects all children to SLOT onDestroyed */ +/* TODO: move to SUIT_TreeModel void OB_Browser::createConnections( SUIT_DataObject* obj ) { if ( !obj ) @@ -1215,10 +697,11 @@ void OB_Browser::createConnections( SUIT_DataObject* obj ) for ( DataObjectListIterator it( childList ); it.current(); ++it ) it.current()->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) ); } - +*/ /*! Disconnects all children from SLOT onDestroyed */ +/* TODO: move to SUIT_TreeModel void OB_Browser::removeConnections( SUIT_DataObject* obj ) { if ( !obj ) @@ -1232,7 +715,7 @@ void OB_Browser::removeConnections( SUIT_DataObject* obj ) for ( DataObjectListIterator it( childList ); it.current(); ++it ) it.current()->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) ); } - +*/ /*! Stores states (opened, selected) of current tree items \return current item @@ -1240,6 +723,7 @@ void OB_Browser::removeConnections( SUIT_DataObject* obj ) \param openObjs, openKeys - maps of opened objects \param curKey - map of current objects */ +/* TODO: to be revised SUIT_DataObject* OB_Browser::storeState( DataObjectMap& selObjs, DataObjectMap& openObjs, DataObjectKeyMap& selKeys, DataObjectKeyMap& openKeys, DataObjectKey& curKey ) const @@ -1268,13 +752,14 @@ SUIT_DataObject* OB_Browser::storeState( DataObjectMap& selObjs, DataObjectMap& return curObj; } - +*/ /*! Restores states (opened, selected) of current tree items \param selObjs, selKeys - maps of selected objects \param openObjs, openKeys - maps of opened objects \param curKey - map of current objects */ +/* TODO: to be revised void OB_Browser::restoreState( const DataObjectMap& selObjs, const DataObjectMap& openObjs, const SUIT_DataObject* curObj, const DataObjectKeyMap& selKeys, const DataObjectKeyMap& openKeys, const DataObjectKey& curKey ) @@ -1309,8 +794,8 @@ void OB_Browser::restoreState( const DataObjectMap& selObjs, const DataObjectMap { bool parentOpen = true; if( item && item->parent() ) - parentOpen = item->parent()->isOpen(); - + parentOpen = item->parent()->isOpen(); + if ( openObjs[obj] && parentOpen ) lv->setOpen( item, true ); } @@ -1318,10 +803,10 @@ void OB_Browser::restoreState( const DataObjectMap& selObjs, const DataObjectMap { bool parentOpen = true; if( item && item->parent() ) - parentOpen = item->parent()->isOpen(); + parentOpen = item->parent()->isOpen(); if( parentOpen ) - lv->setOpen( item, true ); + lv->setOpen( item, true ); } if ( !curItem && ( curObj == obj || ( !curKey.isNull() && curKey == key )) ) @@ -1333,18 +818,20 @@ void OB_Browser::restoreState( const DataObjectMap& selObjs, const DataObjectMap lv->blockSignals( block ); } - +*/ /*! Creates object key by tree item */ +/* TODO: move to SUIT_TreeModel OB_Browser::DataObjectKey OB_Browser::objectKey( QListViewItem* i ) const { return objectKey( dataObject( i ) ); } - +*/ /*! Creates object key by SUIT object */ +/* TODO: move to SUIT_TreeModel OB_Browser::DataObjectKey OB_Browser::objectKey( SUIT_DataObject* obj ) const { if ( !obj ) @@ -1352,51 +839,104 @@ OB_Browser::DataObjectKey OB_Browser::objectKey( SUIT_DataObject* obj ) const return DataObjectKey( obj->key() ); } +*/ /*! - Custom key press event handler, updates tree by F5 + \brief Get tree view widget. + \return tree view widget of the object browser */ -void OB_Browser::keyPressEvent( QKeyEvent* e ) +QtxTreeView* OB_Browser::treeView() const { - if ( e->key() == Qt::Key_F5 ) - updateTree( 0, false ); + return myView; +} - QFrame::keyPressEvent( e ); +/*! + \brief Process context menu request event. + \param e context menu event +*/ +void OB_Browser::contextMenuEvent( QContextMenuEvent* e ) +{ + QMenu* popup = new QMenu(); + + createPopupMenu( popup ); + + Qtx::simplifySeparators( popup ); + + if ( !popup->actions().isEmpty() ) + popup->exec( e->globalPos() ); + delete popup; +} + +/*! + \brief Get the time of the latest updating. + \return latest updating time +*/ +unsigned long OB_Browser::getModifiedTime() const +{ + return myModifiedTime; +} + +/*! + \brief Update the time of the latest updating. +*/ +void OB_Browser::setModified() +{ + myModifiedTime = clock(); } /*! - SLOT: called if action "Expand all" is activated + \brief Called when "Expand all" popup menu command is activated. + + Expands all selected items recursively. */ -void OB_Browser::onExpand() +void OB_Browser::onExpandAll() { - DataObjectList selected; - getSelected( selected ); - for ( DataObjectListIterator itr( selected ); itr.current(); ++itr ) - expand( listViewItem( itr.current() ) ); + QModelIndexList indexes = selectedIndexes(); + QModelIndex index; + disconnect( treeView(), SIGNAL( expanded( const QModelIndex& ) ), + this, SLOT( onExpanded( const QModelIndex& ) ) ); + + foreach ( index, indexes ) { + myView->expandAll( index ); + } + connect( treeView(), SIGNAL( expanded( const QModelIndex& ) ), + this, SLOT( onExpanded( const QModelIndex& ) ) ); + emit(onExpanded( index)); } /*! - SLOT: called if action "Show/hide column" is activated by popup + \brief Called when "Collapse all" popup menu command is activated. + + Collapse all selected items recursively. */ -void OB_Browser::onColumnVisible( int id ) +void OB_Browser::onCollapseAll() { - setColumnShown( id, !isColumnVisible( id ) ); + QModelIndexList indexes = selectedIndexes(); + QModelIndex index; + + foreach ( index, indexes ) { + myView->collapseAll( index ); + } } /*! SLOT: called if SUIT object is destroyed */ +/* TODO: moved to SUIT_TreeModel void OB_Browser::onDestroyed( SUIT_DataObject* obj ) { removeObject( obj ); } - +*/ /*! SLOT: called on finish of drag-n-drop operation \param items - dragged items \param item - destination (item on that they were dropped) \param action - QDropEvent::Action */ + // TODO: drag-n-drop works differently - SUIT_TreeModel to be updated + // and QTreeView needs some setup +/* void OB_Browser::onDropped( QPtrList items, QListViewItem* item, int action ) { SUIT_DataObject* obj = dataObject( item ); @@ -1414,10 +954,11 @@ void OB_Browser::onDropped( QPtrList items, QListViewItem* item, if ( !lst.isEmpty() ) emit dropped( lst, obj, action ); } - +*/ /*! Updates texts of items */ +/* TODO: to be removed void OB_Browser::updateText() { if ( myColumnIds.isEmpty() ) @@ -1437,11 +978,12 @@ void OB_Browser::updateText() it.current()->setText( itr.data(), obj->text( itr.key() ) ); } } - +*/ /*! \return true if item must be updated \param item - item to be checked */ +/* TODO: to be revised bool OB_Browser::needToUpdateTexts( QListViewItem* item ) const { SUIT_DataObject* obj = dataObject( item ); @@ -1453,11 +995,12 @@ bool OB_Browser::needToUpdateTexts( QListViewItem* item ) const return true; return false; } - +*/ /*! Updates texts of item \param item - item to be updated */ +/* TODO: to be revised void OB_Browser::updateText( QListViewItem* item ) { SUIT_DataObject* obj = dataObject( item ); @@ -1467,78 +1010,46 @@ void OB_Browser::updateText( QListViewItem* item ) for( QMap::iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it ) item->setText( it.data(), obj->text( it.key() ) ); } - -/*! - Custom event filter */ -bool OB_Browser::eventFilter( QObject* o, QEvent* e ) -{ - if ( o == myView && e->type() == QEvent::ContextMenu ) - { - QContextMenuEvent* ce = (QContextMenuEvent*)e; - if ( ce->reason() != QContextMenuEvent::Mouse ) - contextMenuRequest( ce ); - return true; - } - if ( o == myView->viewport() && e->type() == QEvent::MouseButtonRelease ) - { - QMouseEvent* me = (QMouseEvent*)e; - if ( me->button() == RightButton ) - { - QContextMenuEvent ce( QContextMenuEvent::Mouse, me->pos(), me->globalPos(), me->state() ); - contextMenuRequest( &ce ); - return true; - } - } - - return QFrame::eventFilter( o, e ); -} /*! - Adds custom actions to popup - \param menu - popup menu + \brief Add custom actions to the popup menu. + \param menu popup menu */ -void OB_Browser::contextMenuPopup( QPopupMenu* menu ) +void OB_Browser::createPopupMenu( QMenu* menu ) { -/* QValueList cols; - for ( QMap::ConstIterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it ) - { - if ( appropriateColumn( it.key() ) ) - cols.append( it.key() ); - } + menu->addSeparator(); - uint num = menu->count(); - menu->setCheckable( true ); - for ( QValueList::const_iterator iter = cols.begin(); iter != cols.end(); ++iter ) - { - QString name = columnTitle( *iter ); - if ( name.isEmpty() ) - continue; + QModelIndexList indexes = selectedIndexes(); - int id = menu->insertItem( name, this, SLOT( onColumnVisible( int ) ) ); - menu->setItemChecked( id, isColumnVisible( *iter ) ); - menu->setItemParameter( id, *iter ); + bool closed = false, opened = false; + + for ( QModelIndexList::Iterator it = indexes.begin(); + it != indexes.end() && !closed; ++it ) { + closed = hasCollased( *it ); } - if ( menu->count() != num ) - menu->insertSeparator();*/ - DataObjectList selected; - getSelected( selected ); - - bool closed = false; - for ( DataObjectListIterator itr( selected ); itr.current() && !closed; ++itr ) - closed = hasClosed( listViewItem( itr.current() ) ); + for ( QModelIndexList::Iterator it = indexes.begin(); + it != indexes.end() && !opened; ++it ) { + opened = hasExpanded( *it ); + } if ( closed ) - { - menu->insertItem( tr( "MEN_EXPAND_ALL" ), this, SLOT( onExpand() ) ); - menu->insertSeparator(); + menu->addAction( tr( "MEN_EXPAND_ALL" ), this, SLOT( onExpandAll() ) ); + if ( opened ) + menu->addAction( tr( "MEN_COLLAPSE_ALL" ), this, SLOT( onCollapseAll() ) ); + + if ( isSearchToolEnabled() ) { + menu->addSeparator(); + menu->addAction( tr( "MEN_FIND" ), searchTool(), SLOT( find() ), QKeySequence(Qt::CTRL + Qt::Key_F) ); + menu->addSeparator(); } } /*! Expands item with all it's children */ +/* TODO: to be revised void OB_Browser::expand( QListViewItem* item ) { if ( !item ) @@ -1548,23 +1059,49 @@ void OB_Browser::expand( QListViewItem* item ) for ( QListViewItem* child = item->firstChild(); child; child = child->nextSibling() ) expand( child ); } - +*/ /*! - \return true if item or one of it's children isn't opened + \brief Check if model index is collapsed or has collapsed children. + \return \c true if item or one of its children is collapsed */ -bool OB_Browser::hasClosed( QListViewItem* item ) const +bool OB_Browser::hasCollased( const QModelIndex& index ) const { - if ( !item ) - return false; + bool result = false; - if ( item->childCount() && !item->isOpen() ) - return true; + if ( index.isValid() && model() ) { + bool hasChildren = model()->hasChildren( index ); + result = hasChildren && !myView->isExpanded( index ); + if ( !result && hasChildren ) { + int rows = model()->rowCount( index ); + for ( int i = 0; i < rows && !result; i ++ ) { + QModelIndex child = model()->index( i, 0, index ); + result = hasCollased( child ); + } + } + } + return result; +} - bool has = false; - for ( QListViewItem* child = item->firstChild(); child && !has; child = child->nextSibling() ) - has = hasClosed( child ); +/*! + \brief Check if model index is expanded or has expanded children. + \return \c true if item or one of its children is expanded +*/ +bool OB_Browser::hasExpanded( const QModelIndex& index ) const +{ + bool result = false; - return has; + if ( index.isValid() && model() ) { + bool hasChildren = model()->hasChildren( index ); + result = hasChildren && myView->isExpanded( index ); + if ( !result && hasChildren ) { + int rows = model()->rowCount( index ); + for ( int i = 0; i < rows && !result; i ++ ) { + QModelIndex child = model()->index( i, 0, index ); + result = hasExpanded( child ); + } + } + } + return result; } /*! @@ -1572,6 +1109,7 @@ bool OB_Browser::hasClosed( QListViewItem* item ) const \param obj - SUIT object to be removed \param autoUpd - auto tree updating */ +/* TODO: moved to SUIT_TreeModel void OB_Browser::removeObject( SUIT_DataObject* obj, const bool autoUpd ) { if ( !obj ) @@ -1611,21 +1149,23 @@ void OB_Browser::removeObject( SUIT_DataObject* obj, const bool autoUpd ) delete item; } - +*/ /*! Opens branches from 1 to autoOpenLevel() \sa autoOpenLevel() */ +/* TODO: to be revised void OB_Browser::autoOpenBranches() { openLevels(); } - +*/ /*! Opens branch \param item \param level */ +/* TODO: to be revised void OB_Browser::openBranch( QListViewItem* item, const int level ) { if ( level < 1 ) @@ -1638,35 +1178,79 @@ void OB_Browser::openBranch( QListViewItem* item, const int level ) item = item->nextSibling(); } } - +*/ /*! SLOT: called on double click on item, emits signal */ +/* TODO: to be revised void OB_Browser::onDoubleClicked( QListViewItem* item ) { if ( item ) emit doubleClicked( dataObject( item ) ); } +*/ /*! - Stores time of last modification + \fn void OB_Browser::selectionChanged(); + \brief Emitted when selection is changed in the Object Browser. */ -void OB_Browser::setModified() -{ - myModifiedTime = clock(); -} -OB_ObjSearch* OB_Browser::getSearch() const +QByteArray OB_Browser::getOpenStates( int theColumn ) const { - return myFindDlg->getSearch(); + QByteArray aData; + QDataStream aStream( &aData, QIODevice::WriteOnly ); + MapOfOpenStates aMap; + const_cast( this )->openStates( true, aMap, QModelIndex(), theColumn ); + MapOfOpenStates::const_iterator anIt = aMap.begin(), aLast = aMap.end(); + for( ; anIt!=aLast; anIt++ ) + { + QString anEntry = anIt.key(); + qint32 anOpenAttr = anIt.value() ? 1 : 0; + aStream << anEntry << anOpenAttr; + } + return aData; } -void OB_Browser::setSearch( OB_ObjSearch* s ) +void OB_Browser::setOpenStates( const QByteArray& theData, int theColumn ) { - myFindDlg->setSearch( s ); + QByteArray* aData = const_cast( &theData ); + QDataStream aStream( aData, QIODevice::ReadOnly ); + MapOfOpenStates aMap; + while( !aStream.atEnd() ) + { + QString anEntry; + qint32 anOpenAttr; + aStream >> anEntry >> anOpenAttr; + bool isOpen = anOpenAttr!=0; + aMap[anEntry] = isOpen; + } + openStates( false, aMap, QModelIndex(), theColumn ); } -void OB_Browser::enableSearch( const bool on ) +void OB_Browser::openStates( bool isGet, MapOfOpenStates& theMap, const QModelIndex& theIndex, int theColumn ) { - myFindDlg->setShown( on ); + if( theIndex.isValid() ) + { + QString anEntry = theIndex.sibling( theIndex.row(), theColumn ).data().toString(); + bool isOpen; + if( isGet ) + { + isOpen = treeView()->isExpanded( theIndex ); + theMap[anEntry] = isOpen; + } + else + { + isOpen = theMap.contains( anEntry ) ? theMap[anEntry] : false; + treeView()->setExpanded( theIndex, isOpen ); + } + } + + const QAbstractItemModel* aModel = model(); + + int n = aModel->rowCount( theIndex ); + for( int i=0; iindex( i, 0, theIndex ); + openStates( isGet, theMap, aChild, theColumn ); + } }