Salome HOME
a0c819edd38fcbbcd182b24d70546e81f1984e2c
[modules/gui.git] / src / PVViewer / PVViewer_ViewManager.cxx
1 // Copyright (C) 2010-2014  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "PVViewer_ViewManager.h"
20 #include "PVViewer_ViewModel.h"
21 #include "PVViewer_ViewWindow.h"
22 #include "PVViewer_LogWindowAdapter.h"
23 #include "PVViewer_GUIElements.h"
24 #include "PVViewer_Behaviors.h"
25 #include "PVViewer_EngineWrapper.h"
26
27 #include <utilities.h>
28 #include <SalomeApp_Application.h>
29 #include <SUIT_MessageBox.h>
30 #include <SUIT_Desktop.h>
31 #include <SUIT_Session.h>
32 #include <SUIT_ResourceMgr.h>
33 #include <PyInterp_Interp.h>
34 #include <PyConsole_Interp.h>
35 #include <PyConsole_Console.h>
36
37 #include <QApplication>
38 #include <QStringList>
39 #include <QDir>
40
41 #include <string>
42
43 #include <pqOptions.h>
44 #include <pqServer.h>
45 #include <pqSettings.h>
46 #include <pqServerDisconnectReaction.h>
47 #include <pqPVApplicationCore.h>
48 #include <pqTabbedMultiViewWidget.h>
49 #include <pqActiveObjects.h>
50 #include <pqServerConnectReaction.h>
51
52 #include <pqParaViewMenuBuilders.h>
53 #include <pqPipelineBrowserWidget.h>
54
55 //---------- Static init -----------------
56 pqPVApplicationCore* PVViewer_ViewManager::MyCoreApp = 0;
57 bool PVViewer_ViewManager::ConfigLoaded = false;
58 PVViewer_Behaviors * PVViewer_ViewManager::ParaviewBehaviors = NULL;
59
60 /*!
61   Constructor
62 */
63 PVViewer_ViewManager::PVViewer_ViewManager( SUIT_Study* study, SUIT_Desktop* desk )
64 : SUIT_ViewManager( study, desk, new PVViewer_Viewer() ),
65   desktop(desk)
66 {
67   MESSAGE("PARAVIS - view manager created ...")
68   setTitle( tr( "PARAVIEW_VIEW_TITLE" ) );
69   // Initialize minimal paraview stuff (if not already done)
70   ParaviewInitApp(desk);
71
72 //  connect(this, SIGNAL(viewCreated(SUIT_ViewWindow*)), this, SLOT(onPVViewCreated(SUIT_ViewWindow*)));
73 }
74
75 pqPVApplicationCore * PVViewer_ViewManager::GetPVApplication()
76 {
77   return MyCoreApp;
78 }
79
80 /*!
81   \brief Static method, performs initialization of ParaView session.
82   \param fullSetup whether to instanciate all behaviors or just the minimal ones.
83   \return \c true if ParaView has been initialized successfully, otherwise false
84 */
85 bool PVViewer_ViewManager::ParaviewInitApp(SUIT_Desktop * aDesktop)
86 {
87   if ( ! MyCoreApp) {
88       // Obtain command-line arguments
89       int argc = 0;
90       char** argv = 0;
91       QString aOptions = getenv("PARAVIS_OPTIONS");
92       QStringList aOptList = aOptions.split(":", QString::SkipEmptyParts);
93       argv = new char*[aOptList.size() + 1];
94       QStringList args = QApplication::arguments();
95       argv[0] = (args.size() > 0)? strdup(args[0].toLatin1().constData()) : strdup("paravis");
96       argc++;
97
98       foreach (QString aStr, aOptList) {
99         argv[argc] = strdup( aStr.toLatin1().constData() );
100         argc++;
101       }
102       MyCoreApp = new pqPVApplicationCore (argc, argv);
103       if (MyCoreApp->getOptions()->GetHelpSelected() ||
104           MyCoreApp->getOptions()->GetUnknownArgument() ||
105           MyCoreApp->getOptions()->GetErrorMessage() ||
106           MyCoreApp->getOptions()->GetTellVersion()) {
107           return false;
108       }
109
110       // Direct VTK log messages to our SALOME window - TODO: review this
111       vtkOutputWindow::SetInstance(PVViewer_LogWindowAdapter::New());
112
113       new pqTabbedMultiViewWidget(); // registers a "MULTIVIEW_WIDGET" on creation
114
115       // At this stage, the pqPythonManager has been initialized, i.e. the current process has
116       // activated the embedded Python interpreter. "paraview" package has also been imported once already.
117       // Make sure the current process executes paraview's Python command with the "fromGUI" flag.
118       // This is used in pvsimple.py to avoid reconnecting the GUI thread to the pvserver (when
119       // user types "import pvsimple" in SALOME's console).
120       SalomeApp_Application* app =
121                   dynamic_cast< SalomeApp_Application* >(SUIT_Session::session()->activeApplication());
122       PyConsole_Interp* pyInterp = app->pythonConsole()->getInterp();
123       {
124         PyLockWrapper aGil;
125         std::string cmd = "import paraview;paraview.fromGUI = True";
126         pyInterp->run(cmd.c_str());
127       }
128
129       for (int i = 0; i < argc; i++)
130         free(argv[i]);
131       delete[] argv;
132   }
133   // Initialize GUI elements if needed:
134   PVViewer_GUIElements::GetInstance(aDesktop);
135   return true;
136 }
137
138 void PVViewer_ViewManager::ParaviewInitBehaviors(bool fullSetup, SUIT_Desktop* aDesktop)
139 {
140   if (!ParaviewBehaviors)
141       ParaviewBehaviors = new PVViewer_Behaviors(aDesktop);
142
143   if(fullSetup)
144     ParaviewBehaviors->instanciateAllBehaviors(aDesktop);
145   else
146     ParaviewBehaviors->instanciateMinimalBehaviors(aDesktop);
147 }
148
149 void PVViewer_ViewManager::ParaviewLoadConfigurations()
150 {
151   if (!ConfigLoaded)
152     {
153       SUIT_ResourceMgr* resMgr = SUIT_Session::session()->resourceMgr();
154       QString aPath = resMgr->stringValue("resources", "PARAVIS", QString());
155       if (!aPath.isNull()) {
156           MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewFilters.xml");
157           MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewReaders.xml");
158           MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewSources.xml");
159           MyCoreApp->loadConfiguration(aPath + QDir::separator() + "ParaViewWriters.xml");
160       }
161       ConfigLoaded = true;
162     }
163 }
164
165 void PVViewer_ViewManager::ParaviewCleanup()
166 {
167   // Disconnect from server
168   pqServer* server = pqActiveObjects::instance().activeServer();
169   if (server && server->isRemote())
170     {
171       MESSAGE("~PVViewer_Module(): Disconnecting from remote server ...");
172       pqServerDisconnectReaction::disconnectFromServer();
173     }
174
175   pqApplicationCore::instance()->settings()->sync();
176
177   pqPVApplicationCore * app = GetPVApplication();
178   // Schedule destruction of PVApplication singleton:
179   if (app)
180     app->deleteLater();
181 }
182
183 PVViewer_EngineWrapper * PVViewer_ViewManager::GetEngine()
184 {
185   return PVViewer_EngineWrapper::GetInstance();
186 }
187
188 bool PVViewer_ViewManager::ConnectToExternalPVServer(SUIT_Desktop* aDesktop)
189 {
190   SUIT_ResourceMgr* aResourceMgr = SUIT_Session::session()->resourceMgr();
191   bool noConnect = aResourceMgr->booleanValue( "PARAVIS", "no_ext_pv_server", false );
192   if (noConnect)
193     return true;
194
195   pqServer* server = pqActiveObjects::instance().activeServer();
196   if (server && server->isRemote())
197     {
198       // Already connected to an external server, do nothing
199       MESSAGE("connectToExternalPVServer(): Already connected to an external PVServer, won't reconnect.");
200       return false;
201     }
202
203   if (GetEngine()->GetGUIConnected())
204     {
205       // Should never be there as the above should already tell us that we are connected.
206       std::stringstream msg2;
207       msg2 << "Internal error while connecting to the pvserver.";
208       msg2 << "ParaView doesn't see a connection, but PARAVIS engine tells us there is already one!" << std::endl;
209       qWarning(msg2.str().c_str());  // will go to the ParaView console (see ParavisMessageOutput below)
210       SUIT_MessageBox::warning( aDesktop,
211                                       QString("Error connecting to PVServer"), QString(msg2.str().c_str()));
212       return false;
213     }
214
215   std::stringstream msg;
216
217   // Try to connect to the external PVServer - gives priority to an externally specified URL:
218   QString serverUrlEnv = getenv("PARAVIS_PVSERVER_URL");
219   std::string serverUrl;
220   if (!serverUrlEnv.isEmpty())
221     serverUrl = serverUrlEnv.toStdString();
222   else
223     {
224       // Get the URL from the engine (possibly starting the pvserver)
225       serverUrl = GetEngine()->FindOrStartPVServer(0);  // take the first free port
226     }
227
228   msg << "connectToExternalPVServer(): Trying to connect to the external PVServer '" << serverUrl << "' ...";
229   MESSAGE(msg.str());
230
231   if (!pqServerConnectReaction::connectToServer(pqServerResource(serverUrl.c_str())))
232     {
233       std::stringstream msg2;
234       msg2 << "Error while connecting to the requested pvserver '" << serverUrl;
235       msg2 << "'. Might use default built-in connection instead!" << std::endl;
236       qWarning(msg2.str().c_str());  // will go to the ParaView console (see ParavisMessageOutput below)
237       SUIT_MessageBox::warning( aDesktop,
238                                 QString("Error connecting to PVServer"), QString(msg2.str().c_str()));
239       return false;
240     }
241   else
242     {
243       MESSAGE("connectToExternalPVServer(): Connected!");
244       GetEngine()->SetGUIConnected(true);
245     }
246   return true;
247 }
248
249 //void PVViewer_ViewManager::onPVViewCreated(SUIT_ViewWindow* w)
250 //{
251 //  PVViewer_ViewWindow * w2 = dynamic_cast<PVViewer_ViewWindow *>(w);
252 //  Q_ASSERT(w2 != NULL);
253 //  connect(w2, SIGNAL(applyRequest()), ParaviewBehaviors, SLOT(onEmulateApply()));
254 //}
255
256 void PVViewer_ViewManager::onEmulateApply()
257 {
258   PVViewer_GUIElements * guiElements = PVViewer_GUIElements::GetInstance(desktop);
259   guiElements->onEmulateApply();
260 }