1 // Copyright (C) 2007-2023 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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, or (at your option) any later version.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SALOME_PYQT_Module.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "SALOME_PYQT_Module.h"
26 #include "SALOME_PYQT_PyModule.h"
27 #include "SalomeApp_Application.h"
29 #include <SALOME_LifeCycleCORBA.hxx>
30 #include <Container_init_python.hxx>
32 #include <QCoreApplication>
35 // NB: Python requests.
36 // General rule for Python requests created by Python-based GUI modules
37 // (SALOME_PYQT_Module and other ones):
38 // all requests should be executed SYNCHRONOUSLY within the main GUI thread.
39 // However, it is obligatory that ANY Python call is wrapped with a request object,
40 // so that ALL Python API calls are serialized with PyInterp_Dispatcher.
42 // NB: Library initialization
43 // Since the SalomePyQtGUI library is not imported in Python it's initialization function
44 // should be called manually (and only once) in order to initialize global sip data
45 // and to get C API from sip : sipBuildResult for example
48 #define INIT_FUNCTION PyInit_SalomePyQtGUILight
49 #if defined(SIP_STATIC_MODULE)
50 extern "C" void INIT_FUNCTION();
52 PyMODINIT_FUNC INIT_FUNCTION();
56 \fn CAM_Module* createModule()
57 \brief Module factory function.
60 Creates an instance of SALOME_PYQT_Module object by request
61 of an application when the module is loaded and initialized.
63 \return new module object
67 SALOME_PYQT_EXPORT CAM_Module* createModule()
69 QCoreApplication* app = QCoreApplication::instance();
70 bool alreadyInitialized = app && app->property( "salome_pyqt_gui_light_initialized" ).toBool();
72 if ( !alreadyInitialized ) {
73 PyLockWrapper lck; // GIL acquisition
75 if ( app ) app->setProperty( "salome_pyqt_gui_light_initialized", true );
78 return new SALOME_PYQT_Module();
83 \class SALOME_PYQT_Module
84 \brief This class implements GUI module for CORBA engine-based Python SALOME modules.
90 SALOME_PYQT_Module::SALOME_PYQT_Module()
91 : SalomeApp_Module( "noname" ) // name is set explicitly at the module initialization
94 myHelper = new PyModuleHelper( this );
100 SALOME_PYQT_Module::~SALOME_PYQT_Module()
102 // as myHelper is a QObject, it should be deleted automatically
106 \brief Get module engine IOR
108 This function tries to get engine IOR from the Python module using engineIOR() function.
109 That function can load module engine using appropriate container if required.
110 If this function is not available in Python module, the default implementation
111 is used which loads engine to the default FactoryServer container.
113 QString SALOME_PYQT_Module::engineIOR() const
115 // first call helper to get IOR from Python module
116 QString ior = myHelper->engineIOR();
118 // if IOR is still not specified, try default implementation
119 // which loads engine to the default FactoryServer container.
120 if ( ior.isEmpty() ) {
121 Engines::EngineComponent_var comp;
122 // temporary solution
124 comp = getApp()->lcc()->FindOrLoad_Component( "FactoryServer", name().toLatin1() );
126 catch (CORBA::Exception&) {
128 if ( !CORBA::is_nil( comp ) )
129 ior = QString( getApp()->orb()->object_to_string( comp.in() ) );
136 \brief Initialization of the module.
137 \param app parent application object
138 \sa PyModuleHelper::initialize()
140 void SALOME_PYQT_Module::initialize( CAM_Application* app )
142 // call base implementation
143 SalomeApp_Module::initialize( app );
145 // ... then call helper
146 myHelper->initialize( app );
150 \brief Activation of the module.
151 \param study parent study
152 \return \c true if activation is successful and \c false otherwise
153 \sa PyModuleHelper::activate()
155 bool SALOME_PYQT_Module::activateModule( SUIT_Study* study )
157 // call base implementation and then helper
158 return SalomeApp_Module::activateModule( study ) && myHelper->activate( study );
162 \brief Deactivation of the module.
163 \param study parent study
164 \return \c true if deactivation is successful and \c false otherwise
165 \sa PyModuleHelper::deactivate()
167 bool SALOME_PYQT_Module::deactivateModule( SUIT_Study* study )
170 bool res = myHelper->deactivate( study );
172 // ... then call base implementation
173 return SalomeApp_Module::deactivateModule( study ) && res;
177 \brief Get the dockable windows associated with the module.
178 \param winMap output map of dockable windows in form { <window_type> : <dock_area> }
179 \sa PyModuleHelper::windows()
181 void SALOME_PYQT_Module::windows( QMap<int, int>& winMap ) const
183 // get list of dockable windows from helper
184 winMap = myHelper->windows();
188 \brief Define the compatible view windows associated with the module.
189 \param viewList output list of view windows types
190 \sa PyModuleHelper::viewManagers()
192 void SALOME_PYQT_Module::viewManagers( QStringList& viewList ) const
194 // get list of view types from helper
195 viewList = myHelper->viewManagers();
199 \brief Process study activation.
200 \sa PyModuleHelper::studyActivated()
202 void SALOME_PYQT_Module::studyActivated()
205 myHelper->studyActivated( application()->activeStudy() );
209 \brief Process context popup menu request.
210 \param context popup menu context (e.g. "ObjectBrowser")
211 \param menu popup menu
212 \param title popup menu title (not used)
213 \sa PyModuleHelper::contextMenu()
215 void SALOME_PYQT_Module::contextMenuPopup( const QString& context,
220 myHelper->contextMenu( context, menu );
224 \brief Export preferences for the Python module.
225 \sa PyModuleHelper::createPreferences()
227 void SALOME_PYQT_Module::createPreferences()
230 myHelper->createPreferences();
234 \brief Process module's preferences changing.
235 \param section preference resources section
236 \param parameter preference resources parameter name
237 \sa PyModuleHelper::preferencesChanged()
239 void SALOME_PYQT_Module::preferencesChanged( const QString& section, const QString& parameter )
242 myHelper->preferencesChanged( section, parameter );
246 \brief Called when study is closed
247 \param study study being closed
248 \sa PyModuleHelper::studyClosed()
250 void SALOME_PYQT_Module::studyClosed( SUIT_Study* study )
253 myHelper->modelClosed( study );
254 SalomeApp_Module::studyClosed( study );
258 \brief Test if object \a what can be dragged by the user.
259 \param what data object being tested
260 \return \c true if object can be dragged or \c false otherwise
261 \sa PyModuleHelper::isDraggable()
263 bool SALOME_PYQT_Module::isDraggable( const SUIT_DataObject* what ) const
266 return myHelper->isDraggable( what );
270 \brief Test if drop operation can be done on the \a where object.
271 \param where data object being tested
272 \return \c true if if drop operation is supported by object or \c false otherwise
273 \sa PyModuleHelper::isDropAccepted()
275 bool SALOME_PYQT_Module::isDropAccepted( const SUIT_DataObject* where ) const
278 return myHelper->isDropAccepted( where );
282 \brief Perform drop operation
283 \param what list of data objects being dropped
284 \param where target data object for drop operation
285 \param row line (child item index) where drop operation is performed to
286 \param action current drop action (copy or move)
287 \sa PyModuleHelper::dropObjects()
289 void SALOME_PYQT_Module::dropObjects( const DataObjectList& what, SUIT_DataObject* where,
290 const int row, Qt::DropAction action )
293 myHelper->dropObjects( what, where, row, action );