Salome HOME
New Help for KERNEL & GUI.
[modules/gui.git] / src / SalomeApp / SalomeApp_Module.cxx
1 // File:      SalomeApp_Module.cxx
2 // Created:   10/25/2004 11:39:56 AM
3 // Author:    Sergey LITONIN
4 // Copyright (C) CEA 2004
5
6 #include "SalomeApp_Module.h"
7
8 #include "SalomeApp_Study.h"
9 #include "SalomeApp_DataModel.h"
10 #include "SalomeApp_Application.h"
11 #include "SalomeApp_Preferences.h"
12 #include "SalomeApp_UpdateFlags.h"
13 #include "SalomeApp_Operation.h"
14 #include "SalomeApp_SwitchOp.h"
15 #include "SalomeApp_ShowHideOp.h"
16
17 #include <OB_Browser.h>
18
19 #include <CAM_Study.h>
20
21 #include <SUIT_MessageBox.h>
22 #include <SUIT_ResourceMgr.h>
23
24 #include <QtxPopupMgr.h>
25
26 #include <SVTK_ViewWindow.h>
27 #include <OCCViewer_ViewWindow.h>
28 #include <OCCViewer_ViewPort3d.h>
29 #include <GLViewer_ViewFrame.h>
30 #include <GLViewer_ViewPort.h>
31 #include <Plot2d_ViewWindow.h>
32 #include <Plot2d_ViewFrame.h>
33
34 /*!Constructor.*/
35 SalomeApp_Module::SalomeApp_Module( const QString& name )
36 : CAM_Module( name ),
37 myPopupMgr( 0 ),
38 mySwitchOp( 0 ),
39 myDisplay( -1 ),
40 myErase( -1 ),
41 myDisplayOnly( -1 )
42 {
43 }
44
45 /*!Destructor.*/
46 SalomeApp_Module::~SalomeApp_Module()
47 {
48   if ( mySwitchOp )
49     delete mySwitchOp;
50 }
51
52 /*!Initialize module.*/
53 void SalomeApp_Module::initialize( CAM_Application* app )
54 {
55   CAM_Module::initialize( app );
56
57   SUIT_ResourceMgr* resMgr = app ? app->resourceMgr() : 0;
58   if ( resMgr )
59     resMgr->raiseTranslators( name() );
60 }
61
62 /*!Activate module.*/
63 bool SalomeApp_Module::activateModule( SUIT_Study* study )
64 {
65   bool res = CAM_Module::activateModule( study );
66
67   if ( res && application() && application()->resourceMgr() )
68     application()->resourceMgr()->raiseTranslators( name() );
69
70   if ( mySwitchOp == 0 )
71     mySwitchOp = new SalomeApp_SwitchOp( this );
72     
73   return res;
74 }
75
76 /*!Deactivate module.*/
77 bool SalomeApp_Module::deactivateModule( SUIT_Study* )
78 {
79   delete mySwitchOp;
80   mySwitchOp = 0;
81   
82   return true;
83 }
84
85 /*!NOT IMPLEMENTED*/
86 void SalomeApp_Module::selectionChanged()
87 {
88 }
89
90 /*!NOT IMPLEMENTED*/
91 void SalomeApp_Module::MenuItem()
92 {
93 }
94
95 /*!NOT IMPLEMENTED*/
96 void SalomeApp_Module::windows( QMap<int, int>& ) const
97 {
98 }
99
100 /*!NOT IMPLEMENTED*/
101 void SalomeApp_Module::viewManagers( QStringList& ) const
102 {
103 }
104
105 /*!NOT IMPLEMENTED*/
106 void SalomeApp_Module::createPreferences()
107 {
108 }
109
110 /*!NOT IMPLEMENTED*/
111 void SalomeApp_Module::preferencesChanged( const QString&, const QString& )
112 {
113 }
114
115 /*!Gets application.*/
116 SalomeApp_Application* SalomeApp_Module::getApp() const
117 {
118   return (SalomeApp_Application*)application();
119 }
120
121 /*!NOT IMPLEMENTED*/
122 void SalomeApp_Module::onModelOpened()
123 {
124 }
125
126 /*!NOT IMPLEMENTED*/
127 void SalomeApp_Module::onModelSaved()
128 {
129 }
130
131 /*!NOT IMPLEMENTED*/
132 void SalomeApp_Module::onModelClosed()
133 {
134 }
135
136 /*!Gets popup manager.(create if not exist)*/
137 QtxPopupMgr* SalomeApp_Module::popupMgr()
138 {
139   if ( !myPopupMgr )
140   {
141     myPopupMgr = new QtxPopupMgr( 0, this );
142
143     QPixmap p;
144     SUIT_Desktop* d = application()->desktop();
145     
146     QAction 
147       *disp = createAction( -1, tr( "TOP_DISPLAY" ), p, tr( "MEN_DISPLAY" ), tr( "STB_DISPLAY" ),
148                             0, d, false, this, SLOT( onShowHide() ) ),
149       *erase = createAction( -1, tr( "TOP_ERASE" ), p, tr( "MEN_ERASE" ), tr( "STB_ERASE" ),
150                              0, d, false, this, SLOT( onShowHide() ) ),
151       *dispOnly = createAction( -1, tr( "TOP_DISPLAY_ONLY" ), p, tr( "MEN_DISPLAY_ONLY" ), tr( "STB_DISPLAY_ONLY" ),
152                                 0, d, false, this, SLOT( onShowHide() ) );
153     myDisplay     = actionId( disp );
154     myErase       = actionId( erase );
155     myDisplayOnly = actionId( dispOnly );
156
157     myPopupMgr->insert( disp, -1, 0 ); 
158     myPopupMgr->insert( erase, -1, 0 );
159     myPopupMgr->insert( dispOnly, -1, 0 );
160     myPopupMgr->insert( separator(), -1, 0 );
161
162     QString uniform = "( count( $component ) = 1 ) and ( component != activeModule ) and ( activeModule = '%1' )";
163     uniform = uniform.arg( name() );
164     myPopupMgr->setRule( disp, QString( "( not isVisible ) and " ) + uniform, true );
165     myPopupMgr->setRule( erase, QString( "( isVisible ) and " ) + uniform, true );
166     myPopupMgr->setRule( dispOnly, uniform, true );
167   }
168   return myPopupMgr;
169 }
170
171 /*!Gets preferences.*/
172 SalomeApp_Preferences* SalomeApp_Module::preferences() const
173 {
174   SalomeApp_Preferences* pref = 0;
175   if ( getApp() )
176     pref = getApp()->preferences();
177   return pref;
178 }
179
180 /*!Create new instance of data model and return it.*/
181 CAM_DataModel* SalomeApp_Module::createDataModel()
182 {
183   return new SalomeApp_DataModel(this);
184 }
185
186 /*!Update object browser.*/
187 void SalomeApp_Module::updateObjBrowser( bool updateDataModel, SUIT_DataObject* root )
188 {
189   if( updateDataModel )
190     if( CAM_DataModel* aDataModel = dataModel() )
191       if( SalomeApp_DataModel* aModel = dynamic_cast<SalomeApp_DataModel*>( aDataModel ) )
192         aModel->update( 0, dynamic_cast<SalomeApp_Study*>( getApp()->activeStudy() ) );
193   getApp()->objectBrowser()->updateTree( root );
194 }
195
196 /*!Context menu popup.*/
197 void SalomeApp_Module::contextMenuPopup( const QString& client, QPopupMenu* menu, QString& /*title*/ )
198 {
199   SalomeApp_Selection* sel = createSelection();
200   sel->init( client, getApp()->selectionMgr() );
201   popupMgr()->updatePopup( menu, sel );
202   delete sel;
203 }
204
205 /*!Create and return instance of SalomeApp_Selection.*/
206 SalomeApp_Selection* SalomeApp_Module::createSelection() const
207 {
208   return new SalomeApp_Selection();
209 }
210
211 /*!Add preference to preferences.*/
212 int SalomeApp_Module::addPreference( const QString& label )
213 {
214   SalomeApp_Preferences* pref = preferences();
215   if ( !pref )
216     return -1;
217
218   int catId = pref->addPreference( moduleName(), -1 );
219   if ( catId == -1 )
220     return -1;
221                              
222   return pref->addPreference( label, catId );
223 }
224
225 /*!Add preference to preferences.*/
226 int SalomeApp_Module::addPreference( const QString& label, const int pId, const int type,
227                                      const QString& section, const QString& param )
228 {
229   SalomeApp_Preferences* pref = preferences();
230   if ( !pref )
231     return -1;
232
233   return pref->addPreference( moduleName(), label, pId, type, section, param );
234 }
235
236 /*!Gets property of preferences.*/
237 QVariant SalomeApp_Module::preferenceProperty( const int id, const QString& prop ) const
238 {
239   QVariant var;
240   SalomeApp_Preferences* pref = preferences();
241   if ( pref )
242     var = pref->itemProperty( id, prop );
243   return var;
244 }
245
246
247 /*!Set property of preferences.*/
248 void SalomeApp_Module::setPreferenceProperty( const int id, const QString& prop, const QVariant& var )
249 {
250   SalomeApp_Preferences* pref = preferences();
251   if ( pref )
252     pref->setItemProperty( id, prop, var );
253 }
254
255 /*!
256  * \brief Update something in accordance with update flags
257   * \param theFlags - update flags
258 *
259 * Update viewer or/and object browser etc. in accordance with update flags ( see
260 * SalomeApp_UpdateFlags enumeration ). Derived modules can redefine this method for their
261 * own purposes
262 */
263 void SalomeApp_Module::update( const int theFlags )
264 {
265   if ( theFlags & UF_Model )
266   {
267     if( CAM_DataModel* aDataModel = dataModel() )
268       if( SalomeApp_DataModel* aModel = dynamic_cast<SalomeApp_DataModel*>( aDataModel ) )
269         aModel->update( 0, dynamic_cast<SalomeApp_Study*>( getApp()->activeStudy() ) );
270   }
271   if ( theFlags & UF_ObjBrowser )
272     getApp()->objectBrowser()->updateTree( 0 );
273   if ( theFlags & UF_Controls )
274     updateControls();
275   if ( theFlags & UF_Viewer )
276   {
277     if ( SUIT_ViewManager* viewMgr = getApp()->activeViewManager() )
278       if ( SUIT_ViewWindow* viewWnd = viewMgr->getActiveView() )
279       {
280         if ( viewWnd->inherits( "SVTK_ViewWindow" ) )
281           ( (SVTK_ViewWindow*)viewWnd )->Repaint();
282         else if ( viewWnd->inherits( "OCCViewer_ViewWindow" ) )
283           ( (OCCViewer_ViewWindow*)viewWnd )->getViewPort()->onUpdate();
284         else if ( viewWnd->inherits( "Plot2d_ViewWindow" ) )
285           ( (Plot2d_ViewWindow*)viewWnd )->getViewFrame()->Repaint();
286         else if ( viewWnd->inherits( "GLViewer_ViewFrame" ) )
287           ( (GLViewer_ViewFrame*)viewWnd )->getViewPort()->onUpdate();
288       }
289   }
290 }
291
292 /*!
293  * \brief Updates controls
294 *
295 * Updates (i.e. disable/enable) controls states (menus, tool bars etc.). This method is
296 * called from update( UF_Controls ). You may redefine it in concrete module.
297 */
298 void SalomeApp_Module::updateControls()
299 {
300 }
301
302 /*!
303  * \brief Starts operation with given identifier
304   * \param id - identifier of operation to be started
305 *
306 * Module stores operations in map. This method starts operation by id.
307 * If operation isn't in map, then it will be created by createOperation method
308 * and will be inserted to map
309 */
310 void SalomeApp_Module::startOperation( const int id )
311 {
312   SalomeApp_Operation* op = 0;
313   if( myOperations.contains( id ) )
314     op = myOperations[ id ];
315   else
316   {
317     op = createOperation( id );
318     if( op )
319     {
320       myOperations.insert( id, op );
321       op->setModule( this );
322       connect( op, SIGNAL( stopped( SUIT_Operation* ) ), this, SLOT( onOperationStopped( SUIT_Operation* ) ) );
323       connect( op, SIGNAL( destroyed() ), this, SLOT( onOperationDestroyed() ) );
324     }
325   }
326
327   if( op )
328     op->start();
329 }
330
331 /*!
332  * \brief Creates operation with given identifier
333   * \param id - identifier of operation to be started
334   * \return Pointer on created operation or NULL if operation is not created
335 *
336 * Creates operation with given id. You should not call this method, it will be called
337 * automatically from startOperation. You may redefine this method in concrete module to
338 * create operations. 
339 */
340 SalomeApp_Operation* SalomeApp_Module::createOperation( const int id ) const
341 {
342   if( id==-1 )
343     return 0;
344
345   if( id==myDisplay )
346     return new SalomeApp_ShowHideOp( SalomeApp_ShowHideOp::DISPLAY );
347   else if( id==myErase )
348     return new SalomeApp_ShowHideOp( SalomeApp_ShowHideOp::ERASE );
349   else if( id==myDisplayOnly )
350     return new SalomeApp_ShowHideOp( SalomeApp_ShowHideOp::DISPLAY_ONLY );
351   else
352     return 0;
353 }
354
355 /*!
356  * \brief Virtual protected slot called when operation stopped
357   * \param theOp - stopped operation
358 *
359 * Virtual protected slot called when operation stopped. Redefine this slot if you want to
360 * perform actions after stopping operation
361 */
362 void SalomeApp_Module::onOperationStopped( SUIT_Operation* /*theOp*/ )
363 {
364 }
365
366 /*!
367  * \brief Virtual protected slot called when operation destroyed
368   * \param theOp - destroyed operation
369 *
370 * Virtual protected slot called when operation destroyed. Redefine this slot if you want to
371 * perform actions after destroying operation. Base implementation removes pointer on
372 * destroyed operation from the map of operations
373 */
374 void SalomeApp_Module::onOperationDestroyed()
375 {
376   const QObject* s = sender();
377   if( s && s->inherits( "SalomeApp_Operation" ) )
378   {
379     const SalomeApp_Operation* op = ( SalomeApp_Operation* )s;
380     MapOfOperation::const_iterator anIt = myOperations.begin(),
381                                    aLast = myOperations.end();
382     for( ; anIt!=aLast; anIt++ )
383       if( anIt.data()==op )
384       {
385         myOperations.remove( anIt.key() );
386         break;
387       }
388   }
389 }
390
391 SalomeApp_Displayer* SalomeApp_Module::displayer()
392 {
393   return 0;
394 }
395
396 void SalomeApp_Module::onShowHide()
397 {
398   if( !sender()->inherits( "QAction" ) || !popupMgr() )
399     return;
400
401   QAction* act = ( QAction* )sender();
402   int id = actionId( act );
403   if( id!=-1 )
404     startOperation( id );
405 }