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;
146 <h2>Building and installing PARAVIS</h2>
147 As any other SALOME module, PARAVIS requires PARAVIS_ROOT_DIR environment variable to be set to PARAVIS
148 installation directory.
149 Other variables needed for correct detection of ParaView location:
150 \li PVSRCHOME - points at the root of ParaView source directory tree
151 \li PVINSTALLHOME - points at the top of ParaView build tree (currently, due to some drawbacks in its buld procedure
152 ParaView should not be installed, its build directory is used instead).
154 It also requires common SALOME environment including GUI_ROOT_DIR and other prerequsites.
156 As soon as the environment is set, excute the following commands in a shell:
160 ../PARAVIS_SRC/build_configure
161 ../PARAVIS_SRC/configure --prefix=${PARAVIS_ROOT_DIR}
167 PARAVIS module can be launched using the following commands:
168 \li Light SALOME configuration
170 runLightSalome.sh --modules="PARAVIS"
173 \li Full SALOME configuration
175 runSalome --modules="PARAVIS"
178 <h2>ParaView GUI integration</h2>
179 <h3>ParaView GUI integration overview</h3>
181 The main idea is to reuse ParaView GUI internal logic as much as possible, providing a layer
182 between it and SALOME GUI that hides the following SALOME GUI implementation details from ParaView:
184 \li SALOME GUI executable and Qt event loop
185 \li SALOME GUI desktop
186 \li Dock windows areas
187 \li SALOME menu and toolbar managers
189 Major part of the integration is implemented in PVGUI_Module class.
191 <h3>ParaView client initalization</h3>
193 ParaView client initalization is performed when an instance of PVGUI_Module class has been created
194 and \link PVGUI_Module::initialize() PVGUI_Module::initialize()\endlink method is called by SALOME GUI.
195 The actual client start-up is done in \link PVGUI_Module::pvInit() PVGUI_Module::pvInit()\endlink method.
196 It simulates actions perfomed by pqMain::Run( QApplication&, pqProcessModuleGUIHelper* ) method.
198 Custom PVGUI_ProcessModuleHelper class derived from %pqProcessModuleGUIHelper base is the main actor in ParaView
199 client initialization. It initializes the client that uses the main window (SALOME desktop) supplied from the outside,
200 it does not start Qt event loop as this is done in SALOME GUI executable (SUITApp or SALOME_Session_Server), and after all
201 it redirects ParaView diagnostic output to SALOME LogWindow with help of PVGUI_OutputWindowAdapter class.
202 This is achieved by reimplementing \link PVGUI_ProcessModuleHelper::InitializeApplication() InitializeApplication()\endlink,
203 \link PVGUI_ProcessModuleHelper::appExec() appExec()\endlink, \link PVGUI_ProcessModuleHelper::postAppExec() postAppExec()\endlink
204 virtual methods as well as those responsible for main window management.
206 <h3>ParaView GUI connection to SALOME desktop</h3>
208 ParaView Qt components include pqMainWindowCore class that handles most ParaView GUI client actions,
209 updates menu states and connects many GUI components.
210 After the client initalization \link PVGUI_Module::initialize() PVGUI_Module::initialize()\endlink method creates
211 an instance of internal PVGUI_Module::pqImplementation class (declared PVGUI_Module_impl.h) that wraps some ParaView GUI components:
212 pqMainWindowCore, pqServer, etc. Instance of SALOME desktop widget is passed to pqMainWindowCore instead of ParaView main window.
214 Basically it simulates constructor of ParaView client's %MainWindow class (src/Applications/Client/MainWindow.cxx). It creates the same
215 menu and toolbar commands using SALOME menu and toolbar managers, connecting the actions to %pqMainWindowCore slots or to the module's
216 slots in some cases. It also sets up dock widgets for ParaView widgets, such as object inspector, pipeline browser, etc.
218 ParaView GUI resources (icons) are reused directly from the ParaView resource directory, they are loaded into SALOME GUI
219 resource manager, the path to these icons is specified in PARAVIS configuration XML files (LightApp.xml and SlomeApp.xml).
221 As both SALOME destop and ParaView main window classes inherit QMainWindow and %pqMainWindowCore deals with QMainWindow API to control
222 menus, tollbars and dock widgets, its integration into SALOME GUI is straightforward and smooth.
224 <h3>Multi-view manager</h3>
226 SALOME GUI requires that each kind of view be implemnted with help of (at least) three classes. For ParaView multi-view manager
229 \li PVGUI_ViewManager - view manager class
230 \li PVGUI_Viewer - view model class
231 \li PVGUI_ViewWindow - view window class that acts as a parent for %pqViewManager
233 Single instances of PVGUI_ViewManager and PVGUI_ViewWindow classes are created by \link PVGUI_Module::showView()
234 PVGUI_Module::showView()\endlink method upon the first PARAVIS module activation. The same method hides the multi-view manager
235 when the module is deactivated (the user switches to another module or a study is closed).
236 A special trick is used to make PVGUI_ViewWindow the parent of %pqViewManager widget. It is created initally by %pqMainWindowCore
237 with the desktop as a parent, so when it is shown PVGUI_ViewWindow instance is passed to its setParent() method. In
238 \link PVGUI_ViewWindow::~PVGUI_ViewWindow() PVGUI_ViewWindow::~PVGUI_ViewWindow()\endlink the parent is nullified to avoid deletion
239 of %pqViewManager widget that would break %pqMainWindowCore class.
241 <h3>ParaView plugins</h3>
242 ParaView server and client plugins are managed by %pqMainWindowCore slots that has full access to PARAVIS menus and toolbars.
243 As a result they appears automatically in PARAVIS menus and toolbars if loaded successfully.
245 <h2>Limitations of 2008 year prototype</h2>
246 \li SALOME persistence (possibility to save the module data into a tsudy file) is not implemented for PARAVIS module.
247 \li As a light module, PARAVIS does not have a CORBA engine that follows SALOME rules, however PARAVIS can use load a CORBA engine
248 on its own if needed.
253 \brief Implementation of light (no-CORBA-engine)
254 SALOME module wrapping ParaView GUI.
258 \brief Constructor. Sets the default name for the module.
260 PVGUI_Module::PVGUI_Module()
261 : LightApp_Module( "PARAVIS" ),
263 mySelectionControlsTb( -1 ),
264 mySourcesMenuId( -1 ),
265 myFiltersMenuId( -1 )
272 PVGUI_Module::~PVGUI_Module()
277 \brief Initialize module. Creates menus, prepares context menu, etc.
278 \param app SALOME GUI application instance
280 void PVGUI_Module::initialize( CAM_Application* app )
282 LightApp_Module::initialize( app );
284 // Uncomment to debug ParaView initialization
285 // "aa" used instead of "i" as GDB doesn't like "i" variables :)
293 // Initialize ParaView client
296 // Create GUI elements (menus, toolbars, dock widgets)
297 if ( !Implementation ){
298 LightApp_Application* anApp = getApp();
300 // Simulate ParaView client main window
301 Implementation = new pqImplementation( anApp->desktop() );
309 setupDockWidgetsContextMenu();
311 // Now that we're ready, initialize everything ...
312 Implementation->Core.initializeStates();
317 \brief Get list of compliant dockable GUI elements
318 \param m map to be filled in ("type":"default_position")
320 void PVGUI_Module::windows( QMap<int, int>& m ) const
322 m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
323 m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
324 // ParaView diagnostic output redirected here
325 m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
329 \brief Static method, performs initialization of ParaView session.
330 \return \c true if ParaView has been initialized successfully, otherwise false
332 bool PVGUI_Module::pvInit()
334 if ( !pqImplementation::myPVMain ){
335 // Obtain command-line arguments
337 QStringList args = QApplication::arguments();
338 char** argv = new char*[args.size()];
339 for ( QStringList::const_iterator it = args.begin(); argc < 1 && it != args.end(); it++, argc++ )
340 argv[argc] = strdup( (*it).toLatin1().constData() );
342 vtkPVMain::SetInitializeMPI(0); // pvClient never runs with MPI.
343 vtkPVMain::Initialize(&argc, &argv); // Perform any initializations.
345 // TODO: Set plugin dir from preferences
346 //QApplication::setLibraryPaths(QStringList(dir.absolutePath()));
348 pqImplementation::myPVMain = vtkPVMain::New();
349 if ( !pqImplementation::myPVOptions )
350 pqImplementation::myPVOptions = pqOptions::New();
351 if ( !pqImplementation::myPVHelper )
352 pqImplementation::myPVHelper = PVGUI_ProcessModuleHelper::New();
354 pqImplementation::myPVOptions->SetProcessType(vtkPVOptions::PVCLIENT);
356 // This creates the Process Module and initializes it.
357 int ret = pqImplementation::myPVMain->Initialize(pqImplementation::myPVOptions,
358 pqImplementation::myPVHelper,
359 ParaViewInitializeInterpreter,
362 // Tell process module that we support Multiple connections.
363 // This must be set before starting the event loop.
364 vtkProcessModule::GetProcessModule()->SupportMultipleConnectionsOn();
365 ret = pqImplementation::myPVHelper->Run(pqImplementation::myPVOptions);
376 \brief Static method, cleans up ParaView session at application exit.
378 void PVGUI_Module::pvShutdown()
380 if ( pqImplementation::myPVHelper )
381 pqImplementation::myPVHelper->finalize();
385 \brief Shows (toShow = true) or hides ParaView view window
387 void PVGUI_Module::showView( bool toShow )
389 LightApp_Application* anApp = getApp();
390 PVGUI_ViewManager* viewMgr = dynamic_cast<PVGUI_ViewManager*>( anApp->getViewManager( PVGUI_Viewer::Type(), false ) );
392 viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() );
393 anApp->addViewManager( viewMgr );
394 connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
395 anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
398 PVGUI_ViewWindow* pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->getActiveView() );
400 pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->createViewWindow() );
401 pvWnd->setMultiViewManager( &Implementation->Core.multiViewManager() );
404 pvWnd->setShown( toShow );
408 \brief Manage the label of Undo operation.
410 void PVGUI_Module::onUndoLabel( const QString& label )
412 action(UndoId)->setText(
413 label.isEmpty() ? tr("MEN_CANTUNDO") : QString(tr("MEN_UNDO_ACTION")).arg(label));
414 action(UndoId)->setStatusTip(
415 label.isEmpty() ? tr("MEN_CANTUNDO") : QString(tr("MEN_UNDO_ACTION_TIP")).arg(label));
419 \brief Manage the label of Redo operation.
421 void PVGUI_Module::onRedoLabel( const QString& label )
423 action(RedoId)->setText(
424 label.isEmpty() ? tr("MEN_CANTREDO") : QString(tr("MEN_REDO_ACTION")).arg(label));
425 action(RedoId)->setStatusTip(
426 label.isEmpty() ? tr("MEN_CANTREDO") : QString(tr("MEN_REDO_ACTION_TIP")).arg(label));
430 \brief Manage the label of Undo Camera operation.
432 void PVGUI_Module::onCameraUndoLabel( const QString& label )
434 action(CameraUndoId)->setText(
435 label.isEmpty() ? tr("MEN_CANT_CAMERA_UNDO") : QString(tr("MEN_CAMERA_UNDO_ACTION")).arg(label));
436 action(CameraUndoId)->setStatusTip(
437 label.isEmpty() ? tr("MEN_CANT_CAMERA_UNDO") : QString(tr("MEN_CAMERA_UNDO_ACTION_TIP")).arg(label));
441 \brief Manage the label of Redo Camera operation.
443 void PVGUI_Module::onCameraRedoLabel( const QString& label )
445 action(CameraRedoId)->setText(
446 label.isEmpty() ? tr("MEN_CANT_CAMERA_REDO") : QString(tr("MEN_CAMERA_REDO_ACTION")).arg(label));
447 action(CameraRedoId)->setStatusTip(
448 label.isEmpty() ? tr("MEN_CANT_CAMERA_REDO") : QString(tr("MEN_CAMERA_REDO_ACTION_TIP")).arg(label));
452 \brief Slot to delete all objects.
454 void PVGUI_Module::onDeleteAll()
456 pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
457 Implementation->Core.getApplicationUndoStack()->beginUndoSet("Delete All");
458 builder->destroyPipelineProxies();
459 Implementation->Core.getApplicationUndoStack()->endUndoSet();
463 \brief Slot to check/uncheck the action for corresponding selection mode.
465 void PVGUI_Module::onSelectionModeChanged( int mode )
467 if( toolMgr()->toolBar( mySelectionControlsTb )->isEnabled() ) {
468 if(mode == pqRubberBandHelper::SELECT) //surface selection
469 action(SelectCellsOnId)->setChecked(true);
470 else if(mode == pqRubberBandHelper::SELECT_POINTS) //surface selection
471 action(SelectPointsOnId)->setChecked(true);
472 else if(mode == pqRubberBandHelper::FRUSTUM)
473 action(SelectCellsThroughId)->setChecked(true);
474 else if(mode == pqRubberBandHelper::FRUSTUM_POINTS)
475 action(SelectPointsThroughId)->setChecked(true);
476 else if (mode == pqRubberBandHelper::BLOCKS)
477 action(SelectBlockId)->setChecked(true);
479 action(InteractId)->setChecked(true);
484 \brief Slot to manage the change of axis center.
486 void PVGUI_Module::onShowCenterAxisChanged( bool enabled )
488 action(ShowCenterId)->setEnabled(enabled);
489 action(ShowCenterId)->blockSignals(true);
490 pqRenderView* renView = qobject_cast<pqRenderView*>(
491 pqActiveView::instance().current());
492 action(ShowCenterId)->setChecked( renView ? renView->getCenterAxesVisibility() : false);
493 action(ShowCenterId)->blockSignals(false);
497 \brief Slot to set tooltips for the first anf the last frames, i.e. a time range of animation.
499 void PVGUI_Module::setTimeRanges( double start, double end )
501 action(FirstFrameId)->setToolTip(QString("First Frame (%1)").arg(start, 0, 'g'));
502 action(LastFrameId)->setToolTip(QString("Last Frame (%1)").arg(end, 0, 'g'));
506 \brief Slot to manage the plaing process of animation.
508 void PVGUI_Module::onPlaying( bool playing )
510 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
512 disconnect( action(PlayId), SIGNAL( triggered() ),
513 &Implementation->Core.VCRController(), SLOT( onPlay() ) );
514 connect( action(PlayId), SIGNAL( triggered() ),
515 &Implementation->Core.VCRController(), SLOT( onPause() ) );
516 action(PlayId)->setIcon(QIcon(resMgr->loadPixmap("ParaView",tr("ICON_PAUSE"),false)));
517 action(PlayId)->setText("Pa&use");
520 connect( action(PlayId), SIGNAL( triggered() ),
521 &Implementation->Core.VCRController(), SLOT( onPlay() ) );
522 disconnect( action(PlayId), SIGNAL( triggered() ),
523 &Implementation->Core.VCRController(), SLOT( onPause() ) );
524 action(PlayId)->setIcon(QIcon(resMgr->loadPixmap("ParaView",tr("ICON_PLAY"),false)));
525 action(PlayId)->setText("&Play");
528 Implementation->Core.setSelectiveEnabledState(!playing);
532 \brief Slot to add camera link.
534 void PVGUI_Module::onAddCameraLink()
536 pqView* vm = pqActiveView::instance().current();
537 pqRenderView* rm = qobject_cast<pqRenderView*>(vm);
538 if(rm) rm->linkToOtherView();
539 else SUIT_MessageBox::warning(getApp()->desktop(),
540 tr("WARNING"), tr("WRN_ADD_CAMERA_LINK"));
544 \brief Slot to show information about ParaView.
546 void PVGUI_Module::onHelpAbout()
548 pqClientAboutDialog* const dialog = new pqClientAboutDialog(getApp()->desktop());
549 dialog->setAttribute(Qt::WA_DeleteOnClose);
554 \brief Slot to show native ParaView user documentation.
556 void PVGUI_Module::onParaViewHelp()
558 showHelpForProxy("index");
562 \brief Slot to show help for proxy.
564 void PVGUI_Module::showHelpForProxy( const QString& proxy )
566 // make sure assistant is ready
567 this->makeAssistant();
569 if(this->Implementation->AssistantClient) {
570 this->Implementation->AssistantClient->openAssistant();
571 QString page("%1/Documentation/%2.html");
572 page = page.arg(this->Implementation->DocumentationDir);
573 page = page.arg(proxy);
574 this->Implementation->AssistantClient->showPage(page);
578 QString Locate( const QString& appName )
580 QString app_dir = QCoreApplication::applicationDirPath();
581 const char* inst_dirs[] = {
587 for (const char** dir = inst_dirs; *dir; ++dir) {
588 QString path = app_dir;
591 //cout << "Checking : " << path.toAscii().data() << " ... ";
593 QFileInfo finfo (path);
594 if (finfo.exists()) {
595 //cout << " Success!" << endl;
598 //cout << " Failed" << endl;
600 return app_dir + QDir::separator() + appName;
604 \brief Initialized an assistant client.
606 void PVGUI_Module::makeAssistant()
608 if(this->Implementation->AssistantClient)
611 QString assistantExe;
614 const char* assistantName = "assistant";
616 const char* binDir = "\\";
617 const char* binDir1 = "\\..\\";
619 const char* binDir = "/bin/";
620 const char* binDir1 = "/bin/bin/";
623 QString helper = QString(getenv("PVHOME")) + binDir + QString("pqClientDocFinder.txt");
624 if(!QFile::exists(helper))
625 helper = QString(getenv("PVHOME")) + binDir1 + QString("pqClientDocFinder.txt");
626 if(QFile::exists(helper)) {
628 if(file.open(QIODevice::ReadOnly)) {
629 assistantExe = file.readLine().trimmed();
630 profileFile = file.readLine().trimmed();
631 // CMake escapes spaces, we need to unescape those.
632 assistantExe.replace("\\ ", " ");
633 profileFile.replace("\\ ", " ");
637 if(assistantExe.isEmpty()) {
638 assistantExe = ::Locate(assistantName);//assistantExe = ::Locate(assistantProgName);
640 QString assistant = QCoreApplication::applicationDirPath();
641 assistant += QDir::separator();
642 assistant += assistantName;
643 assistantExe = assistant;
647 this->Implementation->AssistantClient = new QAssistantClient(assistantExe, this);
648 QObject::connect(this->Implementation->AssistantClient, SIGNAL(error(const QString&)),
649 this, SLOT(assistantError(const QString&)));
652 args.append(QString("-profile"));
654 if(profileFile.isEmpty()) {
655 // see if help is bundled up with the application
656 QString profile = ::Locate("pqClient.adp");
657 /*QCoreApplication::applicationDirPath() + QDir::separator()
658 + QString("pqClient.adp");*/
660 if(QFile::exists(profile))
661 profileFile = profile;
664 if(profileFile.isEmpty() && getenv("PARAVIEW_HELP")) {
665 // not bundled, ask for help
666 args.append(getenv("PARAVIEW_HELP"));
668 else if(profileFile.isEmpty()) {
669 // no help, error out
670 SUIT_MessageBox::critical(getApp()->desktop(),"Help error", "Couldn't find"
671 " pqClient.adp.\nTry setting the PARAVIEW_HELP environment variable which"
672 " points to that file");
673 delete this->Implementation->AssistantClient;
677 QFileInfo fi(profileFile);
678 this->Implementation->DocumentationDir = fi.absolutePath();
680 args.append(profileFile);
682 this->Implementation->AssistantClient->setArguments(args);
686 \brief Slot to call the message handler with the critical message.
688 void PVGUI_Module::assistantError( const QString& error )
690 qCritical(error.toAscii().data());
694 \brief Slot to show the waiting state.
696 void PVGUI_Module::onPreAccept()
698 getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
699 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
703 \brief Slot to show the ready state.
705 void PVGUI_Module::onPostAccept()
707 getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
708 QTimer::singleShot(0, this, SLOT(endWaitCursor()));
712 \brief Slot to switch off wait cursor.
714 void PVGUI_Module::endWaitCursor()
716 QApplication::restoreOverrideCursor();
720 \brief Returns the ParaView multi-view manager.
722 pqViewManager* PVGUI_Module::getMultiViewManager() const
724 pqViewManager* aMVM = 0;
725 if ( Implementation )
726 aMVM = &Implementation->Core.multiViewManager();
731 \brief Processes QEvent::ActionAdded and QEvent::ActionRemoved from Lookmarks toolbar
732 in order to register/unregister this action in/from QtxActionToolMgr.
734 bool PVGUI_Module::eventFilter( QObject* theObject, QEvent* theEvent )
736 QToolBar* aTB = toolMgr()->toolBar(tr("TOOL_LOOKMARKS"));
737 if ( theObject == aTB ) {
739 if ( theEvent->type() == QEvent::ActionAdded ) {
740 QList<QAction*> anActns = aTB->actions();
741 for (int i = 0; i < anActns.size(); ++i)
742 if ( toolMgr()->actionId(anActns.at(i)) == -1 ) {
743 toolMgr()->setUpdatesEnabled(false);
744 createTool( anActns.at(i), tr("TOOL_LOOKMARKS") );
745 toolMgr()->setUpdatesEnabled(true);
749 if ( theEvent->type() == QEvent::ActionRemoved ) {
750 QList<QAction*> anActns = aTB->actions();
751 QIntList aIDL = toolMgr()->idList();
752 for (int i = 0; i < aIDL.size(); ++i) {
753 if ( toolMgr()->action(aIDL.at(i))->parent() == aTB
755 !anActns.contains( toolMgr()->action(aIDL.at(i)) ) ) {
756 toolMgr()->setUpdatesEnabled(false);
757 toolMgr()->unRegisterAction( aIDL.at(i) );
758 toolMgr()->remove( aIDL.at(i), tr("TOOL_LOOKMARKS") );
759 toolMgr()->setUpdatesEnabled(true);
766 return QObject::eventFilter( theObject, theEvent );
770 \brief Activate module.
771 \param study current study
772 \return \c true if activaion is done successfully or 0 to prevent
775 bool PVGUI_Module::activateModule( SUIT_Study* study )
777 bool isDone = LightApp_Module::activateModule( study );
778 if ( !isDone ) return false;
782 if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
783 if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
784 setMenuShown( true );
785 setToolShown( true );
787 toolMgr()->toolBar(tr("TOOL_LOOKMARKS"))->installEventFilter(this);
789 // Make default server connection
790 if ( Implementation )
791 Implementation->Core.makeDefaultConnectionIfNoneExists();
793 restoreDockWidgetsState();
800 \brief Deactivate module.
801 \param study current study
802 \return \c true if deactivaion is done successfully or 0 to prevent
803 deactivation on error
805 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
807 toolMgr()->toolBar(tr("TOOL_LOOKMARKS"))->removeEventFilter(this);
812 menuMgr()->hide(mySourcesMenuId);
813 menuMgr()->hide(myFiltersMenuId);
814 setMenuShown( false );
815 setToolShown( false );
817 saveDockWidgetsState();
819 return LightApp_Module::deactivateModule( study );
823 \brief Called when application is closed.
825 Process finalize application functionality from ParaView in order to save server settings
826 and nullify application pointer if the application is being closed.
828 \param theApp application
830 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
834 CAM_Module::onApplicationClosed(theApp);
838 \brief Compares the contents of the window with the given reference image,
839 returns true if they "match" within some tolerance.
841 bool PVGUI_Module::compareView( const QString& ReferenceImage, double Threshold,
842 ostream& Output, const QString& TempDirectory )
844 if ( Implementation )
845 return Implementation->Core.compareView( ReferenceImage, Threshold, Output, TempDirectory );
850 \fn CAM_Module* createModule();
851 \brief Export module instance (factory function).
852 \return new created instance of the module
856 #define PVGUI_EXPORT __declspec(dllexport)
862 PVGUI_EXPORT CAM_Module* createModule() {
863 return new PVGUI_Module();