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