]> SALOME platform Git repositories - modules/paravis.git/blob - src/PVGUI/PVGUI_Module.cxx
Salome HOME
Debugging Python initialization
[modules/paravis.git] / src / PVGUI / PVGUI_Module.cxx
1 // PARAVIS : ParaView wrapper SALOME module
2 //
3 // Copyright (C) 2003  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   : PVGUI_Module.cxx
23 // Author : Julia DOROVSKIKH
24 //
25
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"
32
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 <QtxActionToolMgr.h>
40
41 #include <QAction>
42 #include <QApplication>
43 #include <QCursor>
44 #include <QDir>
45 #include <QFile>
46 #include <QFileInfo>
47 #include <QIcon>
48 #include <QInputDialog>
49 #include <QStatusBar>
50 #include <QString>
51 #include <QStringList>
52 #include <QTimer>
53 #include <QToolBar>
54
55 #include <pqApplicationCore.h>
56 #include <pqActiveServer.h>
57 #include <pqActiveView.h>
58 #include <pqClientAboutDialog.h>
59 #include <pqObjectBuilder.h>
60 #include <pqOptions.h>
61 #include <pqRenderView.h>
62 #include <pqRubberBandHelper.h>
63 #include <pqServer.h>
64 #include <pqServerManagerModel.h>
65 #include <pqServerResource.h>
66 #include <pqUndoStack.h>
67 #include <pqVCRController.h>
68 #include <pqViewManager.h>
69 #include <vtkPVMain.h>
70 #include <vtkProcessModule.h>
71
72 /*
73  * Make sure all the kits register their classes with vtkInstantiator.
74  * Since ParaView uses Tcl wrapping, all of VTK is already compiled in
75  * anyway.  The instantiators will add no more code for the linker to
76  * collect.
77  */
78
79 #include <vtkCommonInstantiator.h>
80 #include <vtkFilteringInstantiator.h>
81 #include <vtkGenericFilteringInstantiator.h>
82 #include <vtkIOInstantiator.h>
83 #include <vtkImagingInstantiator.h>
84 #include <vtkInfovisInstantiator.h>
85 #include <vtkGraphicsInstantiator.h>
86
87 #include <vtkRenderingInstantiator.h>
88 #include <vtkVolumeRenderingInstantiator.h>
89 #include <vtkHybridInstantiator.h>
90 #include <vtkParallelInstantiator.h>
91
92 #include <vtkPVServerCommonInstantiator.h>
93 #include <vtkPVFiltersInstantiator.h>
94 #include <vtkPVServerManagerInstantiator.h>
95 #include <vtkClientServerInterpreter.h>
96
97
98 //----------------------------------------------------------------------------
99 // ClientServer wrapper initialization functions.
100 // Taken from ParaView sources (file pqMain.cxx)
101 extern "C" void vtkCommonCS_Initialize(vtkClientServerInterpreter*);
102 extern "C" void vtkFilteringCS_Initialize(vtkClientServerInterpreter*);
103 extern "C" void vtkGenericFilteringCS_Initialize(vtkClientServerInterpreter*);
104 extern "C" void vtkImagingCS_Initialize(vtkClientServerInterpreter*);
105 extern "C" void vtkInfovisCS_Initialize(vtkClientServerInterpreter*);
106 extern "C" void vtkGraphicsCS_Initialize(vtkClientServerInterpreter*);
107 extern "C" void vtkIOCS_Initialize(vtkClientServerInterpreter*);
108 extern "C" void vtkRenderingCS_Initialize(vtkClientServerInterpreter*);
109 extern "C" void vtkVolumeRenderingCS_Initialize(vtkClientServerInterpreter*);
110 extern "C" void vtkHybridCS_Initialize(vtkClientServerInterpreter*);
111 extern "C" void vtkWidgetsCS_Initialize(vtkClientServerInterpreter*);
112 extern "C" void vtkParallelCS_Initialize(vtkClientServerInterpreter*);
113 extern "C" void vtkPVServerCommonCS_Initialize(vtkClientServerInterpreter*);
114 extern "C" void vtkPVFiltersCS_Initialize(vtkClientServerInterpreter*);
115 extern "C" void vtkXdmfCS_Initialize(vtkClientServerInterpreter *);
116
117 //----------------------------------------------------------------------------
118 void ParaViewInitializeInterpreter(vtkProcessModule* pm)
119 {
120   // Initialize built-in wrapper modules.
121   vtkCommonCS_Initialize(pm->GetInterpreter());
122   vtkFilteringCS_Initialize(pm->GetInterpreter());
123   vtkGenericFilteringCS_Initialize(pm->GetInterpreter());
124   vtkImagingCS_Initialize(pm->GetInterpreter());
125   vtkInfovisCS_Initialize(pm->GetInterpreter());
126   vtkGraphicsCS_Initialize(pm->GetInterpreter());
127   vtkIOCS_Initialize(pm->GetInterpreter());
128   vtkRenderingCS_Initialize(pm->GetInterpreter());
129   vtkVolumeRenderingCS_Initialize(pm->GetInterpreter());
130   vtkHybridCS_Initialize(pm->GetInterpreter());
131   vtkWidgetsCS_Initialize(pm->GetInterpreter());
132   vtkParallelCS_Initialize(pm->GetInterpreter());
133   vtkPVServerCommonCS_Initialize(pm->GetInterpreter());
134   vtkPVFiltersCS_Initialize(pm->GetInterpreter());
135   vtkXdmfCS_Initialize(pm->GetInterpreter());
136 }
137
138 vtkPVMain*                 PVGUI_Module::pqImplementation::myPVMain = 0;
139 pqOptions*                 PVGUI_Module::pqImplementation::myPVOptions = 0;
140 PVGUI_ProcessModuleHelper* PVGUI_Module::pqImplementation::myPVHelper = 0;
141
142 /*!
143   \class PVGUI_Module
144   \brief Implementation of light (no-CORBA-engine) 
145          SALOME module wrapping ParaView GUI.
146 */
147
148 /*!
149   \brief Constructor. Sets the default name for the module.
150 */
151 PVGUI_Module::PVGUI_Module()
152   : LightApp_Module( "PARAVIS" ),
153     Implementation( 0 )
154 {
155 }
156
157 /*!
158   \brief Destructor.
159 */
160 PVGUI_Module::~PVGUI_Module()
161 {
162 }
163
164 /*!
165   \brief Initialize module. Creates menus, prepares context menu, etc.
166   \param app application instance
167 */
168 void PVGUI_Module::initialize( CAM_Application* app )
169 {
170   LightApp_Module::initialize( app );
171
172   // Uncomment to debug ParaView initialization
173   // "aa" used instead of "i" as GDB doesn't like "i" variables :)
174   /*
175   int aa = 1;
176   while( aa ){
177     aa = aa;
178   }
179   */
180   
181   pvInit();
182
183 }
184
185 /*!
186   \brief Get list of compliant dockable GUI elements
187   \param m map to be filled in ("type":"default_position")
188 */
189 void PVGUI_Module::windows( QMap<int, int>& m ) const
190 {
191   m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
192   m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
193   // ParaView diagnostic output redirected here
194   m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
195 }
196
197 /*!
198   \brief Create custom popup menu selection object.
199   \return new selected object
200 */
201 /*LightApp_Selection* PVGUI_Module::createSelection() const
202 {
203   return new PVGUI_Selection();
204 }*/
205
206 /*!
207   \brief Create data model.
208   \return module specific data model
209 */
210 /*CAM_DataModel* PVGUI_Module::createDataModel()
211 {
212   return new PVGUI_DataModel( this );
213 }*/
214
215 /*!
216   \brief Static method, performs initialization of ParaView session.
217   \return \c true if ParaView has been initialized successfully, otherwise false
218 */
219 bool PVGUI_Module::pvInit()
220 {
221   if ( !pqImplementation::myPVMain ){
222     // Obtain command-line arguments
223     int argc = 0;
224     QStringList args = QApplication::arguments();
225     char** argv = new char*[args.size()];
226     for ( QStringList::const_iterator it = args.begin(); argc < 1 && it != args.end(); it++, argc++ )
227       argv[argc] = strdup( (*it).toLatin1().constData() );
228
229     vtkPVMain::SetInitializeMPI(0);  // pvClient never runs with MPI.
230     vtkPVMain::Initialize(&argc, &argv); // Perform any initializations.
231
232     // TODO: Set plugin dir from preferences
233     //QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
234
235     pqImplementation::myPVMain = vtkPVMain::New();
236     if ( !pqImplementation::myPVOptions )
237       pqImplementation::myPVOptions = pqOptions::New();
238     if ( !pqImplementation::myPVHelper )
239       pqImplementation::myPVHelper = PVGUI_ProcessModuleHelper::New();
240
241     pqImplementation::myPVOptions->SetProcessType(vtkPVOptions::PVCLIENT);
242
243     // This creates the Process Module and initializes it.
244     int ret = pqImplementation::myPVMain->Initialize(pqImplementation::myPVOptions, 
245                                                      pqImplementation::myPVHelper, 
246                                                      ParaViewInitializeInterpreter,
247                                                      argc, argv);
248     if (!ret){
249       // Tell process module that we support Multiple connections.
250       // This must be set before starting the event loop.
251       vtkProcessModule::GetProcessModule()->SupportMultipleConnectionsOn();
252       ret = pqImplementation::myPVHelper->Run(pqImplementation::myPVOptions);
253     }
254
255     delete[] argv;
256     return !ret;
257   }
258   
259   return true;
260 }
261  
262 /*!
263   \brief Static method, cleans up ParaView session at application exit.
264 */
265 void PVGUI_Module::pvShutdown()
266 {
267   // TODO...
268 }  
269
270 /*!
271   \brief Shows (toShow = true) or hides ParaView view window
272 */
273 void PVGUI_Module::showView( bool toShow )
274 {
275   // TODO: check if ParaView view already exists
276   if ( !Implementation ){
277     LightApp_Application* anApp = getApp();
278     SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
279     PVGUI_ViewManager* viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() );
280     anApp->addViewManager( viewMgr );
281     connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
282              anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
283     //connect( viewMgr, SIGNAL( viewCreated( SUIT_ViewWindow* ) ), vm, SLOT( onViewCreated( SUIT_ViewWindow* ) ) );
284     //connect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ), this, SLOT( onViewDeleted( SUIT_ViewWindow* ) ) );
285     SUIT_ViewWindow* wnd = viewMgr->createViewWindow();  
286
287     // Simulate ParaView client main window
288     Implementation = new pqImplementation( anApp->desktop() );
289     PVGUI_ViewWindow* pvWnd = dynamic_cast<PVGUI_ViewWindow*>( wnd );
290     pvWnd->setMultiViewManager( &Implementation->Core.multiViewManager() );
291
292     setupDockWidgets();
293     
294     pvCreateActions();
295     pvCreateMenus();
296     pvCreateToolBars();
297     
298     setupDockWidgetsContextMenu();
299
300     // Now that we're ready, initialize everything ...
301     Implementation->Core.initializeStates();
302   }
303 }
304
305 /*!
306   \brief Manage the label of Undo operation.
307 */
308 void PVGUI_Module::onUndoLabel( const QString& label )
309 {
310   action(UndoId)->setText(
311     label.isEmpty() ? tr("Can't Undo") : QString(tr("&Undo %1")).arg(label));
312   action(UndoId)->setStatusTip(
313     label.isEmpty() ? tr("Can't Undo") : QString(tr("Undo %1")).arg(label));
314 }
315
316 /*!
317   \brief Manage the label of Redo operation.
318 */
319 void PVGUI_Module::onRedoLabel( const QString& label )
320 {
321   action(RedoId)->setText(
322     label.isEmpty() ? tr("Can't Redo") : QString(tr("&Redo %1")).arg(label));
323   action(RedoId)->setStatusTip(
324     label.isEmpty() ? tr("Can't Redo") : QString(tr("Redo %1")).arg(label));
325 }
326
327 /*!
328   \brief Manage the label of Undo Camera operation.
329 */
330 void PVGUI_Module::onCameraUndoLabel( const QString& label )
331 {
332   action(CameraUndoId)->setText(
333     label.isEmpty() ? tr("Can't Undo Camera") : QString(tr("U&ndo %1")).arg(label));
334   action(CameraUndoId)->setStatusTip(
335     label.isEmpty() ? tr("Can't Undo Camera") : QString(tr("Undo %1")).arg(label));
336 }
337
338 /*!
339   \brief Manage the label of Redo Camera operation.
340 */
341 void PVGUI_Module::onCameraRedoLabel( const QString& label )
342 {
343   action(CameraRedoId)->setText(
344     label.isEmpty() ? tr("Can't Redo Camera") : QString(tr("R&edo %1")).arg(label));
345   action(CameraRedoId)->setStatusTip(
346     label.isEmpty() ? tr("Can't Redo Camera") : QString(tr("Redo %1")).arg(label));
347 }
348
349 /*!
350   \brief Slot to delete all objects.
351 */
352 void PVGUI_Module::onDeleteAll()
353 {
354   pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
355   Implementation->Core.getApplicationUndoStack()->beginUndoSet("Delete All");
356   builder->destroyPipelineProxies();
357   Implementation->Core.getApplicationUndoStack()->endUndoSet();
358 }
359
360 /*!
361   \brief Slot to check/uncheck the action for corresponding selection mode.
362 */
363 void PVGUI_Module::onSelectionModeChanged( int mode )
364 {
365   if( toolMgr()->toolBar( mySelectionControlsTb )->isEnabled() ) {
366     if(mode == pqRubberBandHelper::SELECT) //surface selection
367       action(SelectCellsOnId)->setChecked(true);
368     else if(mode == pqRubberBandHelper::SELECT_POINTS) //surface selection
369       action(SelectPointsOnId)->setChecked(true);
370     else if(mode == pqRubberBandHelper::FRUSTUM)
371       action(SelectCellsThroughId)->setChecked(true);
372     else if(mode == pqRubberBandHelper::FRUSTUM_POINTS)
373       action(SelectPointsThroughId)->setChecked(true);
374     else if (mode == pqRubberBandHelper::BLOCKS)
375       action(SelectBlockId)->setChecked(true);
376     else // INTERACT
377       action(InteractId)->setChecked(true);
378   }
379 }
380
381 /*!
382   \brief Slot to manage the change of axis center.
383 */
384 void PVGUI_Module::onShowCenterAxisChanged( bool enabled )
385 {
386   action(ShowCenterId)->setEnabled(enabled);
387   action(ShowCenterId)->blockSignals(true);
388   pqRenderView* renView = qobject_cast<pqRenderView*>(
389     pqActiveView::instance().current());
390   action(ShowCenterId)->setChecked( renView ? renView->getCenterAxesVisibility() : false);
391   action(ShowCenterId)->blockSignals(false);
392 }
393
394 /*!
395   \brief Slot to set tooltips for the first anf the last frames, i.e. a time range of animation.
396 */
397 void PVGUI_Module::setTimeRanges( double start, double end )
398 {
399   action(FirstFrameId)->setToolTip(QString("First Frame (%1)").arg(start, 0, 'g'));
400   action(LastFrameId)->setToolTip(QString("Last Frame (%1)").arg(end, 0, 'g'));
401 }
402
403 /*!
404   \brief Slot to manage the plaing process of animation.
405 */
406 void PVGUI_Module::onPlaying( bool playing )
407 {
408   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
409   if(playing) {
410     disconnect( action(PlayId),                        SIGNAL( triggered() ),
411                 &Implementation->Core.VCRController(), SLOT( onPlay() ) );
412     connect( action(PlayId),                        SIGNAL( triggered() ),
413              &Implementation->Core.VCRController(), SLOT( onPause() ) );
414     action(PlayId)->setIcon(QIcon(resMgr->loadPixmap("ParaView",tr("ICON_PAUSE"),false)));
415     action(PlayId)->setText("Pa&use");
416   }
417   else {
418     connect( action(PlayId),                        SIGNAL( triggered() ),
419              &Implementation->Core.VCRController(), SLOT( onPlay() ) );
420     disconnect( action(PlayId),                        SIGNAL( triggered() ),
421                 &Implementation->Core.VCRController(), SLOT( onPause() ) );
422     action(PlayId)->setIcon(QIcon(resMgr->loadPixmap("ParaView",tr("ICON_PLAY"),false)));
423     action(PlayId)->setText("&Play");
424   }
425
426   Implementation->Core.setSelectiveEnabledState(!playing);
427 }
428
429 /*!
430   \brief Slot to add camera link.
431 */
432 void PVGUI_Module::onAddCameraLink()
433 {
434   pqView* vm = pqActiveView::instance().current();
435   pqRenderView* rm = qobject_cast<pqRenderView*>(vm);
436   if(rm) rm->linkToOtherView();
437   else SUIT_MessageBox::warning(getApp()->desktop(),
438                                 tr("WARNING"), tr("WRN_ADD_CAMERA_LINK"));
439 }
440
441 /*!
442   \brief Slot to show information about ParaView.
443 */
444 void PVGUI_Module::onHelpAbout()
445 {
446   pqClientAboutDialog* const dialog = new pqClientAboutDialog(getApp()->desktop());
447   dialog->setAttribute(Qt::WA_DeleteOnClose);
448   dialog->show();
449 }
450
451 /*!
452   \brief Slot to show help for proxy.
453 */
454 void PVGUI_Module::showHelpForProxy( const QString& proxy )
455 {
456   // make sure assistant is ready
457   this->makeAssistant();
458
459   if(this->Implementation->AssistantClient) {
460     this->Implementation->AssistantClient->openAssistant();
461     QString page("%1/Documentation/%2.html");
462     page = page.arg(this->Implementation->DocumentationDir);
463     page = page.arg(proxy);
464     this->Implementation->AssistantClient->showPage(page);
465   }
466 }
467
468 QString Locate( const QString& appName )
469 {
470   QString app_dir = QCoreApplication::applicationDirPath();
471   const char* inst_dirs[] = {
472     "/./",
473     "/../bin/",
474     "/../../bin/",
475     0
476   };
477   for (const char** dir = inst_dirs; *dir; ++dir) {
478     QString path = app_dir;
479     path += *dir;
480     path += appName;
481     //cout << "Checking : " << path.toAscii().data() << " ... ";
482     //cout.flush();
483     QFileInfo finfo (path);
484     if (finfo.exists()) {
485       //cout << " Success!" << endl;
486       return path;
487     }
488     //cout << " Failed" << endl;
489   }
490   return app_dir + QDir::separator() + appName;
491 }
492
493 /*!
494   \brief Initialized an assistant client.
495 */
496 void PVGUI_Module::makeAssistant()
497 {
498   if(this->Implementation->AssistantClient)
499     return;
500   
501   QString assistantExe;
502   QString profileFile;
503   
504   const char* assistantName = "assistant";
505 #ifdef WNT
506   const char* binDir = "\\";
507   const char* binDir1 = "\\..\\";
508 #else
509   const char* binDir = "/bin/";
510   const char* binDir1 = "/bin/bin/";
511 #endif
512
513   QString helper = QString(getenv("PVHOME")) + binDir + QString("pqClientDocFinder.txt");
514   if(!QFile::exists(helper))
515     helper = QString(getenv("PVHOME")) + binDir1 + QString("pqClientDocFinder.txt");
516   if(QFile::exists(helper)) {
517     QFile file(helper);
518     if(file.open(QIODevice::ReadOnly)) {
519       assistantExe = file.readLine().trimmed();
520       profileFile = file.readLine().trimmed();
521       // CMake escapes spaces, we need to unescape those.
522       assistantExe.replace("\\ ", " ");
523       profileFile.replace("\\ ", " ");
524     }
525   }
526
527   if(assistantExe.isEmpty()) {
528     assistantExe = ::Locate(assistantName);//assistantExe = ::Locate(assistantProgName);
529     /*
530     QString assistant = QCoreApplication::applicationDirPath();
531     assistant += QDir::separator();
532     assistant += assistantName;
533     assistantExe = assistant;
534     */
535   }
536
537   this->Implementation->AssistantClient = new QAssistantClient(assistantExe, this);
538   QObject::connect(this->Implementation->AssistantClient, SIGNAL(error(const QString&)),
539                    this,                                  SLOT(assistantError(const QString&)));
540
541   QStringList args;
542   args.append(QString("-profile"));
543
544   if(profileFile.isEmpty()) {
545     // see if help is bundled up with the application
546     QString profile = ::Locate("pqClient.adp");
547     /*QCoreApplication::applicationDirPath() + QDir::separator()
548       + QString("pqClient.adp");*/
549     
550     if(QFile::exists(profile))
551       profileFile = profile;
552   }
553
554   if(profileFile.isEmpty() && getenv("PARAVIEW_HELP")) {
555     // not bundled, ask for help
556     args.append(getenv("PARAVIEW_HELP"));
557   }
558   else if(profileFile.isEmpty()) {
559     // no help, error out
560     SUIT_MessageBox::critical(getApp()->desktop(),"Help error", "Couldn't find"
561                               " pqClient.adp.\nTry setting the PARAVIEW_HELP environment variable which"
562                               " points to that file");
563     delete this->Implementation->AssistantClient;
564     return;
565   }
566
567   QFileInfo fi(profileFile);
568   this->Implementation->DocumentationDir = fi.absolutePath();
569
570   args.append(profileFile);
571
572   this->Implementation->AssistantClient->setArguments(args);
573 }
574
575 /*!
576   \brief Slot to call the message handler with the critical message.
577 */
578 void PVGUI_Module::assistantError( const QString& error )
579 {
580   qCritical(error.toAscii().data());
581 }
582
583 /*!
584   \brief Slot to show the waiting state.
585 */
586 void PVGUI_Module::onPreAccept()
587 {
588   getApp()->desktop()->statusBar()->showMessage(tr("Updating..."));
589   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
590 }
591
592 /*!
593   \brief Slot to show the ready state.
594 */
595 void PVGUI_Module::onPostAccept()
596 {
597   getApp()->desktop()->statusBar()->showMessage(tr("Ready"), 2000);
598   QTimer::singleShot(0, this, SLOT(endWaitCursor()));
599 }
600
601 /*!
602   \brief Slot to switch off wait cursor.
603 */
604 void PVGUI_Module::endWaitCursor()
605 {
606   QApplication::restoreOverrideCursor();
607 }
608
609 /*!
610   \brief Returns the ParaView multi-view manager.
611 */
612 pqViewManager* PVGUI_Module::getMultiViewManager() const
613 {
614   pqViewManager* aMVM = 0; 
615   if ( Implementation )
616     aMVM = &Implementation->Core.multiViewManager();
617   return aMVM;
618 }
619
620 /*!
621   \brief Activate module.
622   \param study current study
623   \return \c true if activaion is done successfully or 0 to prevent
624   activation on error
625 */
626 bool PVGUI_Module::activateModule( SUIT_Study* study )
627 {
628   bool isDone = LightApp_Module::activateModule( study );
629   if ( !isDone ) return false;
630
631   setMenuShown( true );
632
633   showView( true );
634
635   // Make default server connection
636   if ( Implementation )
637     Implementation->Core.makeDefaultConnectionIfNoneExists();
638
639   return isDone;
640 }
641
642
643 /*!
644   \brief Deactivate module.
645   \param study current study
646   \return \c true if deactivaion is done successfully or 0 to prevent
647   deactivation on error
648 */
649 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
650 {
651   // hide menus
652   setMenuShown( false );
653
654   return LightApp_Module::deactivateModule( study );
655 }
656
657 /*!
658   \fn CAM_Module* createModule();
659   \brief Export module instance (factory function).
660   \return new created instance of the module
661 */
662
663 #ifdef WNT
664 #define PVGUI_EXPORT __declspec(dllexport)
665 #else   // WNT
666 #define PVGUI_EXPORT
667 #endif  // WNT
668
669 extern "C" {
670   PVGUI_EXPORT CAM_Module* createModule() {
671     return new PVGUI_Module();
672   }
673 }