1 // PARAVIS : ParaView wrapper SALOME module
3 // Copyright (C) 2010-2012 CEA/DEN, EDF R&D
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License.
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 // File : PVGUI_Module.cxx
22 // Author : Julia DOROVSKIKH
24 #include <Standard_math.hxx> // E.A. must be included before Python.h to fix compilation on windows
26 #undef HAVE_FINITE // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined
28 #include <vtkPython.h> // Python first
29 #include "PVGUI_Module.h"
31 #include "SALOMEconfig.h"
33 #include CORBA_CLIENT_HEADER(VISU_Gen)
35 #include CORBA_SERVER_HEADER(SALOMEDS)
38 #include "PARAVIS_Gen_i.hh"
42 #include "PVGUI_ViewModel.h"
43 #include "PVGUI_ViewManager.h"
44 #include "PVGUI_ViewWindow.h"
45 #include "PVGUI_Tools.h"
46 #include "PVGUI_ParaViewSettingsPane.h"
47 #include "PVGUI_OutputWindowAdapter.h"
49 #include <SUIT_DataBrowser.h>
50 #include <SUIT_Desktop.h>
51 #include <SUIT_MessageBox.h>
52 #include <SUIT_ResourceMgr.h>
53 #include <SUIT_Session.h>
54 #include <SUIT_OverrideCursor.h>
55 #include <SUIT_ExceptionHandler.h>
58 #include "SALOME_LifeCycleCORBA.hxx"
59 #include "SALOMEDS_SObject.hxx"
61 #include "LightApp_SelectionMgr.h"
62 #include "LightApp_NameDlg.h"
64 #include <SalomeApp_Application.h>
65 #include <SalomeApp_Study.h>
66 #include <SALOME_ListIO.hxx>
67 #include <SALOMEDS_Tool.hxx>
68 #include <PyInterp_Dispatcher.h>
70 #include <QtxActionMenuMgr.h>
71 #include <QtxActionToolMgr.h>
74 #include <QApplication>
80 #include <QInputDialog>
84 #include <QStringList>
87 #include <QTextStream>
89 #include <QDockWidget>
90 #include <QHelpEngine>
92 #include <pqApplicationCore.h>
93 #include <pqPVApplicationCore.h>
94 #include <pqActiveView.h>
95 #include <pqObjectBuilder.h>
96 #include <pqOptions.h>
97 #include <pqRenderView.h>
99 #include <pqUndoStack.h>
100 #include <pqVCRController.h>
101 #include <pqTabbedMultiViewWidget.h>
102 #include <pqPipelineSource.h>
103 #include <pqActiveObjects.h>
104 #include <vtkProcessModule.h>
105 #include <vtkSMSession.h>
106 #include <vtkPVProgressHandler.h>
107 #include <pqParaViewBehaviors.h>
108 #include <pqHelpReaction.h>
109 #include <vtkOutputWindow.h>
110 #include <pqPluginManager.h>
111 //#include <vtkPVPluginInformation.h>
112 #include "pqInterfaceTracker.h"
113 #include <pqSettings.h>
114 #include <pqPythonDialog.h>
115 #include <pqPythonManager.h>
116 #include <pqPythonShell.h>
117 #include <pqBrandPluginsLoader.h>
118 #include <pqLoadDataReaction.h>
119 #include <vtkEventQtSlotConnect.h>
120 #include <pqPythonScriptEditor.h>
121 #include <pqStandardSummaryPanelImplementation.h>
122 #include <pqCollaborationBehavior.h>
123 #include <pqDataRepresentation.h>
124 #include <pqPipelineRepresentation.h>
125 #include <pqLookupTableManager.h>
126 #include <pqDisplayColorWidget.h>
128 #include <PARAVIS_version.h>
130 #include <vtkPVConfig.h>
132 #include CORBA_SERVER_HEADER(SALOME_ModuleCatalog)
135 * Make sure all the kits register their classes with vtkInstantiator.
136 * Since ParaView uses Tcl wrapping, all of VTK is already compiled in
137 * anyway. The instantiators will add no more code for the linker to
141 #include <vtkCommonInstantiator.h>
142 #include <vtkFilteringInstantiator.h>
143 #include <vtkGenericFilteringInstantiator.h>
144 #include <vtkIOInstantiator.h>
145 #include <vtkImagingInstantiator.h>
146 #include <vtkInfovisInstantiator.h>
147 #include <vtkGraphicsInstantiator.h>
149 #include <vtkRenderingInstantiator.h>
150 #include <vtkVolumeRenderingInstantiator.h>
151 #include <vtkHybridInstantiator.h>
152 #include <vtkParallelInstantiator.h>
154 #include <pqAlwaysConnectedBehavior.h>
155 #include <pqApplicationCore.h>
156 #include <pqAutoLoadPluginXMLBehavior.h>
157 #include <pqCommandLineOptionsBehavior.h>
158 #include <pqCrashRecoveryBehavior.h>
159 #include <pqDataTimeStepBehavior.h>
160 #include <pqDefaultViewBehavior.h>
161 #include <pqDeleteBehavior.h>
162 #include <pqObjectPickingBehavior.h>
163 #include <pqPersistentMainWindowStateBehavior.h>
164 #include <pqPipelineContextMenuBehavior.h>
165 #include <pqPluginActionGroupBehavior.h>
166 #include <pqPluginDockWidgetsBehavior.h>
167 #include <pqPluginManager.h>
168 #include <pqPVNewSourceBehavior.h>
169 #include <pqSpreadSheetVisibilityBehavior.h>
170 #include <pqStandardViewModules.h>
171 #include <pqUndoRedoBehavior.h>
172 #include <pqViewFrameActionsBehavior.h>
173 #include <pqServerManagerObserver.h>
175 #include <vtkClientServerInterpreterInitializer.h>
178 //----------------------------------------------------------------------------
179 pqPVApplicationCore* PVGUI_Module::MyCoreApp = 0;
180 //PVGUI_OutputWindowAdapter* PVGUI_Module::pqImplementation::OutputWindowAdapter = 0;
181 //QPointer<pqHelpWindow> PVGUI_Module::pqImplementation::helpWindow = 0;
183 PVGUI_Module* ParavisModule = 0;
188 <h2>Building and installing PARAVIS</h2>
189 As any other SALOME module, PARAVIS requires PARAVIS_ROOT_DIR environment variable to be set to PARAVIS
190 installation directory.
191 Other variables needed for correct detection of ParaView location:
192 \li PVHOME - points at the ParaView installation directory tree
193 \li PVVERSION - number of ParaView version
195 It also requires common SALOME environment including GUI_ROOT_DIR and other prerequsites.
198 PARAVIS module can be launched using the following commands:
199 \li Full SALOME configuration
201 runSalome --modules="PARAVIS"
204 <h2>ParaView GUI integration</h2>
205 <h3>ParaView GUI integration overview</h3>
207 The main idea is to reuse ParaView GUI internal logic as much as possible, providing a layer
208 between it and SALOME GUI that hides the following SALOME GUI implementation details from ParaView:
210 \li SALOME GUI executable and Qt event loop
211 \li SALOME GUI desktop
212 \li Dock windows areas
213 \li SALOME menu and toolbar managers
215 Major part of the integration is implemented in PVGUI_Module class.
217 <h3>ParaView client initalization</h3>
219 ParaView client initalization is performed when an instance of PVGUI_Module class has been created
220 and \link PVGUI_Module::initialize() PVGUI_Module::initialize()\endlink method is called by SALOME GUI.
221 The actual client start-up is done in \link PVGUI_Module::pvInit() PVGUI_Module::pvInit()\endlink method.
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.
248 \brief Implementation
249 SALOME module wrapping ParaView GUI.
254 Fix for the issue 21730: [CEA 596] Slice of polyhedron in PARAVIS returns no cell.
255 Wrap vtkEDFCutter filter.
258 extern "C" void vtkEDFCutterCS_Initialize(vtkClientServerInterpreter*);
259 static void vtkEDFHelperInit();
261 void vtkEDFHelperInit(vtkClientServerInterpreter* interp){
262 vtkEDFCutterCS_Initialize(interp);
265 void vtkEDFHelperInit() {
266 vtkClientServerInterpreterInitializer::GetInitializer()->
267 RegisterCallback(&vtkEDFHelperInit);
272 ClientFindOrCreateParavisComponent(_PTR(Study) theStudyDocument)
274 _PTR(SComponent) aSComponent = theStudyDocument->FindComponent("PARAVIS");
276 _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
277 aStudyBuilder->NewCommand();
278 int aLocked = theStudyDocument->GetProperties()->IsLocked();
279 if (aLocked) theStudyDocument->GetProperties()->SetLocked(false);
280 aSComponent = aStudyBuilder->NewComponent("PARAVIS");
281 _PTR(GenericAttribute) anAttr =
282 aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeName");
283 _PTR(AttributeName) aName (anAttr);
285 CORBA::ORB_var anORB = PARAVIS::PARAVIS_Gen_i::GetORB();
286 SALOME_NamingService *NamingService = new SALOME_NamingService( anORB );
287 CORBA::Object_var objVarN = NamingService->Resolve("/Kernel/ModulCatalog");
288 SALOME_ModuleCatalog::ModuleCatalog_var Catalogue =
289 SALOME_ModuleCatalog::ModuleCatalog::_narrow(objVarN);
290 SALOME_ModuleCatalog::Acomponent_var Comp = Catalogue->GetComponent( "PARAVIS" );
291 if (!Comp->_is_nil()) {
292 aName->SetValue(Comp->componentusername());
295 anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributePixMap");
296 _PTR(AttributePixMap) aPixmap (anAttr);
297 aPixmap->SetPixMap( "pqAppIcon16.png" );
299 // Create Attribute parameters for future using
300 anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeParameter");
303 PARAVIS::PARAVIS_Gen_var aPARAVIS = PARAVIS::PARAVIS_Gen_i::GetParavisGenImpl()->_this();
305 aStudyBuilder->DefineComponentInstance(aSComponent, aPARAVIS->GetIOR());
306 if (aLocked) theStudyDocument->GetProperties()->SetLocked(true);
307 aStudyBuilder->CommitCommand();
313 Clean up function; used to stop ParaView progress events when
314 exception is caught by global exception handler.
316 void paravisCleanUp()
318 if ( pqApplicationCore::instance() ) {
319 pqServer* s = pqApplicationCore::instance()->getActiveServer();
320 if ( s ) s->session()->GetProgressHandler()->CleanupPendingProgress();
325 \brief Constructor. Sets the default name for the module.
327 PVGUI_Module::PVGUI_Module()
328 : SalomeApp_Module( "PARAVIS" ),
329 LightApp_Module( "PARAVIS" ),
330 // Implementation( 0 ),
331 mySelectionControlsTb( -1 ),
332 mySourcesMenuId( -1 ),
333 myFiltersMenuId( -1 ),
335 myToolbarsMenuId(-1),
342 Q_INIT_RESOURCE( PVGUI );
344 ParavisModule = this;
347 QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
351 QDir aDestDir(aDestPath);
352 QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files);
353 foreach (QString aStr, aDestFiles) {
354 aDestDir.remove(aStr);
361 PVGUI_Module::~PVGUI_Module()
368 \brief Initialize module. Creates menus, prepares context menu, etc.
369 \param app SALOME GUI application instance
371 void PVGUI_Module::initialize( CAM_Application* app )
373 SalomeApp_Module::initialize( app );
375 // Create ParaViS actions
377 // Create ParaViS menus
380 // Uncomment to debug ParaView initialization
381 // "aa" used instead of "i" as GDB doesn't like "i" variables :)
389 // Initialize ParaView client
392 // Create GUI elements (menus, toolbars, dock widgets)
393 //if ( !Implementation ){
394 SalomeApp_Application* anApp = getApp();
395 SUIT_Desktop* aDesktop = anApp->desktop();
397 // connect(aDesktop, SIGNAL()
399 // Remember current state of desktop toolbars
400 QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
402 // Simulate ParaView client main window
403 //Implementation = new pqImplementation( aDesktop );
411 // new pqParaViewBehaviors(anApp->desktop(), this);
412 // Has to be replaced in order to exclude using of pqQtMessageHandlerBehaviour
413 // Start pqParaViewBehaviors
414 // Register ParaView interfaces.
415 //pqPluginManager* pgm = pqApplicationCore::instance()->getPluginManager();
416 pqInterfaceTracker* pgm = pqApplicationCore::instance()->interfaceTracker();
418 // * adds support for standard paraview views.
419 pgm->addInterface(new pqStandardViewModules(pgm));
420 pgm->addInterface(new pqStandardSummaryPanelImplementation(pgm));
422 // Load plugins distributed with application.
423 pqApplicationCore::instance()->loadDistributedPlugins();
425 // Define application behaviors.
426 //new pqQtMessageHandlerBehavior(this);
427 new pqDataTimeStepBehavior(this);
428 new pqViewFrameActionsBehavior(this);
429 new pqSpreadSheetVisibilityBehavior(this);
430 new pqPipelineContextMenuBehavior(this);
431 new pqDefaultViewBehavior(this);
432 new pqAlwaysConnectedBehavior(this);
433 new pqPVNewSourceBehavior(this);
434 new pqDeleteBehavior(this);
435 new pqUndoRedoBehavior(this);
436 new pqCrashRecoveryBehavior(this);
437 new pqAutoLoadPluginXMLBehavior(this);
438 new pqPluginDockWidgetsBehavior(aDesktop);
439 //new pqVerifyRequiredPluginBehavior(this);
440 new pqPluginActionGroupBehavior(aDesktop);
441 //new pqFixPathsInStateFilesBehavior(this);
442 new pqCommandLineOptionsBehavior(this);
443 new pqPersistentMainWindowStateBehavior(aDesktop);
444 new pqObjectPickingBehavior(aDesktop);
445 new pqCollaborationBehavior(this);
447 // Setup quick-launch shortcuts.
448 QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
449 QObject::connect(ctrlSpace, SIGNAL(activated()),
450 pqApplicationCore::instance(), SLOT(quickLaunch()));
451 QShortcut *altSpace = new QShortcut(Qt::ALT + Qt::Key_Space, aDesktop);
452 QObject::connect(altSpace, SIGNAL(activated()),
453 pqApplicationCore::instance(), SLOT(quickLaunch()));
454 // End pqParaViewBehaviors
457 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
458 QString aPath = resMgr->stringValue("resources", "PARAVIS", QString());
459 if (!aPath.isNull()) {
460 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewFilters.xml");
461 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewReaders.xml");
462 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewSources.xml");
463 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewWriters.xml");
466 // Force creation of engine
467 PARAVIS::GetParavisGen(this);
470 // Find created toolbars
471 QCoreApplication::processEvents();
473 QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
474 foreach(QToolBar* aBar, allToolbars) {
475 if (!foreignToolbars.contains(aBar)) {
476 myToolbars[aBar] = true;
477 myToolbarBreaks[aBar] = false;
478 aBar->setVisible(false);
479 aBar->toggleViewAction()->setVisible(false);
486 // we need to start trace after connection is done
487 connect(pqApplicationCore::instance()->getObjectBuilder(), SIGNAL(finishedAddingServer(pqServer*)),
488 this, SLOT(onFinishedAddingServer(pqServer*)));
490 connect(pqApplicationCore::instance()->getObjectBuilder(), SIGNAL(dataRepresentationCreated(pqDataRepresentation*)),
491 this, SLOT(onDataRepresentationCreated(pqDataRepresentation*)));
494 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
495 bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false );
496 // start timer to activate trace in a proper moment
500 this->VTKConnect = vtkEventQtSlotConnect::New();
501 vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
503 this->VTKConnect->Connect(pm, vtkCommand::StartEvent,
504 this, SLOT(onStartProgress()));
505 this->VTKConnect->Connect(pm, vtkCommand::EndEvent,
506 this, SLOT(onEndProgress()));
508 connect(&pqActiveObjects::instance(),
509 SIGNAL(representationChanged(pqRepresentation*)),
510 this, SLOT(onRepresentationChanged(pqRepresentation*)));
513 void PVGUI_Module::onStartProgress()
515 QApplication::setOverrideCursor(Qt::WaitCursor);
518 void PVGUI_Module::onEndProgress()
520 QApplication::restoreOverrideCursor();
523 void PVGUI_Module::onFinishedAddingServer(pqServer* /*server*/)
525 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
526 bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false );
531 void PVGUI_Module::onDataRepresentationCreated(pqDataRepresentation* data) {
535 if(!data->getLookupTable())
538 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
542 bool visible = aResourceMgr->booleanValue( "PARAVIS", "show_color_legend", false );
543 pqLookupTableManager* lut_mgr = pqApplicationCore::instance()->getLookupTableManager();
546 lut_mgr->setScalarBarVisibility(data,visible);
550 void PVGUI_Module::onVariableChanged(pqVariableType t, const QString) {
552 pqDisplayColorWidget* colorWidget = qobject_cast<pqDisplayColorWidget*>(sender());
556 if( t == VARIABLE_TYPE_NONE )
559 pqDataRepresentation* data = colorWidget->getRepresentation();
561 if( !data->getLookupTable() )
564 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
569 bool visible = aResourceMgr->booleanValue( "PARAVIS", "show_color_legend", false );
574 pqLookupTableManager* lut_mgr = pqApplicationCore::instance()->getLookupTableManager();
577 lut_mgr->setScalarBarVisibility(data,visible);
584 \brief Launches a tracing of current server
586 void PVGUI_Module::timerEvent(QTimerEvent* te )
589 PyInterp_Dispatcher* aDispatcher = PyInterp_Dispatcher::Get();
590 if ( !aDispatcher->IsBusy() ) {
591 pqPythonManager* manager = qobject_cast<pqPythonManager*>
592 ( pqApplicationCore::instance()->manager( "PYTHON_MANAGER" ) );
594 pqPythonDialog* pyDiag = manager->pythonShellDialog();
596 pqPythonShell* shell = pyDiag->shell();
598 QString script = "from paraview import smtrace\nsmtrace.start_trace()\n";
599 shell->executeScript(script);
600 killTimer( te->timerId() );
608 void PVGUI_Module::updateMacros()
610 pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
611 if(!aPythonManager) {
615 QString aRootDir = getenv("PARAVIS_ROOT_DIR");
617 QString aSourcePath = aRootDir + "/bin/salome/Macro";
622 QDir aSourceDir(aSourcePath);
623 QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
624 foreach (QString aStr, aSourceFiles) {
625 aPythonManager->addMacro(aSourcePath + "/" + aStr);
631 \brief Get list of compliant dockable GUI elements
632 \param m map to be filled in ("type":"default_position")
634 void PVGUI_Module::windows( QMap<int, int>& m ) const
636 m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
637 m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
638 // ParaView diagnostic output redirected here
639 m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
643 \brief Static method, performs initialization of ParaView session.
644 \return \c true if ParaView has been initialized successfully, otherwise false
646 bool PVGUI_Module::pvInit()
648 // if ( !pqImplementation::Core ){
650 // Obtain command-line arguments
653 QString aOptions = getenv("PARAVIS_OPTIONS");
654 QStringList aOptList = aOptions.split(":", QString::SkipEmptyParts);
655 argv = new char*[aOptList.size() + 1];
656 QStringList args = QApplication::arguments();
657 argv[0] = (args.size() > 0)? strdup(args[0].toLatin1().constData()) : strdup("paravis");
660 foreach (QString aStr, aOptList) {
661 argv[argc] = strdup( aStr.toLatin1().constData() );
664 MyCoreApp = new pqPVApplicationCore (argc, argv);
665 if (MyCoreApp->getOptions()->GetHelpSelected() ||
666 MyCoreApp->getOptions()->GetUnknownArgument() ||
667 MyCoreApp->getOptions()->GetErrorMessage() ||
668 MyCoreApp->getOptions()->GetTellVersion()) {
672 // Not sure why this is needed. Andy added this ages ago with comment saying
673 // needed for Mac apps. Need to check that it's indeed still required.
674 QDir dir(QApplication::applicationDirPath());
677 QApplication::addLibraryPath(dir.absolutePath());
678 // Load required application plugins.
679 QString plugin_string = "";
680 QStringList plugin_list = plugin_string.split(';',QString::SkipEmptyParts);
681 pqBrandPluginsLoader loader;
682 if (loader.loadPlugins(plugin_list) == false) {
683 printf("Failed to load required plugins for this application\n");
687 // Load optional plugins.
689 plugin_list = plugin_string.split(';',QString::SkipEmptyParts);
690 loader.loadPlugins(plugin_list, true); //quietly skip not-found plugins.
692 // End of Initializer code
694 vtkOutputWindow::SetInstance(PVGUI_OutputWindowAdapter::New());
696 new pqTabbedMultiViewWidget(); // it registers as "MULTIVIEW_WIDGET on creation
698 for (int i = 0; i < argc; i++)
707 \brief Shows (toShow = true) or hides ParaView view window
709 void PVGUI_Module::showView( bool toShow )
711 SalomeApp_Application* anApp = getApp();
712 PVGUI_ViewManager* viewMgr =
713 dynamic_cast<PVGUI_ViewManager*>( anApp->getViewManager( PVGUI_Viewer::Type(), false ) );
715 viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() );
716 anApp->addViewManager( viewMgr );
717 connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
718 anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
721 PVGUI_ViewWindow* pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->getActiveView() );
723 pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->createViewWindow() );
726 pvWnd->setShown( toShow );
727 if ( toShow ) pvWnd->setFocus();
731 \brief Slot to show help for proxy.
733 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
735 pqHelpReaction::showProxyHelp(groupname, proxyname);
740 \brief Slot to show the waiting state.
742 void PVGUI_Module::onPreAccept()
744 getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
745 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
749 \brief Slot to show the ready state.
751 void PVGUI_Module::onPostAccept()
753 getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
754 QTimer::singleShot(0, this, SLOT(endWaitCursor()));
758 \brief Slot to switch off wait cursor.
760 void PVGUI_Module::endWaitCursor()
762 QApplication::restoreOverrideCursor();
766 \brief Returns the ParaView multi-view manager.
768 pqTabbedMultiViewWidget* PVGUI_Module::getMultiViewManager() const
770 return qobject_cast<pqTabbedMultiViewWidget*>(pqApplicationCore::instance()->manager("MULTIVIEW_WIDGET"));
774 static void ParavisMessageOutput(QtMsgType type, const char *msg)
779 vtkOutputWindow::GetInstance()->DisplayText(msg);
782 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
785 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
788 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
796 \brief Activate module.
797 \param study current study
798 \return \c true if activaion is done successfully or 0 to prevent
801 bool PVGUI_Module::activateModule( SUIT_Study* study )
803 myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
805 SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp );
807 bool isDone = SalomeApp_Module::activateModule( study );
808 if ( !isDone ) return false;
811 if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
812 if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
813 if ( myFiltersMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
814 if ( myFiltersMenuId != -1 ) menuMgr()->show(myToolbarsMenuId);
815 setMenuShown( true );
816 setToolShown( true );
818 restoreDockWidgetsState();
820 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
822 QList<QAction*> anActns = aMenu->actions();
823 for (int i = 0; i < anActns.size(); ++i) {
824 QAction* a = anActns.at(i);
830 if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
832 ClientFindOrCreateParavisComponent(PARAVIS::GetCStudy(this));
839 \brief Deactivate module.
840 \param study current study
841 \return \c true if deactivaion is done successfully or 0 to prevent
842 deactivation on error
844 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
846 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
848 QList<QAction*> anActns = aMenu->actions();
849 for (int i = 0; i < anActns.size(); ++i) {
850 QAction* a = anActns.at(i);
852 a->setVisible(false);
856 QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
857 foreach(QDockWidget* aView, aStreamingViews) {
858 if (!myDockWidgets.contains(aView))
859 myDockWidgets[aView] = aView->isVisible();
862 /*if (pqImplementation::helpWindow) {
863 pqImplementation::helpWindow->hide();
867 menuMgr()->hide(myRecentMenuId);
868 menuMgr()->hide(mySourcesMenuId);
869 menuMgr()->hide(myFiltersMenuId);
870 menuMgr()->hide(myMacrosMenuId);
871 menuMgr()->hide(myToolbarsMenuId);
872 setMenuShown( false );
873 setToolShown( false );
876 saveDockWidgetsState();
878 SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
881 qInstallMsgHandler(myOldMsgHandler);
883 return SalomeApp_Module::deactivateModule( study );
888 \brief Called when application is closed.
890 Process finalize application functionality from ParaView in order to save server settings
891 and nullify application pointer if the application is being closed.
893 \param theApp application
895 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
897 pqApplicationCore::instance()->settings()->sync();
898 int aAppsNb = SUIT_Session::session()->applications().size();
900 deleteTemporaryFiles();
901 MyCoreApp->deleteLater();
903 CAM_Module::onApplicationClosed(theApp);
908 \brief Called when study is closed.
910 Removes data model from the \a study.
912 \param study study being closed
914 void PVGUI_Module::studyClosed(SUIT_Study* study)
916 clearParaviewState();
918 SalomeApp_Module::studyClosed(study);
922 \brief Called when study is opened.
924 void PVGUI_Module::onModelOpened()
926 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
931 _PTR(SComponent) paravisComp =
932 studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType());
937 _PTR(ChildIterator) anIter(studyDS->NewChildIterator(paravisComp));
938 for (; anIter->More(); anIter->Next()) {
939 _PTR(SObject) aSObj = anIter->Value();
940 _PTR(GenericAttribute) anAttr;
941 if (!aSObj->FindAttribute(anAttr, "AttributeLocalID")) {
944 _PTR(AttributeLocalID) anID(anAttr);
945 if (anID->Value() == PVSTATEID) {
952 \brief Returns IOR of current engine
954 QString PVGUI_Module::engineIOR() const
956 CORBA::String_var anIOR = PARAVIS::GetParavisGen(this)->GetIOR();
957 return QString(anIOR.in());
962 \brief Open file of format supported by ParaView
964 void PVGUI_Module::openFile(const char* theName)
968 pqLoadDataReaction::loadData(aFiles);
971 void PVGUI_Module::executeScript(const char *script)
974 pqPythonManager* manager = qobject_cast<pqPythonManager*>(
975 pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
977 pqPythonDialog* pyDiag = manager->pythonShellDialog();
979 pyDiag->runString(script);
986 \brief Returns trace string
988 static const QString MYReplaceStr("paraview.simple");
989 static const QString MYReplaceImportStr("except: from pvsimple import *");
990 QString PVGUI_Module::getTraceString()
994 pqPythonManager* manager = qobject_cast<pqPythonManager*>(
995 pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
997 pqPythonDialog* pyDiag = manager->pythonShellDialog();
999 pyDiag->runString("from paraview import smtrace\n"
1000 "__smtraceString = smtrace.get_trace_string()\n");
1001 pyDiag->shell()->makeCurrent();
1002 PyObject* main_module = PyImport_AddModule((char*)"__main__");
1003 PyObject* global_dict = PyModule_GetDict(main_module);
1004 PyObject* string_object = PyDict_GetItemString(global_dict, "__smtraceString");
1005 char* string_ptr = string_object ? PyString_AsString(string_object) : 0;
1007 traceString = string_ptr;
1009 pyDiag->shell()->releaseControl();
1012 if ((!traceString.isNull()) && traceString.length() != 0) {
1013 int aPos = traceString.indexOf(MYReplaceStr);
1014 while (aPos != -1) {
1015 traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple");
1016 aPos = traceString.indexOf(MYReplaceStr, aPos);
1018 int aImportPos = traceString.indexOf(MYReplaceImportStr);
1019 if(aImportPos != -1)
1021 traceString = traceString.replace(aImportPos, MYReplaceImportStr.length(), "except:\n import pvsimple\n from pvsimple import *");
1029 \brief Saves trace string to disk file
1031 void PVGUI_Module::saveTrace(const char* theName)
1033 QFile file(theName);
1034 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
1035 MESSAGE( "Could not open file:" << theName );
1038 QTextStream out(&file);
1039 out << getTraceString();
1044 \brief Saves ParaView state to a disk file
1046 void PVGUI_Module::saveParaviewState(const char* theFileName)
1048 pqApplicationCore::instance()->saveState(theFileName);
1052 \brief Delete all objects for Paraview Pipeline Browser
1054 void PVGUI_Module::clearParaviewState()
1056 QAction* deleteAllAction = action(DeleteAllId);
1057 if (deleteAllAction) {
1058 deleteAllAction->activate(QAction::Trigger);
1063 \brief Restores ParaView state from a disk file
1065 If toClear == true, the current ojects will be deleted
1067 void PVGUI_Module::loadParaviewState(const char* theFileName)
1069 pqApplicationCore::instance()->loadState(theFileName, getActiveServer());
1073 \brief Imports MED data from VISU module by data entry
1075 void PVGUI_Module::onImportFromVisu(QString theEntry)
1078 SUIT_OverrideCursor aWaitCursor;
1081 SalomeApp_Study* activeStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
1082 if(!activeStudy) return;
1084 // get SALOMEDS client study
1085 _PTR(Study) aStudy = activeStudy->studyDS();
1088 // find VISU component in a study
1089 _PTR(SComponent) aVisuComp = aStudy->FindComponent( "VISU" );
1090 if(!aVisuComp) return;
1092 // get SObject client by entry
1093 _PTR(SObject) aSObj = aStudy->FindObjectID(qPrintable(theEntry));
1096 // get CORBA SObject
1097 SALOMEDS_SObject* aSObject = _CAST(SObject, aSObj);
1098 if ( !aSObject ) return;
1101 SALOME_NamingService* aNamingService = SalomeApp_Application::namingService();
1102 SALOME_LifeCycleCORBA aLCC(aNamingService);
1104 Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","VISU");
1105 VISU::VISU_Gen_var aVISU = VISU::VISU_Gen::_narrow(aComponent);
1106 if(CORBA::is_nil(aVISU)) return;
1108 _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
1109 aStudyBuilder->LoadWith( aVisuComp, SalomeApp_Application::orb()->object_to_string(aVISU) );
1111 // get VISU result object
1112 CORBA::Object_var aResultObject = aSObject->GetObject();
1113 if (CORBA::is_nil(aResultObject)) return;
1114 VISU::Result_var aResult = VISU::Result::_narrow( aResultObject );
1115 if (CORBA::is_nil(aResult)) return;
1117 // export VISU result to the MED file
1118 std::string aTmpDir = SALOMEDS_Tool::GetTmpDir();
1119 std::string aFileName = aSObject->GetName();
1120 std::string aFilePath = aTmpDir + aFileName;
1122 if (aResult->ExportMED(aFilePath.c_str())) {
1123 openFile(aFilePath.c_str());
1124 myTemporaryFiles.append(QString(aFilePath.c_str()));
1127 MESSAGE("Visu module is not found.");
1132 \brief Deletes temporary files created during import operation from VISU
1134 void PVGUI_Module::deleteTemporaryFiles()
1136 foreach(QString aFile, myTemporaryFiles) {
1137 if (QFile::exists(aFile)) {
1138 QFile::remove(aFile);
1145 \brief Returns current active ParaView server
1147 pqServer* PVGUI_Module::getActiveServer()
1149 return pqApplicationCore::instance()->getActiveServer();
1154 \brief Creates PARAVIS preference pane
1156 void PVGUI_Module::createPreferences()
1158 // Paraview settings tab
1159 int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
1160 int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, "PARAVIS", "");
1161 setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane()));
1163 // Paravis settings tab
1164 int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
1165 addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, "PARAVIS", "stop_trace");
1167 int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
1168 LightApp_Preferences::Selector,
1169 "PARAVIS", "savestate_type");
1170 QList<QVariant> aIndices;
1171 QStringList aStrings;
1173 aStrings<<tr("PREF_SAVE_TYPE_0");
1174 aStrings<<tr("PREF_SAVE_TYPE_1");
1175 aStrings<<tr("PREF_SAVE_TYPE_2");
1176 setPreferenceProperty(aSaveType, "strings", aStrings);
1177 setPreferenceProperty(aSaveType, "indexes", aIndices);
1179 //rnv: imp 21712: [CEA 581] Preference to display legend by default
1180 int aDispColoreLegend = addPreference( tr( "PREF_SHOW_COLOR_LEGEND" ), aParaVisSettingsTab,
1181 LightApp_Preferences::Bool, "PARAVIS", "show_color_legend");
1185 \brief Creates ParaViS context menu popup
1187 void PVGUI_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
1189 SalomeApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
1191 // Check if we are in Object Browser
1192 SUIT_DataBrowser* ob = getApp()->objectBrowser();
1193 bool isOBClient = (ob && theClient == ob->popupClientType());
1198 // Get list of selected objects
1199 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1200 SALOME_ListIO aListIO;
1201 aSelectionMgr->selectedObjects(aListIO);
1202 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1203 QString entry = QString(aListIO.First()->getEntry());
1206 SalomeApp_Study* activeStudy =
1207 dynamic_cast<SalomeApp_Study*>(getApp()->activeStudy());
1212 // Get SALOMEDS client study
1213 _PTR(Study) studyDS = activeStudy->studyDS();
1218 QString paravisDataType(PARAVIS::GetParavisGen(this)->ComponentDataType());
1219 if(activeStudy && activeStudy->isComponent(entry) &&
1220 activeStudy->componentDataType(entry) == paravisDataType) {
1221 // ParaViS module object
1222 theMenu->addSeparator();
1223 theMenu->addAction(action(SaveStatePopupId));
1226 // Try to get state object
1227 _PTR(SObject) stateSObj =
1228 studyDS->FindObjectID(entry.toLatin1().constData());
1234 _PTR(GenericAttribute) anAttr;
1235 if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1239 _PTR(AttributeLocalID) anID(anAttr);
1241 if (anID->Value() == PVSTATEID) {
1242 // Paraview state object
1243 theMenu->addSeparator();
1244 theMenu->addAction(action(AddStatePopupId));
1245 theMenu->addAction(action(CleanAndAddStatePopupId));
1246 theMenu->addSeparator();
1247 theMenu->addAction(action(ParaVisRenameId));
1248 theMenu->addAction(action(ParaVisDeleteId));
1254 void PVGUI_Module::onShowTrace()
1256 if (!myTraceWindow) {
1257 myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
1259 myTraceWindow->setText(getTraceString());
1260 myTraceWindow->show();
1261 myTraceWindow->raise();
1262 myTraceWindow->activateWindow();
1266 \brief Show ParaView view.
1268 void PVGUI_Module::onNewParaViewWindow()
1274 \brief Save state under the module root object.
1276 void PVGUI_Module::onSaveMultiState()
1278 // Create state study object
1280 // Get SALOMEDS client study
1281 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1286 _PTR(SComponent) paravisComp =
1287 studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType());
1292 // Unlock the study if it is locked
1293 bool isLocked = studyDS->GetProperties()->IsLocked();
1295 studyDS->GetProperties()->SetLocked(false);
1298 QString stateName = tr("SAVED_PARAVIEW_STATE_NAME") +
1299 QString::number(myStateCounter + 1);
1301 _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1302 _PTR(SObject) newSObj = studyBuilder->NewObject(paravisComp);
1305 _PTR(GenericAttribute) anAttr;
1306 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeName");
1307 _PTR(AttributeName) nameAttr(anAttr);
1309 nameAttr->SetValue(stateName.toLatin1().constData());
1312 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeLocalID");
1313 _PTR(AttributeLocalID) localIdAttr(anAttr);
1315 localIdAttr->SetValue(PVSTATEID);
1318 QString stateEntry = QString::fromStdString(newSObj->GetID());
1320 // File name for state saving
1321 QString tmpDir = QString::fromStdString(SALOMEDS_Tool::GetTmpDir());
1322 QString fileName = QString("%1_paravisstate:%2").arg(tmpDir,
1325 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeString");
1326 _PTR(AttributeString) stringAttr(anAttr);
1328 stringAttr->SetValue(fileName.toLatin1().constData());
1330 // Lock the study back if necessary
1332 studyDS->GetProperties()->SetLocked(true);
1336 saveParaviewState(fileName.toLatin1().constData());
1337 myTemporaryFiles.append(fileName);
1339 // Increment the counter
1346 \brief Restore the selected state by merging with the current one.
1348 void PVGUI_Module::onAddState()
1350 loadSelectedState(false);
1354 \brief Clean the current state and restore the selected one.
1356 void PVGUI_Module::onCleanAddState()
1358 loadSelectedState(true);
1362 \brief Rename the selected object.
1364 void PVGUI_Module::onRename()
1366 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1367 SALOME_ListIO aListIO;
1368 aSelectionMgr->selectedObjects(aListIO);
1370 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1371 std::string entry = aListIO.First()->getEntry();
1373 // Get SALOMEDS client study
1374 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1379 // Unlock the study if it is locked
1380 bool isLocked = studyDS->GetProperties()->IsLocked();
1382 studyDS->GetProperties()->SetLocked(false);
1385 // Rename the selected state object
1386 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1391 _PTR(GenericAttribute) anAttr;
1392 if (stateSObj->FindAttribute(anAttr, "AttributeName")) {
1393 _PTR(AttributeName) nameAttr (anAttr);
1395 LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str());
1396 if (!newName.isEmpty()) {
1397 nameAttr->SetValue(newName.toLatin1().constData());
1398 aListIO.First()->setName(newName.toLatin1().constData());
1402 // Lock the study back if necessary
1404 studyDS->GetProperties()->SetLocked(true);
1407 // Update object browser
1414 \brief Delete the selected objects.
1416 void PVGUI_Module::onDelete()
1418 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1419 SALOME_ListIO aListIO;
1420 aSelectionMgr->selectedObjects(aListIO);
1422 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1423 std::string entry = aListIO.First()->getEntry();
1425 // Get SALOMEDS client study
1426 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1431 // Unlock the study if it is locked
1432 bool isLocked = studyDS->GetProperties()->IsLocked();
1434 studyDS->GetProperties()->SetLocked(false);
1437 // Remove the selected state from the study
1438 _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1439 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1440 studyBuilder->RemoveObject(stateSObj);
1442 // Lock the study back if necessary
1444 studyDS->GetProperties()->SetLocked(true);
1447 // Update object browser
1453 \brief Discover help project files from the resources.
1454 \return name of the help file.
1456 QString PVGUI_Module::getHelpFileName() {
1457 QString aPVHome(getenv("PVHOME"));
1458 if (aPVHome.isNull()) {
1459 qWarning("Wariable PVHOME is not defined");
1462 QChar aSep = QDir::separator();
1463 //PARAVIEW_VERSION from the vtkPVConfig.h file
1464 QString aFileName = aPVHome + aSep + "share" + aSep + "doc" + aSep + "paraview-"+ PARAVIEW_VERSION + aSep + "paraview.qch";
1470 \brief Load selected paraview state
1472 If toClear == true, the current state will be cleared
1474 void PVGUI_Module::loadSelectedState(bool toClear)
1478 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1479 SALOME_ListIO aListIO;
1480 aSelectionMgr->selectedObjects(aListIO);
1482 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1483 std::string entry = aListIO.First()->getEntry();
1485 // Get SALOMEDS client study
1486 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1492 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1493 _PTR(GenericAttribute) anAttr;
1494 if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1497 _PTR(AttributeLocalID) anID(anAttr);
1498 if (!anID->Value() == PVSTATEID) {
1502 // Get state file name
1503 if (stateSObj->FindAttribute(anAttr, "AttributeString")) {
1504 _PTR(AttributeString) aStringAttr(anAttr);
1505 QString stringValue(aStringAttr->Value().c_str());
1507 if (QFile::exists(stringValue)) {
1508 fileName = stringValue;
1513 if (!fileName.isEmpty()) {
1515 clearParaviewState();
1518 loadParaviewState(fileName.toLatin1().constData());
1521 SUIT_MessageBox::critical(getApp()->desktop(),
1523 tr("ERR_STATE_CANNOT_BE_RESTORED"));
1527 void PVGUI_Module::onRepresentationChanged(pqRepresentation*) {
1530 //rnv: to fix the issue "21712: [CEA 581] Preference to display legend by default"
1531 // find the pqDisplayColorWidget instances and connect the variableChanged SIGNAL on the
1532 // onVariableChanged slot of this class. This connection needs to change visibility
1533 // of the "Colored Legend" after change the "Color By" array.
1534 QList<pqDisplayColorWidget*> aWidget = getApp()->desktop()->findChildren<pqDisplayColorWidget*>();
1536 for (int i = 0; i < aWidget.size() ; i++ ) {
1538 connect( aWidget[i], SIGNAL ( variableChanged ( pqVariableType, const QString ) ),
1539 this, SLOT(onVariableChanged( pqVariableType, const QString) ), Qt::UniqueConnection );
1546 \fn CAM_Module* createModule();
1547 \brief Export module instance (factory function).
1548 \return new created instance of the module
1552 #define PVGUI_EXPORT __declspec(dllexport)
1554 #define PVGUI_EXPORT
1560 PVGUI_EXPORT CAM_Module* createModule() {
1565 return new PVGUI_Module();
1568 PVGUI_EXPORT char* getModuleVersion() {
1569 return (char*)PARAVIS_VERSION_STR;