+// Copyright (C) 2007-2022 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, 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
+// 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_Filter.h"
+//#include "OB_ListItem.h"
+//#include "OB_ListView.h"
+
+#include <QtxTreeView.h>
+#include <QtxSearchTool.h>
+//#include <SUIT_DataObjectIterator.h>
+
+#include <QAction>
+#include <QMenu>
+#include <QItemSelection>
+#include <QKeyEvent>
+#include <QVBoxLayout>
+#include <QAbstractItemModel>
+#include <QAbstractItemDelegate>
+#include <QHeaderView>
+
+#include <time.h>
-#include <qcursor.h>
-#include <qlayout.h>
-#include <qtooltip.h>
-#include <qpainter.h>
-#include <qwmatrix.h>
-#include <qlistview.h>
-#include <qpopupmenu.h>
/*!
- Class: OB_Browser::ToolTip
- Descr: Tool tip for OB_Browser.
+ \class OB_Browser::ToolTip
+ Tool tip for OB_Browser.
*/
+//TODO: ToolTip commented - to be removed or revised
+/*
class OB_Browser::ToolTip : public QToolTip
{
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();
tip( aRect, aText );
}
+*/
+
/*!
- Class: OB_Browser
- Descr: Hierarchical tree object browser.
-*/
+ \class OB_Browser
+ \brief Object browser widget which can be used to handle tree-like data model.
-OB_Browser::OB_Browser( QWidget* parent, SUIT_DataObject* root )
-: QFrame( parent ),
+ 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.
-myRoot( 0 ),
-myTooltip( 0 ),
-myAutoOpenLevel( 0 ),
-myAutoUpdate( false ),
-myAutoDelObjs( false ),
-myRootDecorated( true )
-{
- 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 );
+ Object browser can be used with conjuction of any custom item model inherited
+ from QAbstractItemModel class (see Qt 4 reference manual).
+ The class provides a functionality get/modify selection, drag-n-drop of the
+ objects, etc.
+*/
+
+/*!
+ \brief Constructor
+ \param parent paren widget
+ \param model data model
+*/
+OB_Browser::OB_Browser( QWidget* parent, QAbstractItemModel* model )
+: QWidget( parent ),
+ myAutoOpenLevel( 0 )
+{
+ // 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 );
- myShowToolTips = true;
- myTooltip = new ToolTip( this, myView->viewport() );
+ // TODO: decide what to do with tooltip
+ //myShowToolTips = true;
+ //myTooltip = new ToolTip( this, myView->viewport() );
- connect( myView, SIGNAL( dropped( QPtrList<QListViewItem>, QListViewItem*, int ) ),
- this, SLOT( onDropped( QPtrList<QListViewItem>, QListViewItem*, int ) ) );
- connect( myView, SIGNAL( selectionChanged() ), this, SIGNAL( selectionChanged() ) );
- connect( myView, SIGNAL( doubleClicked( QListViewItem* ) ),
- this, SLOT( onDoubleClicked( QListViewItem* ) ) );
+ // TODO: drag-n-drop works differently - SUIT_TreeModel to be updated
+ // and QTreeView needs some setup
+ //connect( myView, SIGNAL( dropped( QPtrList<QListViewItem>, QListViewItem*, int ) ),
+ // this, SLOT( onDropped( QPtrList<QListViewItem>, QListViewItem*, int ) ) );
+ setModel( model );
- setRootObject( root );
+ connect( myView, SIGNAL( selectionChanged() ),
+ this, SIGNAL( selectionChanged() ) );
}
+/*!
+ \brief Destructor.
+*/
OB_Browser::~OB_Browser()
{
- myItems.clear();
- delete myTooltip;
-}
-
-bool OB_Browser::rootIsDecorated() const
-{
- return myRootDecorated;
+ //delete myTooltip;
+ //setUpdater( 0 );
}
-void OB_Browser::setRootIsDecorated( const bool decor )
-{
- if ( decor == rootIsDecorated() )
- return;
-
- myRootDecorated = decor;
- updateTree();
-}
-
-int OB_Browser::autoOpenLevel() const
-{
- return myAutoOpenLevel;
-}
-
-void OB_Browser::setAutoOpenLevel( const int level )
+/*!
+ \brief Get data model.
+ \return data model
+ \sa setModel()
+*/
+QAbstractItemModel* OB_Browser::model() const
{
- if ( myAutoOpenLevel == level )
- return;
-
- myAutoOpenLevel = level;
-
- autoOpenBranches();
+ return myView->model();
}
-bool OB_Browser::isShowToolTips()
+/*!
+ \brief Set data model.
+ \param model data model
+ \sa model()
+*/
+void OB_Browser::setModel( QAbstractItemModel* model )
{
- return myShowToolTips;
+ myView->setModel( model );
+ myView->update();
+ setModified();
}
-void OB_Browser::setShowToolTips( const bool theDisplay )
+/*!
+ \brief Get current item delegate (items renderer).
+ \return currently used item delegate
+ \sa setItemDelegate()
+*/
+QAbstractItemDelegate* OB_Browser::itemDelegate() const
{
- myShowToolTips = theDisplay;
+ return myView->itemDelegate();
}
-bool OB_Browser::isAutoUpdate() const
+/*!
+ \brief Set item delegate (items renderer).
+ \param d custom item delegate
+ \sa itemDelegate()
+*/
+void OB_Browser::setItemDelegate( QAbstractItemDelegate* d )
{
- return myAutoUpdate;
+ myView->setItemDelegate( d );
}
-void OB_Browser::setAutoUpdate( const bool on )
+/*!
+ \brief Check if controls for expanding and collapsing top-level items are shown.
+ \return \c true if top-level items are decorated
+ \sa setRootIsDecorated()
+*/
+bool OB_Browser::rootIsDecorated() const
{
- myAutoUpdate = on;
+ return myView->rootIsDecorated();
}
-bool OB_Browser::isAutoDeleteObjects() const
+/*!
+ \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_Browser::setRootIsDecorated( const bool decor )
{
- return myAutoDelObjs;
+ if ( decor != rootIsDecorated() )
+ myView->setRootIsDecorated( decor );
}
-void OB_Browser::setAutoDeleteObjects( const bool on )
+/*
+ \brief Check if "Sorting" popup menu command for the header is enabled.
+ \return \c true if "Sorting" menu command is enabled
+ \sa setSortMenuEnabled()
+*/
+bool OB_Browser::sortMenuEnabled() const
{
- myAutoDelObjs = on;
+ return myView->sortMenuEnabled();
}
-SUIT_DataObject* OB_Browser::getRootObject() const
+/*
+ \brief Enable/disable "Sorting" popup menu command for the header.
+ \param enableSortMenu if \c true, enable "Sorting" menu command
+ \sa sortMenuEnabled()
+*/
+void OB_Browser::setSortMenuEnabled( const bool enabled )
{
- return myRoot;
+ if ( enabled != sortMenuEnabled() )
+ myView->setSortMenuEnabled( enabled );
}
-void OB_Browser::setRootObject( SUIT_DataObject* theRoot )
-{
- 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;
-
- myRoot = theRoot;
-
- createConnections( myRoot );
-
- if ( myRoot )
- updateView( myRoot );
- else if ( listView() )
- {
- myItems.clear();
- listView()->clear();
- }
-
- restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
-
- autoOpenBranches();
-
- if ( selNum != numberOfSelected() )
- emit selectionChanged();
-}
-
-int OB_Browser::numberOfSelected() const
+/*!
+ \brief Get search tool widget.
+ \return search tool widget
+ \sa isSearchToolEnabled(), setSearchToolEnabled()
+*/
+QtxSearchTool* OB_Browser::searchTool() const
{
- int count = 0;
- if ( listView() )
- {
- for ( QListViewItemIterator it( listView() ); it.current(); ++it )
- if ( it.current()->isSelected() )
- count++;
- }
- return count;
+ return mySearchTool;
}
-DataObjectList OB_Browser::getSelected() const
+/*!
+ \brief Check if search tool is enabled.
+ \return \c true if search tool is enabled
+ \sa setSearchToolEnabled(), searchTool()
+*/
+bool OB_Browser::isSearchToolEnabled() const
{
- DataObjectList lst;
- getSelected( lst );
- return lst;
+ return mySearchTool->isEnabled();
}
-void OB_Browser::getSelected( DataObjectList& theObjList ) const
+/*!
+ \brief Enable/disable search tool.
+ \param enable pass \c true to enable search tool
+ \sa isSearchToolEnabled(), searchTool()
+*/
+void OB_Browser::setSearchToolEnabled( const bool enable )
{
- theObjList.clear();
-
- if ( !listView() )
+ if ( mySearchTool->isEnabled() == enable )
return;
- for ( QListViewItemIterator it( listView() ); it.current(); ++it )
- {
- if ( it.current()->isSelected() )
- {
- SUIT_DataObject* obj = dataObject( it.current() );
- if ( obj )
- theObjList.append( obj );
- }
- }
+ mySearchTool->setEnabled( enable );
+ if ( !mySearchTool->isEnabled() )
+ mySearchTool->hide();
}
-void OB_Browser::setSelected( const SUIT_DataObject* theObject, const bool append )
+/*!
+ \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
{
- DataObjectList lst;
- lst.append( theObject );
- setSelected( lst, append );
+ return myAutoOpenLevel;
}
-void OB_Browser::setSelected( const DataObjectList& theObjLst, const bool append )
+/*!
+ \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 levels )
{
- QListView* lv = listView();
-
- if ( !lv )
- return;
-
- bool changed = false;
- bool block = lv->signalsBlocked();
- lv->blockSignals( true );
-
- QMap<QListViewItem*, int> 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();
- }
+ if ( myAutoOpenLevel != levels )
+ myAutoOpenLevel = levels;
}
-bool OB_Browser::isOpen( SUIT_DataObject* theObject ) const
+/*!
+ \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 )
{
- bool res = false;
- if ( listView() )
- res = listView()->isOpen( listViewItem( theObject ) );
- return res;
+ myView->expandLevels( levels < 0 ? autoOpenLevel() : levels );
}
-void OB_Browser::setOpen( SUIT_DataObject* theObject, const bool theOpen )
+/*!
+ \return state "are tooltips shown"
+*/
+/*
+bool OB_Browser::isShowToolTips()
{
- if ( listView() )
- listView()->setOpen( listViewItem( theObject ), theOpen );
+ return myShowToolTips;
}
-
-SUIT_DataObject* OB_Browser::dataObjectAt( const QPoint& pos ) const
+*/
+/*!
+ Sets new value of state "are tooltips shown"
+ \param theDisplay - new value
+*/
+/*
+void OB_Browser::setShowToolTips( const bool theDisplay )
{
- SUIT_DataObject* obj = 0;
-
- QListView* lv = listView();
- if ( lv )
- obj = dataObject( lv->itemAt( pos ) );
-
- return obj;
+ myShowToolTips = theDisplay;
}
+*/
-OB_Filter* OB_Browser::filter() const
+/*!
+ \brief Get number of selected items.
+ \return number of selected items
+*/
+int OB_Browser::numberOfSelected() const
{
- return myView->filter();
+ // we take selection by rows
+ return myView->selectionModel() ? myView->selectionModel()->selectedRows().count() : 0;
}
-void OB_Browser::setFilter( OB_Filter* f )
+/*!
+ \brief Get all selected items.
+ \return unsorted list of selected indexes with no duplicates
+*/
+QModelIndexList OB_Browser::selectedIndexes() const
{
- myView->setFilter( f );
+ // we take selection by rows
+ return myView->selectionModel() ? myView->selectionModel()->selectedRows() : QModelIndexList();
}
-int OB_Browser::addColumn( const QString& label, const int id, const int width )
+/*!
+ \brief Get selection containing information about selected ranges.
+ \return QItemSelection instance
+*/
+const QItemSelection OB_Browser::selection() const
{
- return addColumn( QIconSet(), label, id, width );
+ static QItemSelection emptySel;
+ QItemSelection sel = emptySel;
+ if ( myView->selectionModel() )
+ sel = myView->selectionModel()->selection();
+ return sel;
}
-int OB_Browser::addColumn( const QIconSet& icon, const QString& label, const int id, const int width )
+/*!
+ \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::select( const QModelIndex& index, const bool on, const bool keepSelection )
{
- QListView* lv = listView();
- if ( !lv )
- return -1;
+ if ( myView->selectionModel() ) {
+ QItemSelectionModel::SelectionFlags f = on ? QItemSelectionModel::Select : QItemSelectionModel::Deselect;
+ f = f | QItemSelectionModel::Rows;
+ if ( !keepSelection )
+ f = f | QItemSelectionModel::Clear;
- int theId = id;
- if ( theId < 0 )
- {
- while ( myColumnIds.contains( theId ) )
- theId++;
+ myView->selectionModel()->select( index, f );
}
-
- 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;
}
-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<int, int>::iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
+/*!
+ \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().row()==last.parent().row() && idx.parent().column()==last.parent().column() &&
+ 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 )
{
- if ( it.key() > id )
- it.data()--;
+ myView->clearSelection();
}
- updateText();
-}
-void OB_Browser::setNameTitle( const QString& label )
-{
- setNameTitle( QIconSet(), label );
+ myView->blockSignals( blocked );
+ emit( selectionChanged() );
}
-void OB_Browser::setNameTitle( const QIconSet& icon, const QString& label )
+/*!
+ \brief Check if specified model index is expanded or collapsed.
+ \param index model index
+ \return \c true if model index is expanded
+ \sa setOpen()
+*/
+bool OB_Browser::isOpen( const QModelIndex& index ) const
{
- QListView* lv = listView();
- if ( !lv )
- return;
-
- if ( icon.isNull() )
- lv->setColumnText( 0, label );
- else
- lv->setColumnText( 0, icon, label );
+ return index.isValid() && model() && model()->hasChildren( index ) && myView->isExpanded( index );
}
-void OB_Browser::setColumnTitle( const int id, const QString& label )
+/*!
+ \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::setOpen( const QModelIndex& index, const bool open )
{
- setColumnTitle( id, QIconSet(), label );
+ myView->setExpanded( index, open ); // hasChildren() ???
}
-void OB_Browser::setColumnTitle( const int id, const QIconSet& icon, const QString& label )
+/*!
+ \brief Adjust first column width to its contents.
+*/
+void OB_Browser::adjustWidth()
{
- QListView* lv = listView();
- if ( !lv || !myColumnIds.contains( id ) )
- return;
-
- if ( icon.isNull() )
- lv->setColumnText( myColumnIds[id], label );
- else
- lv->setColumnText( myColumnIds[id], icon, label );
+ myView->resizeColumnToEncloseContents( 0 );
}
-QString OB_Browser::nameTitle() const
+/*!
+ \brief Adjust first column width to its contents.
+*/
+void OB_Browser::adjustFirstColumnWidth()
{
- return myView->columnText( 0 );
+ myView->resizeColumnToEncloseContents( 0 );
}
-QString OB_Browser::columnTitle( const int id ) const
+/*!
+ \brief Adjust all columns width to its contents except the first column.
+*/
+void OB_Browser::adjustColumnsWidth()
{
- QString txt;
- if ( myColumnIds.contains( id ) )
- txt = myView->columnText( myColumnIds[id] );
- return txt;
+ for ( int aCol = 1; aCol < myView->header()->count(); aCol++ ) {
+ if ( myView->columnWidth( aCol ) > 0 )
+ myView->resizeColumnToEncloseContents( aCol );
+ }
}
-bool OB_Browser::isColumnVisible( const int id ) const
+/*!
+ \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
{
- return myColumnIds.contains( id ) && myView->isShown( myColumnIds[id] );
-}
+ SUIT_DataObject* obj = 0;
-void OB_Browser::setColumnShown( const int id, const bool on )
-{
- if ( !myColumnIds.contains( id ) )
- return;
+ QListView* lv = listView();
+ if ( lv )
+ obj = dataObject( lv->itemAt( pos ) );
- myView->setShown( myColumnIds[id], on );
+ return obj;
}
-
-void OB_Browser::setWidthMode( QListView::WidthMode mode )
+*/
+/*!
+ \return filter of list view
+*/
+/* TODO: removed
+OB_Filter* OB_Browser::filter() const
{
- for ( int i = 0, n = myView->columns(); i < n; i++ )
- myView->setColumnWidthMode( i, mode );
+ return myView->filter();
}
-
-QValueList<int> OB_Browser::columns() const
+*/
+/*!
+ Changes filter of list view
+ \param f - new filter
+*/
+/* TODO: removed
+void OB_Browser::setFilter( OB_Filter* f )
{
- QValueList<int> lst;
- for ( QMap<int, int>::ConstIterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
- lst.append( it.key() );
- return lst;
+ myView->setFilter( f );
}
-
-bool OB_Browser::appropriateColumn( const int id ) const
+*/
+/*!
+ Sets global width mode
+ \param mode - new width mode
+*/
+/* TODO: removed
+void OB_Browser::setWidthMode( QListView::WidthMode mode )
{
- bool res = false;
- if ( myColumnIds.contains( id ) )
- res = myView->appropriate( myColumnIds[id] );
- return res;
+ for ( int i = 0, n = myView->columns(); i < n; i++ )
+ if( mode!=QListView::Maximum || myView->columnWidth( i )>0 )
+ myView->setColumnWidthMode( i, mode );
}
-
-void OB_Browser::setAppropriateColumn( const int id, const bool 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 )
{
- if ( !myColumnIds.contains( id ) )
- return;
+// QTime t1 = QTime::currentTime();
- myView->setAppropriate( myColumnIds[id], on );
-}
-
-void OB_Browser::updateTree( SUIT_DataObject* obj )
-{
if ( !obj && !(obj = getRootObject()) )
return;
updateView( obj );
- restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
-
- autoOpenBranches();
-
- if ( selNum != numberOfSelected() )
- emit selectionChanged();
-}
-
-void OB_Browser::replaceTree( SUIT_DataObject* src, SUIT_DataObject* trg )
-{
- if ( !src || !trg || src == trg || src->root() != getRootObject() )
- return;
-
- DataObjectKey curKey;
- DataObjectMap selObjs, openObjs;
- DataObjectKeyMap selKeys, openKeys;
-
- int selNum = numberOfSelected();
-
- SUIT_DataObject* curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
-
- SUIT_DataObject* parent = src->parent();
- int pos = parent ? parent->childPos( src ) : -1;
-
- src->setParent( 0 );
-
- removeConnections( src );
- if ( isAutoDeleteObjects() )
- delete src;
-
- if ( parent && pos != -1 )
- parent->insertChild( trg, pos );
-
- trg->setParent( parent );
-
- updateView( trg );
- createConnections( trg );
-
- restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
-
- autoOpenBranches();
-
- if ( selNum != numberOfSelected() )
- emit selectionChanged();
-}
-
-void OB_Browser::updateView( const SUIT_DataObject* theStartObj )
-{
- QListView* lv = listView();
- if ( !lv )
- return;
-
- if ( !theStartObj || theStartObj->root() != getRootObject() )
- return;
-
- QListViewItem* after = 0;
- QListViewItem* parent = 0;
- QListViewItem* startItem = listViewItem( theStartObj );
-
- if ( theStartObj->parent() )
- parent = listViewItem( theStartObj->parent() );
-
- QListViewItem* prv = 0;
- QListViewItem* cur = parent ? parent->firstChild() : lv->firstChild();
- while ( !after && cur )
- {
- if ( cur == startItem )
- after = prv;
-
- prv = cur;
- cur = cur->nextSibling();
- }
-
- QPtrList<QListViewItem> delList;
- if ( !startItem && theStartObj == getRootObject() )
- {
- for ( QListViewItem* item = lv->firstChild(); item; item = item->nextSibling() )
- delList.append( item );
- }
- else
- delList.append( startItem );
-
- for ( QPtrListIterator<QListViewItem> it( delList ); it.current(); ++it )
- {
- removeReferences( it.current() );
- delete it.current();
- }
-
- // for myRoot object, if myShowRoot==false, then creating multiple top-level QListViewItem-s
- // (which will correspond to myRoot's children = Modules).
- if ( rootIsDecorated() && theStartObj == myRoot )
- {
- DataObjectList lst;
- theStartObj->children( lst );
- DataObjectListIterator it ( lst );
- // iterating backward to preserve the order of elements in the tree
- for ( it.toLast(); it.current(); --it )
- createTree( it.current(), 0, 0 );
- }
- else
- createTree( theStartObj, parent, after ? after : parent );
-}
-
-QListViewItem* OB_Browser::createTree( const SUIT_DataObject* obj,
- QListViewItem* parent, QListViewItem* after )
-{
- if ( !obj )
- return 0;
-
- QListViewItem* item = createItem( obj, parent, after );
+ restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
- DataObjectList lst;
- obj->children( lst );
- for ( DataObjectListIterator it ( lst ); it.current(); ++it )
- createTree( it.current(), item );
+ if ( autoOpen )
+ autoOpenBranches();
- if ( item )
- item->setOpen( obj->isOpen() );
+ setModified();
- return item;
-}
+ if ( selNum != numberOfSelected() )
+ emit selectionChanged();
-QListViewItem* OB_Browser::createItem( const SUIT_DataObject* o,
- QListViewItem* parent, QListViewItem* after )
+// 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 )
{
- QListView* lv = listView();
+ if ( !src || !trg || src == trg || src->root() != getRootObject() )
+ return;
- if ( !lv || !o )
- return 0;
+ DataObjectKey curKey;
+ DataObjectMap selObjs, openObjs;
+ DataObjectKeyMap selKeys, openKeys;
- QListViewItem* item = 0;
- SUIT_DataObject* obj = (SUIT_DataObject*)o;
+ int selNum = numberOfSelected();
- int type = -1;
+ SUIT_DataObject* curObj = storeState( selObjs, openObjs, selKeys, openKeys, curKey );
- switch ( obj->checkType() )
- {
- case SUIT_DataObject::CheckBox:
- type = QCheckListItem::CheckBox;
- break;
- case SUIT_DataObject::RadioButton:
- type = QCheckListItem::RadioButton;
- break;
- }
+ SUIT_DataObject* parent = src->parent();
+ int pos = parent ? parent->childPos( src ) : -1;
- if ( parent )
- {
- if ( parent->childCount() && !after )
- {
- after = parent->firstChild();
- while ( after->nextSibling() )
- after = after->nextSibling();
- }
+ src->setParent( 0 );
- 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 ( type == -1 )
- item = new OB_ListItem( obj, parent );
- else
- item = new OB_CheckListItem( obj, parent, (QCheckListItem::Type)type );
- }
- }
- else // ROOT item
- {
- if ( type == -1 )
- item = new OB_ListItem( obj, lv );
- else
- item = new OB_CheckListItem( obj, lv, (QCheckListItem::Type)type );
- }
+ removeConnections( src );
+ if ( isAutoDeleteObjects() )
+ delete src;
- myItems.insert( obj, item );
- obj->connect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
+ if ( parent && pos != -1 )
+ parent->insertChild( trg, pos );
- updateText( item );
+ trg->setParent( parent );
- return item;
-}
+ updateView( trg );
+ createConnections( trg );
-void OB_Browser::adjustWidth()
-{
- if ( !listView() )
- return;
+ restoreState( selObjs, openObjs, curObj, selKeys, openKeys, curKey );
- listView()->setColumnWidth( 0, 0 );
- if ( listView()->firstChild() )
- adjustWidth( listView()->firstChild() );
-}
+ setModified();
+ if ( selNum != numberOfSelected() )
+ emit selectionChanged();
+}
+*/
+/*!
+ Adjusts width by item
+ \param item
+*/
+/*
void OB_Browser::adjustWidth( QListViewItem* item )
{
while ( item )
item = item->nextSibling();
}
}
+*/
-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;
-}
-
-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;
-}
-
-QListView* OB_Browser::listView() const
-{
- return myView;
-}
-
+/*!
+ \remove all items referencing current (through data objects)
+*/
+/* TODO:
void OB_Browser::removeReferences( QListViewItem* item )
{
if ( !item )
i = i->nextSibling();
}
}
-
+*/
+/*!
+ Connects all children to SLOT onDestroyed
+*/
+/* TODO: move to SUIT_TreeModel
void OB_Browser::createConnections( SUIT_DataObject* obj )
{
if ( !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 )
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
+ \param selObjs, selKeys - maps of selected objects
+ \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
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 )
if ( openObjs.contains( obj ) )
{
- if ( openObjs[obj] )
+ bool parentOpen = true;
+ if( item && item->parent() )
+ parentOpen = item->parent()->isOpen();
+
+ if ( openObjs[obj] && parentOpen )
lv->setOpen( item, true );
}
else if ( !key.isNull() && openKeys.contains( key ) )
- lv->setOpen( item, true );
+ {
+ bool parentOpen = true;
+ if( item && item->parent() )
+ parentOpen = item->parent()->isOpen();
+
+ if( parentOpen )
+ lv->setOpen( item, true );
+ }
if ( !curItem && ( curObj == obj || ( !curKey.isNull() && curKey == key )) )
curItem = item;
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 )
return DataObjectKey( obj->key() );
}
+*/
+
+/*!
+ \brief Get tree view widget.
+ \return tree view widget of the object browser
+*/
+QtxTreeView* OB_Browser::treeView() const
+{
+ return myView;
+}
-void OB_Browser::keyPressEvent( QKeyEvent* e )
+/*!
+ \brief Process context menu request event.
+ \param e context menu event
+*/
+void OB_Browser::contextMenuEvent( QContextMenuEvent* e )
{
- if ( e->key() == Qt::Key_F5 )
- updateTree();
+ QMenu* popup = new QMenu();
+
+ createPopupMenu( popup );
+
+ Qtx::simplifySeparators( popup );
- QFrame::keyPressEvent( e );
+ 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();
}
-void OB_Browser::onExpand()
+/*!
+ \brief Called when "Expand all" popup menu command is activated.
+
+ Expands all selected items recursively.
+*/
+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));
}
-void OB_Browser::onColumnVisible( int id )
+/*!
+ \brief Called when "Collapse all" popup menu command is activated.
+
+ Collapse all selected items recursively.
+*/
+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<QListViewItem> items, QListViewItem* item, int action )
{
SUIT_DataObject* obj = dataObject( item );
if ( !lst.isEmpty() )
emit dropped( lst, obj, action );
}
-
+*/
+/*!
+ Updates texts of items
+*/
+/* TODO: to be removed
void OB_Browser::updateText()
{
if ( myColumnIds.isEmpty() )
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 );
+ if ( !obj )
+ return false;
+ for( QMap<int, int>::const_iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
+ if( item->text( it.data() ) != obj->text( it.key() ) )
+ 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 );
for( QMap<int, int>::iterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
item->setText( it.data(), obj->text( it.key() ) );
}
+*/
-bool OB_Browser::eventFilter( QObject* o, QEvent* e )
+/*!
+ \brief Add custom actions to the popup menu.
+ \param menu popup menu
+*/
+void OB_Browser::createPopupMenu( QMenu* menu )
{
- 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;
- }
- }
+ menu->addSeparator();
- return QFrame::eventFilter( o, e );
-}
+ QModelIndexList indexes = selectedIndexes();
-void OB_Browser::contextMenuPopup( QPopupMenu* menu )
-{
-/* QValueList<int> cols;
- for ( QMap<int, int>::ConstIterator it = myColumnIds.begin(); it != myColumnIds.end(); ++it )
- {
- if ( appropriateColumn( it.key() ) )
- cols.append( it.key() );
+ bool closed = false, opened = false;
+
+ for ( QModelIndexList::Iterator it = indexes.begin();
+ it != indexes.end() && !closed; ++it ) {
+ closed = hasCollased( *it );
}
- uint num = menu->count();
- menu->setCheckable( true );
- for ( QValueList<int>::const_iterator iter = cols.begin(); iter != cols.end(); ++iter )
- {
- QString name = columnTitle( *iter );
- if ( name.isEmpty() )
- continue;
-
- int id = menu->insertItem( name, this, SLOT( onColumnVisible( int ) ) );
- menu->setItemChecked( id, isColumnVisible( *iter ) );
- menu->setItemParameter( id, *iter );
+ for ( QModelIndexList::Iterator it = indexes.begin();
+ it != indexes.end() && !opened; ++it ) {
+ opened = hasExpanded( *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() ) );
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 )
for ( QListViewItem* child = item->firstChild(); child; child = child->nextSibling() )
expand( child );
}
+*/
+/*!
+ \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::hasCollased( const QModelIndex& index ) const
+{
+ bool result = false;
+
+ 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 OB_Browser::hasClosed( QListViewItem* item ) const
-{
- if ( !item )
- return false;
-
- if ( item->childCount() && !item->isOpen() )
- return true;
-
- bool has = false;
- for ( QListViewItem* child = item->firstChild(); child && !has; child = child->nextSibling() )
- has = hasClosed( child );
-
- return has;
+/*!
+ \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;
+
+ 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;
}
+/*!
+ Removes SUIT object
+ \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 )
// Otherwise, "delete item" line will destroy all item's children,
// and <myItems> will contain invalid pointers (see ~QListViewItem() description in Qt docs)
DataObjectList childList;
- obj->children( childList );
+ obj->children( childList, true );
for ( DataObjectListIterator it( childList ); it.current(); ++it )
- removeObject( it.current(), false );
+ {
+ it.current()->disconnect( this, SLOT( onDestroyed( SUIT_DataObject* ) ) );
+ myItems.remove( it.current() );
+ }
QListViewItem* item = listViewItem( obj );
myItems.remove( obj );
if ( obj == myRoot )
- myRoot = 0;
+ {
+ // remove all child list view items
+ setRootObject( 0 );
+ return;
+ }
- if ( !autoUpd )
+ if( !autoUpd )
return;
if ( isAutoUpdate() )
{
SUIT_DataObject* pObj = item && item->parent() ? dataObject( item->parent() ) : 0;
- updateTree( pObj );
+ updateTree( pObj, false );
}
- else
- delete item;
-}
+ delete item;
+}
+*/
+/*!
+ Opens branches from 1 to autoOpenLevel()
+ \sa autoOpenLevel()
+*/
+/* TODO: to be revised
void OB_Browser::autoOpenBranches()
{
- int level = autoOpenLevel();
- QListView* lv = listView();
- if ( !lv || level < 1 )
- return;
-
- QListViewItem* item = lv->firstChild();
- while ( item )
- {
- openBranch( item, level );
- item = item->nextSibling();
- }
+ openLevels();
}
-
+*/
+/*!
+ Opens branch
+ \param item
+ \param level
+*/
+/* TODO: to be revised
void OB_Browser::openBranch( QListViewItem* item, const int level )
{
if ( level < 1 )
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 ) );
}
+*/
+
+/*!
+ \fn void OB_Browser::selectionChanged();
+ \brief Emitted when selection is changed in the Object Browser.
+*/
+
+QByteArray OB_Browser::getOpenStates( int theColumn ) const
+{
+ QByteArray aData;
+ QDataStream aStream( &aData, QIODevice::WriteOnly );
+ MapOfOpenStates aMap;
+ const_cast<OB_Browser*>( 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::setOpenStates( const QByteArray& theData, int theColumn )
+{
+ QByteArray* aData = const_cast<QByteArray*>( &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::openStates( bool isGet, MapOfOpenStates& theMap, const QModelIndex& theIndex, int theColumn )
+{
+ 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; i<n; i++ )
+ {
+ QModelIndex aChild = aModel->index( i, 0, theIndex );
+ openStates( isGet, theMap, aChild, theColumn );
+ }
+}