Salome HOME
PROJECT: POST-PROCESSOR 2005 TASK: T 1.5
[modules/kernel.git] / src / SALOME_PYQT / SALOME_PYQT_GUI.cxx
1 //=============================================================================
2 // File      : SALOME_PYQT_GUI.cxx
3 // Created   : mer jun  4 17:17:20 UTC 2003
4 // Author    : Paul RASCLE, EDF 
5 // Project   : SALOME
6 // Copyright : EDF 2003
7 // $Header$
8 //=============================================================================
9
10 #include "SALOME_PYQT_GUI.h"
11
12 #include "QAD_Desktop.h"
13
14 #include "SALOME_Selection.h"
15 #include "SALOME_InteractiveObject.hxx"
16 #include "SALOMEGUI_QtCatchCorbaException.hxx"
17 #include "utilities.h"
18
19 #include <sipSalomePyQtDeclSalomePyQt.h>
20 #include <sipqtQWorkspace.h>
21 #include <sipqtQPopupMenu.h>
22
23 #include <map>
24 #include <string>
25
26 using namespace std;
27
28 static PyInterp_PyQt *interp = NULL;
29 static map<int,PyInterp_PyQt*> mapInterp;
30
31 //=============================================================================
32 /*!
33  *  Calls module.setWorkSpace with PyQt QWorkspace object to use with
34  *  interpreter.
35  */
36 //=============================================================================
37
38 void SALOME_PYQT_GUI::setWorkSpace()
39 {
40   MESSAGE("setWorkSpace");
41   PyLockWrapper aLock = interp->GetLockWrapper();
42
43   //   Try to import qt module. If it's not possible don't go on
44   PyObjWrapper qtmodule(PyImport_ImportModule("qt"));
45   if(!qtmodule){
46     PyErr_Print();
47     return ;
48   }  
49
50   PyObjWrapper pyws(sipMapCppToSelf( QAD_Application::getDesktop()->getMainFrame(),
51                                      sipClass_QWorkspace));
52   PyObjWrapper res(PyObject_CallMethod(_module,"setWorkSpace","O",pyws.get()));
53   SCRUTE(pyws->ob_refcnt);
54   if(!res){
55     PyErr_Print();
56     return ;
57   }
58 }
59
60 //=============================================================================
61 /*!
62  *  Import Python module (from _moduleName)                   
63  */
64 //=============================================================================
65 void SALOME_PYQT_GUI::importModule()
66 {
67   PyLockWrapper aLock = interp->GetLockWrapper();
68
69   PyObjWrapper amod = PyImport_ImportModule("salome");
70   if(!amod){
71     MESSAGE ( " Problem import salome... " );
72     PyErr_Print();
73     return;
74   }
75
76   PyObjWrapper res(PyObject_CallMethod(amod,"salome_init",""));
77   if(!res){
78     MESSAGE ( " Problem... " );
79     PyErr_Print();
80     return;
81   }
82
83   _module=PyImport_ImportModule((char*)_moduleName.c_str());
84   if(!_module){
85     MESSAGE ( " Problem... " );
86     PyErr_Print();
87     return;
88   }
89 }
90
91 //=============================================================================
92 /*!
93  *  Initialises python interpreter (only one per study), imports python module
94  *  from given module name, sets static reference to module,
95  *  sets module workspace.
96  */
97 //=============================================================================
98
99 void SALOME_PYQT_GUI::initInterp(int StudyID)
100 {
101   MESSAGE("SALOME_PYQT_GUI::initInterp");
102   if(mapInterp.find(StudyID) != mapInterp.end()){
103     MESSAGE ( "SALOME_PYQT_GUI::initInterp StudyID is found " << StudyID );
104     interp = mapInterp[StudyID];
105     return;
106   }else{
107     MESSAGE ( "SALOME_PYQT_GUI::initInterp StudyID is not found " << StudyID );
108     /*
109      * The creation of Python interpretor must be protected par a C++ Lock because of C threads
110      */
111     ThreadLock aPyLock = GetPyThreadLock("SALOME_PYQT_GUI::initInterp");
112     interp = new PyInterp_PyQt();
113     interp->initialize();
114     mapInterp[StudyID] = interp;
115   }
116   // imports Python GUI module and puts it in _module attribute
117   importModule();
118   // calls _module.setWorkspace and passes the SIP object main workspace
119   setWorkSpace();
120
121 }
122
123 //=============================================================================
124 /*!
125  * constructor : only calls SALOMEGUI constructor
126  */
127 //=============================================================================
128 SALOME_PYQT_GUI::SALOME_PYQT_GUI( const QString& theName, QObject* theParent ) :
129     SALOMEGUI( theName, theParent ),_module(0)
130 {
131     MESSAGE("SALOME_PYQT_GUI::SALOME_PYQT_GUI");
132 }
133
134 //=============================================================================
135 /*!
136  * destructor : do nothing
137  */
138 //=============================================================================
139 SALOME_PYQT_GUI::~SALOME_PYQT_GUI()
140 {
141 }
142
143 //=============================================================================
144 /*!
145  *  Calls python module.OnGUIEvent(theCommandID)
146  */
147 //=============================================================================
148
149 bool SALOME_PYQT_GUI::OnGUIEvent (int theCommandID,
150                                   QAD_Desktop* parent)
151 {
152   MESSAGE("SALOME_PYQT_GUI::OnGUIEvent");
153   ThreadLock aPyLock = GetPyThreadLock("SALOME_PYQT_GUI::OnGUIEvent");
154   PyLockWrapper aLock = interp->GetLockWrapper();
155
156   PyObjWrapper res(PyObject_CallMethod(_module,"OnGUIEvent","i",theCommandID));
157   if(!res){
158     PyErr_Print();
159     return false;
160   }
161   return true;
162 }
163
164 //=============================================================================
165 /*!
166  *  no call to python module.OnKeyPress()
167  */
168 //=============================================================================
169
170 bool SALOME_PYQT_GUI::OnKeyPress (QKeyEvent* pe,
171                                   QAD_Desktop* parent,
172                                   QAD_StudyFrame* studyFrame)
173 {
174   MESSAGE("SALOME_PYQT_GUI::OnKeyPress");
175   return true;
176 }
177
178 //=============================================================================
179 /*!
180  *  no call to python module.OnMousePress()
181  */
182 //=============================================================================
183
184 bool SALOME_PYQT_GUI::OnMousePress (QMouseEvent* pe ,
185                                     QAD_Desktop* parent, 
186                                     QAD_StudyFrame* studyFrame)
187 {
188   MESSAGE("SALOME_PYQT_GUI::OnMousePress");
189   return false;
190 }
191
192 //=============================================================================
193 /*!
194  *  no call to python module.OnMouseMove()
195  */
196 //=============================================================================
197
198 bool SALOME_PYQT_GUI::OnMouseMove (QMouseEvent* pe ,
199                                    QAD_Desktop* parent, 
200                                    QAD_StudyFrame* studyFrame)
201 {
202   // Commented out to avoid multiple traces ...
203   // MESSAGE("SALOME_PYQT_GUI::OnMouseMove");
204   return true;
205 }
206
207 //=============================================================================
208 /*!
209  *  Calls initInterp to initialise python interpreter (only one per study) and
210  *  to import python module. Calls module.setSettings() 
211  */
212 //=============================================================================
213
214 bool SALOME_PYQT_GUI::SetSettings (QAD_Desktop* parent, char* moduleName)
215 {
216   MESSAGE("SALOME_PYQT_GUI::SetSettings");
217   int StudyID = QAD_Application::getDesktop()->getActiveStudy()->getStudyId();
218   SCRUTE ( StudyID );
219   _moduleName = moduleName + string("GUI");
220   SCRUTE(_moduleName);
221
222   // initializes one Python interpreter by study and puts it in interp global variable
223   // imports Python GUI module and puts it in _module attribute
224   // calls _module.setWorkspace and passes the SIP object main workspace
225   initInterp(StudyID);
226   
227   PyLockWrapper aLock = interp->GetLockWrapper();
228
229   _module = PyImport_ImportModule((char*)_moduleName.c_str());
230   if(!_module){
231     PyErr_Print();
232     return false;
233   }
234
235   PyObjWrapper res(PyObject_CallMethod(_module,"setSettings",""));
236   if(!res){
237     PyErr_Print();
238     return false;
239   }
240   return true;
241 }
242
243 //=============================================================================
244 /*!
245  * Calls module.customPopup with popup menu to custom, and string values of 
246  * context, parent and selected object (strings defined by DefinePopup, which
247  * is called before).
248  */
249 //=============================================================================
250
251 bool SALOME_PYQT_GUI::CustomPopup ( QAD_Desktop* parent,
252                                     QPopupMenu* popup,
253                                     const QString & theContext,
254                                     const QString & theParent,
255                                     const QString & theObject )
256 {
257   MESSAGE("SALOME_PYQT_GUI::CustomPopup");
258
259   MESSAGE ( " theContext : " << theContext.latin1() );
260   MESSAGE ( " theParent : " << theParent.latin1() );
261   MESSAGE ( " theObject : " << theObject.latin1() );
262
263   PyLockWrapper aLock = interp->GetLockWrapper();
264
265   PyObjWrapper pypop(sipMapCppToSelf( popup, sipClass_QPopupMenu));
266
267   PyObjWrapper res(PyObject_CallMethod(_module,"customPopup",
268                                        "Osss",pypop.get(),
269                                        theContext.latin1(), 
270                                        theObject.latin1(), 
271                                        theParent.latin1()));
272   if(!res){
273     PyErr_Print();
274     return false;
275   }
276   return true;
277 }
278
279
280 //=============================================================================
281 /*!
282  * Calls module.definePopup to modify the strings that define context parent
283  * and selected object. Called before CustomPopup.
284  */
285 //=============================================================================
286
287 void SALOME_PYQT_GUI::DefinePopup( QString & theContext,
288                                    QString & theParent,
289                                    QString & theObject )
290 {
291   MESSAGE("SALOME_PYQT_GUI::DefinePopup");
292   theContext = "";
293   theObject = "";
294   theParent = "";
295   
296   PyLockWrapper aLock = interp->GetLockWrapper();
297
298   PyObjWrapper res(PyObject_CallMethod(_module,"definePopup","sss",
299                                        theContext.latin1(), 
300                                        theObject.latin1(), 
301                                        theParent.latin1()));
302   if(!res){
303     PyErr_Print();
304     return;
305   }
306   char *co, *ob, *pa;
307   if(!PyArg_ParseTuple(res, "sss", &co, &ob, &pa))
308   {
309     // It's not a valid tuple. Do nothing.
310     return;
311   }
312
313   MESSAGE ("parseOk ");
314   MESSAGE (" --- " << co << " " << ob << " " << pa);
315
316   theContext = co;
317   theObject = ob;
318   theParent = pa;
319
320   MESSAGE ( " theContext : " << theContext.latin1() );
321   MESSAGE ( " theParent : " << theParent.latin1() );
322   MESSAGE ( " theObject : " << theObject.latin1() );
323 }
324
325 //=============================================================================
326 /*!
327  * Initialize new interpreter (if not exists) with new study ID.
328  * Calls module.activeStudyChanged with new study ID. Called twice.
329  */
330 //=============================================================================
331
332 bool SALOME_PYQT_GUI::ActiveStudyChanged( QAD_Desktop* parent )
333 {
334   
335   int StudyID = parent->getActiveApp()->getActiveStudy()->getStudyId();
336   MESSAGE("SALOME_PYQT_GUI::ActiveStudyChanged"<<StudyID<<" - " <<this);
337   initInterp(StudyID);
338   
339   PyLockWrapper aLock = interp->GetLockWrapper();
340
341   PyObjWrapper res(PyObject_CallMethod(_module,"activeStudyChanged","i", StudyID ));
342   if(!res){
343     PyErr_Print();
344     return false;
345   }
346   return true;
347 }
348
349 //=============================================================================
350 /*!
351  *  no call to python module.BuildPresentation() (not yet ???)
352  */
353 //=============================================================================
354 void SALOME_PYQT_GUI::BuildPresentation( const Handle(SALOME_InteractiveObject)&,
355                                          QAD_ViewFrame* )
356 {
357 }
358
359 //=============================================================================
360 /*!
361  *  no call to python module.SupportedViewType() (not yet ???)
362  */
363 //=============================================================================
364 void SALOME_PYQT_GUI::SupportedViewType(int* /*buffer*/, int /*bufferSize*/ )
365 {
366 }
367
368 //=============================================================================
369 /*!
370  *  no call to python module.Deactivate() (not yet ???)
371  */
372 //=============================================================================
373 void SALOME_PYQT_GUI::Deactivate()
374 {
375 }
376
377
378
379
380 //=============================================================================
381 /*!
382  *  Component GUI Factory : returns a new GUI obj at each call
383  */
384 //=============================================================================
385
386 extern "C"
387 {
388   Standard_EXPORT SALOMEGUI* GetComponentGUI() {
389     MESSAGE("SALOME_PYQT_GUI::GetComponentGUI");
390     SALOMEGUI* aGUI = new SALOME_PYQT_GUI("");
391     return aGUI;
392   }
393 }