1 // PARAVIS : ParaView wrapper SALOME module
3 // Copyright (C) 2003 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 : PVGUI_Module.cxx
23 // Author : Julia DOROVSKIKH
26 #include "PVGUI_Module.h"
27 #include "PVGUI_Module_impl.h"
28 #include "PVGUI_ProcessModuleHelper.h"
29 #include "PVGUI_ViewModel.h"
30 #include "PVGUI_ViewManager.h"
31 #include "PVGUI_ViewWindow.h"
33 #include <SUIT_Desktop.h>
34 #include <SUIT_MessageBox.h>
35 #include <SUIT_ResourceMgr.h>
36 #include <SUIT_Session.h>
37 #include <LightApp_Application.h>
38 #include <LightApp_SelectionMgr.h>
39 #include <QtxActionMenuMgr.h>
40 #include <QtxActionToolMgr.h>
43 #include <QApplication>
49 #include <QInputDialog>
52 #include <QStringList>
56 #include <pqApplicationCore.h>
57 #include <pqActiveServer.h>
58 #include <pqActiveView.h>
59 #include <pqClientAboutDialog.h>
60 #include <pqObjectBuilder.h>
61 #include <pqOptions.h>
62 #include <pqRenderView.h>
63 #include <pqRubberBandHelper.h>
65 #include <pqServerManagerModel.h>
66 #include <pqServerResource.h>
67 #include <pqUndoStack.h>
68 #include <pqVCRController.h>
69 #include <pqViewManager.h>
70 #include <vtkPVMain.h>
71 #include <vtkProcessModule.h>
74 * Make sure all the kits register their classes with vtkInstantiator.
75 * Since ParaView uses Tcl wrapping, all of VTK is already compiled in
76 * anyway. The instantiators will add no more code for the linker to
80 #include <vtkCommonInstantiator.h>
81 #include <vtkFilteringInstantiator.h>
82 #include <vtkGenericFilteringInstantiator.h>
83 #include <vtkIOInstantiator.h>
84 #include <vtkImagingInstantiator.h>
85 #include <vtkInfovisInstantiator.h>
86 #include <vtkGraphicsInstantiator.h>
88 #include <vtkRenderingInstantiator.h>
89 #include <vtkVolumeRenderingInstantiator.h>
90 #include <vtkHybridInstantiator.h>
91 #include <vtkParallelInstantiator.h>
93 #include <vtkPVServerCommonInstantiator.h>
94 #include <vtkPVFiltersInstantiator.h>
95 #include <vtkPVServerManagerInstantiator.h>
96 #include <vtkClientServerInterpreter.h>
99 //----------------------------------------------------------------------------
100 // ClientServer wrapper initialization functions.
101 // Taken from ParaView sources (file pqMain.cxx)
102 extern "C" void vtkCommonCS_Initialize(vtkClientServerInterpreter*);
103 extern "C" void vtkFilteringCS_Initialize(vtkClientServerInterpreter*);
104 extern "C" void vtkGenericFilteringCS_Initialize(vtkClientServerInterpreter*);
105 extern "C" void vtkImagingCS_Initialize(vtkClientServerInterpreter*);
106 extern "C" void vtkInfovisCS_Initialize(vtkClientServerInterpreter*);
107 extern "C" void vtkGraphicsCS_Initialize(vtkClientServerInterpreter*);
108 extern "C" void vtkIOCS_Initialize(vtkClientServerInterpreter*);
109 extern "C" void vtkRenderingCS_Initialize(vtkClientServerInterpreter*);
110 extern "C" void vtkVolumeRenderingCS_Initialize(vtkClientServerInterpreter*);
111 extern "C" void vtkHybridCS_Initialize(vtkClientServerInterpreter*);
112 extern "C" void vtkWidgetsCS_Initialize(vtkClientServerInterpreter*);
113 extern "C" void vtkParallelCS_Initialize(vtkClientServerInterpreter*);
114 extern "C" void vtkPVServerCommonCS_Initialize(vtkClientServerInterpreter*);
115 extern "C" void vtkPVFiltersCS_Initialize(vtkClientServerInterpreter*);
116 extern "C" void vtkXdmfCS_Initialize(vtkClientServerInterpreter *);
118 //----------------------------------------------------------------------------
119 void ParaViewInitializeInterpreter(vtkProcessModule* pm)
121 // Initialize built-in wrapper modules.
122 vtkCommonCS_Initialize(pm->GetInterpreter());
123 vtkFilteringCS_Initialize(pm->GetInterpreter());
124 vtkGenericFilteringCS_Initialize(pm->GetInterpreter());
125 vtkImagingCS_Initialize(pm->GetInterpreter());
126 vtkInfovisCS_Initialize(pm->GetInterpreter());
127 vtkGraphicsCS_Initialize(pm->GetInterpreter());
128 vtkIOCS_Initialize(pm->GetInterpreter());
129 vtkRenderingCS_Initialize(pm->GetInterpreter());
130 vtkVolumeRenderingCS_Initialize(pm->GetInterpreter());
131 vtkHybridCS_Initialize(pm->GetInterpreter());
132 vtkWidgetsCS_Initialize(pm->GetInterpreter());
133 vtkParallelCS_Initialize(pm->GetInterpreter());
134 vtkPVServerCommonCS_Initialize(pm->GetInterpreter());
135 vtkPVFiltersCS_Initialize(pm->GetInterpreter());
136 vtkXdmfCS_Initialize(pm->GetInterpreter());
139 vtkPVMain* PVGUI_Module::pqImplementation::myPVMain = 0;
140 pqOptions* PVGUI_Module::pqImplementation::myPVOptions = 0;
141 PVGUI_ProcessModuleHelper* PVGUI_Module::pqImplementation::myPVHelper = 0;
145 \brief Implementation of light (no-CORBA-engine)
146 SALOME module wrapping ParaView GUI.
150 \brief Constructor. Sets the default name for the module.
152 PVGUI_Module::PVGUI_Module()
153 : LightApp_Module( "PARAVIS" ),
155 mySelectionControlsTb( -1 ),
156 mySourcesMenuId( -1 ),
157 myFiltersMenuId( -1 )
164 PVGUI_Module::~PVGUI_Module()
169 \brief Initialize module. Creates menus, prepares context menu, etc.
170 \param app application instance
172 void PVGUI_Module::initialize( CAM_Application* app )
174 LightApp_Module::initialize( app );
176 // Uncomment to debug ParaView initialization
177 // "aa" used instead of "i" as GDB doesn't like "i" variables :)
185 // Initialize ParaView client
188 // Create GUI elements (menus, toolbars, dock widgets)
189 if ( !Implementation ){
190 LightApp_Application* anApp = getApp();
192 // Simulate ParaView client main window
193 Implementation = new pqImplementation( anApp->desktop() );
201 setupDockWidgetsContextMenu();
203 // Now that we're ready, initialize everything ...
204 Implementation->Core.initializeStates();
209 \brief Get list of compliant dockable GUI elements
210 \param m map to be filled in ("type":"default_position")
212 void PVGUI_Module::windows( QMap<int, int>& m ) const
214 m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
215 m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
216 // ParaView diagnostic output redirected here
217 m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
221 \brief Create custom popup menu selection object.
222 \return new selected object
224 /*LightApp_Selection* PVGUI_Module::createSelection() const
226 return new PVGUI_Selection();
230 \brief Create data model.
231 \return module specific data model
233 /*CAM_DataModel* PVGUI_Module::createDataModel()
235 return new PVGUI_DataModel( this );
239 \brief Static method, performs initialization of ParaView session.
240 \return \c true if ParaView has been initialized successfully, otherwise false
242 bool PVGUI_Module::pvInit()
244 if ( !pqImplementation::myPVMain ){
245 // Obtain command-line arguments
246 // Workaround to avoid pqOptions messages: pass only the executable path to vtkPVMain
248 QStringList args = QApplication::arguments();
249 char** argv = new char*[args.size()];
250 for ( QStringList::const_iterator it = args.begin(); argc < 1 && it != args.end(); it++, argc++ )
251 argv[argc] = strdup( (*it).toLatin1().constData() );
253 vtkPVMain::SetInitializeMPI(0); // pvClient never runs with MPI.
254 vtkPVMain::Initialize(&argc, &argv); // Perform any initializations.
256 // TODO: Set plugin dir from preferences
257 //QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
259 pqImplementation::myPVMain = vtkPVMain::New();
260 if ( !pqImplementation::myPVOptions )
261 pqImplementation::myPVOptions = pqOptions::New();
262 if ( !pqImplementation::myPVHelper )
263 pqImplementation::myPVHelper = PVGUI_ProcessModuleHelper::New();
265 pqImplementation::myPVOptions->SetProcessType(vtkPVOptions::PVCLIENT);
267 // This creates the Process Module and initializes it.
268 int ret = pqImplementation::myPVMain->Initialize(pqImplementation::myPVOptions,
269 pqImplementation::myPVHelper,
270 ParaViewInitializeInterpreter,
273 // Tell process module that we support Multiple connections.
274 // This must be set before starting the event loop.
275 vtkProcessModule::GetProcessModule()->SupportMultipleConnectionsOn();
276 ret = pqImplementation::myPVHelper->Run(pqImplementation::myPVOptions);
287 \brief Static method, cleans up ParaView session at application exit.
289 void PVGUI_Module::pvShutdown()
295 \brief Shows (toShow = true) or hides ParaView view window
297 void PVGUI_Module::showView( bool toShow )
299 LightApp_Application* anApp = getApp();
300 PVGUI_ViewManager* viewMgr = dynamic_cast<PVGUI_ViewManager*>( anApp->getViewManager( PVGUI_Viewer::Type(), false ) );
302 viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() );
303 anApp->addViewManager( viewMgr );
304 connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
305 anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
308 PVGUI_ViewWindow* pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->getActiveView() );
310 pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->createViewWindow() );
311 pvWnd->setMultiViewManager( &Implementation->Core.multiViewManager() );
314 pvWnd->setShown( toShow );
318 \brief Manage the label of Undo operation.
320 void PVGUI_Module::onUndoLabel( const QString& label )
322 action(UndoId)->setText(
323 label.isEmpty() ? tr("MEN_CANTUNDO") : QString(tr("MEN_UNDO_ACTION")).arg(label));
324 action(UndoId)->setStatusTip(
325 label.isEmpty() ? tr("MEN_CANTUNDO") : QString(tr("MEN_UNDO_ACTION_TIP")).arg(label));
329 \brief Manage the label of Redo operation.
331 void PVGUI_Module::onRedoLabel( const QString& label )
333 action(RedoId)->setText(
334 label.isEmpty() ? tr("MEN_CANTREDO") : QString(tr("MEN_REDO_ACTION")).arg(label));
335 action(RedoId)->setStatusTip(
336 label.isEmpty() ? tr("MEN_CANTREDO") : QString(tr("MEN_REDO_ACTION_TIP")).arg(label));
340 \brief Manage the label of Undo Camera operation.
342 void PVGUI_Module::onCameraUndoLabel( const QString& label )
344 action(CameraUndoId)->setText(
345 label.isEmpty() ? tr("MEN_CANT_CAMERA_UNDO") : QString(tr("MEN_CAMERA_UNDO_ACTION")).arg(label));
346 action(CameraUndoId)->setStatusTip(
347 label.isEmpty() ? tr("MEN_CANT_CAMERA_UNDO") : QString(tr("MEN_CAMERA_UNDO_ACTION_TIP")).arg(label));
351 \brief Manage the label of Redo Camera operation.
353 void PVGUI_Module::onCameraRedoLabel( const QString& label )
355 action(CameraRedoId)->setText(
356 label.isEmpty() ? tr("MEN_CANT_CAMERA_REDO") : QString(tr("MEN_CAMERA_REDO_ACTION")).arg(label));
357 action(CameraRedoId)->setStatusTip(
358 label.isEmpty() ? tr("MEN_CANT_CAMERA_REDO") : QString(tr("MEN_CAMERA_REDO_ACTION_TIP")).arg(label));
362 \brief Slot to delete all objects.
364 void PVGUI_Module::onDeleteAll()
366 pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
367 Implementation->Core.getApplicationUndoStack()->beginUndoSet("Delete All");
368 builder->destroyPipelineProxies();
369 Implementation->Core.getApplicationUndoStack()->endUndoSet();
373 \brief Slot to check/uncheck the action for corresponding selection mode.
375 void PVGUI_Module::onSelectionModeChanged( int mode )
377 if( toolMgr()->toolBar( mySelectionControlsTb )->isEnabled() ) {
378 if(mode == pqRubberBandHelper::SELECT) //surface selection
379 action(SelectCellsOnId)->setChecked(true);
380 else if(mode == pqRubberBandHelper::SELECT_POINTS) //surface selection
381 action(SelectPointsOnId)->setChecked(true);
382 else if(mode == pqRubberBandHelper::FRUSTUM)
383 action(SelectCellsThroughId)->setChecked(true);
384 else if(mode == pqRubberBandHelper::FRUSTUM_POINTS)
385 action(SelectPointsThroughId)->setChecked(true);
386 else if (mode == pqRubberBandHelper::BLOCKS)
387 action(SelectBlockId)->setChecked(true);
389 action(InteractId)->setChecked(true);
394 \brief Slot to manage the change of axis center.
396 void PVGUI_Module::onShowCenterAxisChanged( bool enabled )
398 action(ShowCenterId)->setEnabled(enabled);
399 action(ShowCenterId)->blockSignals(true);
400 pqRenderView* renView = qobject_cast<pqRenderView*>(
401 pqActiveView::instance().current());
402 action(ShowCenterId)->setChecked( renView ? renView->getCenterAxesVisibility() : false);
403 action(ShowCenterId)->blockSignals(false);
407 \brief Slot to set tooltips for the first anf the last frames, i.e. a time range of animation.
409 void PVGUI_Module::setTimeRanges( double start, double end )
411 action(FirstFrameId)->setToolTip(QString("First Frame (%1)").arg(start, 0, 'g'));
412 action(LastFrameId)->setToolTip(QString("Last Frame (%1)").arg(end, 0, 'g'));
416 \brief Slot to manage the plaing process of animation.
418 void PVGUI_Module::onPlaying( bool playing )
420 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
422 disconnect( action(PlayId), SIGNAL( triggered() ),
423 &Implementation->Core.VCRController(), SLOT( onPlay() ) );
424 connect( action(PlayId), SIGNAL( triggered() ),
425 &Implementation->Core.VCRController(), SLOT( onPause() ) );
426 action(PlayId)->setIcon(QIcon(resMgr->loadPixmap("ParaView",tr("ICON_PAUSE"),false)));
427 action(PlayId)->setText("Pa&use");
430 connect( action(PlayId), SIGNAL( triggered() ),
431 &Implementation->Core.VCRController(), SLOT( onPlay() ) );
432 disconnect( action(PlayId), SIGNAL( triggered() ),
433 &Implementation->Core.VCRController(), SLOT( onPause() ) );
434 action(PlayId)->setIcon(QIcon(resMgr->loadPixmap("ParaView",tr("ICON_PLAY"),false)));
435 action(PlayId)->setText("&Play");
438 Implementation->Core.setSelectiveEnabledState(!playing);
442 \brief Slot to add camera link.
444 void PVGUI_Module::onAddCameraLink()
446 pqView* vm = pqActiveView::instance().current();
447 pqRenderView* rm = qobject_cast<pqRenderView*>(vm);
448 if(rm) rm->linkToOtherView();
449 else SUIT_MessageBox::warning(getApp()->desktop(),
450 tr("WARNING"), tr("WRN_ADD_CAMERA_LINK"));
454 \brief Slot to show information about ParaView.
456 void PVGUI_Module::onHelpAbout()
458 pqClientAboutDialog* const dialog = new pqClientAboutDialog(getApp()->desktop());
459 dialog->setAttribute(Qt::WA_DeleteOnClose);
464 \brief Slot to show help for proxy.
466 void PVGUI_Module::showHelpForProxy( const QString& proxy )
468 // make sure assistant is ready
469 this->makeAssistant();
471 if(this->Implementation->AssistantClient) {
472 this->Implementation->AssistantClient->openAssistant();
473 QString page("%1/Documentation/%2.html");
474 page = page.arg(this->Implementation->DocumentationDir);
475 page = page.arg(proxy);
476 this->Implementation->AssistantClient->showPage(page);
480 QString Locate( const QString& appName )
482 QString app_dir = QCoreApplication::applicationDirPath();
483 const char* inst_dirs[] = {
489 for (const char** dir = inst_dirs; *dir; ++dir) {
490 QString path = app_dir;
493 //cout << "Checking : " << path.toAscii().data() << " ... ";
495 QFileInfo finfo (path);
496 if (finfo.exists()) {
497 //cout << " Success!" << endl;
500 //cout << " Failed" << endl;
502 return app_dir + QDir::separator() + appName;
506 \brief Initialized an assistant client.
508 void PVGUI_Module::makeAssistant()
510 if(this->Implementation->AssistantClient)
513 QString assistantExe;
516 const char* assistantName = "assistant";
518 const char* binDir = "\\";
519 const char* binDir1 = "\\..\\";
521 const char* binDir = "/bin/";
522 const char* binDir1 = "/bin/bin/";
525 QString helper = QString(getenv("PVHOME")) + binDir + QString("pqClientDocFinder.txt");
526 if(!QFile::exists(helper))
527 helper = QString(getenv("PVHOME")) + binDir1 + QString("pqClientDocFinder.txt");
528 if(QFile::exists(helper)) {
530 if(file.open(QIODevice::ReadOnly)) {
531 assistantExe = file.readLine().trimmed();
532 profileFile = file.readLine().trimmed();
533 // CMake escapes spaces, we need to unescape those.
534 assistantExe.replace("\\ ", " ");
535 profileFile.replace("\\ ", " ");
539 if(assistantExe.isEmpty()) {
540 assistantExe = ::Locate(assistantName);//assistantExe = ::Locate(assistantProgName);
542 QString assistant = QCoreApplication::applicationDirPath();
543 assistant += QDir::separator();
544 assistant += assistantName;
545 assistantExe = assistant;
549 this->Implementation->AssistantClient = new QAssistantClient(assistantExe, this);
550 QObject::connect(this->Implementation->AssistantClient, SIGNAL(error(const QString&)),
551 this, SLOT(assistantError(const QString&)));
554 args.append(QString("-profile"));
556 if(profileFile.isEmpty()) {
557 // see if help is bundled up with the application
558 QString profile = ::Locate("pqClient.adp");
559 /*QCoreApplication::applicationDirPath() + QDir::separator()
560 + QString("pqClient.adp");*/
562 if(QFile::exists(profile))
563 profileFile = profile;
566 if(profileFile.isEmpty() && getenv("PARAVIEW_HELP")) {
567 // not bundled, ask for help
568 args.append(getenv("PARAVIEW_HELP"));
570 else if(profileFile.isEmpty()) {
571 // no help, error out
572 SUIT_MessageBox::critical(getApp()->desktop(),"Help error", "Couldn't find"
573 " pqClient.adp.\nTry setting the PARAVIEW_HELP environment variable which"
574 " points to that file");
575 delete this->Implementation->AssistantClient;
579 QFileInfo fi(profileFile);
580 this->Implementation->DocumentationDir = fi.absolutePath();
582 args.append(profileFile);
584 this->Implementation->AssistantClient->setArguments(args);
588 \brief Slot to call the message handler with the critical message.
590 void PVGUI_Module::assistantError( const QString& error )
592 qCritical(error.toAscii().data());
596 \brief Slot to show the waiting state.
598 void PVGUI_Module::onPreAccept()
600 getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
601 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
605 \brief Slot to show the ready state.
607 void PVGUI_Module::onPostAccept()
609 getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
610 QTimer::singleShot(0, this, SLOT(endWaitCursor()));
614 \brief Slot to switch off wait cursor.
616 void PVGUI_Module::endWaitCursor()
618 QApplication::restoreOverrideCursor();
622 \brief Returns the ParaView multi-view manager.
624 pqViewManager* PVGUI_Module::getMultiViewManager() const
626 pqViewManager* aMVM = 0;
627 if ( Implementation )
628 aMVM = &Implementation->Core.multiViewManager();
633 \brief Processes QEvent::ActionAdded and QEvent::ActionRemoved from Lookmarks toolbar
634 in order to register/unregister this action in/from QtxActionToolMgr.
636 bool PVGUI_Module::eventFilter( QObject* theObject, QEvent* theEvent )
638 QToolBar* aTB = toolMgr()->toolBar(tr("TOOL_LOOKMARKS"));
639 if ( theObject == aTB ) {
641 if ( theEvent->type() == QEvent::ActionAdded ) {
642 QList<QAction*> anActns = aTB->actions();
643 for (int i = 0; i < anActns.size(); ++i)
644 if ( toolMgr()->actionId(anActns.at(i)) == -1 ) {
645 toolMgr()->setUpdatesEnabled(false);
646 createTool( anActns.at(i), tr("TOOL_LOOKMARKS") );
647 toolMgr()->setUpdatesEnabled(true);
651 if ( theEvent->type() == QEvent::ActionRemoved ) {
652 QList<QAction*> anActns = aTB->actions();
653 QIntList aIDL = toolMgr()->idList();
654 for (int i = 0; i < aIDL.size(); ++i) {
655 if ( toolMgr()->action(aIDL.at(i))->parent() == aTB
657 !anActns.contains( toolMgr()->action(aIDL.at(i)) ) ) {
658 toolMgr()->setUpdatesEnabled(false);
659 toolMgr()->unRegisterAction( aIDL.at(i) );
660 toolMgr()->remove( aIDL.at(i), tr("TOOL_LOOKMARKS") );
661 toolMgr()->setUpdatesEnabled(true);
668 return QObject::eventFilter( theObject, theEvent );
672 \brief Activate module.
673 \param study current study
674 \return \c true if activaion is done successfully or 0 to prevent
677 bool PVGUI_Module::activateModule( SUIT_Study* study )
679 bool isDone = LightApp_Module::activateModule( study );
680 if ( !isDone ) return false;
684 if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
685 if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
686 setMenuShown( true );
687 setToolShown( true );
689 toolMgr()->toolBar(tr("TOOL_LOOKMARKS"))->installEventFilter(this);
691 // Make default server connection
692 if ( Implementation )
693 Implementation->Core.makeDefaultConnectionIfNoneExists();
695 restoreDockWidgetsState();
702 \brief Deactivate module.
703 \param study current study
704 \return \c true if deactivaion is done successfully or 0 to prevent
705 deactivation on error
707 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
709 toolMgr()->toolBar(tr("TOOL_LOOKMARKS"))->removeEventFilter(this);
714 menuMgr()->hide(mySourcesMenuId);
715 menuMgr()->hide(myFiltersMenuId);
716 setMenuShown( false );
717 setToolShown( false );
719 saveDockWidgetsState();
721 return LightApp_Module::deactivateModule( study );
725 \fn CAM_Module* createModule();
726 \brief Export module instance (factory function).
727 \return new created instance of the module
731 #define PVGUI_EXPORT __declspec(dllexport)
737 PVGUI_EXPORT CAM_Module* createModule() {
738 return new PVGUI_Module();