1 // Copyright (C) 2014-2015 EDF-R&D
2 // This library is free software; you can redistribute it and/or
3 // modify it under the terms of the GNU Lesser General Public
4 // License as published by the Free Software Foundation; either
5 // version 2.1 of the License, or (at your option) any later version.
7 // This library is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 // Lesser General Public License for more details.
12 // You should have received a copy of the GNU Lesser General Public
13 // License along with this library; if not, write to the Free Software
14 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "HYDROGUI_DataBrowser.h"
20 #include "HYDROGUI_Module.h"
21 #include "HYDROGUI_DataObject.h"
23 #include <LightApp_Application.h>
24 #include <LightApp_OBSelector.h>
25 #include <LightApp_SelectionMgr.h>
26 #include <QHeaderView>
27 #include <QtxSearchTool.h>
28 #include <QtxTreeView.h>
29 #include <SUIT_DataObject.h>
30 #include <SUIT_ResourceMgr.h>
31 #include <SUIT_SelectionMgr.h>
32 #include <SUIT_DataObjectIterator.h>
34 #define VISIBILITY_COLUMN_WIDTH 25
37 #include <SUIT_Selector.h>
38 #include <SUIT_DataOwner.h>
43 class SUIT_DataBrowser;
44 class LightApp_DataObject;
47 #include "LightApp_DataOwner.h"
48 #include "LightApp_DataObject.h"
49 #include "LightApp_Application.h"
50 #include <SUIT_DataBrowser.h>
51 #include <SUIT_Session.h>
52 #include <SUIT_DataObjectIterator.h>
57 // The selector is redefined in order to correct the selection in the browser.
58 // The main modification is to call fillEntries without the selector modified
59 // time compare. The modified time is result of the clock() method.
60 // On Linux, the method clock() returns the same values with some delay. So, it is possible,
61 // that time has the same value, but the browser has already other objects.
62 // So, the obsole entries can be in the saved entries by the filled method.
63 // May be it will be improved in the latest version of GUI_SRC.
64 // This redefinition is done for tag V7_3_0 of GUI_SRC.
65 class HYDROGUI_OBSelector : public LightApp_OBSelector
68 HYDROGUI_OBSelector( SUIT_DataBrowser*, SUIT_SelectionMgr* );
69 virtual ~HYDROGUI_OBSelector();
72 virtual void getSelection( SUIT_DataOwnerPtrList& ) const;
73 virtual void setSelection( const SUIT_DataOwnerPtrList& );
76 void fillEntries( QMap<QString, LightApp_DataObject*>& );
79 SUIT_DataOwnerPtrList mySelectedList;
80 QMap<QString, LightApp_DataObject*> myEntries;
83 HYDROGUI_OBSelector::HYDROGUI_OBSelector( SUIT_DataBrowser* ob, SUIT_SelectionMgr* mgr )
84 : LightApp_OBSelector( ob, mgr )
91 HYDROGUI_OBSelector::~HYDROGUI_OBSelector()
96 \brief Get list of currently selected objects.
97 \param theList list to be filled with the selected objects owners
98 \ This method is necessary to fill the cach containter mySelectedList
99 \ It is the same as in LightApp_OBSelector
101 void HYDROGUI_OBSelector::getSelection( SUIT_DataOwnerPtrList& theList ) const
103 SUIT_DataBrowser* aBrowser = browser();
105 if ( mySelectedList.count() == 0 ) {
106 SUIT_Session* session = SUIT_Session::session();
107 SUIT_Application* sapp = session ? session->activeApplication() : 0;
108 LightApp_Application* app = dynamic_cast<LightApp_Application*>( sapp );
109 if( !app || !aBrowser )
112 DataObjectList objlist;
113 aBrowser->getSelected( objlist );
114 HYDROGUI_OBSelector* that = (HYDROGUI_OBSelector*)this;
115 QListIterator<SUIT_DataObject*> it( objlist );
116 while ( it.hasNext() ) {
117 LightApp_DataObject* obj = dynamic_cast<LightApp_DataObject*>( it.next() );
118 if ( obj && app->checkDataObject( obj) ) {
119 #ifndef DISABLE_SALOMEOBJECT
120 Handle(SALOME_InteractiveObject) aSObj = new SALOME_InteractiveObject
121 ( obj->entry().toLatin1().constData(),
122 obj->componentDataType().toLatin1().constData(),
123 obj->name().toLatin1().constData() );
124 LightApp_DataOwner* owner = new LightApp_DataOwner( aSObj );
126 LightApp_DataOwner* owner = new LightApp_DataOwner( obj->entry() );
128 that->mySelectedList.append( SUIT_DataOwnerPtr( owner ) );
132 theList = mySelectedList;
136 \brief Set selection.
137 \param theList list of the object owners to be set selected
138 \ It is the same as in LightApp_OBSelector. The difference is in the row with
139 \ the modification time check.
141 void HYDROGUI_OBSelector::setSelection( const SUIT_DataOwnerPtrList& theList )
143 SUIT_DataBrowser* aBrowser = browser();
147 // this is the difference to LightApp_OBSelector. For this, this class is redefined
148 //if( myEntries.count() == 0 || myModifiedTime < aBrowser->getModifiedTime() )
150 fillEntries( myEntries );
153 DataObjectList objList;
154 for ( SUIT_DataOwnerPtrList::const_iterator it = theList.begin();
155 it != theList.end(); ++it ) {
156 const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*it).operator->() );
158 if ( owner && myEntries.contains( owner->entry() ) )
159 objList.append( myEntries[owner->entry()] );
162 aBrowser->setSelected( objList );
163 mySelectedList.clear();
167 \brief Fill map of the data objects currently shown in the Object Browser.
168 \param entries map to be filled
169 \ It is the same as in LightApp_OBSelector
171 void HYDROGUI_OBSelector::fillEntries( QMap<QString, LightApp_DataObject*>& entries )
175 SUIT_DataBrowser* aBrowser = browser();
179 for ( SUIT_DataObjectIterator it( aBrowser->root(),
180 SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
181 LightApp_DataObject* obj = dynamic_cast<LightApp_DataObject*>( it.current() );
183 entries.insert( obj->entry(), obj );
190 HYDROGUI_DataBrowser::HYDROGUI_DataBrowser( HYDROGUI_Module* theModule, SUIT_DataObject* theRoot, QWidget* theParent )
191 : SUIT_DataBrowser( theRoot, theParent ), myModule( theModule )
193 SUIT_ResourceMgr* resMgr = theModule->getApp()->resourceMgr();
195 if ( ( !theRoot ) && theModule )
197 // Initialize the root with the module data model
198 setRoot( new CAM_ModuleObject( theModule->dataModel(), NULL ) );
201 setSortMenuEnabled( true );
202 setAutoUpdate( true );
203 setUpdateModified( true );
205 if ( resMgr->hasValue( "ObjectBrowser", "auto_hide_search_tool" ) )
206 searchTool()->enableAutoHide( resMgr->booleanValue( "ObjectBrowser", "auto_hide_search_tool" ) );
208 setWindowTitle( tr( "OBJECT_BROWSER" ) );
209 connect( this, SIGNAL( requestUpdate() ), theModule->getApp(), SLOT( onRefresh() ) );
211 QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
212 QString RefObjCol = tr( "REF_OBJECT_COLUMN" );
213 QString AltitudeCol = tr( "ALTITUDE_COLUMN" );
215 SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( model() );
216 //RKV: treeModel->setSearcher( theModule->getApp() );
217 treeModel->setSearcher( this ); //RKV
218 treeModel->registerColumn( 0, EntryCol, LightApp_DataObject::EntryId );
219 treeModel->setAppropriate( EntryCol, Qtx::Toggled );
220 treeModel->registerColumn( 0, RefObjCol, HYDROGUI_DataObject::RefObjectId );
221 treeModel->setAppropriate( RefObjCol, Qtx::Toggled );
222 treeModel->registerColumn( 0, AltitudeCol, HYDROGUI_DataObject::AltitudeObjId );
223 treeModel->setAppropriate( AltitudeCol, Qtx::Toggled );
225 // Mantis issue 0020136: Drag&Drop in OB
226 SUIT_ProxyModel* proxyModel = dynamic_cast<SUIT_ProxyModel*>(treeModel);
229 SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ),
230 SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ) );
232 //// Connect signal emitted after editing for updating after objects renaming
233 SUIT_TreeModel* aMiniModel = dynamic_cast<SUIT_TreeModel*>( proxyModel->sourceModel() );
236 connect( aMiniModel, SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ),
237 SIGNAL( dataChanged() ) );
240 // Do updating also in the module's main object browser.
243 SUIT_DataBrowser* aModulBrowser = theModule->getApp()->objectBrowser();
246 SUIT_ProxyModel* aPModel = dynamic_cast<SUIT_ProxyModel*>(aModulBrowser->model());
249 SUIT_TreeModel* aModel = dynamic_cast<SUIT_TreeModel*>(aPModel->sourceModel());
250 //connect( proxyModel, SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ),
251 // aPModel, SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ) );
252 //connect( proxyModel, SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ),
253 // aModel, SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ) );
254 connect( proxyModel, SIGNAL( modelUpdated() ), aModel, SIGNAL( modelUpdated() ) );
260 // temporary commented
262 OB_ListView* ob_list = dynamic_cast<OB_ListView*>( const_cast<QListView*>( listView() ) );
264 ob_list->setColumnMaxWidth( 0, theModule->getApp()->desktop()->width()/4 );
266 setFilter( new LightApp_OBFilter( theModule->getApp()->selectionMgr() ) );
270 new HYDROGUI_OBSelector( this, theModule->getApp()->selectionMgr() );
272 treeView()->header()->setResizeMode(SUIT_DataObject::VisibilityId, QHeaderView::Fixed);
273 treeView()->header()->moveSection(SUIT_DataObject::NameId,SUIT_DataObject::VisibilityId);
274 treeView()->setColumnWidth(SUIT_DataObject::VisibilityId, VISIBILITY_COLUMN_WIDTH);
275 treeView()->hideColumn( SUIT_DataObject::VisibilityId );
276 treeView()->hideColumn( LightApp_DataObject::EntryId );
277 //RKV: connectPopupRequest( theModule->getApp(), SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
280 HYDROGUI_DataBrowser::~HYDROGUI_DataBrowser()
284 SUIT_DataObject* HYDROGUI_DataBrowser::findObject( const QString& theEntry ) const
286 LightApp_DataObject* aCurObj;
287 for ( SUIT_DataObjectIterator it( root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
288 aCurObj = dynamic_cast<LightApp_DataObject*>( it.current() );
289 if ( aCurObj && aCurObj->entry() == theEntry )
296 \brief Switch read only mode for the Object Browser.
297 \param theIsReadOnly if true - read only mode will be turned on
299 void HYDROGUI_DataBrowser::setReadOnly( const bool theIsReadOnly )
301 //TODO: to be reimplemented
303 // Enable/disable edit triggers
304 foreach ( QTreeView* aView, findChildren<QTreeView*>() ) {
305 aView->setDragEnabled ( !theIsReadOnly );
306 aView->setEditTriggers ( theIsReadOnly ?
307 QAbstractItemView::NoEditTriggers :
308 QAbstractItemView::DoubleClicked );
311 // Enable/disable rename shortcut
312 QList<QShortcut*> aShortcuts = findChildren<QShortcut*>();
313 QShortcut* aShortcut;
314 foreach( aShortcut, aShortcuts ) {
315 if ( aShortcut->key() == QKeySequence( shortcutKey( RenameShortcut ) ) ) {
316 aShortcut->setEnabled( !theIsReadOnly );