Salome HOME
752c7ea7a1a79ca0f82c69062ae5cc2d5808c024
[modules/paravis.git] / 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   /*
173   int i = 1;
174   while( i ){
175     i = i;
176   }
177   */
178
179   pvInit();
180
181   /*
182   createAction( lgLoadFile, tr( "TOP_LOAD_FILE" ), QIcon(), tr( "MEN_LOAD_FILE" ),
183                 tr( "STB_LOAD_FILE" ), 0, desk, false, this, SLOT( onLoadFile() ) );
184   createAction( lgDisplayLine, tr( "TOP_DISPLAY_LINE" ), QIcon(), tr( "MEN_DISPLAY_LINE" ),
185                 tr( "STB_DISPLAY_LINE" ), 0, desk, false, this, SLOT( onDisplayLine() ) );
186   createAction( lgEraseLine, tr( "TOP_ERASE_LINE" ), QIcon(), tr( "MEN_ERASE_LINE" ),
187                 tr( "STB_ERASE_LINE" ), 0, desk, false, this, SLOT( onEraseLine() ) );
188   createAction( lgSaveFile, tr( "TOP_SAVE_FILE" ), QIcon(), tr( "MEN_SAVE_FILE" ),
189                 tr( "STB_SAVE_FILE" ), 0, desk, false, this, SLOT( onSaveFile() ) );
190   createAction( lgEditLine, tr( "TOP_EDIT_LINE" ), QIcon(), tr( "MEN_EDIT_LINE" ),
191                 tr( "STB_EDIT_LINE" ), 0, desk, false, this, SLOT( onEditLine() ) );
192   createAction( lgAddLine,  tr( "TOP_ADD_LINE" ),  QIcon(), tr( "MEN_ADD_LINE" ),
193                 tr( "STB_ADD_LINE" ),  0, desk, false, this, SLOT( onAddLine() ) );
194   createAction( lgDelLine,  tr( "TOP_DEL_LINE" ),  QIcon(), tr( "MEN_DEL_LINE" ),
195                 tr( "STB_DEL_LINE" ),  0, desk, false, this, SLOT( onDelLine() ) );
196   createAction( lgClear,    tr( "TOP_CLEAR_ALL" ), QIcon(), tr( "MEN_CLEAR_ALL" ),
197                 tr( "STB_CLEAR_ALL" ), 0, desk, false, this, SLOT( onClear() ) );
198
199   int aFileMnu = createMenu( tr( "MEN_FILE" ), -1, -1 );
200   createMenu( separator(), aFileMnu, -1, 10 );
201   createMenu( lgLoadFile,  aFileMnu, 10 );
202   createMenu( lgSaveFile,  aFileMnu, 10 );
203
204   int aLightMnu = createMenu( tr( "MEN_LIGHT" ), -1, -1, 50 );
205   createMenu( lgAddLine,      aLightMnu, 10 );
206   createMenu( lgEditLine,     aLightMnu, 10 );
207   createMenu( lgDelLine,      aLightMnu, 10 );
208   createMenu( separator(),    aLightMnu, -1, 10 );
209   createMenu( lgClear,        aLightMnu, 10 );
210
211   QString rule = "(client='ObjectBrowser' or client='OCCViewer') and selcount=1 and type='TextLine' and !empty";
212
213   popupMgr()->insert ( action( lgDisplayLine ), -1, 0 );
214   popupMgr()->setRule( action( lgDisplayLine ), rule + " and !visible"  );
215
216   popupMgr()->insert ( action( lgEraseLine ), -1, 0 );
217   popupMgr()->setRule( action( lgEraseLine ), rule + " and activeView='OCCViewer' and visible"  );
218
219   rule = "client='ObjectBrowser' and selcount=1 and type='TextLine'";
220
221   popupMgr()->insert ( action( lgEditLine ), -1, 0 );
222   popupMgr()->setRule( action( lgEditLine ), rule  );
223
224   popupMgr()->insert ( action( lgAddLine ),  -1, 0 );
225   popupMgr()->setRule( action( lgAddLine ),  rule );
226
227   popupMgr()->insert ( separator(),          -1, 0 );
228
229   popupMgr()->insert ( action( lgDelLine ),  -1, 0 );
230   popupMgr()->setRule( action( lgDelLine ),  rule );
231
232   rule = "client='ObjectBrowser'";
233
234   popupMgr()->insert ( action( lgClear ),    -1, 0 );
235   popupMgr()->setRule( action( lgClear ),    rule );*/
236 }
237
238 /*!
239   \brief Get list of compliant dockable GUI elements
240   \param m map to be filled in ("type":"default_position")
241 */
242 void PVGUI_Module::windows( QMap<int, int>& m ) const
243 {
244   m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
245   // TODO: creation of Python console leads to SIGSEGV on Python initialization...
246   //m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
247   // ParaView diagnostic output redirected here
248   m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
249 }
250
251 /*!
252   \brief Create custom popup menu selection object.
253   \return new selected object
254 */
255 /*LightApp_Selection* PVGUI_Module::createSelection() const
256 {
257   return new PVGUI_Selection();
258 }*/
259
260 /*!
261   \brief Create data model.
262   \return module specific data model
263 */
264 /*CAM_DataModel* PVGUI_Module::createDataModel()
265 {
266   return new PVGUI_DataModel( this );
267 }*/
268
269 /*!
270   \brief Static method, performs initialization of ParaView session.
271   \return \c true if ParaView has been initialized successfully, otherwise false
272 */
273 bool PVGUI_Module::pvInit()
274 {
275   if ( !pqImplementation::myPVMain ){
276     // Obtain command-line arguments
277     int argc = 0;
278     QStringList args = QApplication::arguments();
279     char** argv = new char*[args.size()];
280     for ( QStringList::const_iterator it = args.begin(); argc < 1 && it != args.end(); it++, argc++ )
281       argv[argc] = strdup( (*it).toLatin1().constData() );
282
283     vtkPVMain::SetInitializeMPI(0);  // pvClient never runs with MPI.
284     vtkPVMain::Initialize(&argc, &argv); // Perform any initializations.
285
286     // TODO: Set plugin dir from preferences
287     //QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
288
289     pqImplementation::myPVMain = vtkPVMain::New();
290     if ( !pqImplementation::myPVOptions )
291       pqImplementation::myPVOptions = pqOptions::New();
292     if ( !pqImplementation::myPVHelper )
293       pqImplementation::myPVHelper = PVGUI_ProcessModuleHelper::New();
294
295     pqImplementation::myPVOptions->SetProcessType(vtkPVOptions::PVCLIENT);
296
297     // This creates the Process Module and initializes it.
298     int ret = pqImplementation::myPVMain->Initialize(pqImplementation::myPVOptions, 
299                                                      pqImplementation::myPVHelper, 
300                                                      ParaViewInitializeInterpreter,
301                                                      argc, argv);
302     if (!ret){
303       // Tell process module that we support Multiple connections.
304       // This must be set before starting the event loop.
305       vtkProcessModule::GetProcessModule()->SupportMultipleConnectionsOn();
306       ret = pqImplementation::myPVHelper->Run(pqImplementation::myPVOptions);
307     }
308
309     delete[] argv;
310     return !ret;
311   }
312   
313   return true;
314 }
315  
316 /*!
317   \brief Static method, cleans up ParaView session at application exit.
318 */
319 void PVGUI_Module::pvShutdown()
320 {
321   // TODO...
322 }  
323
324 /*!
325   \brief Shows (toShow = true) or hides ParaView view window
326 */
327 void PVGUI_Module::showView( bool toShow )
328 {
329   // TODO: check if ParaView view already exists
330   if ( !Implementation ){
331     LightApp_Application* anApp = getApp();
332     SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
333     PVGUI_ViewManager* viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() );
334     anApp->addViewManager( viewMgr );
335     connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
336              anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
337     //connect( viewMgr, SIGNAL( viewCreated( SUIT_ViewWindow* ) ), vm, SLOT( onViewCreated( SUIT_ViewWindow* ) ) );
338     //connect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ), this, SLOT( onViewDeleted( SUIT_ViewWindow* ) ) );
339     SUIT_ViewWindow* wnd = viewMgr->createViewWindow();  
340
341     // Simulate ParaView client main window
342     Implementation = new pqImplementation( anApp->desktop() );
343     PVGUI_ViewWindow* pvWnd = dynamic_cast<PVGUI_ViewWindow*>( wnd );
344     pvWnd->setMultiViewManager( &Implementation->Core.multiViewManager() );
345
346     setupDockWidgets();
347     
348     pvCreateActions();
349     pvCreateMenus();
350     pvCreateToolBars();
351     
352     setupDockWidgetsContextMenu();
353
354     // Now that we're ready, initialize everything ...
355     Implementation->Core.initializeStates();
356   }
357 }
358
359 /*!
360   \brief Manage the label of Undo operation.
361 */
362 void PVGUI_Module::onUndoLabel( const QString& label )
363 {
364   action(UndoId)->setText(
365     label.isEmpty() ? tr("Can't Undo") : QString(tr("&Undo %1")).arg(label));
366   action(UndoId)->setStatusTip(
367     label.isEmpty() ? tr("Can't Undo") : QString(tr("Undo %1")).arg(label));
368 }
369
370 /*!
371   \brief Manage the label of Redo operation.
372 */
373 void PVGUI_Module::onRedoLabel( const QString& label )
374 {
375   action(RedoId)->setText(
376     label.isEmpty() ? tr("Can't Redo") : QString(tr("&Redo %1")).arg(label));
377   action(RedoId)->setStatusTip(
378     label.isEmpty() ? tr("Can't Redo") : QString(tr("Redo %1")).arg(label));
379 }
380
381 /*!
382   \brief Manage the label of Undo Camera operation.
383 */
384 void PVGUI_Module::onCameraUndoLabel( const QString& label )
385 {
386   action(CameraUndoId)->setText(
387     label.isEmpty() ? tr("Can't Undo Camera") : QString(tr("U&ndo %1")).arg(label));
388   action(CameraUndoId)->setStatusTip(
389     label.isEmpty() ? tr("Can't Undo Camera") : QString(tr("Undo %1")).arg(label));
390 }
391
392 /*!
393   \brief Manage the label of Redo Camera operation.
394 */
395 void PVGUI_Module::onCameraRedoLabel( const QString& label )
396 {
397   action(CameraRedoId)->setText(
398     label.isEmpty() ? tr("Can't Redo Camera") : QString(tr("R&edo %1")).arg(label));
399   action(CameraRedoId)->setStatusTip(
400     label.isEmpty() ? tr("Can't Redo Camera") : QString(tr("Redo %1")).arg(label));
401 }
402
403 /*!
404   \brief Slot to delete all objects.
405 */
406 void PVGUI_Module::onDeleteAll()
407 {
408   pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
409   Implementation->Core.getApplicationUndoStack()->beginUndoSet("Delete All");
410   builder->destroyPipelineProxies();
411   Implementation->Core.getApplicationUndoStack()->endUndoSet();
412 }
413
414 /*!
415   \brief Slot to check/uncheck the action for corresponding selection mode.
416 */
417 void PVGUI_Module::onSelectionModeChanged( int mode )
418 {
419   if( toolMgr()->toolBar( mySelectionControlsTb )->isEnabled() ) {
420     if(mode == pqRubberBandHelper::SELECT) //surface selection
421       action(SelectCellsOnId)->setChecked(true);
422     else if(mode == pqRubberBandHelper::SELECT_POINTS) //surface selection
423       action(SelectPointsOnId)->setChecked(true);
424     else if(mode == pqRubberBandHelper::FRUSTUM)
425       action(SelectCellsThroughId)->setChecked(true);
426     else if(mode == pqRubberBandHelper::FRUSTUM_POINTS)
427       action(SelectPointsThroughId)->setChecked(true);
428     else if (mode == pqRubberBandHelper::BLOCKS)
429       action(SelectBlockId)->setChecked(true);
430     else // INTERACT
431       action(InteractId)->setChecked(true);
432   }
433 }
434
435 /*!
436   \brief Slot to manage the change of axis center.
437 */
438 void PVGUI_Module::onShowCenterAxisChanged( bool enabled )
439 {
440   action(ShowCenterId)->setEnabled(enabled);
441   action(ShowCenterId)->blockSignals(true);
442   pqRenderView* renView = qobject_cast<pqRenderView*>(
443     pqActiveView::instance().current());
444   action(ShowCenterId)->setChecked( renView ? renView->getCenterAxesVisibility() : false);
445   action(ShowCenterId)->blockSignals(false);
446 }
447
448 /*!
449   \brief Slot to set tooltips for the first anf the last frames, i.e. a time range of animation.
450 */
451 void PVGUI_Module::setTimeRanges( double start, double end )
452 {
453   action(FirstFrameId)->setToolTip(QString("First Frame (%1)").arg(start, 0, 'g'));
454   action(LastFrameId)->setToolTip(QString("Last Frame (%1)").arg(end, 0, 'g'));
455 }
456
457 /*!
458   \brief Slot to manage the plaing process of animation.
459 */
460 void PVGUI_Module::onPlaying( bool playing )
461 {
462   SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
463   if(playing) {
464     disconnect( action(PlayId),                        SIGNAL( triggered() ),
465                 &Implementation->Core.VCRController(), SLOT( onPlay() ) );
466     connect( action(PlayId),                        SIGNAL( triggered() ),
467              &Implementation->Core.VCRController(), SLOT( onPause() ) );
468     action(PlayId)->setIcon(QIcon(resMgr->loadPixmap("ParaView",tr("ICON_PAUSE"),false)));
469     action(PlayId)->setText("Pa&use");
470   }
471   else {
472     connect( action(PlayId),                        SIGNAL( triggered() ),
473              &Implementation->Core.VCRController(), SLOT( onPlay() ) );
474     disconnect( action(PlayId),                        SIGNAL( triggered() ),
475                 &Implementation->Core.VCRController(), SLOT( onPause() ) );
476     action(PlayId)->setIcon(QIcon(resMgr->loadPixmap("ParaView",tr("ICON_PLAY"),false)));
477     action(PlayId)->setText("&Play");
478   }
479
480   Implementation->Core.setSelectiveEnabledState(!playing);
481 }
482
483 /*!
484   \brief Slot to add camera link.
485 */
486 void PVGUI_Module::onAddCameraLink()
487 {
488   pqView* vm = pqActiveView::instance().current();
489   pqRenderView* rm = qobject_cast<pqRenderView*>(vm);
490   if(rm) rm->linkToOtherView();
491   else SUIT_MessageBox::warning(getApp()->desktop(),
492                                 tr("WARNING"), tr("WRN_ADD_CAMERA_LINK"));
493 }
494
495 /*!
496   \brief Slot to show information about ParaView.
497 */
498 void PVGUI_Module::onHelpAbout()
499 {
500   pqClientAboutDialog* const dialog = new pqClientAboutDialog(getApp()->desktop());
501   dialog->setAttribute(Qt::WA_DeleteOnClose);
502   dialog->show();
503 }
504
505 /*!
506   \brief Slot to show help for proxy.
507 */
508 void PVGUI_Module::showHelpForProxy( const QString& proxy )
509 {
510   // make sure assistant is ready
511   this->makeAssistant();
512
513   if(this->Implementation->AssistantClient) {
514     this->Implementation->AssistantClient->openAssistant();
515     QString page("%1/Documentation/%2.html");
516     page = page.arg(this->Implementation->DocumentationDir);
517     page = page.arg(proxy);
518     this->Implementation->AssistantClient->showPage(page);
519   }
520 }
521
522 QString Locate( const QString& appName )
523 {
524   QString app_dir = QCoreApplication::applicationDirPath();
525   const char* inst_dirs[] = {
526     "/./",
527     "/../bin/",
528     "/../../bin/",
529     0
530   };
531   for (const char** dir = inst_dirs; *dir; ++dir) {
532     QString path = app_dir;
533     path += *dir;
534     path += appName;
535     //cout << "Checking : " << path.toAscii().data() << " ... ";
536     //cout.flush();
537     QFileInfo finfo (path);
538     if (finfo.exists()) {
539       //cout << " Success!" << endl;
540       return path;
541     }
542     //cout << " Failed" << endl;
543   }
544   return app_dir + QDir::separator() + appName;
545 }
546
547 /*!
548   \brief Initialized an assistant client.
549 */
550 void PVGUI_Module::makeAssistant()
551 {
552   if(this->Implementation->AssistantClient)
553     return;
554   
555   QString assistantExe;
556   QString profileFile;
557   
558   const char* assistantName = "assistant";
559 #ifdef WNT
560   const char* extString = ".exe";
561   const char* binDir = "\\";
562   const char* binDir1 = "\\..\\";
563 #else
564   const char* extString = "";
565   const char* binDir = "/";
566   const char* binDir1 = "/";
567 #endif
568
569   QString assistantProgName;
570   assistantProgName = assistantProgName + assistantName + extString;
571
572   QString helper = QCoreApplication::applicationDirPath() + binDir + QString("pqClientDocFinder.txt");
573   if(!QFile::exists(helper))
574     helper = QCoreApplication::applicationDirPath() + binDir1 + QString("pqClientDocFinder.txt");
575   if(QFile::exists(helper)) {
576     QFile file(helper);
577     if(file.open(QIODevice::ReadOnly)) {
578       assistantExe = file.readLine().trimmed() + assistantProgName;
579       profileFile = file.readLine().trimmed();
580     }
581   }
582
583   if(assistantExe.isEmpty()) {
584     assistantExe = ::Locate(assistantProgName);
585     /*
586     QString assistant = QCoreApplication::applicationDirPath();
587     assistant += QDir::separator();
588     assistant += assistantName;
589     assistantExe = assistant;
590     */
591   }
592
593   this->Implementation->AssistantClient = new QAssistantClient(assistantExe, this);
594   QObject::connect(this->Implementation->AssistantClient, SIGNAL(error(const QString&)),
595                    this,                                  SLOT(assistantError(const QString&)));
596
597   QStringList args;
598   args.append(QString("-profile"));
599
600   if(profileFile.isEmpty()) {
601     // see if help is bundled up with the application
602     QString profile = ::Locate("pqClient.adp");
603     /*QCoreApplication::applicationDirPath() + QDir::separator()
604       + QString("pqClient.adp");*/
605     
606     if(QFile::exists(profile))
607       profileFile = profile;
608   }
609
610   if(profileFile.isEmpty() && getenv("PARAVIEW_HELP")) {
611     // not bundled, ask for help
612     args.append(getenv("PARAVIEW_HELP"));
613   }
614   else if(profileFile.isEmpty()) {
615     // no help, error out
616     SUIT_MessageBox::critical(getApp()->desktop(),"Help error", "Couldn't find"
617                               " pqClient.adp.\nTry setting the PARAVIEW_HELP environment variable which"
618                               " points to that file");
619     delete this->Implementation->AssistantClient;
620     return;
621   }
622
623   QFileInfo fi(profileFile);
624   this->Implementation->DocumentationDir = fi.absolutePath();
625
626   args.append(profileFile);
627
628   this->Implementation->AssistantClient->setArguments(args);
629 }
630
631 /*!
632   \brief Slot to call the message handler with the critical message.
633 */
634 void PVGUI_Module::assistantError( const QString& error )
635 {
636   qCritical(error.toAscii().data());
637 }
638
639 /*!
640   \brief Slot to show the waiting state.
641 */
642 void PVGUI_Module::onPreAccept()
643 {
644   getApp()->desktop()->statusBar()->showMessage(tr("Updating..."));
645   QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
646 }
647
648 /*!
649   \brief Slot to show the ready state.
650 */
651 void PVGUI_Module::onPostAccept()
652 {
653   getApp()->desktop()->statusBar()->showMessage(tr("Ready"), 2000);
654   QTimer::singleShot(0, this, SLOT(endWaitCursor()));
655 }
656
657 /*!
658   \brief Slot to switch off wait cursor.
659 */
660 void PVGUI_Module::endWaitCursor()
661 {
662   QApplication::restoreOverrideCursor();
663 }
664
665 /*!
666   \brief Returns the ParaView multi-view manager.
667 */
668 pqViewManager* PVGUI_Module::getMultiViewManager() const
669 {
670   pqViewManager* aMVM = 0; 
671   if ( Implementation )
672     aMVM = &Implementation->Core.multiViewManager();
673   return aMVM;
674 }
675
676 /*!
677   \brief Activate module.
678   \param study current study
679   \return \c true if activaion is done successfully or 0 to prevent
680   activation on error
681 */
682 bool PVGUI_Module::activateModule( SUIT_Study* study )
683 {
684   bool isDone = LightApp_Module::activateModule( study );
685   if ( !isDone ) return false;
686
687   setMenuShown( true );
688
689   showView( true );
690
691   // Make default server connection
692   if ( Implementation )
693     Implementation->Core.makeDefaultConnectionIfNoneExists();
694
695   return isDone;
696 }
697
698
699 /*!
700   \brief Deactivate module.
701   \param study current study
702   \return \c true if deactivaion is done successfully or 0 to prevent
703   deactivation on error
704 */
705 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
706 {
707   // hide menus
708   setMenuShown( false );
709
710   return LightApp_Module::deactivateModule( study );
711 }
712
713 /*!
714   \fn CAM_Module* createModule();
715   \brief Export module instance (factory function).
716   \return new created instance of the module
717 */
718
719 #ifdef WNT
720 #define PVGUI_EXPORT __declspec(dllexport)
721 #else   // WNT
722 #define PVGUI_EXPORT
723 #endif  // WNT
724
725 extern "C" {
726   PVGUI_EXPORT CAM_Module* createModule() {
727     return new PVGUI_Module();
728   }
729 }