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 // Implementation( 0 ),
330 mySelectionControlsTb( -1 ),
331 mySourcesMenuId( -1 ),
332 myFiltersMenuId( -1 ),
334 myToolbarsMenuId(-1),
341 Q_INIT_RESOURCE( PVGUI );
343 ParavisModule = this;
346 QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
350 QDir aDestDir(aDestPath);
351 QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files);
352 foreach (QString aStr, aDestFiles) {
353 aDestDir.remove(aStr);
360 PVGUI_Module::~PVGUI_Module()
367 \brief Initialize module. Creates menus, prepares context menu, etc.
368 \param app SALOME GUI application instance
370 void PVGUI_Module::initialize( CAM_Application* app )
372 SalomeApp_Module::initialize( app );
374 // Create ParaViS actions
376 // Create ParaViS menus
379 // Uncomment to debug ParaView initialization
380 // "aa" used instead of "i" as GDB doesn't like "i" variables :)
388 // Initialize ParaView client
391 // Create GUI elements (menus, toolbars, dock widgets)
392 //if ( !Implementation ){
393 SalomeApp_Application* anApp = getApp();
394 SUIT_Desktop* aDesktop = anApp->desktop();
396 // connect(aDesktop, SIGNAL()
398 // Remember current state of desktop toolbars
399 QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
401 // Simulate ParaView client main window
402 //Implementation = new pqImplementation( aDesktop );
410 // new pqParaViewBehaviors(anApp->desktop(), this);
411 // Has to be replaced in order to exclude using of pqQtMessageHandlerBehaviour
412 // Start pqParaViewBehaviors
413 // Register ParaView interfaces.
414 //pqPluginManager* pgm = pqApplicationCore::instance()->getPluginManager();
415 pqInterfaceTracker* pgm = pqApplicationCore::instance()->interfaceTracker();
417 // * adds support for standard paraview views.
418 pgm->addInterface(new pqStandardViewModules(pgm));
419 pgm->addInterface(new pqStandardSummaryPanelImplementation(pgm));
421 // Load plugins distributed with application.
422 pqApplicationCore::instance()->loadDistributedPlugins();
424 // Define application behaviors.
425 //new pqQtMessageHandlerBehavior(this);
426 new pqDataTimeStepBehavior(this);
427 new pqViewFrameActionsBehavior(this);
428 new pqSpreadSheetVisibilityBehavior(this);
429 new pqPipelineContextMenuBehavior(this);
430 new pqDefaultViewBehavior(this);
431 new pqAlwaysConnectedBehavior(this);
432 new pqPVNewSourceBehavior(this);
433 new pqDeleteBehavior(this);
434 new pqUndoRedoBehavior(this);
435 new pqCrashRecoveryBehavior(this);
436 new pqAutoLoadPluginXMLBehavior(this);
437 new pqPluginDockWidgetsBehavior(aDesktop);
438 //new pqVerifyRequiredPluginBehavior(this);
439 new pqPluginActionGroupBehavior(aDesktop);
440 //new pqFixPathsInStateFilesBehavior(this);
441 new pqCommandLineOptionsBehavior(this);
442 new pqPersistentMainWindowStateBehavior(aDesktop);
443 new pqObjectPickingBehavior(aDesktop);
444 new pqCollaborationBehavior(this);
446 // Setup quick-launch shortcuts.
447 QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
448 QObject::connect(ctrlSpace, SIGNAL(activated()),
449 pqApplicationCore::instance(), SLOT(quickLaunch()));
450 QShortcut *altSpace = new QShortcut(Qt::ALT + Qt::Key_Space, aDesktop);
451 QObject::connect(altSpace, SIGNAL(activated()),
452 pqApplicationCore::instance(), SLOT(quickLaunch()));
453 // End pqParaViewBehaviors
456 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
457 QString aPath = resMgr->stringValue("resources", "PARAVIS", QString());
458 if (!aPath.isNull()) {
459 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewFilters.xml");
460 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewReaders.xml");
461 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewSources.xml");
462 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewWriters.xml");
465 // Force creation of engine
466 PARAVIS::GetParavisGen(this);
469 // Find created toolbars
470 QCoreApplication::processEvents();
472 QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
473 foreach(QToolBar* aBar, allToolbars) {
474 if (!foreignToolbars.contains(aBar)) {
475 myToolbars[aBar] = true;
476 myToolbarBreaks[aBar] = false;
477 aBar->setVisible(false);
478 aBar->toggleViewAction()->setVisible(false);
485 // we need to start trace after connection is done
486 connect(pqApplicationCore::instance()->getObjectBuilder(), SIGNAL(finishedAddingServer(pqServer*)),
487 this, SLOT(onFinishedAddingServer(pqServer*)));
489 connect(pqApplicationCore::instance()->getObjectBuilder(), SIGNAL(dataRepresentationCreated(pqDataRepresentation*)),
490 this, SLOT(onDataRepresentationCreated(pqDataRepresentation*)));
493 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
494 bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false );
495 // start timer to activate trace in a proper moment
499 this->VTKConnect = vtkEventQtSlotConnect::New();
500 vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
502 this->VTKConnect->Connect(pm, vtkCommand::StartEvent,
503 this, SLOT(onStartProgress()));
504 this->VTKConnect->Connect(pm, vtkCommand::EndEvent,
505 this, SLOT(onEndProgress()));
507 connect(&pqActiveObjects::instance(),
508 SIGNAL(representationChanged(pqRepresentation*)),
509 this, SLOT(onRepresentationChanged(pqRepresentation*)));
512 void PVGUI_Module::onStartProgress()
514 QApplication::setOverrideCursor(Qt::WaitCursor);
517 void PVGUI_Module::onEndProgress()
519 QApplication::restoreOverrideCursor();
522 void PVGUI_Module::onFinishedAddingServer(pqServer* /*server*/)
524 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
525 bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false );
530 void PVGUI_Module::onDataRepresentationCreated(pqDataRepresentation* data) {
534 if(!data->getLookupTable())
537 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
541 bool visible = aResourceMgr->booleanValue( "PARAVIS", "show_color_legend", false );
542 pqLookupTableManager* lut_mgr = pqApplicationCore::instance()->getLookupTableManager();
545 lut_mgr->setScalarBarVisibility(data,visible);
549 void PVGUI_Module::onVariableChanged(pqVariableType t, const QString) {
551 pqDisplayColorWidget* colorWidget = qobject_cast<pqDisplayColorWidget*>(sender());
555 if( t == VARIABLE_TYPE_NONE )
558 pqDataRepresentation* data = colorWidget->getRepresentation();
560 if( !data->getLookupTable() )
563 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
568 bool visible = aResourceMgr->booleanValue( "PARAVIS", "show_color_legend", false );
573 pqLookupTableManager* lut_mgr = pqApplicationCore::instance()->getLookupTableManager();
576 lut_mgr->setScalarBarVisibility(data,visible);
583 \brief Launches a tracing of current server
585 void PVGUI_Module::timerEvent(QTimerEvent* te )
588 PyInterp_Dispatcher* aDispatcher = PyInterp_Dispatcher::Get();
589 if ( !aDispatcher->IsBusy() ) {
590 pqPythonManager* manager = qobject_cast<pqPythonManager*>
591 ( pqApplicationCore::instance()->manager( "PYTHON_MANAGER" ) );
593 pqPythonDialog* pyDiag = manager->pythonShellDialog();
595 pqPythonShell* shell = pyDiag->shell();
597 QString script = "from paraview import smtrace\nsmtrace.start_trace()\n";
598 shell->executeScript(script);
599 killTimer( te->timerId() );
607 void PVGUI_Module::updateMacros()
609 pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
610 if(!aPythonManager) {
614 QString aRootDir = getenv("PARAVIS_ROOT_DIR");
616 QString aSourcePath = aRootDir + "/bin/salome/Macro";
621 QDir aSourceDir(aSourcePath);
622 QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
623 foreach (QString aStr, aSourceFiles) {
624 aPythonManager->addMacro(aSourcePath + "/" + aStr);
630 \brief Get list of compliant dockable GUI elements
631 \param m map to be filled in ("type":"default_position")
633 void PVGUI_Module::windows( QMap<int, int>& m ) const
635 m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
636 m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
637 // ParaView diagnostic output redirected here
638 m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
642 \brief Static method, performs initialization of ParaView session.
643 \return \c true if ParaView has been initialized successfully, otherwise false
645 bool PVGUI_Module::pvInit()
647 // if ( !pqImplementation::Core ){
649 // Obtain command-line arguments
652 QString aOptions = getenv("PARAVIS_OPTIONS");
653 QStringList aOptList = aOptions.split(":", QString::SkipEmptyParts);
654 argv = new char*[aOptList.size() + 1];
655 QStringList args = QApplication::arguments();
656 argv[0] = (args.size() > 0)? strdup(args[0].toLatin1().constData()) : strdup("paravis");
659 foreach (QString aStr, aOptList) {
660 argv[argc] = strdup( aStr.toLatin1().constData() );
663 MyCoreApp = new pqPVApplicationCore (argc, argv);
664 if (MyCoreApp->getOptions()->GetHelpSelected() ||
665 MyCoreApp->getOptions()->GetUnknownArgument() ||
666 MyCoreApp->getOptions()->GetErrorMessage() ||
667 MyCoreApp->getOptions()->GetTellVersion()) {
671 // Not sure why this is needed. Andy added this ages ago with comment saying
672 // needed for Mac apps. Need to check that it's indeed still required.
673 QDir dir(QApplication::applicationDirPath());
676 QApplication::addLibraryPath(dir.absolutePath());
677 // Load required application plugins.
678 QString plugin_string = "";
679 QStringList plugin_list = plugin_string.split(';',QString::SkipEmptyParts);
680 pqBrandPluginsLoader loader;
681 if (loader.loadPlugins(plugin_list) == false) {
682 printf("Failed to load required plugins for this application\n");
686 // Load optional plugins.
688 plugin_list = plugin_string.split(';',QString::SkipEmptyParts);
689 loader.loadPlugins(plugin_list, true); //quietly skip not-found plugins.
691 // End of Initializer code
693 vtkOutputWindow::SetInstance(PVGUI_OutputWindowAdapter::New());
695 new pqTabbedMultiViewWidget(); // it registers as "MULTIVIEW_WIDGET on creation
697 for (int i = 0; i < argc; i++)
706 \brief Shows (toShow = true) or hides ParaView view window
708 void PVGUI_Module::showView( bool toShow )
710 SalomeApp_Application* anApp = getApp();
711 PVGUI_ViewManager* viewMgr =
712 dynamic_cast<PVGUI_ViewManager*>( anApp->getViewManager( PVGUI_Viewer::Type(), false ) );
714 viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() );
715 anApp->addViewManager( viewMgr );
716 connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
717 anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
720 PVGUI_ViewWindow* pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->getActiveView() );
722 pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->createViewWindow() );
725 pvWnd->setShown( toShow );
726 if ( toShow ) pvWnd->setFocus();
730 \brief Slot to show help for proxy.
732 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
734 pqHelpReaction::showProxyHelp(groupname, proxyname);
739 \brief Slot to show the waiting state.
741 void PVGUI_Module::onPreAccept()
743 getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
744 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
748 \brief Slot to show the ready state.
750 void PVGUI_Module::onPostAccept()
752 getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
753 QTimer::singleShot(0, this, SLOT(endWaitCursor()));
757 \brief Slot to switch off wait cursor.
759 void PVGUI_Module::endWaitCursor()
761 QApplication::restoreOverrideCursor();
765 \brief Returns the ParaView multi-view manager.
767 pqTabbedMultiViewWidget* PVGUI_Module::getMultiViewManager() const
769 return qobject_cast<pqTabbedMultiViewWidget*>(pqApplicationCore::instance()->manager("MULTIVIEW_WIDGET"));
773 static void ParavisMessageOutput(QtMsgType type, const char *msg)
778 vtkOutputWindow::GetInstance()->DisplayText(msg);
781 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
784 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
787 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
795 \brief Activate module.
796 \param study current study
797 \return \c true if activaion is done successfully or 0 to prevent
800 bool PVGUI_Module::activateModule( SUIT_Study* study )
802 myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
804 SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp );
806 bool isDone = SalomeApp_Module::activateModule( study );
807 if ( !isDone ) return false;
810 if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
811 if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
812 if ( myFiltersMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
813 if ( myFiltersMenuId != -1 ) menuMgr()->show(myToolbarsMenuId);
814 setMenuShown( true );
815 setToolShown( true );
817 restoreDockWidgetsState();
819 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
821 QList<QAction*> anActns = aMenu->actions();
822 for (int i = 0; i < anActns.size(); ++i) {
823 QAction* a = anActns.at(i);
829 if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
831 ClientFindOrCreateParavisComponent(PARAVIS::GetCStudy(this));
838 \brief Deactivate module.
839 \param study current study
840 \return \c true if deactivaion is done successfully or 0 to prevent
841 deactivation on error
843 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
845 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
847 QList<QAction*> anActns = aMenu->actions();
848 for (int i = 0; i < anActns.size(); ++i) {
849 QAction* a = anActns.at(i);
851 a->setVisible(false);
855 QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
856 foreach(QDockWidget* aView, aStreamingViews) {
857 if (!myDockWidgets.contains(aView))
858 myDockWidgets[aView] = aView->isVisible();
861 /*if (pqImplementation::helpWindow) {
862 pqImplementation::helpWindow->hide();
866 menuMgr()->hide(myRecentMenuId);
867 menuMgr()->hide(mySourcesMenuId);
868 menuMgr()->hide(myFiltersMenuId);
869 menuMgr()->hide(myMacrosMenuId);
870 menuMgr()->hide(myToolbarsMenuId);
871 setMenuShown( false );
872 setToolShown( false );
875 saveDockWidgetsState();
877 SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
880 qInstallMsgHandler(myOldMsgHandler);
882 return SalomeApp_Module::deactivateModule( study );
887 \brief Called when application is closed.
889 Process finalize application functionality from ParaView in order to save server settings
890 and nullify application pointer if the application is being closed.
892 \param theApp application
894 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
896 pqApplicationCore::instance()->settings()->sync();
897 int aAppsNb = SUIT_Session::session()->applications().size();
899 deleteTemporaryFiles();
900 MyCoreApp->deleteLater();
902 CAM_Module::onApplicationClosed(theApp);
907 \brief Called when study is closed.
909 Removes data model from the \a study.
911 \param study study being closed
913 void PVGUI_Module::studyClosed(SUIT_Study* study)
915 clearParaviewState();
917 SalomeApp_Module::studyClosed(study);
921 \brief Called when study is opened.
923 void PVGUI_Module::onModelOpened()
925 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
930 _PTR(SComponent) paravisComp =
931 studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType());
936 _PTR(ChildIterator) anIter(studyDS->NewChildIterator(paravisComp));
937 for (; anIter->More(); anIter->Next()) {
938 _PTR(SObject) aSObj = anIter->Value();
939 _PTR(GenericAttribute) anAttr;
940 if (!aSObj->FindAttribute(anAttr, "AttributeLocalID")) {
943 _PTR(AttributeLocalID) anID(anAttr);
944 if (anID->Value() == PVSTATEID) {
951 \brief Returns IOR of current engine
953 QString PVGUI_Module::engineIOR() const
955 CORBA::String_var anIOR = PARAVIS::GetParavisGen(this)->GetIOR();
956 return QString(anIOR.in());
961 \brief Open file of format supported by ParaView
963 void PVGUI_Module::openFile(const char* theName)
967 pqLoadDataReaction::loadData(aFiles);
970 void PVGUI_Module::executeScript(const char *script)
973 pqPythonManager* manager = qobject_cast<pqPythonManager*>(
974 pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
976 pqPythonDialog* pyDiag = manager->pythonShellDialog();
978 pyDiag->runString(script);
985 \brief Returns trace string
987 static const QString MYReplaceStr("paraview.simple");
988 static const QString MYReplaceImportStr("except: from pvsimple import *");
989 QString PVGUI_Module::getTraceString()
993 pqPythonManager* manager = qobject_cast<pqPythonManager*>(
994 pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
996 pqPythonDialog* pyDiag = manager->pythonShellDialog();
998 pyDiag->runString("from paraview import smtrace\n"
999 "__smtraceString = smtrace.get_trace_string()\n");
1000 pyDiag->shell()->makeCurrent();
1001 PyObject* main_module = PyImport_AddModule((char*)"__main__");
1002 PyObject* global_dict = PyModule_GetDict(main_module);
1003 PyObject* string_object = PyDict_GetItemString(global_dict, "__smtraceString");
1004 char* string_ptr = string_object ? PyString_AsString(string_object) : 0;
1006 traceString = string_ptr;
1008 pyDiag->shell()->releaseControl();
1011 if ((!traceString.isNull()) && traceString.length() != 0) {
1012 int aPos = traceString.indexOf(MYReplaceStr);
1013 while (aPos != -1) {
1014 traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple");
1015 aPos = traceString.indexOf(MYReplaceStr, aPos);
1017 int aImportPos = traceString.indexOf(MYReplaceImportStr);
1018 if(aImportPos != -1)
1020 traceString = traceString.replace(aImportPos, MYReplaceImportStr.length(), "except:\n import pvsimple\n from pvsimple import *");
1028 \brief Saves trace string to disk file
1030 void PVGUI_Module::saveTrace(const char* theName)
1032 QFile file(theName);
1033 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
1034 MESSAGE( "Could not open file:" << theName );
1037 QTextStream out(&file);
1038 out << getTraceString();
1043 \brief Saves ParaView state to a disk file
1045 void PVGUI_Module::saveParaviewState(const char* theFileName)
1047 pqApplicationCore::instance()->saveState(theFileName);
1051 \brief Delete all objects for Paraview Pipeline Browser
1053 void PVGUI_Module::clearParaviewState()
1055 QAction* deleteAllAction = action(DeleteAllId);
1056 if (deleteAllAction) {
1057 deleteAllAction->activate(QAction::Trigger);
1062 \brief Restores ParaView state from a disk file
1064 If toClear == true, the current ojects will be deleted
1066 void PVGUI_Module::loadParaviewState(const char* theFileName)
1068 pqApplicationCore::instance()->loadState(theFileName, getActiveServer());
1072 \brief Imports MED data from VISU module by data entry
1074 void PVGUI_Module::onImportFromVisu(QString theEntry)
1077 SUIT_OverrideCursor aWaitCursor;
1080 SalomeApp_Study* activeStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
1081 if(!activeStudy) return;
1083 // get SALOMEDS client study
1084 _PTR(Study) aStudy = activeStudy->studyDS();
1087 // find VISU component in a study
1088 _PTR(SComponent) aVisuComp = aStudy->FindComponent( "VISU" );
1089 if(!aVisuComp) return;
1091 // get SObject client by entry
1092 _PTR(SObject) aSObj = aStudy->FindObjectID(qPrintable(theEntry));
1095 // get CORBA SObject
1096 SALOMEDS_SObject* aSObject = _CAST(SObject, aSObj);
1097 if ( !aSObject ) return;
1100 SALOME_NamingService* aNamingService = SalomeApp_Application::namingService();
1101 SALOME_LifeCycleCORBA aLCC(aNamingService);
1103 Engines::EngineComponent_var aComponent = aLCC.FindOrLoad_Component("FactoryServer","VISU");
1104 VISU::VISU_Gen_var aVISU = VISU::VISU_Gen::_narrow(aComponent);
1105 if(CORBA::is_nil(aVISU)) return;
1107 _PTR(StudyBuilder) aStudyBuilder = aStudy->NewBuilder();
1108 aStudyBuilder->LoadWith( aVisuComp, SalomeApp_Application::orb()->object_to_string(aVISU) );
1110 // get VISU result object
1111 CORBA::Object_var aResultObject = aSObject->GetObject();
1112 if (CORBA::is_nil(aResultObject)) return;
1113 VISU::Result_var aResult = VISU::Result::_narrow( aResultObject );
1114 if (CORBA::is_nil(aResult)) return;
1116 // export VISU result to the MED file
1117 std::string aTmpDir = SALOMEDS_Tool::GetTmpDir();
1118 std::string aFileName = aSObject->GetName();
1119 std::string aFilePath = aTmpDir + aFileName;
1121 if (aResult->ExportMED(aFilePath.c_str())) {
1122 openFile(aFilePath.c_str());
1123 myTemporaryFiles.append(QString(aFilePath.c_str()));
1126 MESSAGE("Visu module is not found.");
1131 \brief Deletes temporary files created during import operation from VISU
1133 void PVGUI_Module::deleteTemporaryFiles()
1135 foreach(QString aFile, myTemporaryFiles) {
1136 if (QFile::exists(aFile)) {
1137 QFile::remove(aFile);
1144 \brief Returns current active ParaView server
1146 pqServer* PVGUI_Module::getActiveServer()
1148 return pqApplicationCore::instance()->getActiveServer();
1153 \brief Creates PARAVIS preference pane
1155 void PVGUI_Module::createPreferences()
1157 // Paraview settings tab
1158 int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
1159 int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, "PARAVIS", "");
1160 setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane()));
1162 // Paravis settings tab
1163 int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
1164 addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, "PARAVIS", "stop_trace");
1166 int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
1167 LightApp_Preferences::Selector,
1168 "PARAVIS", "savestate_type");
1169 QList<QVariant> aIndices;
1170 QStringList aStrings;
1172 aStrings<<tr("PREF_SAVE_TYPE_0");
1173 aStrings<<tr("PREF_SAVE_TYPE_1");
1174 aStrings<<tr("PREF_SAVE_TYPE_2");
1175 setPreferenceProperty(aSaveType, "strings", aStrings);
1176 setPreferenceProperty(aSaveType, "indexes", aIndices);
1178 //rnv: imp 21712: [CEA 581] Preference to display legend by default
1179 int aDispColoreLegend = addPreference( tr( "PREF_SHOW_COLOR_LEGEND" ), aParaVisSettingsTab,
1180 LightApp_Preferences::Bool, "PARAVIS", "show_color_legend");
1184 \brief Creates ParaViS context menu popup
1186 void PVGUI_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
1188 SalomeApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
1190 // Check if we are in Object Browser
1191 SUIT_DataBrowser* ob = getApp()->objectBrowser();
1192 bool isOBClient = (ob && theClient == ob->popupClientType());
1197 // Get list of selected objects
1198 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1199 SALOME_ListIO aListIO;
1200 aSelectionMgr->selectedObjects(aListIO);
1201 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1202 QString entry = QString(aListIO.First()->getEntry());
1205 SalomeApp_Study* activeStudy =
1206 dynamic_cast<SalomeApp_Study*>(getApp()->activeStudy());
1211 // Get SALOMEDS client study
1212 _PTR(Study) studyDS = activeStudy->studyDS();
1217 QString paravisDataType(PARAVIS::GetParavisGen(this)->ComponentDataType());
1218 if(activeStudy && activeStudy->isComponent(entry) &&
1219 activeStudy->componentDataType(entry) == paravisDataType) {
1220 // ParaViS module object
1221 theMenu->addSeparator();
1222 theMenu->addAction(action(SaveStatePopupId));
1225 // Try to get state object
1226 _PTR(SObject) stateSObj =
1227 studyDS->FindObjectID(entry.toLatin1().constData());
1233 _PTR(GenericAttribute) anAttr;
1234 if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1238 _PTR(AttributeLocalID) anID(anAttr);
1240 if (anID->Value() == PVSTATEID) {
1241 // Paraview state object
1242 theMenu->addSeparator();
1243 theMenu->addAction(action(AddStatePopupId));
1244 theMenu->addAction(action(CleanAndAddStatePopupId));
1245 theMenu->addSeparator();
1246 theMenu->addAction(action(ParaVisRenameId));
1247 theMenu->addAction(action(ParaVisDeleteId));
1253 void PVGUI_Module::onShowTrace()
1255 if (!myTraceWindow) {
1256 myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
1258 myTraceWindow->setText(getTraceString());
1259 myTraceWindow->show();
1260 myTraceWindow->raise();
1261 myTraceWindow->activateWindow();
1265 \brief Show ParaView view.
1267 void PVGUI_Module::onNewParaViewWindow()
1273 \brief Save state under the module root object.
1275 void PVGUI_Module::onSaveMultiState()
1277 // Create state study object
1279 // Get SALOMEDS client study
1280 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1285 _PTR(SComponent) paravisComp =
1286 studyDS->FindComponent(PARAVIS::GetParavisGen(this)->ComponentDataType());
1291 // Unlock the study if it is locked
1292 bool isLocked = studyDS->GetProperties()->IsLocked();
1294 studyDS->GetProperties()->SetLocked(false);
1297 QString stateName = tr("SAVED_PARAVIEW_STATE_NAME") +
1298 QString::number(myStateCounter + 1);
1300 _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1301 _PTR(SObject) newSObj = studyBuilder->NewObject(paravisComp);
1304 _PTR(GenericAttribute) anAttr;
1305 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeName");
1306 _PTR(AttributeName) nameAttr(anAttr);
1308 nameAttr->SetValue(stateName.toLatin1().constData());
1311 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeLocalID");
1312 _PTR(AttributeLocalID) localIdAttr(anAttr);
1314 localIdAttr->SetValue(PVSTATEID);
1317 QString stateEntry = QString::fromStdString(newSObj->GetID());
1319 // File name for state saving
1320 QString tmpDir = QString::fromStdString(SALOMEDS_Tool::GetTmpDir());
1321 QString fileName = QString("%1_paravisstate:%2").arg(tmpDir,
1324 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeString");
1325 _PTR(AttributeString) stringAttr(anAttr);
1327 stringAttr->SetValue(fileName.toLatin1().constData());
1329 // Lock the study back if necessary
1331 studyDS->GetProperties()->SetLocked(true);
1335 saveParaviewState(fileName.toLatin1().constData());
1336 myTemporaryFiles.append(fileName);
1338 // Increment the counter
1345 \brief Restore the selected state by merging with the current one.
1347 void PVGUI_Module::onAddState()
1349 loadSelectedState(false);
1353 \brief Clean the current state and restore the selected one.
1355 void PVGUI_Module::onCleanAddState()
1357 loadSelectedState(true);
1361 \brief Rename the selected object.
1363 void PVGUI_Module::onRename()
1365 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1366 SALOME_ListIO aListIO;
1367 aSelectionMgr->selectedObjects(aListIO);
1369 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1370 std::string entry = aListIO.First()->getEntry();
1372 // Get SALOMEDS client study
1373 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1378 // Unlock the study if it is locked
1379 bool isLocked = studyDS->GetProperties()->IsLocked();
1381 studyDS->GetProperties()->SetLocked(false);
1384 // Rename the selected state object
1385 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1390 _PTR(GenericAttribute) anAttr;
1391 if (stateSObj->FindAttribute(anAttr, "AttributeName")) {
1392 _PTR(AttributeName) nameAttr (anAttr);
1394 LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str());
1395 if (!newName.isEmpty()) {
1396 nameAttr->SetValue(newName.toLatin1().constData());
1397 aListIO.First()->setName(newName.toLatin1().constData());
1401 // Lock the study back if necessary
1403 studyDS->GetProperties()->SetLocked(true);
1406 // Update object browser
1413 \brief Delete the selected objects.
1415 void PVGUI_Module::onDelete()
1417 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1418 SALOME_ListIO aListIO;
1419 aSelectionMgr->selectedObjects(aListIO);
1421 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1422 std::string entry = aListIO.First()->getEntry();
1424 // Get SALOMEDS client study
1425 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1430 // Unlock the study if it is locked
1431 bool isLocked = studyDS->GetProperties()->IsLocked();
1433 studyDS->GetProperties()->SetLocked(false);
1436 // Remove the selected state from the study
1437 _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1438 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1439 studyBuilder->RemoveObject(stateSObj);
1441 // Lock the study back if necessary
1443 studyDS->GetProperties()->SetLocked(true);
1446 // Update object browser
1452 \brief Discover help project files from the resources.
1453 \return name of the help file.
1455 QString PVGUI_Module::getHelpFileName() {
1456 QString aPVHome(getenv("PVHOME"));
1457 if (aPVHome.isNull()) {
1458 qWarning("Wariable PVHOME is not defined");
1461 QChar aSep = QDir::separator();
1462 //PARAVIEW_VERSION from the vtkPVConfig.h file
1463 QString aFileName = aPVHome + aSep + "share" + aSep + "doc" + aSep + "paraview-"+ PARAVIEW_VERSION + aSep + "paraview.qch";
1469 \brief Load selected paraview state
1471 If toClear == true, the current state will be cleared
1473 void PVGUI_Module::loadSelectedState(bool toClear)
1477 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1478 SALOME_ListIO aListIO;
1479 aSelectionMgr->selectedObjects(aListIO);
1481 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1482 std::string entry = aListIO.First()->getEntry();
1484 // Get SALOMEDS client study
1485 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1491 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1492 _PTR(GenericAttribute) anAttr;
1493 if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1496 _PTR(AttributeLocalID) anID(anAttr);
1497 if (!anID->Value() == PVSTATEID) {
1501 // Get state file name
1502 if (stateSObj->FindAttribute(anAttr, "AttributeString")) {
1503 _PTR(AttributeString) aStringAttr(anAttr);
1504 QString stringValue(aStringAttr->Value().c_str());
1506 if (QFile::exists(stringValue)) {
1507 fileName = stringValue;
1512 if (!fileName.isEmpty()) {
1514 clearParaviewState();
1517 loadParaviewState(fileName.toLatin1().constData());
1520 SUIT_MessageBox::critical(getApp()->desktop(),
1522 tr("ERR_STATE_CANNOT_BE_RESTORED"));
1526 void PVGUI_Module::onRepresentationChanged(pqRepresentation*) {
1529 //rnv: to fix the issue "21712: [CEA 581] Preference to display legend by default"
1530 // find the pqDisplayColorWidget instances and connect the variableChanged SIGNAL on the
1531 // onVariableChanged slot of this class. This connection needs to change visibility
1532 // of the "Colored Legend" after change the "Color By" array.
1533 QList<pqDisplayColorWidget*> aWidget = getApp()->desktop()->findChildren<pqDisplayColorWidget*>();
1535 for (int i = 0; i < aWidget.size() ; i++ ) {
1537 connect( aWidget[i], SIGNAL ( variableChanged ( pqVariableType, const QString ) ),
1538 this, SLOT(onVariableChanged( pqVariableType, const QString) ), Qt::UniqueConnection );
1545 \fn CAM_Module* createModule();
1546 \brief Export module instance (factory function).
1547 \return new created instance of the module
1551 #define PVGUI_EXPORT __declspec(dllexport)
1553 #define PVGUI_EXPORT
1559 PVGUI_EXPORT CAM_Module* createModule() {
1564 return new PVGUI_Module();
1567 PVGUI_EXPORT char* getModuleVersion() {
1568 return (char*)PARAVIS_VERSION_STR;