Salome HOME
Merge from V6_main_20120808 08Aug12
[modules/gui.git] / src / SALOME_PYQT / SALOME_PYQT_GUI / SALOME_PYQT_Module.cxx
1 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File   : SALOME_PYQT_Module.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
24
25 #include <PyInterp_Dispatcher.h>
26
27 #include "SALOME_PYQT_Module.h"
28 #include "SalomeApp_Application.h"
29 #include "SALOME_PYQT_ModuleLight.h"
30
31 #include <SALOME_LifeCycleCORBA.hxx>
32 #include <Container_init_python.hxx>
33 #include <CORBA.h>
34
35
36 //
37 // NB: Library initialization
38 // Since the SalomePyQtGUILight library is not imported in Python it's initialization function
39 // should be called manually (and only once) in order to initialize global sip data
40 // and to get C API from sip : sipBuildResult for example
41 //
42
43 #define INIT_FUNCTION initSalomePyQtGUILight
44 #if defined(SIP_STATIC_MODULE)
45 extern "C" void INIT_FUNCTION();
46 #else
47 PyMODINIT_FUNC INIT_FUNCTION();
48 #endif
49
50 /*!
51   \fn CAM_Module* createModule()
52   \brief Module factory function.
53   \internal
54   
55   Creates an instance of SALOME_PYQT_Module object by request
56   of an application when the module is loaded and initialized.
57
58   \return new module object
59 */
60
61 extern "C" {
62   SALOME_PYQT_EXPORT CAM_Module* createModule() {
63
64     static bool alreadyInitialized = false;
65     if ( !alreadyInitialized ) {
66       // call only once (see comment above) !
67
68       PyEval_RestoreThread( KERNEL_PYTHON::_gtstate);
69       INIT_FUNCTION();
70       PyEval_ReleaseThread( KERNEL_PYTHON::_gtstate);
71       alreadyInitialized = !alreadyInitialized;
72     }
73     return new SALOME_PYQT_Module();
74   }
75 }
76
77
78 /*!
79   \var __DEFAULT_NAME__ - Default name of the module, replaced at the moment of module creation
80 */
81 const char* __DEFAULT_NAME__  = "SALOME_PYQT_Module";
82
83 /*!
84  * Constructor
85  */
86 SALOME_PYQT_Module::SALOME_PYQT_Module()
87   : SalomeApp_Module(__DEFAULT_NAME__),
88     LightApp_Module(__DEFAULT_NAME__),
89     SALOME_PYQT_ModuleLight()
90 {
91 }
92
93 /*!
94  * Destructor
95  */
96 SALOME_PYQT_Module::~SALOME_PYQT_Module()
97 {
98 }
99
100 /*!
101  * Get module engine, returns nil var if engine is not found in LifeCycleCORBA
102  */
103 Engines::EngineComponent_var SALOME_PYQT_Module::getEngine() const
104 {
105   Engines::EngineComponent_var comp;
106   // temporary solution
107   try {
108     comp = getApp()->lcc()->FindOrLoad_Component( "FactoryServerPy", name().toLatin1() );
109   }
110   catch (CORBA::Exception&) {
111   }
112   return comp;
113 }
114
115 /*!
116  * Get module engine IOR, returns empty string if engine is not found in LifeCycleCORBA
117  */
118 QString SALOME_PYQT_Module::engineIOR() const
119 {
120   class EngineIORReq : public PyInterp_LockRequest
121   {
122   public:
123     EngineIORReq( PyInterp_Interp*    _py_interp,
124                   SALOME_PYQT_Module* _obj )
125       : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
126         myObj( _obj ) {}
127
128   protected:
129     virtual void execute()
130     {
131       myObj->getEngineIOR();
132     }
133
134   private:
135     SALOME_PYQT_Module* myObj;
136   };
137
138   // post request
139   PyInterp_Dispatcher::Get()->Exec( new EngineIORReq( myInterp, const_cast<SALOME_PYQT_Module*>( this ) ) );
140
141   return myIOR;
142 }
143
144
145 /*!
146  * Redefined to invokec correct version
147  */
148 bool SALOME_PYQT_Module::activateModule( SUIT_Study* theStudy )
149 {
150   // call base implementation
151   bool res = SalomeApp_Module::activateModule( theStudy );
152
153   if ( !res )
154     return res;
155
156   // internal activation
157   return activateModuleInternal( theStudy );
158 }
159
160 /*!
161  * Tries to get engine IOR from the Python module using engineIOR() function.
162  * That function can load module engine using appropriate container if required.
163  * If this function is not available in Python module, the default implementation
164  * is used which loads engine to the default FactoryServerPy container.
165  */
166 void SALOME_PYQT_Module::getEngineIOR()
167 {
168   myIOR = "";
169
170   // Python interpreter should be initialized and Python module should be
171   // import first
172   if ( !myInterp || !myModule )
173     return;
174
175   if ( PyObject_HasAttrString( myModule , "engineIOR" ) ) {
176     PyObjWrapper res( PyObject_CallMethod( myModule, (char*)"engineIOR", (char*)"" ) );
177     if ( !res ) {
178       PyErr_Print();
179     }
180     else {
181       // parse the return value, result chould be string
182       if ( PyString_Check( res ) ) {
183         myIOR = PyString_AsString( res );
184       }
185     }
186   }
187   else if ( !CORBA::is_nil( getEngine() ) )
188     myIOR = QString( getApp()->orb()->object_to_string( getEngine() ) );
189 }
190
191 CAM_DataModel* SALOME_PYQT_Module::createDataModel()
192 {
193   MESSAGE( "SALOME_PYQT_Module::createDataModel()" );
194   CAM_DataModel * dm = SalomeApp_Module::createDataModel();
195   return dm;
196 }
197
198 /*!
199   \brief Process GUI action (from main menu, toolbar or 
200   context popup menu action).
201 */
202 void SALOME_PYQT_Module::onGUIEvent(){
203   SALOME_PYQT_ModuleLight::onGUIEvent();
204 }
205
206 /*!
207   \brief Signal handler closing(SUIT_ViewWindow*) of a view
208   \param pview view being closed
209 */
210 void SALOME_PYQT_Module::onViewClosed( SUIT_ViewWindow* pview )
211 {
212   SALOME_PYQT_ModuleLight::onViewClosed( pview );
213 }
214
215 /*!
216   \brief Signal handler tryClose(SUIT_ViewWindow*) of a view
217   \param pview view user tries to close
218 */
219 void SALOME_PYQT_Module::onViewTryClose( SUIT_ViewWindow* pview )
220 {
221   SALOME_PYQT_ModuleLight::onViewTryClose( pview );
222 }
223
224 /*!
225   \breif Process application preferences changing.
226
227   Called when any application setting is changed.
228
229   \param module preference module
230   \param section preference resource file section
231   \param setting preference resource name
232 */
233 void SALOME_PYQT_Module::preferenceChanged( const QString& module, 
234                                             const QString& section, 
235                                             const QString& setting )
236 {
237   SALOME_PYQT_ModuleLight::preferenceChanged(module,section,setting);
238 }
239
240 /*!
241   \brief Signal handler windowActivated(SUIT_ViewWindow*) of SUIT_Desktop
242   \param pview view being activated
243 */
244 void SALOME_PYQT_Module::onActiveViewChanged( SUIT_ViewWindow* pview )
245 {
246   SALOME_PYQT_ModuleLight::onActiveViewChanged(pview);
247 }
248
249 /*!
250   \brief Signal handler cloneView() of OCCViewer_ViewWindow
251   \param pview view being cloned
252 */
253 void SALOME_PYQT_Module::onViewCloned( SUIT_ViewWindow* pview )
254 {
255   SALOME_PYQT_ModuleLight::onViewCloned(pview);
256 }