]> SALOME platform Git repositories - modules/hydro.git/blob - src/HYDROGUI/HYDROGUI_DataBrowser.cxx
Salome HOME
copyrights are updated
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_DataBrowser.cxx
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.
6 //
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.
11 //
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
15 //
16 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
17 //
18
19 #include "HYDROGUI_DataBrowser.h"
20 #include "HYDROGUI_Module.h"
21 #include "HYDROGUI_DataObject.h"
22
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>
33         
34 #define VISIBILITY_COLUMN_WIDTH 25
35
36
37 #include <SUIT_Selector.h>
38 #include <SUIT_DataOwner.h>
39
40 #include <QObject>
41 #include <QShortcut>
42
43 class SUIT_DataBrowser;
44 class LightApp_DataObject;
45
46
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>
53 #include <QTime>
54 #include <time.h>
55
56
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
66 {
67 public:
68   HYDROGUI_OBSelector( SUIT_DataBrowser*, SUIT_SelectionMgr* );
69   virtual ~HYDROGUI_OBSelector();
70
71 protected:
72   virtual void       getSelection( SUIT_DataOwnerPtrList& ) const;
73   virtual void       setSelection( const SUIT_DataOwnerPtrList& );
74
75 private:
76   void               fillEntries( QMap<QString, LightApp_DataObject*>& );
77
78 private:
79   SUIT_DataOwnerPtrList               mySelectedList;
80   QMap<QString, LightApp_DataObject*> myEntries;
81 };
82
83 HYDROGUI_OBSelector::HYDROGUI_OBSelector( SUIT_DataBrowser* ob, SUIT_SelectionMgr* mgr )
84 : LightApp_OBSelector( ob, mgr )
85 {
86 }
87
88 /*!
89   \brief Destructor.
90 */
91 HYDROGUI_OBSelector::~HYDROGUI_OBSelector()
92 {
93 }
94
95 /*!
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
100 */
101 void HYDROGUI_OBSelector::getSelection( SUIT_DataOwnerPtrList& theList ) const
102 {
103   SUIT_DataBrowser* aBrowser = browser();
104
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 )
110       return;
111
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  );
125 #else
126         LightApp_DataOwner* owner = new LightApp_DataOwner( obj->entry() );
127 #endif
128         that->mySelectedList.append( SUIT_DataOwnerPtr( owner ) );
129       }
130     }
131   }
132   theList = mySelectedList;
133 }
134
135 /*!
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.
140 */
141 void HYDROGUI_OBSelector::setSelection( const SUIT_DataOwnerPtrList& theList )
142 {
143   SUIT_DataBrowser* aBrowser = browser();
144   if ( !aBrowser )
145     return;
146
147   // this is the difference to LightApp_OBSelector. For this, this class is redefined
148   //if( myEntries.count() == 0 || myModifiedTime < aBrowser->getModifiedTime() )
149   {
150     fillEntries( myEntries );
151   }
152
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->() );
157
158     if ( owner && myEntries.contains( owner->entry() ) )
159       objList.append( myEntries[owner->entry()] );
160   }
161
162   aBrowser->setSelected( objList );
163   mySelectedList.clear();
164 }
165
166 /*!
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
170 */
171 void HYDROGUI_OBSelector::fillEntries( QMap<QString, LightApp_DataObject*>& entries )
172 {
173   entries.clear();
174
175   SUIT_DataBrowser* aBrowser = browser();
176   if ( !aBrowser )
177     return;
178
179   for ( SUIT_DataObjectIterator it( aBrowser->root(),
180                                     SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
181     LightApp_DataObject* obj = dynamic_cast<LightApp_DataObject*>( it.current() );
182     if ( obj )
183       entries.insert( obj->entry(), obj );
184   }
185
186   setModified();
187 }
188
189
190 HYDROGUI_DataBrowser::HYDROGUI_DataBrowser( HYDROGUI_Module* theModule, SUIT_DataObject* theRoot, QWidget* theParent )
191 : SUIT_DataBrowser( theRoot, theParent ), myModule( theModule )
192 {
193   SUIT_ResourceMgr* resMgr = theModule->getApp()->resourceMgr();
194
195   if ( ( !theRoot ) && theModule )
196   {
197     // Initialize the root with the module data model
198     setRoot( new CAM_ModuleObject( theModule->dataModel(), NULL ) );
199   }
200
201   setSortMenuEnabled( true );
202   setAutoUpdate( true );
203   setUpdateModified( true );
204
205   if ( resMgr->hasValue( "ObjectBrowser", "auto_hide_search_tool" ) )
206     searchTool()->enableAutoHide( resMgr->booleanValue( "ObjectBrowser", "auto_hide_search_tool" ) );
207
208   setWindowTitle( tr( "OBJECT_BROWSER" ) );
209   connect( this, SIGNAL( requestUpdate() ), theModule->getApp(), SLOT( onRefresh() ) );
210
211   QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
212   QString RefObjCol = tr( "REF_OBJECT_COLUMN" );
213   QString AltitudeCol = tr( "ALTITUDE_COLUMN" );
214
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 );
224
225   // Mantis issue 0020136: Drag&Drop in OB
226   SUIT_ProxyModel* proxyModel = dynamic_cast<SUIT_ProxyModel*>(treeModel);
227   if ( proxyModel ) {
228     connect( proxyModel, 
229       SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ),
230       SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ) );
231
232     //// Connect signal emitted after editing for updating after objects renaming
233     SUIT_TreeModel* aMiniModel = dynamic_cast<SUIT_TreeModel*>( proxyModel->sourceModel() );
234     if ( aMiniModel )
235     {
236       connect( aMiniModel, SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ), 
237         SIGNAL( dataChanged() ) );
238     }
239
240     // Do updating also in the module's main object browser.
241     if ( theModule )
242     {
243       SUIT_DataBrowser* aModulBrowser = theModule->getApp()->objectBrowser();
244       if ( aModulBrowser )
245       {
246         SUIT_ProxyModel* aPModel = dynamic_cast<SUIT_ProxyModel*>(aModulBrowser->model());
247         if ( aPModel )
248         {
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() ) );
255         }
256       }
257     }
258   }
259
260   // temporary commented
261   /*
262   OB_ListView* ob_list = dynamic_cast<OB_ListView*>( const_cast<QListView*>( listView() ) );
263   if( ob_list )
264     ob_list->setColumnMaxWidth( 0, theModule->getApp()->desktop()->width()/4 );
265
266   setFilter( new LightApp_OBFilter( theModule->getApp()->selectionMgr() ) );
267   */
268
269   // Create OBSelector
270   new HYDROGUI_OBSelector( this, theModule->getApp()->selectionMgr() );
271
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* ) ) );
278 }
279
280 HYDROGUI_DataBrowser::~HYDROGUI_DataBrowser()
281 {
282 }
283
284 SUIT_DataObject* HYDROGUI_DataBrowser::findObject( const QString& theEntry ) const
285 {
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 )
290       return aCurObj;
291   }
292   return NULL;
293 }
294
295 /*!
296   \brief Switch read only mode for the Object Browser.
297   \param theIsReadOnly if true - read only mode will be turned on
298 */
299 void HYDROGUI_DataBrowser::setReadOnly( const bool theIsReadOnly )
300 {
301   //TODO: to be reimplemented
302
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 );
309   }
310
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 );
317     }
318   }
319 }