1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : SUIT_DataBrowser.cxx
21 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
23 #include "SUIT_DataBrowser.h"
24 #include "SUIT_TreeModel.h"
25 #include <QtxTreeView.h>
30 \class SUIT_DataBrowser
31 \brief Object browser customization.
36 \param parent parent widget
38 SUIT_DataBrowser::SUIT_DataBrowser( QWidget* parent )
39 : OB_Browser( parent )
46 \param root root data object
47 \param parent parent widget
49 SUIT_DataBrowser::SUIT_DataBrowser( SUIT_DataObject* root, QWidget* parent )
50 : OB_Browser( parent )
58 SUIT_DataBrowser::~SUIT_DataBrowser()
63 \brief Get popup menu client type.
64 \return popup client type
66 QString SUIT_DataBrowser::popupClientType() const
68 return "ObjectBrowser";
72 \brief Get root object.
75 SUIT_DataObject* SUIT_DataBrowser::root() const
77 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
78 return m ? m->root() : 0;
82 \brief Set root object.
83 \param r new root object
85 void SUIT_DataBrowser::setRoot( SUIT_DataObject* r )
87 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
93 \brief Get 'auto-update tree' flag value.
94 \return 'auto-update tree' flag value
95 \sa setAutoUpdate(), updateTree()
97 bool SUIT_DataBrowser::autoUpdate() const
99 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
100 return m ? m->autoUpdate() : false;
104 \brief Set 'auto-update tree' flag value.
106 If this flag is set to \c true (by default), the object browser is updated
107 automatically when data tree is changed.
109 \param on 'auto-update tree' flag value
110 \sa autoUpdate(), updateTree()
112 void SUIT_DataBrowser::setAutoUpdate( const bool on )
114 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
116 m->setAutoUpdate( on );
120 \brief Get 'updateModified' flag value.
121 \return 'updateModified' flag value
123 bool SUIT_DataBrowser::updateModified() const
125 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
126 return m ? m->updateModified() : false;
130 \brief Set 'updateModified' flag value.
131 \param on 'updateModified' flag value
133 void SUIT_DataBrowser::setUpdateModified( const bool on )
135 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
137 m->setUpdateModified( on );
141 \brief Update object browser starting from the object \obj;
142 open all branches automatically if \a autoOpen is \c true.
143 \param obj starting object for updating
144 \param autoOpen if \c true automatically open branches
146 void SUIT_DataBrowser::updateTree( SUIT_DataObject* obj, const bool autoOpen )
148 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
150 m->updateTree( obj );
153 if (myAutoSizeFirstColumn)
154 adjustFirstColumnWidth();
155 if (myAutoSizeColumns)
156 adjustColumnsWidth();
161 \brief Get current key accelerator by id.
162 \return current key accelerator
163 \sa setShortcutKey(), requestUpdate(), requestRename()
165 int SUIT_DataBrowser::shortcutKey(const int id) const
167 return myShortcutMap.value(id)->key();
171 \brief Assign the key accelerator for the shortcut.
173 \param id id of the shortcut
174 \param key new key accelerator
175 \sa shortcutKey(), requestUpdate(), requestRename()
177 void SUIT_DataBrowser::setShortcutKey( const int id, const int key )
179 ShortcutMap::iterator it = myShortcutMap.find( id );
180 if( it != myShortcutMap.end() )
185 \brief Get list of selected data objects.
186 \return list of the currently selected data objects
188 DataObjectList SUIT_DataBrowser::getSelected() const
196 \brief Get list of selected data objects.
198 \param lst list to be filled with the currently selected data objects
200 void SUIT_DataBrowser::getSelected( DataObjectList& lst ) const
204 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
207 QModelIndexList sel = selectedIndexes();
210 foreach( idx, sel ) {
211 SUIT_DataObject* obj = m->object( idx );
219 \brief Set selected object.
220 \param obj data object to set selected
221 \param append if \c true, the object is added to the current selection;
222 otherwise the previous selection is first cleared
224 void SUIT_DataBrowser::setSelected( const SUIT_DataObject* obj, const bool append )
226 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
229 QModelIndex index = m->index( obj );
230 if ( index.isValid() )
231 select( index, true, append );
236 \brief function to sort QModelIndexList with qSort
238 bool modelIndexLessThan(const QModelIndex& lhs, const QModelIndex& rhs)
240 QModelIndex lhs_parent=lhs.parent();
241 QModelIndex rhs_parent=rhs.parent();
242 if(lhs_parent < rhs_parent)return true;
243 if(lhs_parent == rhs_parent) return lhs < rhs;
248 \brief Set list of selected data objects.
249 \param lst list of the data object to set selected
250 \param append if \c true, the objects are added to the current selection;
251 otherwise the previous selection is first cleared
253 void SUIT_DataBrowser::setSelected( const DataObjectList& lst, const bool append )
255 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
258 QModelIndexList indexes;
259 SUIT_DataObject* obj;
261 foreach( obj, lst ) {
262 QModelIndex index = m->index( obj );
263 if ( index.isValid() )
264 indexes.append( index );
266 qSort(indexes.begin(), indexes.end(), modelIndexLessThan);
268 select( indexes, true, append ); // if !indexes.isEmpty() ???
273 \brief Make the view item for specified data object is visible.
274 \param obj data object
276 void SUIT_DataBrowser::ensureVisible( SUIT_DataObject* obj )
283 ensureVisible( lst );
287 \brief Make the view items for specified data objects is visible.
288 \param lst data object list
290 void SUIT_DataBrowser::ensureVisible( const DataObjectList& lst )
292 QtxTreeView* tv = treeView();
293 SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( model() );
294 if ( !tv || !treeModel )
297 for ( DataObjectList::const_iterator it = lst.begin(); it != lst.end(); ++it )
299 QModelIndex idx = treeModel->index( *it );
306 \brief Add custom actions to the popup menu.
307 \param menu popup menu
309 void SUIT_DataBrowser::contextMenuPopup( QMenu* menu )
311 createPopupMenu( menu );
315 \brief Set 'auto-size first column' flag value.
317 If this flag is set to \c true (by default), the first column width is resized
320 \param on 'auto-size first column' flag value
321 \sa setAutoSizeColumns()
323 void SUIT_DataBrowser::setAutoSizeFirstColumn( const bool on )
325 myAutoSizeFirstColumn = on;
329 \brief Set 'auto-size columns' flag value.
331 If this flag is set to \c true (by default is false), columns width except
332 the first column is resized to its contents.
334 \param on 'auto-size columns' flag value
335 \sa setAutoSizeFirstColumn()
337 void SUIT_DataBrowser::setAutoSizeColumns( const bool on )
339 myAutoSizeColumns = on;
343 \brief Process context menu request event.
344 \param e context menu event
346 void SUIT_DataBrowser::contextMenuEvent( QContextMenuEvent* e )
348 contextMenuRequest( e );
352 \brief Set 'resize on expand item' flag value.
354 If this flag is set to \c true (by default is false), after
355 expanding an item columns will be resized to its contents.
357 \param on 'resize on expand item' flag value
359 void SUIT_DataBrowser::setResizeOnExpandItem( const bool on )
361 myResizeOnExpandItem = on;
365 \brief Initialize object browser.
366 \param root root data object
368 void SUIT_DataBrowser::init( SUIT_DataObject* root )
370 SUIT_ProxyModel* m = new SUIT_ProxyModel( root, this );
371 connect( m, SIGNAL( modelUpdated() ), this, SLOT( onModelUpdated() ) );
374 setItemDelegate( qobject_cast<SUIT_ProxyModel*>( model() )->delegate() );
375 connect( treeView(), SIGNAL( sortingEnabled( bool ) ),
376 model(), SLOT( setSortingEnabled( bool ) ) );
377 connect( treeView(), SIGNAL( clicked( const QModelIndex& ) ),
378 this, SLOT( onClicked( const QModelIndex& ) ) );
379 connect( treeView(), SIGNAL( doubleClicked( const QModelIndex& ) ),
380 this, SLOT( onDblClicked( const QModelIndex& ) ) );
381 connect( treeView(), SIGNAL( expanded( const QModelIndex& ) ),
382 this, SLOT( onExpanded( const QModelIndex& ) ) );
383 connect( this , SIGNAL( requestRename() ),
384 this , SLOT ( onStartEditing() ));
386 myShortcutMap.insert(UpdateShortcut , new QShortcut( Qt::Key_F5, this, SIGNAL( requestUpdate() ), SIGNAL( requestUpdate() ) ) );
387 myShortcutMap.insert(RenameShortcut , new QShortcut( Qt::Key_F2, this, SIGNAL( requestRename() ), SIGNAL( requestRename() ) ) );
389 myAutoSizeFirstColumn = true;
390 myAutoSizeColumns = false;
391 myResizeOnExpandItem = false;
395 \fn void SUIT_DataBrowser::requestUpdate();
396 \brief The signal is emitted when the key accelerator
397 assigned for the update operation is pressed by the user.
399 By default, \c [F5] key is assigned for the update operation.
400 The key accelerator can be changed with the setShortcutKey() method.
402 \sa shortcutKey(), setShortcutKey()
406 \fn void SUIT_DataBrowser::clicked( SUIT_DataObject* o );
407 \brief This signal is emitted when a mouse button is clicked.
409 The data object the mouse was clicked on is specified by \a o.
410 The signal is only emitted when the object is valid.
412 \param o data object which is clicked
416 \fn void SUIT_DataBrowser::doubleClicked( SUIT_DataObject* o );
417 \brief This signal is emitted when a mouse button is double-clicked.
419 The data object the mouse was double-clicked on is specified by \a o.
420 The signal is only emitted when the object is valid.
422 \param o data object which is double-clicked
426 \brief Update internal modification time just after data model update
428 void SUIT_DataBrowser::onModelUpdated()
434 \brief Called when item is clicked in the tree view
437 Emits signal clicked( SUIT_DataObject* );
439 void SUIT_DataBrowser::onClicked( const QModelIndex& index )
441 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
444 SUIT_DataObject* obj = m->object( index );
446 emit( clicked( obj ) );
447 m->emitClicked(obj, index);
453 \brief Called when item is double-clicked in the tree view
456 Emits signal doubleClicked( SUIT_DataObject* );
458 void SUIT_DataBrowser::onDblClicked( const QModelIndex& index )
460 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
463 SUIT_DataObject* obj = m->object( index );
464 if ( obj ) emit( doubleClicked( obj ) );
469 \brief Called when item specified by index is expanded.
472 void SUIT_DataBrowser::onExpanded( const QModelIndex& index )
474 if (myResizeOnExpandItem) {
475 adjustFirstColumnWidth();
476 adjustColumnsWidth();
481 \brief Make editable selected item in place.
484 void SUIT_DataBrowser::onStartEditing() {
485 DataObjectList sel = getSelected();
486 SUIT_ProxyModel* m = qobject_cast<SUIT_ProxyModel*>( model() );
487 if(treeView() && m && sel.count() == 1){
488 treeView()->edit(m->index( sel.first(), SUIT_DataObject::NameId ));