1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File: LightApp_Module.cxx
23 // Created: 6/20/2005 16:30:56 AM
26 #include "LightApp_Module.h"
28 #include "CAM_Application.h"
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"
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>
51 #ifndef DISABLE_SALOMEOBJECT
52 #include <SALOME_ListIO.hxx>
53 #include <SALOME_ListIteratorOfListIO.hxx>
56 #ifndef DISABLE_VTKVIEWER
57 #ifndef DISABLE_SALOMEOBJECT
58 #include <SVTK_ViewWindow.h>
59 #include <SVTK_ViewModel.h>
61 #include <VTKViewer_ViewWindow.h>
63 #include <VTKViewer_ViewModel.h>
65 #ifndef DISABLE_OCCVIEWER
66 #include <OCCViewer_ViewWindow.h>
67 #include <OCCViewer_ViewPort3d.h>
68 #ifndef DISABLE_SALOMEOBJECT
69 #include <SOCC_ViewModel.h>
71 #include <OCCViewer_ViewModel.h>
74 #ifndef DISABLE_GLVIEWER
75 #include <GLViewer_ViewFrame.h>
76 #include <GLViewer_ViewPort.h>
78 #ifndef DISABLE_PLOT2DVIEWER
79 #include <Plot2d_ViewWindow.h>
80 #include <Plot2d_ViewFrame.h>
81 #ifndef DISABLE_SALOMEOBJECT
82 #include <SPlot2d_ViewModel.h>
84 #include <Plot2d_ViewModel.h>
88 #include <QtxPopupMgr.h>
92 #include <QStringList>
96 LightApp_Module::LightApp_Module( const QString& name )
108 LightApp_Module::~LightApp_Module()
114 /*!Initialize module.*/
115 void LightApp_Module::initialize( CAM_Application* app )
117 CAM_Module::initialize( app );
119 SUIT_ResourceMgr* resMgr = app ? app->resourceMgr() : 0;
121 resMgr->raiseTranslators( name() );
125 void LightApp_Module::windows( QMap<int, int>& ) const
130 void LightApp_Module::viewManagers( QStringList& ) const
134 /*!Context menu popup.*/
135 void LightApp_Module::contextMenuPopup( const QString& client, QMenu* menu, QString& /*title*/ )
137 LightApp_Selection* sel = createSelection();
138 sel->init( client, getApp()->selectionMgr() );
139 popupMgr()->setSelection( sel );
140 popupMgr()->setMenu( menu );
141 popupMgr()->updateMenu();
144 /*!Update object browser.
145 * For updating model or whole object browser use update() method can be used.
147 void LightApp_Module::updateObjBrowser( bool theIsUpdateDataModel,
148 SUIT_DataObject* theDataObject )
150 bool upd = getApp()->objectBrowser()->autoUpdate();
151 getApp()->objectBrowser()->setAutoUpdate( false );
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();
160 LightApp_DataObject* anObject = dynamic_cast<LightApp_DataObject*>(theDataObject);
161 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(getApp()->activeStudy());
162 aModel->update( anObject, aStudy );
167 getApp()->objectBrowser()->setAutoUpdate( upd );
168 getApp()->objectBrowser()->updateTree( 0, false );
172 void LightApp_Module::selectionChanged()
176 /*! \brief If return false, selection will be cleared at module activation
178 bool LightApp_Module::isSelectionCompatible()
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 );
187 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( getApp()->activeStudy() );
188 LightApp_DataObject* aRoot = dynamic_cast<LightApp_DataObject*>( dataModel()->root() );
189 if ( aStudy && aRoot ) {
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 );
203 /*!Activate module.*/
204 bool LightApp_Module::activateModule( SUIT_Study* study )
206 bool res = CAM_Module::activateModule( study );
208 if ( !isSelectionCompatible() )// PAL19290, PAL18352
209 getApp()->selectionMgr()->clearSelected();
211 if ( res && application() && application()->resourceMgr() )
212 application()->resourceMgr()->raiseTranslators( name() );
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* ) ) );
219 if ( mySwitchOp == 0 )
220 mySwitchOp = new LightApp_SwitchOp( this );
222 QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
223 LightApp_DataModel* m = dynamic_cast<LightApp_DataModel*>( dataModel() );
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 );
233 /*!Deactivate module.*/
234 bool LightApp_Module::deactivateModule( SUIT_Study* study )
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* ) ) );
244 // abort all operations
245 MapOfOperation::const_iterator anIt;
246 for( anIt = myOperations.begin(); anIt != myOperations.end(); anIt++ ) {
247 anIt.value()->abort();
250 QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
251 LightApp_DataModel* m = dynamic_cast<LightApp_DataModel*>( dataModel() );
254 SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( getApp()->objectBrowser()->model() );
256 treeModel->setAppropriate( EntryCol, Qtx::Shown );
257 m->unregisterColumn( getApp()->objectBrowser(), EntryCol );
259 return CAM_Module::deactivateModule( study );
263 void LightApp_Module::MenuItem()
268 void LightApp_Module::createPreferences()
273 void LightApp_Module::preferencesChanged( const QString&, const QString& )
277 /*!Gets application.*/
278 LightApp_Application* LightApp_Module::getApp() const
280 return (LightApp_Application*)application();
284 * \brief Update something in accordance with update flags
285 * \param theFlags - update flags
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
291 void LightApp_Module::update( const int theFlags )
293 if ( theFlags & UF_Model )
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() ) );
300 if ( theFlags & UF_ObjBrowser )
301 getApp()->objectBrowser()->updateTree( 0 );
303 if ( theFlags & UF_Controls )
305 if ( theFlags & UF_Viewer )
307 if ( SUIT_ViewManager* viewMgr = getApp()->activeViewManager() )
308 if ( SUIT_ViewWindow* viewWnd = viewMgr->getActiveView() )
310 #ifndef DISABLE_VTKVIEWER
311 #ifndef DISABLE_SALOMEOBJECT
312 if ( viewWnd->inherits( "SVTK_ViewWindow" ) )
313 ( (SVTK_ViewWindow*)viewWnd )->Repaint();
315 if ( viewWnd->inherits( "VTKViewer_ViewWindow" ) )
316 ( (VTKViewer_ViewWindow*)viewWnd )->Repaint();
319 #ifndef DISABLE_OCCVIEWER
320 if ( viewWnd->inherits( "OCCViewer_ViewWindow" ) )
321 ( (OCCViewer_ViewWindow*)viewWnd )->getViewPort()->onUpdate();
323 #ifndef DISABLE_PLOT2DVIEWER
324 if ( viewWnd->inherits( "Plot2d_ViewWindow" ) )
325 ( (Plot2d_ViewWindow*)viewWnd )->getViewFrame()->Repaint();
327 #ifndef DISABLE_GLVIEWER
328 if ( viewWnd->inherits( "GLViewer_ViewFrame" ) )
329 ( (GLViewer_ViewFrame*)viewWnd )->getViewPort()->onUpdate();
335 * \brief Updates controls
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.
340 void LightApp_Module::updateControls()
344 /*!Create new instance of data model and return it.*/
345 CAM_DataModel* LightApp_Module::createDataModel()
347 return new LightApp_DataModel( this );
350 /*!Create and return instance of LightApp_Selection.*/
351 LightApp_Selection* LightApp_Module::createSelection() const
353 return new LightApp_Selection();
357 void LightApp_Module::onModelOpened()
362 void LightApp_Module::onModelSaved()
367 void LightApp_Module::onModelClosed()
371 /*!Gets popup manager.(create if not exist)*/
372 QtxPopupMgr* LightApp_Module::popupMgr()
376 myPopupMgr = new QtxPopupMgr( 0, this );
379 SUIT_Desktop* d = application()->desktop();
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 );
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 );
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 );
410 #ifndef DISABLE_OCCVIEWER
411 #ifndef DISABLE_SALOMEOBJECT
412 viewers.append( SOCC_Viewer::Type() );
414 viewers.append( OCCViewer_Viewer::Type() );
417 #ifndef DISABLE_VTKVIEWER
418 #ifndef DISABLE_SALOMEOBJECT
419 viewers.append( SVTK_Viewer::Type() );
421 viewers.append( VTKViewer_Viewer::Type() );
424 #ifndef DISABLE_PLOT2DVIEWER
425 #ifndef DISABLE_SALOMEOBJECT
426 viewers.append( SPlot2d_Viewer::Type() );
428 viewers.append( Plot2d_Viewer::Type() );
432 if( !viewers.isEmpty() )
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 );
439 myPopupMgr->setRule( eraseAll, QString( "client in %1" ).arg( strViewers ), QtxPopupMgr::VisibleRule );
445 /*!Gets preferences.*/
446 LightApp_Preferences* LightApp_Module::preferences() const
448 LightApp_Preferences* pref = 0;
450 pref = getApp()->preferences();
454 /*!Add preference to preferences.*/
455 int LightApp_Module::addPreference( const QString& label )
457 LightApp_Preferences* pref = preferences();
461 int catId = pref->addPreference( moduleName(), -1 );
465 return pref->addPreference( label, catId );
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 )
472 LightApp_Preferences* pref = preferences();
476 return pref->addPreference( moduleName(), label, pId, type, section, param );
479 /*!Gets property of preferences.*/
480 QVariant LightApp_Module::preferenceProperty( const int id, const QString& prop ) const
483 LightApp_Preferences* pref = preferences();
485 var = pref->itemProperty( prop, id );
489 /*!Set property of preferences.*/
490 void LightApp_Module::setPreferenceProperty( const int id, const QString& prop, const QVariant& var )
492 LightApp_Preferences* pref = preferences();
494 pref->setItemProperty( prop, var, id );
498 * \brief Starts operation with given identifier
499 * \param id - identifier of operation to be started
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
505 void LightApp_Module::startOperation( const int id )
507 LightApp_Operation* op = 0;
508 if( myOperations.contains( id ) )
509 op = myOperations[ id ];
512 op = createOperation( id );
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() ) );
524 // be sure that operation has correct study pointer
525 op->setStudy( application() ? application()->activeStudy() : 0 );
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
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
539 LightApp_Operation* LightApp_Module::createOperation( const int id ) const
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 );
557 * \brief Virtual protected slot called when operation stopped
558 * \param theOp - stopped operation
560 * Virtual protected slot called when operation stopped. Redefine this slot if you want to
561 * perform actions after stopping operation
563 void LightApp_Module::onOperationStopped( SUIT_Operation* /*theOp*/ )
568 * \brief Virtual protected slot called when operation destroyed
569 * \param theOp - destroyed operation
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
575 void LightApp_Module::onOperationDestroyed()
577 const QObject* s = sender();
578 if( s && s->inherits( "LightApp_Operation" ) )
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 )
586 myOperations.remove( anIt.key() );
593 Must be redefined in order to use standard displayer mechanism
594 \return displayer of module
596 LightApp_Displayer* LightApp_Module::displayer()
602 SLOT: called on activating of standard operations show/hide
604 void LightApp_Module::onShowHide()
606 if( !sender()->inherits( "QAction" ) || !popupMgr() )
609 QAction* act = ( QAction* )sender();
610 int id = actionId( act );
612 startOperation( id );
616 virtual SLOT: called on view manager adding
618 void LightApp_Module::onViewManagerAdded( SUIT_ViewManager* )
623 virtual SLOT: called on view manager removing
625 void LightApp_Module::onViewManagerRemoved( SUIT_ViewManager* )
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
635 LightApp_Operation* LightApp_Module::operation( const int id ) const
637 return myOperations.contains( id ) ? myOperations[id] : 0;