Salome HOME
merge BR_hydro_v_1_0_4 on BR_quadtree
[modules/hydro.git] / src / HYDROGUI / HYDROGUI_DataBrowser.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 #include "HYDROGUI_DataBrowser.h"
24 #include "HYDROGUI_Module.h"
25 #include "HYDROGUI_DataObject.h"
26
27 #include <LightApp_Application.h>
28 #include <LightApp_OBSelector.h>
29 #include <LightApp_SelectionMgr.h>
30 #include <QHeaderView>
31 #include <QtxSearchTool.h>
32 #include <QtxTreeView.h>
33 #include <SUIT_DataObject.h>
34 #include <SUIT_ResourceMgr.h>
35 #include <SUIT_SelectionMgr.h>
36 #include <SUIT_DataObjectIterator.h>
37         
38 #define VISIBILITY_COLUMN_WIDTH 25
39
40
41 #include <SUIT_Selector.h>
42 #include <SUIT_DataOwner.h>
43
44 #include <QObject>
45 #include <QShortcut>
46
47 class SUIT_DataBrowser;
48 class LightApp_DataObject;
49
50
51 #include "LightApp_DataOwner.h"
52 #include "LightApp_DataObject.h"
53 #include "LightApp_Application.h"
54 #include <SUIT_DataBrowser.h>
55 #include <SUIT_Session.h>
56 #include <SUIT_DataObjectIterator.h>
57 #include <QTime>
58 #include <time.h>
59
60
61 // The selector is redefined in order to correct the selection in the browser.
62 // The main modification is to call fillEntries without the selector modified
63 // time compare. The modified time is result of the clock() method.
64 // On Linux, the method clock() returns the same values with some delay. So, it is possible,
65 // that time has the same value, but the browser has already other objects.
66 // So, the obsole entries can be in the saved entries by the filled method.
67 // May be it will be improved in the latest version of GUI_SRC.
68 // This redefinition is done for tag V7_3_0 of GUI_SRC.
69 class HYDROGUI_OBSelector : public LightApp_OBSelector
70 {
71 public:
72   HYDROGUI_OBSelector( SUIT_DataBrowser*, SUIT_SelectionMgr* );
73   virtual ~HYDROGUI_OBSelector();
74
75 protected:
76   virtual void       getSelection( SUIT_DataOwnerPtrList& ) const;
77   virtual void       setSelection( const SUIT_DataOwnerPtrList& );
78
79 private:
80   void               fillEntries( QMap<QString, LightApp_DataObject*>& );
81
82 private:
83   SUIT_DataOwnerPtrList               mySelectedList;
84   QMap<QString, LightApp_DataObject*> myEntries;
85 };
86
87 HYDROGUI_OBSelector::HYDROGUI_OBSelector( SUIT_DataBrowser* ob, SUIT_SelectionMgr* mgr )
88 : LightApp_OBSelector( ob, mgr )
89 {
90 }
91
92 /*!
93   \brief Destructor.
94 */
95 HYDROGUI_OBSelector::~HYDROGUI_OBSelector()
96 {
97 }
98
99 /*!
100   \brief Get list of currently selected objects.
101   \param theList list to be filled with the selected objects owners
102   \ This method is necessary to fill the cach containter mySelectedList
103   \ It is the same as in LightApp_OBSelector
104 */
105 void HYDROGUI_OBSelector::getSelection( SUIT_DataOwnerPtrList& theList ) const
106 {
107   SUIT_DataBrowser* aBrowser = browser();
108
109   if ( mySelectedList.count() == 0 ) {
110     SUIT_Session* session = SUIT_Session::session();
111     SUIT_Application* sapp = session ? session->activeApplication() : 0;
112     LightApp_Application* app = dynamic_cast<LightApp_Application*>( sapp );
113     if( !app || !aBrowser )
114       return;
115
116     DataObjectList objlist;
117     aBrowser->getSelected( objlist );
118     HYDROGUI_OBSelector* that = (HYDROGUI_OBSelector*)this;
119     QListIterator<SUIT_DataObject*> it( objlist );
120     while ( it.hasNext() ) {
121       LightApp_DataObject* obj = dynamic_cast<LightApp_DataObject*>( it.next() );
122       if ( obj && app->checkDataObject( obj) ) {
123 #ifndef DISABLE_SALOMEOBJECT
124         Handle(SALOME_InteractiveObject) aSObj = new SALOME_InteractiveObject
125           ( obj->entry().toLatin1().constData(),
126             obj->componentDataType().toLatin1().constData(),
127             obj->name().toLatin1().constData() );
128         LightApp_DataOwner* owner = new LightApp_DataOwner( aSObj  );
129 #else
130         LightApp_DataOwner* owner = new LightApp_DataOwner( obj->entry() );
131 #endif
132         that->mySelectedList.append( SUIT_DataOwnerPtr( owner ) );
133       }
134     }
135   }
136   theList = mySelectedList;
137 }
138
139 /*!
140   \brief Set selection.
141   \param theList list of the object owners to be set selected
142   \ It is the same as in LightApp_OBSelector. The difference is in the row with
143   \ the modification time check.
144 */
145 void HYDROGUI_OBSelector::setSelection( const SUIT_DataOwnerPtrList& theList )
146 {
147   SUIT_DataBrowser* aBrowser = browser();
148   if ( !aBrowser )
149     return;
150
151   // this is the difference to LightApp_OBSelector. For this, this class is redefined
152   //if( myEntries.count() == 0 || myModifiedTime < aBrowser->getModifiedTime() )
153   {
154     fillEntries( myEntries );
155   }
156
157   DataObjectList objList;
158   for ( SUIT_DataOwnerPtrList::const_iterator it = theList.begin(); 
159         it != theList.end(); ++it ) {
160     const LightApp_DataOwner* owner = dynamic_cast<const LightApp_DataOwner*>( (*it).operator->() );
161
162     if ( owner && myEntries.contains( owner->entry() ) )
163       objList.append( myEntries[owner->entry()] );
164   }
165
166   aBrowser->setSelected( objList );
167   mySelectedList.clear();
168 }
169
170 /*!
171   \brief Fill map of the data objects currently shown in the Object Browser.
172   \param entries map to be filled
173   \ It is the same as in LightApp_OBSelector
174 */
175 void HYDROGUI_OBSelector::fillEntries( QMap<QString, LightApp_DataObject*>& entries )
176 {
177   entries.clear();
178
179   SUIT_DataBrowser* aBrowser = browser();
180   if ( !aBrowser )
181     return;
182
183   for ( SUIT_DataObjectIterator it( aBrowser->root(),
184                                     SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
185     LightApp_DataObject* obj = dynamic_cast<LightApp_DataObject*>( it.current() );
186     if ( obj )
187       entries.insert( obj->entry(), obj );
188   }
189
190   setModified();
191 }
192
193
194 HYDROGUI_DataBrowser::HYDROGUI_DataBrowser( HYDROGUI_Module* theModule, SUIT_DataObject* theRoot, QWidget* theParent )
195 : SUIT_DataBrowser( theRoot, theParent ), myModule( theModule )
196 {
197   SUIT_ResourceMgr* resMgr = theModule->getApp()->resourceMgr();
198
199   if ( ( !theRoot ) && theModule )
200   {
201     // Initialize the root with the module data model
202     setRoot( new CAM_ModuleObject( theModule->dataModel(), NULL ) );
203   }
204
205   setSortMenuEnabled( true );
206   setAutoUpdate( true );
207   setUpdateModified( true );
208
209   if ( resMgr->hasValue( "ObjectBrowser", "auto_hide_search_tool" ) )
210     searchTool()->enableAutoHide( resMgr->booleanValue( "ObjectBrowser", "auto_hide_search_tool" ) );
211
212   setWindowTitle( tr( "OBJECT_BROWSER" ) );
213   connect( this, SIGNAL( requestUpdate() ), theModule->getApp(), SLOT( onRefresh() ) );
214
215   QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
216   QString RefObjCol = tr( "REF_OBJECT_COLUMN" );
217   QString AltitudeCol = tr( "ALTITUDE_COLUMN" );
218
219   SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( model() );
220   //RKV: treeModel->setSearcher( theModule->getApp() );
221   treeModel->setSearcher( this ); //RKV
222   treeModel->registerColumn( 0, EntryCol, LightApp_DataObject::EntryId );
223   treeModel->setAppropriate( EntryCol, Qtx::Toggled );
224   treeModel->registerColumn( 0, RefObjCol, HYDROGUI_DataObject::RefObjectId );
225   treeModel->setAppropriate( RefObjCol, Qtx::Toggled );
226   treeModel->registerColumn( 0, AltitudeCol, HYDROGUI_DataObject::AltitudeObjId );
227   treeModel->setAppropriate( AltitudeCol, Qtx::Toggled );
228
229   // Mantis issue 0020136: Drag&Drop in OB
230   SUIT_ProxyModel* proxyModel = dynamic_cast<SUIT_ProxyModel*>(treeModel);
231   if ( proxyModel ) {
232     connect( proxyModel, 
233       SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ),
234       SIGNAL( dropped( const QList<SUIT_DataObject*>&, SUIT_DataObject*, int, Qt::DropAction ) ) );
235
236     //// Connect signal emitted after editing for updating after objects renaming
237     SUIT_TreeModel* aMiniModel = dynamic_cast<SUIT_TreeModel*>( proxyModel->sourceModel() );
238     if ( aMiniModel )
239     {
240       connect( aMiniModel, SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ), 
241         SIGNAL( dataChanged() ) );
242     }
243
244     // Do updating also in the module's main object browser.
245     if ( theModule )
246     {
247       SUIT_DataBrowser* aModulBrowser = theModule->getApp()->objectBrowser();
248       if ( aModulBrowser )
249       {
250         SUIT_ProxyModel* aPModel = dynamic_cast<SUIT_ProxyModel*>(aModulBrowser->model());
251         if ( aPModel )
252         {
253           SUIT_TreeModel* aModel = dynamic_cast<SUIT_TreeModel*>(aPModel->sourceModel());
254           //connect( proxyModel, SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ), 
255           //  aPModel, SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ) );
256           //connect( proxyModel, SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ), 
257           //  aModel, SIGNAL( dataChanged( const QModelIndex &, const QModelIndex & ) ) );
258           connect( proxyModel, SIGNAL( modelUpdated() ), aModel, SIGNAL( modelUpdated() ) );
259         }
260       }
261     }
262   }
263
264   // temporary commented
265   /*
266   OB_ListView* ob_list = dynamic_cast<OB_ListView*>( const_cast<QListView*>( listView() ) );
267   if( ob_list )
268     ob_list->setColumnMaxWidth( 0, theModule->getApp()->desktop()->width()/4 );
269
270   setFilter( new LightApp_OBFilter( theModule->getApp()->selectionMgr() ) );
271   */
272
273   // Create OBSelector
274   new HYDROGUI_OBSelector( this, theModule->getApp()->selectionMgr() );
275
276   treeView()->header()->setResizeMode(SUIT_DataObject::VisibilityId, QHeaderView::Fixed);
277   treeView()->header()->moveSection(SUIT_DataObject::NameId,SUIT_DataObject::VisibilityId);
278   treeView()->setColumnWidth(SUIT_DataObject::VisibilityId, VISIBILITY_COLUMN_WIDTH);
279   treeView()->hideColumn( SUIT_DataObject::VisibilityId );
280   treeView()->hideColumn( LightApp_DataObject::EntryId );
281   //RKV: connectPopupRequest( theModule->getApp(), SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
282 }
283
284 HYDROGUI_DataBrowser::~HYDROGUI_DataBrowser()
285 {
286 }
287
288 SUIT_DataObject* HYDROGUI_DataBrowser::findObject( const QString& theEntry ) const
289 {
290   LightApp_DataObject* aCurObj;
291   for ( SUIT_DataObjectIterator it( root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
292     aCurObj = dynamic_cast<LightApp_DataObject*>( it.current() );
293     if ( aCurObj && aCurObj->entry() == theEntry )
294       return aCurObj;
295   }
296   return NULL;
297 }
298
299 /*!
300   \brief Switch read only mode for the Object Browser.
301   \param theIsReadOnly if true - read only mode will be turned on
302 */
303 void HYDROGUI_DataBrowser::setReadOnly( const bool theIsReadOnly )
304 {
305   //TODO: to be reimplemented
306
307   // Enable/disable edit triggers
308   foreach ( QTreeView* aView, findChildren<QTreeView*>() ) {
309     aView->setDragEnabled ( !theIsReadOnly );
310     aView->setEditTriggers ( theIsReadOnly ?
311                              QAbstractItemView::NoEditTriggers :
312                              QAbstractItemView::DoubleClicked );
313   }
314
315   // Enable/disable rename shortcut
316   QList<QShortcut*> aShortcuts = findChildren<QShortcut*>();
317   QShortcut* aShortcut;
318   foreach( aShortcut, aShortcuts ) {
319     if ( aShortcut->key() == QKeySequence( shortcutKey( RenameShortcut ) ) ) {
320       aShortcut->setEnabled( !theIsReadOnly );
321     }
322   }
323 }