1 // Copyright (C) 2007-2012 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
23 // File: LightApp_Module.cxx
24 // Created: 6/20/2005 16:30:56 AM
27 #include "LightApp_Module.h"
29 #include "CAM_Application.h"
31 #include "LightApp_Application.h"
32 #include "LightApp_DataModel.h"
33 #include "LightApp_DataObject.h"
34 #include "LightApp_Study.h"
35 #include "LightApp_Preferences.h"
36 #include "LightApp_Selection.h"
37 #include "LightApp_Operation.h"
38 #include "LightApp_SwitchOp.h"
39 #include "LightApp_UpdateFlags.h"
40 #include "LightApp_ShowHideOp.h"
41 #include "LightApp_SelectionMgr.h"
43 #include <SUIT_Study.h>
44 #include <SUIT_DataObject.h>
45 #include <SUIT_DataBrowser.h>
46 #include <SUIT_Operation.h>
47 #include <SUIT_ViewManager.h>
48 #include <SUIT_ResourceMgr.h>
49 #include <SUIT_ShortcutMgr.h>
50 #include <SUIT_Desktop.h>
51 #include <SUIT_TreeModel.h>
53 #ifndef DISABLE_SALOMEOBJECT
54 #include <SALOME_ListIO.hxx>
55 #include <SALOME_ListIteratorOfListIO.hxx>
58 #ifndef DISABLE_VTKVIEWER
59 #ifndef DISABLE_SALOMEOBJECT
60 #include <SVTK_ViewWindow.h>
61 #include <SVTK_ViewModel.h>
63 #include <VTKViewer_ViewWindow.h>
65 #include <VTKViewer_ViewModel.h>
67 #ifndef DISABLE_OCCVIEWER
68 #include <OCCViewer_ViewWindow.h>
69 #include <OCCViewer_ViewPort3d.h>
70 #ifndef DISABLE_SALOMEOBJECT
71 #include <SOCC_ViewModel.h>
73 #include <OCCViewer_ViewModel.h>
76 #ifndef DISABLE_GLVIEWER
77 #include <GLViewer_ViewFrame.h>
78 #include <GLViewer_ViewPort.h>
80 #ifndef DISABLE_PLOT2DVIEWER
81 #include <Plot2d_ViewWindow.h>
82 #include <Plot2d_ViewFrame.h>
83 #ifndef DISABLE_SALOMEOBJECT
84 #include <SPlot2d_ViewModel.h>
86 #include <Plot2d_ViewModel.h>
90 #include <QtxPopupMgr.h>
94 #include <QStringList>
99 LightApp_Module::LightApp_Module( const QString& name )
100 : CAM_Module( name ),
111 LightApp_Module::~LightApp_Module()
117 /*!Initialize module.*/
118 void LightApp_Module::initialize( CAM_Application* app )
120 CAM_Module::initialize( app );
122 SUIT_ResourceMgr* resMgr = app ? app->resourceMgr() : 0;
124 resMgr->raiseTranslators( name() );
128 void LightApp_Module::windows( QMap<int, int>& ) const
133 void LightApp_Module::viewManagers( QStringList& ) const
137 /*!Context menu popup.*/
138 void LightApp_Module::contextMenuPopup( const QString& client, QMenu* menu, QString& /*title*/ )
140 LightApp_Selection* sel = createSelection();
141 sel->init( client, getApp()->selectionMgr() );
143 popupMgr()->setSelection( sel );
144 popupMgr()->setMenu( menu );
145 popupMgr()->updateMenu();
148 /*!Update object browser.
149 * For updating model or whole object browser use update() method can be used.
151 void LightApp_Module::updateObjBrowser( bool theIsUpdateDataModel,
152 SUIT_DataObject* theDataObject )
154 bool upd = getApp()->objectBrowser()->autoUpdate();
155 getApp()->objectBrowser()->setAutoUpdate( false );
157 if( theIsUpdateDataModel ){
158 if( CAM_DataModel* aDataModel = dataModel() ){
159 if ( LightApp_DataModel* aModel = dynamic_cast<LightApp_DataModel*>( aDataModel ) ) {
160 //SUIT_DataObject* aParent = NULL;
161 //if(theDataObject && theDataObject != aDataModel->root())
162 // aParent = theDataObject->parent();
164 LightApp_DataObject* anObject = dynamic_cast<LightApp_DataObject*>(theDataObject);
165 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>(getApp()->activeStudy());
166 aModel->update( anObject, aStudy );
171 getApp()->objectBrowser()->setAutoUpdate( upd );
172 getApp()->objectBrowser()->updateTree( 0, false );
176 void LightApp_Module::selectionChanged()
180 /*! \brief If return false, selection will be cleared at module activation
182 bool LightApp_Module::isSelectionCompatible()
184 // return true if selected objects belong to this module
185 bool isCompatible = true;
186 #ifndef DISABLE_SALOMEOBJECT
187 SALOME_ListIO selected;
188 if ( LightApp_SelectionMgr *Sel = getApp()->selectionMgr() )
189 Sel->selectedObjects( selected );
191 LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( getApp()->activeStudy() );
192 LightApp_DataObject* aRoot = dynamic_cast<LightApp_DataObject*>( dataModel()->root() );
193 if ( aStudy && aRoot ) {
195 QString moduleDataType = aRoot->componentDataType();
196 // check data type of selection
197 SALOME_ListIteratorOfListIO It( selected );
198 for ( ; isCompatible && It.More(); It.Next()) {
199 Handle(SALOME_InteractiveObject)& io = It.Value();
200 isCompatible = ( aStudy->componentDataType( io->getEntry() ) == moduleDataType );
207 /*!Activate module.*/
208 bool LightApp_Module::activateModule( SUIT_Study* study )
210 bool res = CAM_Module::activateModule( study );
212 if ( !isSelectionCompatible() )// PAL19290, PAL18352
213 getApp()->selectionMgr()->clearSelected();
215 if ( res && application() && application()->resourceMgr() )
216 application()->resourceMgr()->raiseTranslators( name() );
218 connect( application(), SIGNAL( viewManagerAdded( SUIT_ViewManager* ) ),
219 this, SLOT( onViewManagerAdded( SUIT_ViewManager* ) ) );
220 connect( application(), SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
221 this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) );
223 if ( mySwitchOp == 0 )
224 mySwitchOp = new LightApp_SwitchOp( this );
226 // Enable Display and Erase actions
227 if ( action(myDisplay) )
228 action(myDisplay)->setEnabled(true);
229 if ( action(myErase) )
230 action(myErase)->setEnabled(true);
232 application()->shortcutMgr()->setSectionEnabled( moduleName() );
234 /* BUG 0020498 : The Entry column is always shown at module activation
235 The registration of column is moved into LightApp_Application
237 QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
238 LightApp_DataModel* m = dynamic_cast<LightApp_DataModel*>( dataModel() );
241 SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( getApp()->objectBrowser()->model() );
242 m->registerColumn( getApp()->objectBrowser(), EntryCol, LightApp_DataObject::EntryId );
243 treeModel->setAppropriate( EntryCol, Qtx::Toggled );
248 /*!Deactivate module.*/
249 bool LightApp_Module::deactivateModule( SUIT_Study* study )
254 disconnect( application(), SIGNAL( viewManagerAdded( SUIT_ViewManager* ) ),
255 this, SLOT( onViewManagerAdded( SUIT_ViewManager* ) ) );
256 disconnect( application(), SIGNAL( viewManagerRemoved( SUIT_ViewManager* ) ),
257 this, SLOT( onViewManagerRemoved( SUIT_ViewManager* ) ) );
259 // abort all operations
260 MapOfOperation::const_iterator anIt;
261 for( anIt = myOperations.begin(); anIt != myOperations.end(); anIt++ ) {
262 anIt.value()->abort();
265 // Disable Display and Erase action
266 if ( action(myDisplay) )
267 action(myDisplay)->setEnabled(false);
268 if ( action(myErase) )
269 action(myErase)->setEnabled(false);
271 application()->shortcutMgr()->setSectionEnabled( moduleName(), false );
273 /* BUG 0020498 : The Entry column is always shown at module activation
274 QString EntryCol = QObject::tr( "ENTRY_COLUMN" );
275 LightApp_DataModel* m = dynamic_cast<LightApp_DataModel*>( dataModel() );
278 SUIT_AbstractModel* treeModel = dynamic_cast<SUIT_AbstractModel*>( getApp()->objectBrowser()->model() );
280 treeModel->setAppropriate( EntryCol, Qtx::Shown );
281 m->unregisterColumn( getApp()->objectBrowser(), EntryCol );
284 return CAM_Module::deactivateModule( study );
288 void LightApp_Module::MenuItem()
293 void LightApp_Module::createPreferences()
298 void LightApp_Module::preferencesChanged( const QString&, const QString& )
303 void LightApp_Module::message( const QString& )
307 /*!Gets application.*/
308 LightApp_Application* LightApp_Module::getApp() const
310 return (LightApp_Application*)application();
314 * \brief Update something in accordance with update flags
315 * \param theFlags - update flags
317 * Update viewer or/and object browser etc. in accordance with update flags ( see
318 * LightApp_UpdateFlags enumeration ). Derived modules can redefine this method for their
321 void LightApp_Module::update( const int theFlags )
323 if ( theFlags & UF_Model )
325 if( CAM_DataModel* aDataModel = dataModel() )
326 if( LightApp_DataModel* aModel = dynamic_cast<LightApp_DataModel*>( aDataModel ) )
327 aModel->update( 0, dynamic_cast<LightApp_Study*>( getApp()->activeStudy() ) );
330 if ( theFlags & UF_ObjBrowser )
331 getApp()->objectBrowser()->updateTree( 0 );
333 if ( theFlags & UF_Controls )
335 if ( theFlags & UF_Viewer )
337 if ( SUIT_ViewManager* viewMgr = getApp()->activeViewManager() )
338 if ( SUIT_ViewWindow* viewWnd = viewMgr->getActiveView() )
340 #ifndef DISABLE_VTKVIEWER
341 #ifndef DISABLE_SALOMEOBJECT
342 if ( viewWnd->inherits( "SVTK_ViewWindow" ) )
343 ( (SVTK_ViewWindow*)viewWnd )->Repaint();
345 if ( viewWnd->inherits( "VTKViewer_ViewWindow" ) )
346 ( (VTKViewer_ViewWindow*)viewWnd )->Repaint();
349 #ifndef DISABLE_OCCVIEWER
350 if ( viewWnd->inherits( "OCCViewer_ViewWindow" ) )
351 ( (OCCViewer_ViewWindow*)viewWnd )->getViewPort()->onUpdate();
353 #ifndef DISABLE_PLOT2DVIEWER
354 if ( viewWnd->inherits( "Plot2d_ViewWindow" ) )
355 ( (Plot2d_ViewWindow*)viewWnd )->getViewFrame()->Repaint();
357 #ifndef DISABLE_GLVIEWER
358 if ( viewWnd->inherits( "GLViewer_ViewFrame" ) )
359 ( (GLViewer_ViewFrame*)viewWnd )->getViewPort()->onUpdate();
365 * \brief Updates controls
367 * Updates (i.e. disable/enable) controls states (menus, tool bars etc.). This method is
368 * called from update( UF_Controls ). You may redefine it in concrete module.
370 void LightApp_Module::updateControls()
374 /*!Create new instance of data model and return it.*/
375 CAM_DataModel* LightApp_Module::createDataModel()
377 return new LightApp_DataModel( this );
380 /*!Create and return instance of LightApp_Selection.*/
381 LightApp_Selection* LightApp_Module::createSelection() const
383 return new LightApp_Selection();
387 void LightApp_Module::onModelOpened()
392 void LightApp_Module::onModelSaved()
397 void LightApp_Module::onModelClosed()
401 /*!Gets popup manager.(create if not exist)*/
402 QtxPopupMgr* LightApp_Module::popupMgr()
406 myPopupMgr = new QtxPopupMgr( 0, this );
409 SUIT_Desktop* d = application()->desktop();
412 *disp = createAction( -1, tr( "TOP_SHOW" ), p, tr( "MEN_SHOW" ), tr( "STB_SHOW" ),
413 0, d, false, this, SLOT( onShowHide() ), QString("General:Show object(s)") ),
414 *erase = createAction( -1, tr( "TOP_HIDE" ), p, tr( "MEN_HIDE" ), tr( "STB_HIDE" ),
415 0, d, false, this, SLOT( onShowHide() ) , QString("General:Hide object(s)") ),
416 *dispOnly = createAction( -1, tr( "TOP_DISPLAY_ONLY" ), p, tr( "MEN_DISPLAY_ONLY" ), tr( "STB_DISPLAY_ONLY" ),
417 0, d, false, this, SLOT( onShowHide() ) ),
418 *eraseAll = createAction( -1, tr( "TOP_ERASE_ALL" ), p, tr( "MEN_ERASE_ALL" ), tr( "STB_ERASE_ALL" ),
419 0, d, false, this, SLOT( onShowHide() ) );
420 myDisplay = actionId( disp );
421 myErase = actionId( erase );
422 myDisplayOnly = actionId( dispOnly );
423 myEraseAll = actionId( eraseAll );
425 myPopupMgr->insert( disp, -1, 0 );
426 myPopupMgr->insert( erase, -1, 0 );
427 myPopupMgr->insert( dispOnly, -1, 0 );
428 myPopupMgr->insert( eraseAll, -1, 0 );
429 myPopupMgr->insert( separator(), -1, 0 );
431 QString oneAndNotActive = "( count( $component ) = 1 ) and ( not( activeModule in $component ) )";
432 QString uniform = "true in $canBeDisplayed and %1 and ( activeModule = '%2' )";
433 uniform = uniform.arg( oneAndNotActive ).arg( name() );
434 myPopupMgr->setRule( disp, /*QString( "( not isVisible ) and " ) + */ uniform, QtxPopupMgr::VisibleRule );
435 myPopupMgr->setRule( erase, /*QString( "( isVisible ) and " ) + */ uniform, QtxPopupMgr::VisibleRule );
436 myPopupMgr->setRule( dispOnly, uniform, QtxPopupMgr::VisibleRule );
440 #ifndef DISABLE_OCCVIEWER
441 #ifndef DISABLE_SALOMEOBJECT
442 viewers.append( SOCC_Viewer::Type() );
444 viewers.append( OCCViewer_Viewer::Type() );
447 #ifndef DISABLE_VTKVIEWER
448 #ifndef DISABLE_SALOMEOBJECT
449 viewers.append( SVTK_Viewer::Type() );
451 viewers.append( VTKViewer_Viewer::Type() );
454 #ifndef DISABLE_PLOT2DVIEWER
455 #ifndef DISABLE_SALOMEOBJECT
456 viewers.append( SPlot2d_Viewer::Type() );
458 viewers.append( Plot2d_Viewer::Type() );
462 if( !viewers.isEmpty() )
464 QString strViewers = "{ ", temp = "'%1' ";
465 QStringList::const_iterator anIt = viewers.begin(), aLast = viewers.end();
466 for( ; anIt!=aLast; anIt++ )
467 strViewers+=temp.arg( *anIt );
469 myPopupMgr->setRule( eraseAll, QString( "client in %1" ).arg( strViewers ), QtxPopupMgr::VisibleRule );
475 /*!Gets preferences.*/
476 LightApp_Preferences* LightApp_Module::preferences() const
478 LightApp_Preferences* pref = 0;
480 pref = getApp()->preferences();
484 /*!Add preference to preferences.*/
485 int LightApp_Module::addPreference( const QString& label )
487 LightApp_Preferences* pref = preferences();
491 int catId = pref->addPreference( moduleName(), -1 );
495 return pref->addPreference( label, catId );
498 /*!Add preference to preferences.*/
499 int LightApp_Module::addPreference( const QString& label, const int pId, const int type,
500 const QString& section, const QString& param )
502 LightApp_Preferences* pref = preferences();
506 return pref->addPreference( moduleName(), label, pId, type, section, param );
509 /*!Gets property of preferences.*/
510 QVariant LightApp_Module::preferenceProperty( const int id, const QString& prop ) const
513 LightApp_Preferences* pref = preferences();
515 var = pref->itemProperty( prop, id );
519 /*!Set property of preferences.*/
520 void LightApp_Module::setPreferenceProperty( const int id, const QString& prop, const QVariant& var )
522 LightApp_Preferences* pref = preferences();
524 pref->setItemProperty( prop, var, id );
528 * \brief Starts operation with given identifier
529 * \param id - identifier of operation to be started
531 * Module stores operations in map. This method starts operation by id.
532 * If operation isn't in map, then it will be created by createOperation method
533 * and will be inserted to map
535 void LightApp_Module::startOperation( const int id )
537 LightApp_Operation* op = 0;
538 if( myOperations.contains( id ) && reusableOperation( id ) )
539 op = myOperations[ id ];
542 op = createOperation( id );
545 myOperations.insert( id, op );
546 op->setModule( this );
547 connect( op, SIGNAL( stopped( SUIT_Operation* ) ), this, SLOT( onOperationStopped( SUIT_Operation* ) ) );
548 connect( op, SIGNAL( destroyed() ), this, SLOT( onOperationDestroyed() ) );
554 // be sure that operation has correct study pointer
555 op->setStudy( application() ? application()->activeStudy() : 0 );
561 * \brief Creates operation with given identifier
562 * \param id - identifier of operation to be started
563 * \return Pointer on created operation or NULL if operation is not created
565 * Creates operation with given id. You should not call this method, it will be called
566 * automatically from startOperation. You may redefine this method in concrete module to
569 LightApp_Operation* LightApp_Module::createOperation( const int id ) const
575 return new LightApp_ShowHideOp( LightApp_ShowHideOp::DISPLAY );
576 else if( id==myErase )
577 return new LightApp_ShowHideOp( LightApp_ShowHideOp::ERASE );
578 else if( id==myDisplayOnly )
579 return new LightApp_ShowHideOp( LightApp_ShowHideOp::DISPLAY_ONLY );
580 else if( id==myEraseAll )
581 return new LightApp_ShowHideOp( LightApp_ShowHideOp::ERASE_ALL );
587 * \brief Virtual protected slot called when operation stopped
588 * \param theOp - stopped operation
590 * Virtual protected slot called when operation stopped. Redefine this slot if you want to
591 * perform actions after stopping operation
593 void LightApp_Module::onOperationStopped( SUIT_Operation* /*theOp*/ )
598 * \brief Virtual protected slot called when operation destroyed
599 * \param theOp - destroyed operation
601 * Virtual protected slot called when operation destroyed. Redefine this slot if you want to
602 * perform actions after destroying operation. Base implementation removes pointer on
603 * destroyed operation from the map of operations
605 void LightApp_Module::onOperationDestroyed()
607 const QObject* s = sender();
608 if( s && s->inherits( "LightApp_Operation" ) )
610 const LightApp_Operation* op = ( LightApp_Operation* )s;
611 MapOfOperation::const_iterator anIt = myOperations.begin(),
612 aLast = myOperations.end();
613 for( ; anIt!=aLast; anIt++ )
614 if( anIt.value()==op )
616 myOperations.remove( anIt.key() );
623 Must be redefined in order to use standard displayer mechanism
624 \return displayer of module
626 LightApp_Displayer* LightApp_Module::displayer()
632 SLOT: called on activating of standard operations show/hide
634 void LightApp_Module::onShowHide()
636 if( !sender()->inherits( "QAction" ) || !popupMgr() )
639 QAction* act = ( QAction* )sender();
640 int id = actionId( act );
642 startOperation( id );
646 virtual SLOT: called on view manager adding
648 void LightApp_Module::onViewManagerAdded( SUIT_ViewManager* )
653 virtual SLOT: called on view manager removing
655 void LightApp_Module::onViewManagerRemoved( SUIT_ViewManager* )
660 \brief Returns instance of operation by its id; if there is no operation
661 corresponding to this id, null pointer is returned
662 \param id - operation id
663 \return operation instance
665 LightApp_Operation* LightApp_Module::operation( const int id ) const
667 return myOperations.contains( id ) ? myOperations[id] : 0;
671 virtual method called to manage the same operations
673 bool LightApp_Module::reusableOperation( const int id )
680 \return true if module can copy the current selection
682 bool LightApp_Module::canCopy() const
689 \return true if module can paste previously copied data
691 bool LightApp_Module::canPaste() const
698 \brief Copies the current selection into clipboard
700 void LightApp_Module::copy()
706 \brief Pastes the current data in the clipboard
708 void LightApp_Module::paste()
714 \return true if module allows dragging the given object
716 bool LightApp_Module::isDraggable( const SUIT_DataObject* /*what*/ ) const
723 \return true if module allows dropping one or more objects (currently selected) on the object \c where
725 bool LightApp_Module::isDropAccepted( const SUIT_DataObject* /*where*/ ) const
732 Complete drag-n-drop operation by processing objects \a what being dragged, dropped to the line \a row
733 within the object \a where. The drop action being performed is specified by \a action.
735 void LightApp_Module::dropObjects( const DataObjectList& /*what*/, SUIT_DataObject* /*where*/,
736 const int /*row*/, Qt::DropAction /*action*/ )
741 \brief Return \c true if object can be renamed
743 bool LightApp_Module::renameAllowed( const QString& /*entry*/ ) const
749 Rename object by entry.
750 \param entry entry of the object
751 \param name new name of the object
752 \brief Return \c true if rename operation finished successfully, \c false otherwise.
754 bool LightApp_Module::renameObject( const QString& /*entry*/, const QString& /*name*/ )