1 // PARAVIS : ParaView wrapper SALOME module
3 // Copyright (C) 2010-2014 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, or (at your option) any later version.
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
23 #include <Standard_math.hxx> // E.A. must be included before Python.h to fix compilation on windows
25 #undef HAVE_FINITE // VSR: avoid compilation warning on Linux : "HAVE_FINITE" redefined
27 #include <vtkPython.h> // Python first
28 #include "PVGUI_Module.h"
30 #ifdef PARAVIS_WITH_FULL_CORBA
31 # include "PARAVIS_Gen_i.hh"
34 #include CORBA_SERVER_HEADER(SALOME_ModuleCatalog)
35 #include CORBA_SERVER_HEADER(SALOMEDS)
37 #include "PVGUI_ViewModel.h"
38 #include "PVGUI_ViewManager.h"
39 #include "PVGUI_ViewWindow.h"
40 #include "PVGUI_Tools.h"
41 #include "PVGUI_ParaViewSettingsPane.h"
42 #include "PVGUI_OutputWindowAdapter.h"
43 #include "PVGUI_Behaviors.h"
46 #include <SUIT_DataBrowser.h>
47 #include <SUIT_Desktop.h>
48 #include <SUIT_MessageBox.h>
49 #include <SUIT_ResourceMgr.h>
50 #include <SUIT_Session.h>
51 #include <SUIT_OverrideCursor.h>
52 #include <SUIT_ExceptionHandler.h>
54 #include <SALOME_LifeCycleCORBA.hxx>
55 #include <SALOMEDS_SObject.hxx>
57 #include <LightApp_SelectionMgr.h>
58 #include <LightApp_NameDlg.h>
59 #include <SalomeApp_Application.h>
60 #include <SalomeApp_Study.h>
61 #include <SALOME_ListIO.hxx>
62 #include <SALOMEDS_Tool.hxx>
63 #include <Utils_ORB_INIT.hxx>
64 #include <Utils_SINGLETON.hxx>
66 #include <QtxActionMenuMgr.h>
67 #include <QtxActionToolMgr.h>
69 #include <PARAVIS_version.h>
75 #include <QApplication>
81 #include <QInputDialog>
85 #include <QStringList>
88 #include <QTextStream>
90 #include <QDockWidget>
91 #include <QHelpEngine>
94 #include <vtkPVConfig.h> // for symbol PARAVIEW_VERSION
95 #include <vtkProcessModule.h>
96 #include <vtkPVSession.h>
97 #include <vtkPVProgressHandler.h>
98 #include <vtkOutputWindow.h>
99 #include <vtkEventQtSlotConnect.h>
101 #include <vtkSMProxy.h>
102 #include <vtkSmartPointer.h>
103 #include <vtkSMSession.h>
104 #include <vtkSMTrace.h>
105 #include <vtkSMSessionProxyManager.h>
106 #include <vtkSMParaViewPipelineController.h>
108 #include <pqApplicationCore.h>
109 #include <pqPVApplicationCore.h>
110 #include <pqActiveView.h>
111 #include <pqObjectBuilder.h>
112 #include <pqOptions.h>
113 #include <pqSettings.h>
114 #include <pqServer.h>
115 #include <pqUndoStack.h>
116 #include <pqTabbedMultiViewWidget.h>
117 #include <pqActiveObjects.h>
118 #include <pqHelpReaction.h>
119 #include <pqPluginManager.h>
120 #include <pqPythonDialog.h>
121 #include <pqPythonManager.h>
122 #include <pqLoadDataReaction.h>
123 #include <pqPythonScriptEditor.h>
124 #include <pqDataRepresentation.h>
125 #include <pqDisplayColorWidget.h>
126 #include <pqColorToolbar.h>
127 #include <pqScalarBarVisibilityReaction.h>
128 #include <pqServerResource.h>
129 #include <pqServerConnectReaction.h>
130 #include <pqServerDisconnectReaction.h>
132 //----------------------------------------------------------------------------
133 pqPVApplicationCore* PVGUI_Module::MyCoreApp = 0;
135 PVGUI_Module* ParavisModule = 0;
137 PARAVIS_ORB::PARAVIS_Gen_var PVGUI_Module::myEngine;
142 <h2>Building and installing PARAVIS</h2>
143 As any other SALOME module, PARAVIS requires PARAVIS_ROOT_DIR environment variable to be set to PARAVIS
144 installation directory.
145 Other variables needed for correct detection of ParaView location:
146 \li PVHOME - points at the ParaView installation directory tree
147 \li PVVERSION - number of ParaView version
149 It also requires common SALOME environment including GUI_ROOT_DIR and other prerequsites.
152 PARAVIS module can be launched using the following commands:
153 \li Full SALOME configuration
155 runSalome --modules="PARAVIS"
158 <h2>ParaView GUI integration</h2>
159 <h3>ParaView GUI integration overview</h3>
161 The main idea is to reuse ParaView GUI internal logic as much as possible, providing a layer
162 between it and SALOME GUI that hides the following SALOME GUI implementation details from ParaView:
164 \li SALOME GUI executable and Qt event loop
165 \li SALOME GUI desktop
166 \li Dock windows areas
167 \li SALOME menu and toolbar managers
169 Major part of the integration is implemented in PVGUI_Module class.
171 <h3>ParaView client initalization</h3>
173 ParaView client initalization is performed when an instance of PVGUI_Module class has been created
174 and \link PVGUI_Module::initialize() PVGUI_Module::initialize()\endlink method is called by SALOME GUI.
175 The actual client start-up is done in \link PVGUI_Module::pvInit() PVGUI_Module::pvInit()\endlink method.
178 <h3>Multi-view manager</h3>
180 SALOME GUI requires that each kind of view be implemnted with help of (at least) three classes. For ParaView multi-view manager
183 \li PVGUI_ViewManager - view manager class
184 \li PVGUI_Viewer - view model class
185 \li PVGUI_ViewWindow - view window class that acts as a parent for %pqViewManager
187 Single instances of PVGUI_ViewManager and PVGUI_ViewWindow classes are created by \link PVGUI_Module::showView()
188 PVGUI_Module::showView()\endlink method upon the first PARAVIS module activation. The same method hides the multi-view manager
189 when the module is deactivated (the user switches to another module or a study is closed).
190 A special trick is used to make PVGUI_ViewWindow the parent of %pqViewManager widget. It is created initally by %pqMainWindowCore
191 with the desktop as a parent, so when it is shown PVGUI_ViewWindow instance is passed to its setParent() method. In
192 \link PVGUI_ViewWindow::~PVGUI_ViewWindow() PVGUI_ViewWindow::~PVGUI_ViewWindow()\endlink the parent is nullified to avoid deletion
193 of %pqViewManager widget that would break %pqMainWindowCore class.
195 <h3>ParaView plugins</h3>
196 ParaView server and client plugins are managed by %pqMainWindowCore slots that has full access to PARAVIS menus and toolbars.
197 As a result they appears automatically in PARAVIS menus and toolbars if loaded successfully.
202 \brief Implementation
203 SALOME module wrapping ParaView GUI.
207 ClientFindOrCreateParavisComponent(_PTR(Study) theStudyDocument)
209 _PTR(SComponent) aSComponent = theStudyDocument->FindComponent("PARAVIS");
211 _PTR(StudyBuilder) aStudyBuilder = theStudyDocument->NewBuilder();
212 aStudyBuilder->NewCommand();
213 int aLocked = theStudyDocument->GetProperties()->IsLocked();
214 if (aLocked) theStudyDocument->GetProperties()->SetLocked(false);
215 aSComponent = aStudyBuilder->NewComponent("PARAVIS");
216 _PTR(GenericAttribute) anAttr =
217 aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeName");
218 _PTR(AttributeName) aName (anAttr);
220 ORB_INIT& init = *SINGLETON_<ORB_INIT>::Instance();
221 CORBA::ORB_var anORB = init( qApp->argc(), qApp->argv() );
223 SALOME_NamingService *NamingService = new SALOME_NamingService( anORB );
224 CORBA::Object_var objVarN = NamingService->Resolve("/Kernel/ModulCatalog");
225 SALOME_ModuleCatalog::ModuleCatalog_var Catalogue =
226 SALOME_ModuleCatalog::ModuleCatalog::_narrow(objVarN);
227 SALOME_ModuleCatalog::Acomponent_var Comp = Catalogue->GetComponent( "PARAVIS" );
228 if (!Comp->_is_nil()) {
229 aName->SetValue(Comp->componentusername());
232 anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributePixMap");
233 _PTR(AttributePixMap) aPixmap (anAttr);
234 aPixmap->SetPixMap( "pqAppIcon16.png" );
236 // Create Attribute parameters for future using
237 anAttr = aStudyBuilder->FindOrCreateAttribute(aSComponent, "AttributeParameter");
239 aStudyBuilder->DefineComponentInstance(aSComponent, PVGUI_Module::GetEngine()->GetIOR());
240 if (aLocked) theStudyDocument->GetProperties()->SetLocked(true);
241 aStudyBuilder->CommitCommand();
247 Clean up function; used to stop ParaView progress events when
248 exception is caught by global exception handler.
250 void paravisCleanUp()
252 if ( pqApplicationCore::instance() ) {
253 pqServer* s = pqApplicationCore::instance()->getActiveServer();
254 if ( s ) s->session()->GetProgressHandler()->CleanupPendingProgress();
259 \brief Constructor. Sets the default name for the module.
261 PVGUI_Module::PVGUI_Module()
262 : SalomeApp_Module( "PARAVIS" ),
263 mySelectionControlsTb( -1 ),
264 mySourcesMenuId( -1 ),
265 myFiltersMenuId( -1 ),
267 myToolbarsMenuId(-1),
276 Q_INIT_RESOURCE( PVGUI );
278 ParavisModule = this;
280 // Clear old copies of embedded macros files
281 QString aDestPath = QString( "%1/.config/%2/Macros" ).arg( QDir::homePath() ).arg( QApplication::applicationName() );
285 QDir aDestDir(aDestPath);
286 QStringList aDestFiles = aDestDir.entryList(aFilter, QDir::Files);
287 foreach (QString aMacrosPath, getEmbeddedMacrosList()) {
288 QString aMacrosName = QFileInfo(aMacrosPath).fileName();
289 if (aDestFiles.contains(aMacrosName)) {
290 aDestDir.remove(aMacrosName);
298 PVGUI_Module::~PVGUI_Module()
300 if (myPushTraceTimer)
301 delete myPushTraceTimer;
304 // Disconnect from server
305 pqServer* server = pqActiveObjects::instance().activeServer();
306 if (server && server->isRemote())
308 MESSAGE("~PVGUI_Module(): Disconnecting from remote server ...");
309 pqServerDisconnectReaction::disconnectFromServer();
313 PARAVIS_ORB::PARAVIS_Gen_var PVGUI_Module::GetEngine()
315 // initialize PARAVIS module engine (load, if necessary)
316 if ( CORBA::is_nil( myEngine ) ) {
317 Engines::EngineComponent_var comp =
318 SalomeApp_Application::lcc()->FindOrLoad_Component( "FactoryServer", "PARAVIS" );
319 myEngine = PARAVIS_ORB::PARAVIS_Gen::_narrow( comp );
325 \brief Initialize module. Creates menus, prepares context menu, etc.
326 \param app SALOME GUI application instance
328 void PVGUI_Module::initialize( CAM_Application* app )
330 SalomeApp_Module::initialize( app );
332 // Create ParaViS actions
334 // Create ParaViS menus
337 // Uncomment to debug ParaView initialization
338 // "aa" used instead of "i" as GDB doesn't like "i" variables :)
346 // Initialize ParaView client
349 // Create GUI elements (menus, toolbars, dock widgets)
350 SalomeApp_Application* anApp = getApp();
351 SUIT_Desktop* aDesktop = anApp->desktop();
353 // Remember current state of desktop toolbars
354 QList<QToolBar*> foreignToolbars = aDesktop->findChildren<QToolBar*>();
362 QList<QDockWidget*> activeDocks = aDesktop->findChildren<QDockWidget*>();
363 QList<QMenu*> activeMenus = aDesktop->findChildren<QMenu*>();
365 PVGUI_Behaviors * behav = new PVGUI_Behaviors(this);
366 behav->instanciateAllBehaviors(aDesktop);
368 // Setup quick-launch shortcuts.
369 QShortcut *ctrlSpace = new QShortcut(Qt::CTRL + Qt::Key_Space, aDesktop);
370 QObject::connect(ctrlSpace, SIGNAL(activated()),
371 pqApplicationCore::instance(), SLOT(quickLaunch()));
373 // Find Plugin Dock Widgets
374 QList<QDockWidget*> currentDocks = aDesktop->findChildren<QDockWidget*>();
375 QList<QDockWidget*>::iterator i;
376 for (i = currentDocks.begin(); i != currentDocks.end(); ++i) {
377 if(!activeDocks.contains(*i)) {
378 myDockWidgets[*i] = false; // hidden by default
384 // [ABN] TODO: fix this - triggers a SEGFAULT at deactivation() time.
385 // QList<QMenu*> currentMenus = aDesktop->findChildren<QMenu*>();
386 // QList<QMenu*>::iterator im;
387 // for (im = currentMenus.begin(); im != currentMenus.end(); ++im) {
388 // if(!activeMenus.contains(*im)) {
389 // QString s = (*im)->title();
390 // std::cout << " MENU "<< s.toStdString() << std::endl;
391 // myMenus.append(*im);
395 SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
396 QString aPath = resMgr->stringValue("resources", "PARAVIS", QString());
397 if (!aPath.isNull()) {
398 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewFilters.xml");
399 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewReaders.xml");
400 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewSources.xml");
401 MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewWriters.xml");
404 // Force creation of the PARAVIS engine
408 // Find created toolbars
409 QCoreApplication::processEvents();
411 QList<QToolBar*> allToolbars = aDesktop->findChildren<QToolBar*>();
412 foreach(QToolBar* aBar, allToolbars) {
413 if (!foreignToolbars.contains(aBar)) {
414 myToolbars[aBar] = true;
415 myToolbarBreaks[aBar] = false;
416 aBar->setVisible(false);
417 aBar->toggleViewAction()->setVisible(false);
423 // we need to start trace after connection is done
424 connect(pqApplicationCore::instance()->getObjectBuilder(), SIGNAL(finishedAddingServer(pqServer*)),
425 this, SLOT(onFinishedAddingServer(pqServer*)));
427 connect(pqApplicationCore::instance()->getObjectBuilder(), SIGNAL(dataRepresentationCreated(pqDataRepresentation*)),
428 this, SLOT(onDataRepresentationCreated(pqDataRepresentation*)));
430 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
431 bool isStop = aResourceMgr->booleanValue( "PARAVIS", "stop_trace", false );
434 // Start a timer to schedule asap:
435 // - the connection to the server
437 myInitTimer = new QTimer(aDesktop);
438 QObject::connect(myInitTimer, SIGNAL(timeout()), this, SLOT(onInitTimer()) );
439 myInitTimer->setSingleShot(true);
440 myInitTimer->start(0);
442 // Another timer to regularly push the trace onto the engine:
443 myPushTraceTimer = new QTimer(aDesktop);
444 QObject::connect(myPushTraceTimer, SIGNAL(timeout()), this, SLOT(onPushTraceTimer()) );
445 myPushTraceTimer->setSingleShot(false);
446 myPushTraceTimer->start(500);
449 this->VTKConnect = vtkEventQtSlotConnect::New();
451 vtkProcessModule* pm = vtkProcessModule::GetProcessModule();
453 vtkPVSession* pvs = dynamic_cast<vtkPVSession*>(pm->GetSession());
455 vtkPVProgressHandler* ph = pvs->GetProgressHandler();
457 this->VTKConnect->Connect(ph, vtkCommand::StartEvent,
458 this, SLOT(onStartProgress()));
459 this->VTKConnect->Connect(ph, vtkCommand::EndEvent,
460 this, SLOT(onEndProgress()));
465 connect(&pqActiveObjects::instance(),
466 SIGNAL(representationChanged(pqRepresentation*)),
467 this, SLOT(onRepresentationChanged(pqRepresentation*)));
470 bool PVGUI_Module::connectToExternalPVServer()
472 pqServer* server = pqActiveObjects::instance().activeServer();
473 if (server && server->isRemote())
475 // Already connected to an external server, do nothing
476 MESSAGE("connectToExternalPVServer(): Already connected to an external PVServer, won't reconnect.");
480 std::stringstream msg;
482 // Try to connect to the external PVServer - gives priority to an externally specified URL:
483 QString serverUrlEnv = getenv("PARAVIS_PVSERVER_URL");
484 std::string serverUrl;
485 if (!serverUrlEnv.isEmpty())
486 serverUrl = serverUrlEnv.toStdString();
489 // Get the URL from the engine (possibly starting the pvserver)
490 CORBA::String_var url = GetEngine()->FindOrStartPVServer(0); // take the first free port
491 serverUrl = (char *)url;
494 msg << "connectToExternalPVServer(): Trying to connect to the external PVServer '" << serverUrl << "' ...";
497 if (!pqServerConnectReaction::connectToServer(pqServerResource(serverUrl.c_str())))
499 std::stringstream msg2;
500 msg2 << "Error while connecting to the requested pvserver '" << serverUrl;
501 msg2 << "'. Might use default built-in connection instead!" << std::endl;
502 qWarning(msg2.str().c_str()); // will go to the ParaView console (see ParavisMessageOutput below)
503 SUIT_MessageBox::warning( getApp()->desktop(),
504 QString("Error connecting to PVServer"), QString(msg2.str().c_str()));
508 MESSAGE("connectToExternalPVServer(): Connected!");
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);
548 // connect(data, SIGNAL(dataUpdated()), this, SLOT(onDataRepresentationUpdated()));
551 void PVGUI_Module::onDataRepresentationUpdated() {
552 SalomeApp_Study* activeStudy = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
553 if(!activeStudy) return;
555 activeStudy->Modified();
558 void PVGUI_Module::onVariableChanged(pqVariableType t, const QString) {
560 pqDisplayColorWidget* colorWidget = qobject_cast<pqDisplayColorWidget*>(sender());
564 if( t == VARIABLE_TYPE_NONE )
567 SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
572 bool visible = aResourceMgr->booleanValue( "PARAVIS", "show_color_legend", false );
577 /*//VTN: getRepresentation is protected
578 pqDataRepresentation* data = colorWidget->getRepresentation();
580 if( !data->getLookupTable() )
583 pqLookupTableManager* lut_mgr = pqApplicationCore::instance()->getLookupTableManager();
586 lut_mgr->setScalarBarVisibility(data,visible);
589 pqColorToolbar* colorTooBar = qobject_cast<pqColorToolbar*>(colorWidget->parent());
593 pqScalarBarVisibilityReaction* scalarBarVisibility = colorTooBar->findChild<pqScalarBarVisibilityReaction *>();
594 if(scalarBarVisibility) {
595 scalarBarVisibility->setScalarBarVisibility(visible);
600 \brief Initialisation timer event - fired only once, after the GUI loop is ready.
601 See creation in initialize().
603 void PVGUI_Module::onInitTimer()
605 #ifndef PARAVIS_WITH_FULL_CORBA
606 connectToExternalPVServer();
612 \brief Get list of embedded macros files
614 QStringList PVGUI_Module::getEmbeddedMacrosList()
616 QString aRootDir = getenv("PARAVIS_ROOT_DIR");
618 QString aSourcePath = aRootDir + "/bin/salome/Macro";
623 QDir aSourceDir(aSourcePath);
624 QStringList aSourceFiles = aSourceDir.entryList(aFilter, QDir::Files);
625 QStringList aFullPathSourceFiles;
626 foreach (QString aMacrosName, aSourceFiles) {
627 aFullPathSourceFiles << aSourceDir.absoluteFilePath(aMacrosName);
629 return aFullPathSourceFiles;
632 void PVGUI_Module::updateMacros()
634 pqPythonManager* aPythonManager = pqPVApplicationCore::instance()->pythonManager();
635 if(!aPythonManager) {
639 foreach (QString aStr, getEmbeddedMacrosList()) {
640 aPythonManager->addMacro(aStr);
646 \brief Get list of compliant dockable GUI elements
647 \param m map to be filled in ("type":"default_position")
649 void PVGUI_Module::windows( QMap<int, int>& m ) const
651 m.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
652 m.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
653 // ParaView diagnostic output redirected here
654 m.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
658 \brief Static method, performs initialization of ParaView session.
659 \return \c true if ParaView has been initialized successfully, otherwise false
661 bool PVGUI_Module::pvInit()
663 // if ( !pqImplementation::Core ){
665 // Obtain command-line arguments
668 QString aOptions = getenv("PARAVIS_OPTIONS");
669 QStringList aOptList = aOptions.split(":", QString::SkipEmptyParts);
670 argv = new char*[aOptList.size() + 1];
671 QStringList args = QApplication::arguments();
672 argv[0] = (args.size() > 0)? strdup(args[0].toLatin1().constData()) : strdup("paravis");
675 foreach (QString aStr, aOptList) {
676 argv[argc] = strdup( aStr.toLatin1().constData() );
679 MyCoreApp = new pqPVApplicationCore (argc, argv);
680 if (MyCoreApp->getOptions()->GetHelpSelected() ||
681 MyCoreApp->getOptions()->GetUnknownArgument() ||
682 MyCoreApp->getOptions()->GetErrorMessage() ||
683 MyCoreApp->getOptions()->GetTellVersion()) {
687 /* VTN: Looks like trash. For porting see branded_paraview_initializer.cxx.in
688 // Not sure why this is needed. Andy added this ages ago with comment saying
689 // needed for Mac apps. Need to check that it's indeed still required.
690 QDir dir(QApplication::applicationDirPath());
693 QApplication::addLibraryPath(dir.absolutePath());
694 // Load required application plugins.
695 QString plugin_string = "";
696 QStringList plugin_list = plugin_string.split(';',QString::SkipEmptyParts);
697 pqBrandPluginsLoader loader;
698 if (loader.loadPlugins(plugin_list) == false) {
699 printf("Failed to load required plugins for this application\n");
703 // Load optional plugins.
705 plugin_list = plugin_string.split(';',QString::SkipEmptyParts);
706 loader.loadPlugins(plugin_list, true); //quietly skip not-found plugins.
708 // End of Initializer code
710 MyCoreApp->settings();
712 vtkOutputWindow::SetInstance(PVGUI_OutputWindowAdapter::New());
714 new pqTabbedMultiViewWidget(); // it registers as "MULTIVIEW_WIDGET on creation
716 for (int i = 0; i < argc; i++)
725 \brief Shows (toShow = true) or hides ParaView view window
727 void PVGUI_Module::showView( bool toShow )
729 SalomeApp_Application* anApp = getApp();
730 PVGUI_ViewManager* viewMgr =
731 dynamic_cast<PVGUI_ViewManager*>( anApp->getViewManager( PVGUI_Viewer::Type(), false ) );
733 viewMgr = new PVGUI_ViewManager( anApp->activeStudy(), anApp->desktop() );
734 anApp->addViewManager( viewMgr );
735 connect( viewMgr, SIGNAL( lastViewClosed( SUIT_ViewManager* ) ),
736 anApp, SLOT( onCloseView( SUIT_ViewManager* ) ) );
739 PVGUI_ViewWindow* pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->getActiveView() );
741 pvWnd = dynamic_cast<PVGUI_ViewWindow*>( viewMgr->createViewWindow() );
744 pvWnd->setShown( toShow );
745 if ( toShow ) pvWnd->setFocus();
749 \brief Slot to show help for proxy.
751 void PVGUI_Module::showHelpForProxy( const QString& groupname, const QString& proxyname )
753 pqHelpReaction::showProxyHelp(groupname, proxyname);
758 \brief Slot to show the waiting state.
760 void PVGUI_Module::onPreAccept()
762 getApp()->desktop()->statusBar()->showMessage(tr("STB_PREACCEPT"));
763 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
767 \brief Slot to show the ready state.
769 void PVGUI_Module::onPostAccept()
771 getApp()->desktop()->statusBar()->showMessage(tr("STB_POSTACCEPT"), 2000);
772 QTimer::singleShot(0, this, SLOT(endWaitCursor()));
776 \brief Slot to switch off wait cursor.
778 void PVGUI_Module::endWaitCursor()
780 QApplication::restoreOverrideCursor();
784 \brief Returns the ParaView multi-view manager.
786 pqTabbedMultiViewWidget* PVGUI_Module::getMultiViewManager() const
788 return qobject_cast<pqTabbedMultiViewWidget*>(pqApplicationCore::instance()->manager("MULTIVIEW_WIDGET"));
792 static void ParavisMessageOutput(QtMsgType type, const char *msg)
797 vtkOutputWindow::GetInstance()->DisplayText(msg);
800 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
803 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
806 vtkOutputWindow::GetInstance()->DisplayErrorText(msg);
814 \brief Activate module.
815 \param study current study
816 \return \c true if activaion is done successfully or 0 to prevent
819 bool PVGUI_Module::activateModule( SUIT_Study* study )
821 myOldMsgHandler = qInstallMsgHandler(ParavisMessageOutput);
823 SUIT_ExceptionHandler::addCleanUpRoutine( paravisCleanUp );
825 storeCommonWindowsState();
827 bool isDone = SalomeApp_Module::activateModule( study );
828 if ( !isDone ) return false;
831 if ( mySourcesMenuId != -1 ) menuMgr()->show(mySourcesMenuId);
832 if ( myFiltersMenuId != -1 ) menuMgr()->show(myFiltersMenuId);
833 if ( myFiltersMenuId != -1 ) menuMgr()->show(myMacrosMenuId);
834 if ( myFiltersMenuId != -1 ) menuMgr()->show(myToolbarsMenuId);
835 setMenuShown( true );
836 setToolShown( true );
838 restoreDockWidgetsState();
840 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
842 QList<QAction*> anActns = aMenu->actions();
843 for (int i = 0; i < anActns.size(); ++i) {
844 QAction* a = anActns.at(i);
850 QList<QMenu*>::iterator it;
851 for (it = myMenus.begin(); it != myMenus.end(); ++it) {
852 QAction* a = (*it)->menuAction();
857 if ( myRecentMenuId != -1 ) menuMgr()->show(myRecentMenuId);
859 ClientFindOrCreateParavisComponent(PARAVIS::GetCStudy(this));
866 \brief Deactivate module.
867 \param study current study
868 \return \c true if deactivaion is done successfully or 0 to prevent
869 deactivation on error
871 bool PVGUI_Module::deactivateModule( SUIT_Study* study )
873 MESSAGE("PARAVIS deactivation ...")
875 QMenu* aMenu = menuMgr()->findMenu( myRecentMenuId );
877 QList<QAction*> anActns = aMenu->actions();
878 for (int i = 0; i < anActns.size(); ++i) {
879 QAction* a = anActns.at(i);
881 a->setVisible(false);
885 QList<QMenu*>::iterator it;
886 for (it = myMenus.begin(); it != myMenus.end(); ++it) {
887 QAction* a = (*it)->menuAction();
889 a->setVisible(false);
892 QList<QDockWidget*> aStreamingViews = application()->desktop()->findChildren<QDockWidget*>("pqStreamingControls");
893 foreach(QDockWidget* aView, aStreamingViews) {
894 if (!myDockWidgets.contains(aView))
895 myDockWidgets[aView] = aView->isVisible();
898 /*if (pqImplementation::helpWindow) {
899 pqImplementation::helpWindow->hide();
903 menuMgr()->hide(myRecentMenuId);
904 menuMgr()->hide(mySourcesMenuId);
905 menuMgr()->hide(myFiltersMenuId);
906 menuMgr()->hide(myMacrosMenuId);
907 menuMgr()->hide(myToolbarsMenuId);
908 setMenuShown( false );
909 setToolShown( false );
911 saveDockWidgetsState();
913 SUIT_ExceptionHandler::removeCleanUpRoutine( paravisCleanUp );
916 qInstallMsgHandler(myOldMsgHandler);
918 restoreCommonWindowsState();
920 return SalomeApp_Module::deactivateModule( study );
925 \brief Called when application is closed.
927 Process finalize application functionality from ParaView in order to save server settings
928 and nullify application pointer if the application is being closed.
930 \param theApp application
932 void PVGUI_Module::onApplicationClosed( SUIT_Application* theApp )
934 pqApplicationCore::instance()->settings()->sync();
935 int aAppsNb = SUIT_Session::session()->applications().size();
937 deleteTemporaryFiles();
938 MyCoreApp->deleteLater();
940 CAM_Module::onApplicationClosed(theApp);
945 \brief Deletes temporary files created during import operation from VISU
947 void PVGUI_Module::deleteTemporaryFiles()
949 foreach(QString aFile, myTemporaryFiles) {
950 if (QFile::exists(aFile)) {
951 QFile::remove(aFile);
958 \brief Called when study is closed.
960 Removes data model from the \a study.
962 \param study study being closed
964 void PVGUI_Module::studyClosed(SUIT_Study* study)
966 clearParaviewState();
968 SalomeApp_Module::studyClosed(study);
972 \brief Called when study is opened.
974 void PVGUI_Module::onModelOpened()
976 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
981 _PTR(SComponent) paravisComp =
982 studyDS->FindComponent(GetEngine()->ComponentDataType());
987 _PTR(ChildIterator) anIter(studyDS->NewChildIterator(paravisComp));
988 for (; anIter->More(); anIter->Next()) {
989 _PTR(SObject) aSObj = anIter->Value();
990 _PTR(GenericAttribute) anAttr;
991 if (!aSObj->FindAttribute(anAttr, "AttributeLocalID")) {
994 _PTR(AttributeLocalID) anID(anAttr);
995 if (anID->Value() == PVSTATEID) {
1002 \brief Returns IOR of current engine
1004 QString PVGUI_Module::engineIOR() const
1006 CORBA::String_var anIOR = GetEngine()->GetIOR();
1007 return QString(anIOR.in());
1012 \brief Open file of format supported by ParaView
1014 void PVGUI_Module::openFile(const char* theName)
1018 pqLoadDataReaction::loadData(aFiles);
1022 * Start trace invoking the newly introduced C++ API (PV 4.2)
1023 * (inspired from pqTraceReaction::start())
1025 void PVGUI_Module::startTrace()
1027 vtkSMSessionProxyManager* pxm = pqActiveObjects::instance().activeServer()->proxyManager();
1029 vtkSmartPointer<vtkSMProxy> proxy;
1030 proxy.TakeReference(pxm->NewProxy("pythontracing", "PythonTraceOptions"));
1033 vtkNew<vtkSMParaViewPipelineController> controller;
1034 controller->InitializeProxy(proxy);
1036 vtkSMTrace* trace = vtkSMTrace::StartTrace();
1039 // Set manually the properties entered via the dialog box poping-up when requiring
1040 // a trace start in PV4.2 (trace options)
1041 trace->SetPropertiesToTraceOnCreate(vtkSMTrace::RECORD_USER_MODIFIED_PROPERTIES);
1042 trace->SetFullyTraceSupplementalProxies(false);
1046 void PVGUI_Module::stopTrace()
1048 vtkSMTrace::StopTrace();
1051 void PVGUI_Module::executeScript(const char *script)
1054 pqPythonManager* manager = qobject_cast<pqPythonManager*>(
1055 pqApplicationCore::instance()->manager("PYTHON_MANAGER"));
1057 pqPythonDialog* pyDiag = manager->pythonShellDialog();
1059 pyDiag->runString(script);
1066 // * Debug function printing out the given interpreter's execution context
1068 //void printInterpContext(PyInterp_Interp * interp )
1070 // // Extract __smtraceString from interpreter's context
1071 // const PyObject* ctxt = interp->getExecutionContext();
1073 // PyObject* lst = PyDict_Keys((PyObject *)ctxt);
1074 // Py_ssize_t siz = PyList_GET_SIZE(lst);
1075 // for (Py_ssize_t i = 0; i < siz; i++)
1077 // PyObject * elem = PyList_GetItem(lst, i);
1078 // if (PyString_Check(elem))
1080 // std::cout << "At pos:" << i << ", " << PyString_AsString(elem) << std::endl;
1083 // std::cout << "At pos:" << i << ", not a string!" << std::endl;
1089 \brief Returns trace string
1091 static const QString MYReplaceStr("paraview.simple");
1092 static const QString MYReplaceImportStr("except: from pvsimple import *");
1093 QString PVGUI_Module::getTraceString()
1095 vtkSMTrace *tracer = vtkSMTrace::GetActiveTracer();
1096 if (!tracer) // trace is not started
1099 QString traceString(tracer->GetCurrentTrace());
1101 // Replace import "paraview.simple" by "pvsimple"
1102 if ((!traceString.isNull()) && traceString.length() != 0) {
1103 int aPos = traceString.indexOf(MYReplaceStr);
1104 while (aPos != -1) {
1105 traceString = traceString.replace(aPos, MYReplaceStr.length(), "pvsimple");
1106 aPos = traceString.indexOf(MYReplaceStr, aPos);
1108 int aImportPos = traceString.indexOf(MYReplaceImportStr);
1109 if(aImportPos != -1)
1111 traceString = traceString.replace(aImportPos, MYReplaceImportStr.length(), "except:\n import pvsimple\n from pvsimple import *");
1119 \brief Saves trace string to disk file
1121 void PVGUI_Module::saveTrace(const char* theName)
1123 QFile file(theName);
1124 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
1125 MESSAGE( "Could not open file:" << theName );
1128 QTextStream out(&file);
1129 out << getTraceString();
1134 \brief Saves ParaView state to a disk file
1136 void PVGUI_Module::saveParaviewState(const char* theFileName)
1138 pqApplicationCore::instance()->saveState(theFileName);
1142 \brief Delete all objects for Paraview Pipeline Browser
1144 void PVGUI_Module::clearParaviewState()
1146 QAction* deleteAllAction = action(DeleteAllId);
1147 if (deleteAllAction) {
1148 deleteAllAction->activate(QAction::Trigger);
1153 \brief Restores ParaView state from a disk file
1155 If toClear == true, the current ojects will be deleted
1157 void PVGUI_Module::loadParaviewState(const char* theFileName)
1159 pqApplicationCore::instance()->loadState(theFileName, getActiveServer());
1163 \brief Returns current active ParaView server
1165 pqServer* PVGUI_Module::getActiveServer()
1167 return pqApplicationCore::instance()->getActiveServer();
1172 \brief Creates PARAVIS preference pane
1174 void PVGUI_Module::createPreferences()
1176 // Paraview settings tab
1177 int aParaViewSettingsTab = addPreference( tr( "TIT_PVIEWSETTINGS" ) );
1178 int aPanel = addPreference(QString(), aParaViewSettingsTab, LightApp_Preferences::UserDefined, "PARAVIS", "");
1179 setPreferenceProperty(aPanel, "content", (qint64)(new PVGUI_ParaViewSettingsPane()));
1181 // Paravis settings tab
1182 int aParaVisSettingsTab = addPreference( tr( "TIT_PVISSETTINGS" ) );
1183 addPreference( tr( "PREF_STOP_TRACE" ), aParaVisSettingsTab, LightApp_Preferences::Bool, "PARAVIS", "stop_trace");
1185 int aSaveType = addPreference(tr( "PREF_SAVE_TYPE_LBL" ), aParaVisSettingsTab,
1186 LightApp_Preferences::Selector,
1187 "PARAVIS", "savestate_type");
1188 QList<QVariant> aIndices;
1189 QStringList aStrings;
1191 aStrings<<tr("PREF_SAVE_TYPE_0");
1192 aStrings<<tr("PREF_SAVE_TYPE_1");
1193 aStrings<<tr("PREF_SAVE_TYPE_2");
1194 setPreferenceProperty(aSaveType, "strings", aStrings);
1195 setPreferenceProperty(aSaveType, "indexes", aIndices);
1197 //rnv: imp 21712: [CEA 581] Preference to display legend by default
1198 // [ABN]: now fixed in ParaView.
1199 // int aDispColoreLegend = addPreference( tr( "PREF_SHOW_COLOR_LEGEND" ), aParaVisSettingsTab,
1200 // LightApp_Preferences::Bool, "PARAVIS", "show_color_legend");
1204 \brief Creates ParaViS context menu popup
1206 void PVGUI_Module::contextMenuPopup(const QString& theClient, QMenu* theMenu, QString& theTitle)
1208 SalomeApp_Module::contextMenuPopup(theClient, theMenu, theTitle);
1210 // Check if we are in Object Browser
1211 SUIT_DataBrowser* ob = getApp()->objectBrowser();
1212 bool isOBClient = (ob && theClient == ob->popupClientType());
1217 // Get list of selected objects
1218 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1219 SALOME_ListIO aListIO;
1220 aSelectionMgr->selectedObjects(aListIO);
1221 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1222 QString entry = QString(aListIO.First()->getEntry());
1225 SalomeApp_Study* activeStudy =
1226 dynamic_cast<SalomeApp_Study*>(getApp()->activeStudy());
1231 // Get SALOMEDS client study
1232 _PTR(Study) studyDS = activeStudy->studyDS();
1237 QString paravisDataType(GetEngine()->ComponentDataType());
1238 if(activeStudy && activeStudy->isComponent(entry) &&
1239 activeStudy->componentDataType(entry) == paravisDataType) {
1240 // ParaViS module object
1241 theMenu->addSeparator();
1242 theMenu->addAction(action(SaveStatePopupId));
1245 // Try to get state object
1246 _PTR(SObject) stateSObj =
1247 studyDS->FindObjectID(entry.toLatin1().constData());
1253 _PTR(GenericAttribute) anAttr;
1254 if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1258 _PTR(AttributeLocalID) anID(anAttr);
1260 if (anID->Value() == PVSTATEID) {
1261 // Paraview state object
1262 theMenu->addSeparator();
1263 theMenu->addAction(action(AddStatePopupId));
1264 theMenu->addAction(action(CleanAndAddStatePopupId));
1265 theMenu->addSeparator();
1266 theMenu->addAction(action(ParaVisRenameId));
1267 theMenu->addAction(action(ParaVisDeleteId));
1274 \brief. Show ParaView python trace.
1276 void PVGUI_Module::onShowTrace()
1278 if (!myTraceWindow) {
1279 myTraceWindow = new pqPythonScriptEditor(getApp()->desktop());
1281 myTraceWindow->setText(getTraceString());
1282 myTraceWindow->show();
1283 myTraceWindow->raise();
1284 myTraceWindow->activateWindow();
1289 \brief. Re-initialize ParaView python trace.
1291 void PVGUI_Module::onRestartTrace()
1298 \brief Show ParaView view.
1300 void PVGUI_Module::onNewParaViewWindow()
1306 \brief Save state under the module root object.
1308 void PVGUI_Module::onSaveMultiState()
1310 // Create state study object
1312 // Get SALOMEDS client study
1313 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1318 _PTR(SComponent) paravisComp =
1319 studyDS->FindComponent(GetEngine()->ComponentDataType());
1324 // Unlock the study if it is locked
1325 bool isLocked = studyDS->GetProperties()->IsLocked();
1327 studyDS->GetProperties()->SetLocked(false);
1330 QString stateName = tr("SAVED_PARAVIEW_STATE_NAME") +
1331 QString::number(myStateCounter + 1);
1333 _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1334 _PTR(SObject) newSObj = studyBuilder->NewObject(paravisComp);
1337 _PTR(GenericAttribute) anAttr;
1338 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeName");
1339 _PTR(AttributeName) nameAttr(anAttr);
1341 nameAttr->SetValue(stateName.toLatin1().constData());
1344 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeLocalID");
1345 _PTR(AttributeLocalID) localIdAttr(anAttr);
1347 localIdAttr->SetValue(PVSTATEID);
1350 QString stateEntry = QString::fromStdString(newSObj->GetID());
1352 // File name for state saving
1353 QString tmpDir = QString::fromStdString(SALOMEDS_Tool::GetTmpDir());
1354 QString fileName = QString("%1_paravisstate:%2").arg(tmpDir, stateEntry);
1356 anAttr = studyBuilder->FindOrCreateAttribute(newSObj, "AttributeString");
1357 _PTR(AttributeString) stringAttr(anAttr);
1359 stringAttr->SetValue(fileName.toLatin1().constData());
1361 // Lock the study back if necessary
1363 studyDS->GetProperties()->SetLocked(true);
1367 saveParaviewState(fileName.toLatin1().constData());
1368 myTemporaryFiles.append(fileName);
1370 // Increment the counter
1377 \brief Restore the selected state by merging with the current one.
1379 void PVGUI_Module::onAddState()
1381 loadSelectedState(false);
1385 \brief Clean the current state and restore the selected one.
1387 void PVGUI_Module::onCleanAddState()
1389 loadSelectedState(true);
1393 \brief Rename the selected object.
1395 void PVGUI_Module::onRename()
1397 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1398 SALOME_ListIO aListIO;
1399 aSelectionMgr->selectedObjects(aListIO);
1401 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1402 std::string entry = aListIO.First()->getEntry();
1404 // Get SALOMEDS client study
1405 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1410 // Unlock the study if it is locked
1411 bool isLocked = studyDS->GetProperties()->IsLocked();
1413 studyDS->GetProperties()->SetLocked(false);
1416 // Rename the selected state object
1417 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1422 _PTR(GenericAttribute) anAttr;
1423 if (stateSObj->FindAttribute(anAttr, "AttributeName")) {
1424 _PTR(AttributeName) nameAttr (anAttr);
1426 LightApp_NameDlg::getName(getApp()->desktop(), nameAttr->Value().c_str());
1427 if (!newName.isEmpty()) {
1428 nameAttr->SetValue(newName.toLatin1().constData());
1429 aListIO.First()->setName(newName.toLatin1().constData());
1433 // Lock the study back if necessary
1435 studyDS->GetProperties()->SetLocked(true);
1438 // Update object browser
1445 \brief Delete the selected objects.
1447 void PVGUI_Module::onDelete()
1449 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1450 SALOME_ListIO aListIO;
1451 aSelectionMgr->selectedObjects(aListIO);
1453 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1454 std::string entry = aListIO.First()->getEntry();
1456 // Get SALOMEDS client study
1457 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1462 // Unlock the study if it is locked
1463 bool isLocked = studyDS->GetProperties()->IsLocked();
1465 studyDS->GetProperties()->SetLocked(false);
1468 // Remove the selected state from the study
1469 _PTR(StudyBuilder) studyBuilder = studyDS->NewBuilder();
1470 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1471 studyBuilder->RemoveObject(stateSObj);
1473 // Lock the study back if necessary
1475 studyDS->GetProperties()->SetLocked(true);
1478 // Update object browser
1483 void PVGUI_Module::onPushTraceTimer()
1485 // MESSAGE("onPushTraceTimer(): Pushing trace to engine...");
1486 GetEngine()->PutPythonTraceStringToEngine(getTraceString().toStdString().c_str());
1490 \brief Discover help project files from the resources.
1491 \return name of the help file.
1493 QString PVGUI_Module::getHelpFileName() {
1494 QString aPVHome(getenv("PVHOME"));
1495 if (aPVHome.isNull()) {
1496 qWarning("Wariable PVHOME is not defined");
1499 QChar aSep = QDir::separator();
1500 //PARAVIEW_VERSION from the vtkPVConfig.h file
1501 QString aFileName = aPVHome + aSep + "share" + aSep + "doc" + aSep + "paraview-"+ PARAVIEW_VERSION + aSep + "paraview.qch";
1507 \brief Load selected paraview state
1509 If toClear == true, the current state will be cleared
1511 void PVGUI_Module::loadSelectedState(bool toClear)
1515 LightApp_SelectionMgr* aSelectionMgr = getApp()->selectionMgr();
1516 SALOME_ListIO aListIO;
1517 aSelectionMgr->selectedObjects(aListIO);
1519 if (aListIO.Extent() == 1 && aListIO.First()->hasEntry()) {
1520 std::string entry = aListIO.First()->getEntry();
1522 // Get SALOMEDS client study
1523 _PTR(Study) studyDS = PARAVIS::GetCStudy(this);
1529 _PTR(SObject) stateSObj = studyDS->FindObjectID(entry);
1530 _PTR(GenericAttribute) anAttr;
1531 if (!stateSObj->FindAttribute(anAttr, "AttributeLocalID")) {
1534 _PTR(AttributeLocalID) anID(anAttr);
1535 if (!anID->Value() == PVSTATEID) {
1539 // Get state file name
1540 if (stateSObj->FindAttribute(anAttr, "AttributeString")) {
1541 _PTR(AttributeString) aStringAttr(anAttr);
1542 QString stringValue(aStringAttr->Value().c_str());
1544 if (QFile::exists(stringValue)) {
1545 fileName = stringValue;
1550 if (!fileName.isEmpty()) {
1552 clearParaviewState();
1555 loadParaviewState(fileName.toLatin1().constData());
1558 SUIT_MessageBox::critical(getApp()->desktop(),
1560 tr("ERR_STATE_CANNOT_BE_RESTORED"));
1564 void PVGUI_Module::onRepresentationChanged(pqRepresentation*) {
1567 //rnv: to fix the issue "21712: [CEA 581] Preference to display legend by default"
1568 // find the pqDisplayColorWidget instances and connect the variableChanged SIGNAL on the
1569 // onVariableChanged slot of this class. This connection needs to change visibility
1570 // of the "Colored Legend" after change the "Color By" array.
1571 QList<pqDisplayColorWidget*> aWidget = getApp()->desktop()->findChildren<pqDisplayColorWidget*>();
1573 for (int i = 0; i < aWidget.size() ; i++ ) {
1575 connect( aWidget[i], SIGNAL ( variableChanged ( pqVariableType, const QString ) ),
1576 this, SLOT(onVariableChanged( pqVariableType, const QString) ), Qt::UniqueConnection );
1583 \fn CAM_Module* createModule();
1584 \brief Export module instance (factory function).
1585 \return new created instance of the module
1589 #define PVGUI_EXPORT __declspec(dllexport)
1591 #define PVGUI_EXPORT
1597 PVGUI_EXPORT CAM_Module* createModule() {
1599 // vtkEDFHelperInit();
1602 return new PVGUI_Module();
1605 PVGUI_EXPORT char* getModuleVersion() {
1606 return (char*)PARAVIS_VERSION_STR;