]> SALOME platform Git repositories - modules/gui.git/blob - src/LightApp/LightApp_Module.cxx
Salome HOME
8bd88c4ea3f0a00d9836ec0a9ca3d85610d6ffd7
[modules/gui.git] / src / LightApp / LightApp_Module.cxx
1 //  Copyright (C) 2007-2008  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 // File:      LightApp_Module.cxx
23 // Created:   6/20/2005 16:30:56 AM
24 // Author:    OCC team
25 //
26 #include "LightApp_Module.h"
27
28 #include "CAM_Application.h"
29
30 #include "LightApp_Application.h"
31 #include "LightApp_DataModel.h"
32 #include "LightApp_DataObject.h"
33 #include "LightApp_Study.h"
34 #include "LightApp_Preferences.h"
35 #include "LightApp_Selection.h"
36 #include "LightApp_Operation.h"
37 #include "LightApp_SwitchOp.h"
38 #include "LightApp_UpdateFlags.h"
39 #include "LightApp_ShowHideOp.h"
40 #include "LightApp_SelectionMgr.h"
41
42 #include <SUIT_Study.h>
43 #include <SUIT_DataObject.h>
44 #include <SUIT_DataBrowser.h>
45 #include <SUIT_Operation.h>
46 #include <SUIT_ViewManager.h>
47 #include <SUIT_ResourceMgr.h>
48 #include <SUIT_Desktop.h>
49 #include <SUIT_TreeModel.h>
50
51 #ifndef DISABLE_SALOMEOBJECT
52 #include <SALOME_ListIO.hxx>
53 #include <SALOME_ListIteratorOfListIO.hxx>
54 #endif
55
56 #ifndef DISABLE_VTKVIEWER
57 #ifndef DISABLE_SALOMEOBJECT
58   #include <SVTK_ViewWindow.h>
59   #include <SVTK_ViewModel.h>
60 #else
61   #include <VTKViewer_ViewWindow.h>
62 #endif
63   #include <VTKViewer_ViewModel.h>
64 #endif
65 #ifndef DISABLE_OCCVIEWER
66   #include <OCCViewer_ViewWindow.h>
67   #include <OCCViewer_ViewPort3d.h>
68 #ifndef DISABLE_SALOMEOBJECT
69   #include <SOCC_ViewModel.h>
70 #else
71   #include <OCCViewer_ViewModel.h>
72 #endif
73 #endif
74 #ifndef DISABLE_GLVIEWER
75   #include <GLViewer_ViewFrame.h>
76   #include <GLViewer_ViewPort.h>
77 #endif
78 #ifndef DISABLE_PLOT2DVIEWER
79   #include <Plot2d_ViewWindow.h>
80   #include <Plot2d_ViewFrame.h>
81 #ifndef DISABLE_SALOMEOBJECT
82   #include <SPlot2d_ViewModel.h>
83 #else
84   #include <Plot2d_ViewModel.h>
85 #endif
86 #endif
87
88 #include <QtxPopupMgr.h>
89
90 #include <QVariant>
91 #include <QString>
92 #include <QStringList>
93
94
95 /*!Constructor.*/
96 LightApp_Module::LightApp_Module( const QString& name )
97 : CAM_Module( name ),
98   myPopupMgr( 0 ),
99   mySwitchOp( 0 ),
100   myDisplay( -1 ),
101   myErase( -1 ),
102   myDisplayOnly( -1 ),
103   myEraseAll( -1 )
104 {
105 }
106
107 /*!Destructor.*/
108 LightApp_Module::~LightApp_Module()
109 {
110   if ( mySwitchOp )
111     delete mySwitchOp;
112 }
113
114 /*!Initialize module.*/
115 void LightApp_Module::initialize( CAM_Application* app )
116 {
117   CAM_Module::initialize( app );
118
119   SUIT_ResourceMgr* resMgr = app ? app->resourceMgr() : 0;
120   if ( resMgr )
121     resMgr->raiseTranslators( name() );
122 }
123
124 /*!NOT IMPLEMENTED*/
125 void LightApp_Module::windows( QMap<int, int>& ) const
126 {
127 }
128
129 /*!NOT IMPLEMENTED*/
130 void LightApp_Module::viewManagers( QStringList& ) const
131 {
132 }
133
134 /*!Context menu popup.*/
135 void LightApp_Module::contextMenuPopup( const QString& client, QMenu* menu, QString& /*title*/ )
136 {
137   LightApp_Selection* sel = createSelection();
138   sel->init( client, getApp()->selectionMgr() );
139   popupMgr()->setSelection( sel );
140   popupMgr()->setMenu( menu );
141   popupMgr()->updateMenu();
142 }
143
144 /*!Update object browser.
145  * For updating model or whole object browser use update() method can be used.
146 */
147 void LightApp_Module::updateObjBrowser( bool theIsUpdateDataModel, 
148                                         SUIT_DataObject* theDataObject )
149 {
150   bool upd = getApp()->objectBrowser()->autoUpdate();
151   getApp()->objectBrowser()->setAutoUpdate( false );
152
153   if( theIsUpdateDataModel ){
154     if( CAM_DataModel* aDataModel = dataModel() ){
155       if ( LightApp_DataModel* aModel = dynamic_cast<LightApp_DataModel*>( aDataModel ) ) {
156         SUIT_DataObject* aParent = NULL;
157         if(theDataObject && theDataObject != aDataModel->root())
158           aParent = theDataObject->parent();
159
160         LightApp_DataObject* anObject = dynamic_cast<LightApp_DataObject*>(theDataObject);
161         LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(getApp()->activeStudy());
162         aModel->update( anObject, aStudy );
163       }
164     }
165   }
166
167   getApp()->objectBrowser()->setAutoUpdate( upd );
168   getApp()->objectBrowser()->updateTree( 0, false );
169 }
170
171 /*!NOT IMPLEMENTED*/
172 void LightApp_Module::selectionChanged()
173 {
174 }
175
176 /*! \brief If return false, selection will be cleared at module activation
177  */
178 bool LightApp_Module::isSelectionCompatible()
179 {
180   // return true if selected objects belong to this module
181   bool isCompatible = true;
182 #ifndef DISABLE_SALOMEOBJECT
183   SALOME_ListIO selected;
184   if ( LightApp_SelectionMgr *Sel = getApp()->selectionMgr() )
185     Sel->selectedObjects( selected );
186
187   LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( getApp()->activeStudy() );
188   LightApp_DataObject* aRoot = dynamic_cast<LightApp_DataObject*>( dataModel()->root() );
189   if ( aStudy && aRoot ) {
190     // my data type
191     QString moduleDataType = aRoot->componentDataType();
192     // check data type of selection
193     SALOME_ListIteratorOfListIO It( selected );
194     for ( ; isCompatible && It.More(); It.Next()) {
195       Handle(SALOME_InteractiveObject)& io = It.Value();
196       isCompatible = ( aStudy->componentDataType( io->getEntry() ) == moduleDataType );
197     }
198   }
199 #endif
200   return isCompatible;
201 }
202
203 /*!Activate module.*/
204 bool LightApp_Module::activateModule( SUIT_Study* study )
205 {
206   bool res = CAM_Module::activateModule( study );
207
208   if ( !isSelectionCompatible() )// PAL19290, PAL18352
209     getApp()->selectionMgr()->clearSelected();
210
211   if ( res && application() && application()->resourceMgr() )
212     application()->resourceMgr()->raiseTranslators( name() );
213
214   connect( application(), SIGNAL( viewManagerAdded( SUIT_ViewManager* ) ),
215            this, SLOT( onViewManagerAdded( SUIT_ViewManager* ) ) );
216   connect( application(), SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
217            this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) );
218
219   if ( mySwitchOp == 0 )
220     mySwitchOp = new LightApp_SwitchOp( this );
221
222   QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
223   LightApp_DataModel* m = dynamic_cast<LightApp_DataModel*>( dataModel() );
224   if( m )
225   {
226     SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( getApp()->objectBrowser()->model() );
227     m->registerColumn( getApp()->objectBrowser(), EntryCol, LightApp_DataObject::EntryId );
228     treeModel->setAppropriate( EntryCol, Qtx::Toggled );
229   }
230   return res;
231 }
232
233 /*!Deactivate module.*/
234 bool LightApp_Module::deactivateModule( SUIT_Study* study )
235 {
236   delete mySwitchOp;
237   mySwitchOp = 0;
238
239   disconnect( application(), SIGNAL( viewManagerAdded( SUIT_ViewManager* ) ),
240               this, SLOT( onViewManagerAdded( SUIT_ViewManager* ) ) );
241   disconnect( application(), SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
242               this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) );
243
244   // abort all operations
245   MapOfOperation::const_iterator anIt;
246   for( anIt = myOperations.begin(); anIt != myOperations.end(); anIt++ ) {
247     anIt.value()->abort();
248   }
249
250   QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
251   LightApp_DataModel* m = dynamic_cast<LightApp_DataModel*>( dataModel() );
252   if( m )
253   {
254     SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( getApp()->objectBrowser()->model() );
255
256     treeModel->setAppropriate( EntryCol, Qtx::Shown );
257     m->unregisterColumn( getApp()->objectBrowser(), EntryCol );
258   }
259   return CAM_Module::deactivateModule( study );
260 }
261
262 /*!NOT IMPLEMENTED*/
263 void LightApp_Module::MenuItem()
264 {
265 }
266
267 /*!NOT IMPLEMENTED*/
268 void LightApp_Module::createPreferences()
269 {
270 }
271
272 /*!NOT IMPLEMENTED*/
273 void LightApp_Module::preferencesChanged( const QString&, const QString& )
274 {
275 }
276
277 /*!Gets application.*/
278 LightApp_Application* LightApp_Module::getApp() const
279 {
280   return (LightApp_Application*)application();
281 }
282
283 /*!
284  * \brief Update something in accordance with update flags
285  * \param theFlags - update flags
286 *
287 * Update viewer or/and object browser etc. in accordance with update flags ( see
288 * LightApp_UpdateFlags enumeration ). Derived modules can redefine this method for their
289 * own purposes
290 */
291 void LightApp_Module::update( const int theFlags )
292 {
293   if ( theFlags & UF_Model )
294   {
295     if( CAM_DataModel* aDataModel = dataModel() )
296       if( LightApp_DataModel* aModel = dynamic_cast<LightApp_DataModel*>( aDataModel ) )
297         aModel->update( 0, dynamic_cast<LightApp_Study*>( getApp()->activeStudy() ) );
298   }
299
300   if ( theFlags & UF_ObjBrowser )
301     getApp()->objectBrowser()->updateTree( 0 );
302
303   if ( theFlags & UF_Controls )
304     updateControls();
305   if ( theFlags & UF_Viewer )
306   {
307     if ( SUIT_ViewManager* viewMgr = getApp()->activeViewManager() )
308       if ( SUIT_ViewWindow* viewWnd = viewMgr->getActiveView() )
309       {
310 #ifndef DISABLE_VTKVIEWER
311 #ifndef DISABLE_SALOMEOBJECT
312         if ( viewWnd->inherits( "SVTK_ViewWindow" ) )
313           ( (SVTK_ViewWindow*)viewWnd )->Repaint();
314 #else
315         if ( viewWnd->inherits( "VTKViewer_ViewWindow" ) )
316           ( (VTKViewer_ViewWindow*)viewWnd )->Repaint();
317 #endif
318 #endif
319 #ifndef DISABLE_OCCVIEWER
320         if ( viewWnd->inherits( "OCCViewer_ViewWindow" ) )
321           ( (OCCViewer_ViewWindow*)viewWnd )->getViewPort()->onUpdate();
322 #endif
323 #ifndef DISABLE_PLOT2DVIEWER
324         if ( viewWnd->inherits( "Plot2d_ViewWindow" ) )
325           ( (Plot2d_ViewWindow*)viewWnd )->getViewFrame()->Repaint();
326 #endif
327 #ifndef DISABLE_GLVIEWER
328         if ( viewWnd->inherits( "GLViewer_ViewFrame" ) )
329           ( (GLViewer_ViewFrame*)viewWnd )->getViewPort()->onUpdate();
330 #endif
331       }
332   }
333 }
334 /*!
335  * \brief Updates controls
336 *
337 * Updates (i.e. disable/enable) controls states (menus, tool bars etc.). This method is
338 * called from update( UF_Controls ). You may redefine it in concrete module.
339 */
340 void LightApp_Module::updateControls()
341 {
342 }
343
344 /*!Create new instance of data model and return it.*/
345 CAM_DataModel* LightApp_Module::createDataModel()
346 {
347   return new LightApp_DataModel( this );
348 }
349
350 /*!Create and return instance of LightApp_Selection.*/
351 LightApp_Selection* LightApp_Module::createSelection() const
352 {
353   return new LightApp_Selection();
354 }
355
356 /*!NOT IMPLEMENTED*/
357 void LightApp_Module::onModelOpened()
358 {
359 }
360
361 /*!NOT IMPLEMENTED*/
362 void LightApp_Module::onModelSaved()
363 {
364 }
365
366 /*!NOT IMPLEMENTED*/
367 void LightApp_Module::onModelClosed()
368 {
369 }
370
371 /*!Gets popup manager.(create if not exist)*/
372 QtxPopupMgr* LightApp_Module::popupMgr()
373 {
374   if ( !myPopupMgr )
375   {
376     myPopupMgr = new QtxPopupMgr( 0, this );
377
378     QPixmap p;
379     SUIT_Desktop* d = application()->desktop();
380     
381     QAction 
382       *disp = createAction( -1, tr( "TOP_SHOW" ), p, tr( "MEN_SHOW" ), tr( "STB_SHOW" ),
383                             0, d, false, this, SLOT( onShowHide() ) ),
384       *erase = createAction( -1, tr( "TOP_HIDE" ), p, tr( "MEN_HIDE" ), tr( "STB_HIDE" ),
385                              0, d, false, this, SLOT( onShowHide() ) ),
386       *dispOnly = createAction( -1, tr( "TOP_DISPLAY_ONLY" ), p, tr( "MEN_DISPLAY_ONLY" ), tr( "STB_DISPLAY_ONLY" ),
387                                 0, d, false, this, SLOT( onShowHide() ) ),
388       *eraseAll = createAction( -1, tr( "TOP_ERASE_ALL" ), p, tr( "MEN_ERASE_ALL" ), tr( "STB_ERASE_ALL" ),
389                                 0, d, false, this, SLOT( onShowHide() ) );
390     myDisplay     = actionId( disp );
391     myErase       = actionId( erase );
392     myDisplayOnly = actionId( dispOnly );
393     myEraseAll    = actionId( eraseAll );
394
395     myPopupMgr->insert( disp, -1, 0 ); 
396     myPopupMgr->insert( erase, -1, 0 );
397     myPopupMgr->insert( dispOnly, -1, 0 );
398     myPopupMgr->insert( eraseAll, -1, 0 );
399     myPopupMgr->insert( separator(), -1, 0 );
400
401     QString oneAndNotActive = "( count( $component ) = 1 ) and ( not( activeModule in $component ) )";
402     QString uniform = "true in $canBeDisplayed and %1 and ( activeModule = '%2' )";
403     uniform = uniform.arg( oneAndNotActive ).arg( name() );
404     myPopupMgr->setRule( disp, /*QString( "( not isVisible ) and " ) + */ uniform, QtxPopupMgr::VisibleRule );
405     myPopupMgr->setRule( erase, /*QString( "( isVisible ) and " ) + */ uniform, QtxPopupMgr::VisibleRule );
406     myPopupMgr->setRule( dispOnly, uniform, QtxPopupMgr::VisibleRule );
407
408     QStringList viewers;
409
410 #ifndef DISABLE_OCCVIEWER
411 #ifndef DISABLE_SALOMEOBJECT
412     viewers.append( SOCC_Viewer::Type() );
413 #else
414     viewers.append( OCCViewer_Viewer::Type() );
415 #endif
416 #endif
417 #ifndef DISABLE_VTKVIEWER
418 #ifndef DISABLE_SALOMEOBJECT
419     viewers.append( SVTK_Viewer::Type() );
420 #else
421     viewers.append( VTKViewer_Viewer::Type() );
422 #endif
423 #endif
424 #ifndef DISABLE_PLOT2DVIEWER
425 #ifndef DISABLE_SALOMEOBJECT
426     viewers.append( SPlot2d_Viewer::Type() );
427 #else
428     viewers.append( Plot2d_Viewer::Type() );
429 #endif
430 #endif
431
432     if( !viewers.isEmpty() )
433     {
434       QString strViewers = "{ ", temp = "'%1' ";
435       QStringList::const_iterator anIt = viewers.begin(), aLast = viewers.end();
436       for( ; anIt!=aLast; anIt++ )
437         strViewers+=temp.arg( *anIt );
438       strViewers+="}";
439       myPopupMgr->setRule( eraseAll, QString( "client in %1" ).arg( strViewers ), QtxPopupMgr::VisibleRule );
440     }
441   }
442   return myPopupMgr;
443 }
444
445 /*!Gets preferences.*/
446 LightApp_Preferences* LightApp_Module::preferences() const
447 {
448   LightApp_Preferences* pref = 0;
449   if ( getApp() )
450     pref = getApp()->preferences();
451   return pref;
452 }
453
454 /*!Add preference to preferences.*/
455 int LightApp_Module::addPreference( const QString& label )
456 {
457   LightApp_Preferences* pref = preferences();
458   if ( !pref )
459     return -1;
460
461   int catId = pref->addPreference( moduleName(), -1 );
462   if ( catId == -1 )
463     return -1;
464
465   return pref->addPreference( label, catId );
466 }
467
468 /*!Add preference to preferences.*/
469 int LightApp_Module::addPreference( const QString& label, const int pId, const int type,
470                                     const QString& section, const QString& param )
471 {
472   LightApp_Preferences* pref = preferences();
473   if ( !pref )
474     return -1;
475
476   return pref->addPreference( moduleName(), label, pId, type, section, param );
477 }
478
479 /*!Gets property of preferences.*/
480 QVariant LightApp_Module::preferenceProperty( const int id, const QString& prop ) const
481 {
482   QVariant var;
483   LightApp_Preferences* pref = preferences();
484   if ( pref )
485     var = pref->itemProperty( prop, id );
486   return var;
487 }
488
489 /*!Set property of preferences.*/
490 void LightApp_Module::setPreferenceProperty( const int id, const QString& prop, const QVariant& var )
491 {
492   LightApp_Preferences* pref = preferences();
493   if ( pref )
494     pref->setItemProperty( prop, var, id );
495 }
496
497 /*!
498  * \brief Starts operation with given identifier
499   * \param id - identifier of operation to be started
500 *
501 * Module stores operations in map. This method starts operation by id.
502 * If operation isn't in map, then it will be created by createOperation method
503 * and will be inserted to map
504 */
505 void LightApp_Module::startOperation( const int id )
506 {
507   LightApp_Operation* op = 0;
508   if( myOperations.contains( id ) )
509     op = myOperations[ id ];
510   else
511   {
512     op = createOperation( id );
513     if( op )
514     {
515       myOperations.insert( id, op );
516       op->setModule( this );
517       connect( op, SIGNAL( stopped( SUIT_Operation* ) ), this, SLOT( onOperationStopped( SUIT_Operation* ) ) );
518       connect( op, SIGNAL( destroyed() ), this, SLOT( onOperationDestroyed() ) );
519     }
520   }
521
522   if( op )
523   {
524     // be sure that operation has correct study pointer
525     op->setStudy( application() ? application()->activeStudy() : 0 );
526     op->start();
527   }
528 }
529
530 /*!
531  * \brief Creates operation with given identifier
532   * \param id - identifier of operation to be started
533   * \return Pointer on created operation or NULL if operation is not created
534 *
535 * Creates operation with given id. You should not call this method, it will be called
536 * automatically from startOperation. You may redefine this method in concrete module to
537 * create operations. 
538 */
539 LightApp_Operation* LightApp_Module::createOperation( const int id ) const
540 {
541   if( id==-1 )
542     return 0;
543
544   if( id==myDisplay )
545     return new LightApp_ShowHideOp( LightApp_ShowHideOp::DISPLAY );
546   else if( id==myErase )
547     return new LightApp_ShowHideOp( LightApp_ShowHideOp::ERASE );
548   else if( id==myDisplayOnly )
549     return new LightApp_ShowHideOp( LightApp_ShowHideOp::DISPLAY_ONLY );
550   else if( id==myEraseAll )
551     return new LightApp_ShowHideOp( LightApp_ShowHideOp::ERASE_ALL );
552   else
553     return 0;
554 }
555
556 /*!
557  * \brief Virtual protected slot called when operation stopped
558  * \param theOp - stopped operation
559 *
560 * Virtual protected slot called when operation stopped. Redefine this slot if you want to
561 * perform actions after stopping operation
562 */
563 void LightApp_Module::onOperationStopped( SUIT_Operation* /*theOp*/ )
564 {
565 }
566
567 /*!
568  * \brief Virtual protected slot called when operation destroyed
569   * \param theOp - destroyed operation
570 *
571 * Virtual protected slot called when operation destroyed. Redefine this slot if you want to
572 * perform actions after destroying operation. Base implementation removes pointer on
573 * destroyed operation from the map of operations
574 */
575 void LightApp_Module::onOperationDestroyed()
576 {
577   const QObject* s = sender();
578   if( s && s->inherits( "LightApp_Operation" ) )
579   {
580     const LightApp_Operation* op = ( LightApp_Operation* )s;
581     MapOfOperation::const_iterator anIt = myOperations.begin(),
582                                    aLast = myOperations.end();
583     for( ; anIt!=aLast; anIt++ )
584       if( anIt.value()==op )
585       {
586         myOperations.remove( anIt.key() );
587         break;
588       }
589   }
590 }
591
592 /*!
593   Must be redefined in order to use standard displayer mechanism
594   \return displayer of module
595 */
596 LightApp_Displayer* LightApp_Module::displayer()
597 {
598   return 0;
599 }
600
601 /*!
602   SLOT: called on activating of standard operations show/hide
603 */
604 void LightApp_Module::onShowHide()
605 {
606   if( !sender()->inherits( "QAction" ) || !popupMgr() )
607     return;
608
609   QAction* act = ( QAction* )sender();
610   int id = actionId( act );
611   if( id!=-1 )
612     startOperation( id );
613 }
614
615 /*!
616   virtual SLOT: called on view manager adding
617 */
618 void LightApp_Module::onViewManagerAdded( SUIT_ViewManager* )
619 {
620 }
621
622 /*!
623   virtual SLOT: called on view manager removing
624 */
625 void LightApp_Module::onViewManagerRemoved( SUIT_ViewManager* )
626 {
627 }
628
629 /*!
630   \brief Returns instance of operation by its id; if there is no operation
631   corresponding to this id, null pointer is returned
632   \param id - operation id 
633   \return operation instance
634 */
635 LightApp_Operation* LightApp_Module::operation( const int id ) const
636 {
637   return myOperations.contains( id ) ? myOperations[id] : 0;
638 }