# transform idl reference in appropriate obj file
LIB_CLIENT_SRC = $(LIB_CLIENT_IDL:%.idl=%$(IDL_CLN_CXX))
LIB_SERVER_SRC = $(LIB_SERVER_IDL:%.idl=%$(IDL_SRV_CXX))
-LIB_SWIG_SRC = $(SWIG_DEF:%.i=%_wrap.cxx)
else
LIB_CLIENT_SRC =
LIB_SERVER_SRC =
LIB_SWIG_SRC =
endif
+LIB_SWIG_SRC = $(SWIG_DEF:%.i=%_wrap.cxx)
LIB_MOC_SRC = $(LIB_MOC:%.h=%_moc.cxx)
LIB_SRC+=$(LIB_MOC_SRC)
LIB_DEP= $(LIB_SRC) $(LIB_CLIENT_SRC) $(LIB_SERVER_SRC) $(LIB_SWIG_SRC)
-
+
+LIB_SWIG_OBJ = $(LIB_SWIG_SRC:%.cxx=%.lo)
+
ifneq ($(GUI_DISABLE_CORBA),yes)
LIB_CLIENT_OBJ = $(LIB_CLIENT_IDL:%.idl=%$(IDL_CLN_OBJ))
LIB_SERVER_OBJ = $(LIB_SERVER_IDL:%.idl=%$(IDL_SRV_OBJ))
-LIB_SWIG_OBJ = $(LIB_SWIG_SRC:%.cxx=%.lo)
else
LIB_CLIENT_OBJ =
LIB_SERVER_OBJ =
-LIB_SWIG_OBJ =
endif
# transform c file in appropriate libtool obj file (.c, .cc and .cxx)
LIB_BUILD_SO = $(patsubst %.so, $(top_builddir)/lib@LIB_LOCATION_SUFFIX@/salome/%.so, $(filter %.so, $(LIB)))
ifneq ($(findstring cmodule.la,$(filter %.la, $(LIB))),)
-ifneq ($(GUI_DISABLE_CORBA),yes)
LIB_SWIG = $(patsubst %cmodule.la,%.so, $(filter %.la, $(LIB)))
else
LIB_SWIG =
endif
-else
-LIB_SWIG =
-endif
lib: $(LIB_BUILD) $(LIB_BUILD_SO) $(LIB_CLIENT_PY)
# we don't build static library !
CHECK_PYTHON
+echo
+echo ---------------------------------------------
+echo testing swig
+echo ---------------------------------------------
+echo
+
+AM_PATH_PYTHON(2.3)
+CHECK_SWIG
+
+
dnl echo
dnl echo ---------------------------------------------
dnl echo testing java
CHECK_DISABLE_CORBA
echo "GUI_DISABLE_CORBA = "$GUI_DISABLE_CORBA
-if test "x${GUI_DISABLE_CORBA}" != "xyes" ; then
-
-echo
-echo ---------------------------------------------
-echo testing swig
-echo ---------------------------------------------
-echo
-
-AM_PATH_PYTHON(2.3)
-CHECK_SWIG
-fi
-
echo
echo ---------------------------------------------
echo testing threads
./src/SALOME_PY/Makefile \
./src/SALOME_PYQT/Makefile \
./src/SALOME_PYQT/SALOME_PYQT_GUI/Makefile \
+ ./src/SALOME_PYQT/SALOME_PYQT_GUILight/Makefile \
./src/SALOME_PYQT/SalomePyQt/Makefile \
./resources/Makefile \
./idl/Makefile \
// Author: Natalia Donis
//
#ifndef DISABLE_PYCONSOLE
- #include <PyConsole_Interp.h> // WARNING! This include must be the first!
+ #include <LightApp_PyInterp.h> // WARNING! This include must be the first!
#include <PyConsole_Console.h>
#endif
#ifndef DISABLE_PYCONSOLE
else if ( flag == WT_PyConsole )
{
- PyConsole_Console* pyCons = new PyConsole_Console( desktop() );
+ PyConsole_Console* pyCons = new PyConsole_Console( desktop(),new LightApp_PyInterp());
pyCons->setWindowTitle( tr( "PYTHON_CONSOLE" ) );
wid = pyCons;
pyCons->connectPopupRequest( this, SLOT( onConnectPopupRequest( SUIT_PopupClient*, QContextMenuEvent* ) ) );
//abd: changed libSalomePyQtGUI to SalomePyQtGUI for WIN32
bool isPythonModule = lib.contains("SalomePyQtGUI");
+ bool isPythonLightModule = lib.contains("libSalomePyQtGUILight");
QStringList paths;
#ifdef WIN32
<< "* Module " << moduleTitle.toLatin1().constData() << " will not be available in GUI mode" << std::endl
<< "****************************************************************" << std::endl );
}
- else if ( !isPythonModule )
+ else if ( !isPythonModule && !isPythonLightModule)
return true;
- if ( isPythonModule )
+ if ( isPythonModule || isPythonLightModule)
{
QString pylib = moduleName( moduleTitle ) + QString(".py");
QString pylibgui = moduleName( moduleTitle ) + QString("GUI.py");
QFileInfo inf( Qtx::addSlash( *anIt ) + pylib );
QFileInfo infgui( Qtx::addSlash( *anIt ) + pylibgui );
- if( !isPyLib && inf.exists() )
- isPyLib = true;
+ if(!isPythonLightModule)
+ if( !isPyLib && inf.exists() )
+ isPyLib = true;
if( !isPyGuiLib && infgui.exists() )
isPyGuiLib = true;
- if ( isPyLib && isPyGuiLib && isLibFound)
+ if ((isPyLib || isPythonLightModule ) && isPyGuiLib && isLibFound)
return true;
}
#include <QApplication>
+#include <SALOME_Event.h>
+
LightApp_EventFilter* LightApp_EventFilter::myFilter = NULL;
/*!Constructor.*/
if ( aDesktop )
aDesktop->emitActivated();
}
+
+ else if(e->type() == SALOME_EVENT)
+ {
+ SALOME_Event* aSE = (SALOME_Event*)((SALOME_CustomEvent*)e)->data();
+ processEvent(aSE);
+ ((SALOME_CustomEvent*)e)->setData( 0 );
+ return true;
+ }
return QObject::eventFilter( o, e );
}
+/*!Process event.*/
+void LightApp_EventFilter::processEvent( SALOME_Event* theEvent )
+{
+ if(theEvent)
+ theEvent->ExecutePostedEvent();
+}
+
+
/*!Create new instance of LightApp_EventFilter*/
void LightApp_EventFilter::Init()
{
#pragma warning( disable: 4251 )
#endif
+
+class SALOME_Event;
+
/*!
Class provide event filter.
*/
private:
/*! global event filter for qapplication */
virtual bool eventFilter( QObject* o, QEvent* e );
+ void processEvent( SALOME_Event* );
private:
static LightApp_EventFilter* myFilter;
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 22/06/2007
+
+#include "LightApp_PyInterp.h"
+
+#include <SUITApp_init_python.hxx>
+#include <PyConsole_Interp.h>
+
+#include <pthread.h>
+
+/*!
+ * constructor : multi Python interpreter, one per SALOME study.
+ * calls initialize method defined in base class, which calls virtual methods
+ * initstate & initcontext redefined here.
+ */
+LightApp_PyInterp::LightApp_PyInterp(): PyConsole_Interp()
+{
+}
+
+/*!
+ * Destructor.
+ */
+LightApp_PyInterp::~LightApp_PyInterp()
+{
+}
+
+/*!\class LightApp_PyInterp
+ * EDF-CCAR
+ * When SALOME uses multi Python interpreter feature,
+ * Every study has its own interpreter and thread state (_tstate = Py_NewInterpreter())
+ * This is fine because every study has its own modules (sys.modules) stdout and stderr
+ * BUT some Python modules must be imported only once. In multi interpreter context Python
+ * modules (*.py) are imported several times.
+ * The pyqt module must be imported only once because it registers classes in a C module.
+ * It's quite the same with omniorb modules (internals and generated with omniidl)
+ * This problem is handled with "shared modules" defined in salome_shared_modules.py
+ * These "shared modules" are imported only once and only copied in all the other interpreters
+ * BUT it's not the only problem. Every interpreter has its own __builtin__ module. That's fine
+ * but if we have copied some modules and imported others problems may arise with operations that
+ * are not allowed in restricted execution environment. So we must impose that all interpreters
+ * have identical __builtin__ module.
+ * That's all, for the moment ...
+ */
+
+
+bool LightApp_PyInterp::initContext()
+{
+ /*!
+ * The GIL is assumed to be held
+ * It is the caller responsability caller to acquire the GIL
+ * It will still be held on initContext output
+ */
+ if ( !PyConsole_Interp::initContext() )
+ return false;
+
+ //Import special module to change the import mechanism
+ PyObjWrapper m1( PyImport_ImportModule( "import_hook" ) );
+ if ( !m1 )
+ {
+ PyErr_Print();
+ return false;
+ }
+
+ // Call init_shared_modules to initialize the shared import mechanism for modules
+ //that must not be imported twice
+ PyObjWrapper m2( PyObject_CallMethod( m1, "init_shared_modules", "O", SUIT_PYTHON::salome_shared_modules_module ) );
+ if ( !m2 )
+ {
+ PyErr_Print();
+ return false;
+ }
+ return true;
+}
+
+/*!
+ Do nothing
+ The initialization has been done in main
+ */
+void LightApp_PyInterp::initPython()
+{
+ _gtstate=SUIT_PYTHON::_gtstate; // initialisation in main
+ _interp=SUIT_PYTHON::_interp;
+}
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 22/06/2007
+
+#ifndef _LIGHTAPP_PYINTERP_H_
+#define _LIGHTAPP_PYINTERP_H_
+
+#include <PyConsole_Interp.h> // this include must be first (see PyInterp_base.h)!
+
+class LightApp_PyInterp : public PyConsole_Interp
+{
+public:
+ LightApp_PyInterp();
+ virtual ~LightApp_PyInterp();
+
+protected:
+ virtual void initPython();
+ virtual bool initContext();
+};
+
+#endif //_LIGHTAPP_PYINTERP_H_
LightApp_PreferencesDlg.h \
LightApp_UpdateFlags.h
+if ENABLE_PYCONSOLE
+ salomeinclude_HEADERS += LightApp_PyInterp.h
+endif
+
# LightApp_OBFilter.h
if ENABLE_VTKVIEWER
LightApp_Preferences.cxx \
LightApp_PreferencesDlg.cxx
+if ENABLE_PYCONSOLE
+ dist_libLightApp_la_SOURCES += LightApp_PyInterp.cxx
+endif
+
# LightApp_OBFilter.cxx
if ENABLE_VTKVIEWER
libLightApp_la_CPPFLAGS += -DDISABLE_OCCVIEWER
endif
if ENABLE_PYCONSOLE
- libLightApp_la_CPPFLAGS += $(PYTHON_INCLUDES) -I$(srcdir)/../PyConsole -I$(srcdir)/../PyInterp
+ libLightApp_la_CPPFLAGS += $(PYTHON_INCLUDES) -I$(srcdir)/../PyConsole -I$(srcdir)/../PyInterp \
+ -I$(srcdir)/../SUITApp
libLightApp_la_LDFLAGS += $(PYTHON_LIBS)
else !ENABLE_PYCONSOLE
libLightApp_la_CPPFLAGS += -DDISABLE_PYCONSOLE
libLightApp_la_LIBADD += ../SPlot2d/libSPlot2d.la
endif
endif
+
if ENABLE_PYCONSOLE
- libLightApp_la_LIBADD += ../PyInterp/libPyInterp.la ../PyConsole/libPyConsole.la
+ libLightApp_la_LIBADD += ../PyInterp/libPyInterp.la ../PyConsole/libPyConsole.la \
+ ../SUITApp/libSUITApp.la
endif
+
if ENABLE_SUPERVGRAPHVIEWER
libLightApp_la_LIBADD += ../SUPERVGraph/libSUPERVGraph.la
endif
<parameter name="file" value="no"/>
<parameter name="key" value="no"/>
<parameter name="interp" value="no"/>
- <parameter name="modules" value="LIGHT"/>
+ <parameter name="modules" value="LIGHT,PYLIGHT"/>
</section>
<section name="language">
<!-- Language settings (resource manager)-->
SUBDIRS += QxScene LightApp ResExporter
if GUI_ENABLE_CORBA
- SUBDIRS += TOOLSGUI Session SalomeApp SALOME_SWIG SALOME_PY SALOME_PYQT
+ SUBDIRS += TOOLSGUI Session SalomeApp
+endif
+
+if ENABLE_PYCONSOLE
+ SUBDIRS += SALOME_SWIG SALOME_PY SALOME_PYQT
endif
DIST_SUBDIRS = CASCatch Qtx Style DDS QDS ObjBrowser SUIT SUITApp STD CAF CAM LogWindow Prs Event \
libSalomePy_la_CPPFLAGS = $(QT_INCLUDES) $(PYTHON_INCLUDES) $(VTK_INCLUDES) \
$(OGL_INCLUDES) $(CAS_CXXFLAGS) $(BOOST_CPPFLAGS) @KERNEL_CXXFLAGS@ \
- -DHAVE_CONFIG_H -I$(srcdir)/../SalomeApp -I$(srcdir)/../LightApp \
+ -DHAVE_CONFIG_H -I$(srcdir)/../LightApp \
-I$(srcdir)/../Event -I$(srcdir)/../Session -I$(srcdir)/../SVTK \
-I$(srcdir)/../Qtx -I$(srcdir)/../SUIT -I$(srcdir)/../CAM \
-I$(srcdir)/../STD -I$(srcdir)/../VTKViewer -I$(srcdir)/../OBJECT \
- @CAS_CPPFLAGS@ \
- -I$(top_builddir)/salome_adm/unix @CORBA_CXXFLAGS@ @CORBA_INCLUDES@
+ @CAS_CPPFLAGS@
+
libSalomePy_la_LDFLAGS = $(PYTHON_LIBS) $(QT_MT_LIBS) $(VTK_LIBS) $(OGL_LIBS) \
- ../SalomeApp/libSalomeApp.la \
+ ../LightApp/libLightApp.la \
-lvtkCommonPythonD -lvtkGraphicsPythonD -lvtkImagingPythonD
#include <SALOME_Event.h>
#include <SUIT_Session.h>
-#include <SalomeApp_Application.h>
-#include <SalomeApp_Study.h>
+#include <LightApp_Application.h>
+#include <LightApp_Study.h>
#include <SVTK_ViewManager.h>
#include <SVTK_ViewWindow.h>
PyObject* aPyClass = 0;
if( !aVTKModule ) {
if ( VTK_MAJOR_VERSION > 3 )
- aVTKModule = PyImport_ImportModule( "libvtkRenderingPython" );
+ aVTKModule = PyImport_ImportModule( "vtk.libvtkRenderingPython" );
else
aVTKModule = PyImport_ImportModule( "libVTKGraphicsPython" );
if( PyErr_Occurred() ) {
SVTK_ViewWindow* aVW = 0;
if ( SUIT_Session::session() ) {
// get application
- SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+ LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
if ( anApp ) {
// get active study
- SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() );
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() );
if ( aStudy ) {
// find or create VTK view manager
if ( toCreate == __Create ) {
#
include $(top_srcdir)/adm_local/unix/make_common_starter.am
-SUBDIRS = SALOME_PYQT_GUI SalomePyQt
+SUBDIRS = SALOME_PYQT_GUILight SalomePyQt
+
+if GUI_ENABLE_CORBA
+ SUBDIRS += SALOME_PYQT_GUI
+endif
# library target
lib_LTLIBRARIES = libSalomePyQtGUI.la
-# extra source files (generated by sip)
-SIP_SRC = sipAPISalomePyQtGUI.h \
- sipSalomePyQtGUIcmodule.cc
-
-# Sip definition file
-SIP_FILES = SALOME_PYQT_GUI.sip
-
-# extra dist files
-EXTRA_DIST += $(SIP_FILES)
-
-# extra clean files
-CLEANFILES = $(SIP_SRC)
-
# moc files (generated my moc)
MOC_FILES = SALOME_PYQT_Module_moc.cxx
# exported header files
-salomeinclude_HEADERS = \
- SALOME_PYQT_GUI.h \
- SALOME_PYQT_PyInterp.h \
- SALOME_PYQT_Module.h
+salomeinclude_HEADERS = \
+ SALOME_PYQT_GUI.h \
+ SALOME_PYQT_Module.h
# library sources
dist_libSalomePyQtGUI_la_SOURCES = \
- SALOME_PYQT_PyInterp.cxx \
- SALOME_PYQT_Module.cxx
-nodist_libSalomePyQtGUI_la_SOURCES = $(MOC_FILES) $(SIP_SRC)
+ SALOME_PYQT_Module.cxx
+
+nodist_libSalomePyQtGUI_la_SOURCES = $(MOC_FILES)
# compilation flags
libSalomePyQtGUI_la_CPPFLAGS = $(QT_INCLUDES) $(SIP_INCLUDES) $(PYTHON_INCLUDES) \
-DHAVE_CONFIG_H @KERNEL_CXXFLAGS@ -DCALL_OLD_METHODS \
-I@builddir@ -I$(srcdir)/../../PyInterp -I$(srcdir)/../../SalomeApp \
-I$(srcdir)/../../SUIT -I$(srcdir)/../../Qtx -I$(srcdir)/../../LightApp \
+ -I$(srcdir)/../SALOME_PYQT_GUILight \
-I$(srcdir)/../../Plot2d -I$(srcdir)/../../OCCViewer \
-I$(srcdir)/../../SalomeApp -I$(srcdir)/../../CAM -I$(srcdir)/../../STD \
-I$(top_builddir)/salome_adm/unix @CORBA_CXXFLAGS@ @CORBA_INCLUDES@
# linkage flags
libSalomePyQtGUI_la_LIBADD = $(PYTHON_LIBS) $(SIP_LIBS) $(PYQT_LIBS) $(VTK_LIBS) \
$(OGL_LIBS) ../../PyInterp/libPyInterp.la ../../SalomeApp/libSalomeApp.la \
- ../../OCCViewer/libOCCViewer.la ../../Plot2d/libPlot2d.la
-
-# Custom build step: generate C++ wrapping according to $(SIP_FILES)
-$(SIP_SRC): $(SIP_FILES)
- $(SIP) $(PYQT_SIPFLAGS) $<
-
-# extra dependency (SALOME_PYQT_Module.cxx depends on header files generated by sip)
-$(dist_libSalomePyQtGUI_la_SOURCES): $(SIP_SRC)
-
+ ../../OCCViewer/libOCCViewer.la ../../Plot2d/libPlot2d.la \
+ ../SALOME_PYQT_GUILight/libSalomePyQtGUILight.la
//
#include "SALOME_PYQT_Module.h"
-
-#include <PyInterp_Dispatcher.h>
-
-#include <SUIT_ResourceMgr.h>
-#include <SUIT_Desktop.h>
-#include <SUIT_ViewModel.h>
-#include <SUIT_ViewWindow.h>
-#include <SUIT_ViewManager.h>
-#include <STD_MDIDesktop.h>
-#include <STD_TabDesktop.h>
-#include <LightApp_Preferences.h>
-#include <SalomeApp_Application.h>
-#include <SalomeApp_Study.h>
-
-#include <QtxWorkstack.h>
-#include <QtxWorkspace.h>
-#include <QtxActionGroup.h>
-#include <QtxActionMenuMgr.h>
-#include <QtxActionToolMgr.h>
+#include "SalomeApp_Application.h"
+#include "SALOME_PYQT_ModuleLight.h"
#include <SALOME_LifeCycleCORBA.hxx>
#include <Container_init_python.hxx>
+#include <CORBA.h>
-#include <QFile>
-#include <QDomDocument>
-#include <QDomNode>
-#include <QDomElement>
-#include <QMenuBar>
-#include <QMenu>
-#include <QAction>
-
-#include "sipAPISalomePyQtGUI.h"
-
-#include <sip.h>
-#if SIP_VERSION < 0x040700
-#include "sipQtGuiQWidget.h"
-#include "sipQtGuiQMenu.h"
-#endif
-
-/*!
- \brief Default name of the module, replaced at the moment
- of module creation.
- \internal
-*/
-const char* DEFAULT_NAME = "SALOME_PYQT_Module";
-
-/*!
- \brief Default menu group number.
- \internal
-*/
-const int DEFAULT_GROUP = 40;
-
-/*!
- \var IsCallOldMethods
- \brief Allow calling obsolete callback methods.
- \internal
-
- If the macro CALL_OLD_METHODS is not defined, the invoking
- of obsolete Python module's methods like setSetting(), definePopup(),
- etc. is blocked.
-
- CALL_OLD_METHODS macro can be defined for example by adding
- -DCALL_OLD_METHODS compilation option to the Makefile.
-*/
-#ifdef CALL_OLD_METHODS
-const bool IsCallOldMethods = true;
-#else
-const bool IsCallOldMethods = false;
-#endif
-
-/* Py_ssize_t for old Pythons */
-/* This code is as recommended by: */
-/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
-#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
-typedef int Py_ssize_t;
-# define PY_SSIZE_T_MAX INT_MAX
-# define PY_SSIZE_T_MIN INT_MIN
-#endif
-
-//
-// NB: Python requests.
-// General rule for Python requests created by SALOME_PYQT_Module:
-// all requests should be executed SYNCHRONOUSLY within the main GUI thread.
-// However, it is obligatory that ANY Python call is wrapped with a request object,
-// so that ALL Python API calls are serialized with PyInterp_Dispatcher.
-//
-
-/*!
- \class SALOME_PYQT_Module::XmlHandler
- \brief XML resource files parser.
- \internal
-
- This class is used to provide backward compatibility with
- existing Python modules in which obsolete menu definition system
- (via XML files) is used.
-*/
-
-class SALOME_PYQT_Module::XmlHandler
-{
-public:
- XmlHandler( SALOME_PYQT_Module* module, const QString& fileName );
- void createActions();
- void createPopup ( QMenu* menu,
- const QString& context,
- const QString& parent,
- const QString& object );
- void activateMenus( bool );
-
-protected:
- void createToolBar ( QDomNode& parentNode );
- void createMenu ( QDomNode& parentNode,
- const int parentMenuId = -1,
- QMenu* parentPopup = 0 );
-
- void insertPopupItems( QDomNode& parentNode,
- QMenu* menu );
-
-private:
- SALOME_PYQT_Module* myModule;
- QDomDocument myDoc;
- QList<int> myMenuItems;
-};
//
// NB: Library initialization
-// Since the SalomePyQtGUI library is not imported in Python it's initialization function
+// Since the SalomePyQtGUILight library is not imported in Python it's initialization function
// should be called manually (and only once) in order to initialize global sip data
// and to get C API from sip : sipBuildResult for example
//
-#define INIT_FUNCTION initSalomePyQtGUI
+
+#define INIT_FUNCTION initSalomePyQtGUILight
#if defined(SIP_STATIC_MODULE)
extern "C" void INIT_FUNCTION();
#else
extern "C" {
SALOME_PYQT_EXPORT CAM_Module* createModule() {
+
static bool alreadyInitialized = false;
if ( !alreadyInitialized ) {
// call only once (see comment above) !
- PyEval_RestoreThread( KERNEL_PYTHON::_gtstate );
+
+ PyEval_RestoreThread( KERNEL_PYTHON::_gtstate);
INIT_FUNCTION();
- PyEval_ReleaseThread( KERNEL_PYTHON::_gtstate );
+ PyEval_ReleaseThread( KERNEL_PYTHON::_gtstate);
alreadyInitialized = !alreadyInitialized;
}
return new SALOME_PYQT_Module();
}
}
-/*!
- \class FuncMsg
- \brief Function call in/out tracer.
- \internal
-*/
-
-class FuncMsg
-{
-public:
- FuncMsg( const QString& funcName )
- {
- myName = funcName;
- MESSAGE( myName.toLatin1().constData() << " [ begin ]" );
- }
- ~FuncMsg()
- {
- MESSAGE( myName.toLatin1().constData() << " [ end ]" );
- }
- void message( const QString& msg )
- {
- MESSAGE( myName.toLatin1().constData() << " : " << msg.toLatin1().constData() );
- }
-private:
- QString myName;
-};
-
-/*!
- \class SALOME_PYQT_Module
- \brief This class implements module API for all the Python-based
- SALOME modules.
-*/
-
-//
-// Static variables definition
-//
-SALOME_PYQT_Module::InterpMap SALOME_PYQT_Module::myInterpMap;
-SALOME_PYQT_Module* SALOME_PYQT_Module::myInitModule = 0;
/*!
- \brief Get the module being initialized.
-
- This is a little trick :) needed to provide an access from Python
- (SalomePyQt) to the module being currently activated. The problem
- that during the process of module initialization (initialize()
- function) it is not yet available via application->activeModule()
- call.
-
- This method returns valid pointer only if called in scope of
- initialize() function.
-
- \return the module being currently initialized
+ \var __DEFAULT_NAME__ - Default name of the module, replaced at the moment of module creation
*/
-SALOME_PYQT_Module* SALOME_PYQT_Module::getInitModule()
-{
- return myInitModule;
-}
+const char* __DEFAULT_NAME__ = "SALOME_PYQT_Module";
/*!
- \brief Constructor
-*/
+ * Constructor
+ */
SALOME_PYQT_Module::SALOME_PYQT_Module()
-: SalomeApp_Module( DEFAULT_NAME ),
- myInterp( 0 ),
- myModule( 0 ),
- myXmlHandler ( 0 ),
- myLastActivateStatus( true )
+ : SalomeApp_Module(__DEFAULT_NAME__),
+ LightApp_Module(__DEFAULT_NAME__),
+ SALOME_PYQT_ModuleLight()
{
}
/*!
- \brief Destructor
-*/
+ * Destructor
+ */
SALOME_PYQT_Module::~SALOME_PYQT_Module()
{
- if ( myXmlHandler )
- delete myXmlHandler;
}
/*!
- \brief Initialization of the module.
-
- This method can be used for creation of the menus, toolbars and
- other such staff.
-
- There are two ways to do this:
- - for obsolete modules this method first tries to read
- <module>_<language>.xml resource file which contains a menu,
- toolbars and popup menus description;
- - new modules can create menus by direct calling of the
- corresponding methods of SalomePyQt Python API in the Python
- module's initialize() method which is called from here.
-
- NOTE: SALOME supports two modes of modules loading:
- - immediate (all the modules are created and initialized
- immediately when the application object is created;
- - postponed modules loading (used currently); in this mode
- the module is loaded only be request.
- If postponed modules loading is not used, the active
- study might be not yet defined at this stage, so initialize()
- method should not perform any study-based initialization.
-
- \param app parent application object
-*/
-void SALOME_PYQT_Module::initialize( CAM_Application* app )
+ * Get module engine, returns nil var if engine is not found in LifeCycleCORBA
+ */
+Engines::Component_var SALOME_PYQT_Module::getEngine() const
{
- FuncMsg fmsg( "SALOME_PYQT_Module::initialize()" );
-
- // call base implementation
- SalomeApp_Module::initialize( app );
-
- // try to get XML resource file name
- SUIT_ResourceMgr* aResMgr = getApp()->resourceMgr();
- if ( !myXmlHandler && aResMgr ) {
- // get current language
- QString aLang = aResMgr->stringValue( "language", "language", QString() );
- if ( aLang.isEmpty() )
- aLang = "en";
- // define resource file name
- QString aFileName = name() + "_" + aLang + ".xml";
- aFileName = aResMgr->path( "resources", name(), aFileName );
- // create XML handler instance
- if ( !aFileName.isEmpty() && QFile::exists( aFileName ) )
- myXmlHandler = new SALOME_PYQT_Module::XmlHandler( this, aFileName );
- // create menus & toolbars from XML file if required
- if ( myXmlHandler )
- myXmlHandler->createActions();
+ Engines::Component_var comp;
+ // temporary solution
+ try {
+ comp = getApp()->lcc()->FindOrLoad_Component( "FactoryServerPy", name().toLatin1() );
}
-
- // perform internal initialization and call module's initialize() funtion
- // InitializeReq: request class for internal init() operation
- class InitializeReq : public PyInterp_Request
- {
- public:
- InitializeReq( CAM_Application* _app,
- SALOME_PYQT_Module* _obj )
- : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
- myApp( _app ),
- myObj( _obj ) {}
-
- protected:
- virtual void execute()
- {
- myObj->init( myApp );
- }
-
- private:
- CAM_Application* myApp;
- SALOME_PYQT_Module* myObj;
- };
-
- // post request
- PyInterp_Dispatcher::Get()->Exec( new InitializeReq( app, this ) );
+ catch (CORBA::Exception&) {
+ }
+ return comp;
}
/*!
- \brief Activation of the module.
-
- This function is usually used in order to show the module's
- specific menus and toolbars, update actions state and perform
- other such actions required when the module is activated.
-
- Note, that returning \c false in this function prevents the
- module activation.
-
- \param theStudy parent study
- \return \c true if activation is successful and \c false otherwise
-*/
-bool SALOME_PYQT_Module::activateModule( SUIT_Study* theStudy )
+ * Get module engine IOR, returns empty string if engine is not found in LifeCycleCORBA
+ */
+QString SALOME_PYQT_Module::engineIOR() const
{
- FuncMsg fmsg( "SALOME_PYQT_Module::activateModule()" );
-
- // call base implementation
- bool res = SalomeApp_Module::activateModule( theStudy );
-
- if ( !res )
- return res;
-
- // reset the activation status to the default value
- myLastActivateStatus = true;
-
- // perform internal activation
- // ActivateReq: request class for internal activate() operation
- class ActivateReq : public PyInterp_Request
- {
- public:
- ActivateReq( SUIT_Study* _study,
- SALOME_PYQT_Module* _obj )
- : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
- myStudy ( _study ),
- myObj ( _obj ) {}
-
- protected:
- virtual void execute()
- {
- myObj->activate( myStudy );
- }
-
- private:
- SUIT_Study* myStudy;
- SALOME_PYQT_Module* myObj;
- };
-
- // post request
- PyInterp_Dispatcher::Get()->Exec( new ActivateReq( theStudy, this ) );
-
- // check activation status (set by activate())
- if ( !lastActivationStatus() )
- return false;
-
- // activate menus, toolbars, etc
- if ( myXmlHandler ) myXmlHandler->activateMenus( true );
- setMenuShown( true );
- setToolShown( true );
-
- // connect preferences changing signal
- connect( getApp(), SIGNAL( preferenceChanged( const QString&, const QString&, const QString& ) ),
- this, SLOT( preferenceChanged( const QString&, const QString&, const QString& ) ) );
-
- // perform custom activation actions
- // CustomizeReq: request class for internal customize() operation
- class CustomizeReq : public PyInterp_Request
- {
- public:
- CustomizeReq( SUIT_Study* _study,
- SALOME_PYQT_Module* _obj )
- : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
- myStudy ( _study ),
- myObj ( _obj ) {}
-
- protected:
- virtual void execute()
- {
- myObj->customize( myStudy );
- }
-
- private:
- SUIT_Study* myStudy;
- SALOME_PYQT_Module* myObj;
- };
-
- // post request
- PyInterp_Dispatcher::Get()->Exec( new CustomizeReq( theStudy, this ) );
+ if ( !CORBA::is_nil( getEngine() ) )
+ return QString( getApp()->orb()->object_to_string( getEngine() ) );
+ return QString( "" );
+}
- return true;
+CAM_DataModel* SALOME_PYQT_Module::createDataModel()
+{
+ MESSAGE( "SALOME_PYQT_Module::createDataModel()" );
+ CAM_DataModel * dm = SalomeApp_Module::createDataModel();
+ return dm;
}
/*!
- \brief Deactivation of the module.
-
- This function is usually used in order to hide the module's
- specific menus and toolbars and perform other such actions
- required when the module is deactivated.
-
- \param theStudy parent study
- \return \c true if deactivation is successful and \c false otherwise
+ \brief Process GUI action (from main menu, toolbar or
+ context popup menu action).
*/
-bool SALOME_PYQT_Module::deactivateModule( SUIT_Study* theStudy )
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::deactivateModule()" );
-
- // disconnect preferences changing signal
- disconnect( getApp(), SIGNAL( preferenceChanged( const QString&, const QString&, const QString& ) ),
- this, SLOT( preferenceChanged( const QString&, const QString&, const QString& ) ) );
-
- // perform internal deactivation
- // DeactivateReq: request class for internal deactivate() operation
- class DeactivateReq : public PyInterp_LockRequest
- {
- public:
- DeactivateReq( PyInterp_Interp* _py_interp,
- SUIT_Study* _study,
- SALOME_PYQT_Module* _obj )
- : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
- myStudy ( _study ),
- myObj ( _obj ) {}
-
- protected:
- virtual void execute()
- {
- myObj->deactivate( myStudy );
- }
-
- private:
- SUIT_Study* myStudy;
- SALOME_PYQT_Module* myObj;
- };
-
- // post request
- PyInterp_Dispatcher::Get()->Exec( new DeactivateReq( myInterp, theStudy, this ) );
-
- // deactivate menus, toolbars, etc
- if ( myXmlHandler ) myXmlHandler->activateMenus( false );
- setMenuShown( false );
- setToolShown( false );
-
- // call base implementation
- return SalomeApp_Module::deactivateModule( theStudy );
+void SALOME_PYQT_Module::onGUIEvent(){
+ SALOME_PYQT_ModuleLight::onGUIEvent();
}
/*!
- \brief Get last activation status.
- \return status of last module activation operation
- \sa activateModule()
+ \brief Signal handler closing(SUIT_ViewWindow*) of a view
+ \param pview view being closed
*/
-bool SALOME_PYQT_Module::lastActivationStatus() const
+void SALOME_PYQT_Module::onViewClosed( SUIT_ViewWindow* pview )
{
- return myLastActivateStatus;
+ SALOME_PYQT_ModuleLight::onViewClosed( pview );
}
/*!
\param section preference resource file section
\param setting preference resource name
*/
-void SALOME_PYQT_Module::preferenceChanged( const QString& module,
+void SALOME_PYQT_ModuleLight::preferenceChanged( const QString& module,
const QString& section,
const QString& setting )
{
- FuncMsg fmsg( "SALOME_PYQT_Module::preferenceChanged()" );
-
- // perform synchronous request to Python event dispatcher
- class Event : public PyInterp_LockRequest
- {
- public:
- Event( PyInterp_Interp* _py_interp,
- SALOME_PYQT_Module* _obj,
- const QString& _section,
- const QString& _setting )
- : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
- myObj ( _obj ),
- mySection( _section ),
- mySetting( _setting ) {}
-
- protected:
- virtual void execute()
- {
- myObj->prefChanged( mySection, mySetting );
- }
-
- private:
- SALOME_PYQT_Module* myObj;
- QString mySection, mySetting;
- };
-
- if ( module != moduleName() ) {
- // module's own preferences are processed by preferencesChanged() method
- // ...
- // post the request only if dispatcher is not busy!
- // execute request synchronously
- if ( !PyInterp_Dispatcher::Get()->IsBusy() )
- PyInterp_Dispatcher::Get()->Exec( new Event( myInterp, this, section, setting ) );
- }
-}
-
-/*!
- \brief Process study activation.
-
- Called when study desktop is activated. Used for notifying the Python
- module about changing of the active study.
-*/
-void SALOME_PYQT_Module::studyActivated()
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::studyActivated()" );
-
- // StudyChangedReq: request class for internal studyChanged() operation
- class StudyChangedReq : public PyInterp_Request
- {
- public:
- StudyChangedReq( SUIT_Study* _study,
- SALOME_PYQT_Module* _obj )
- : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
- myStudy ( _study ),
- myObj ( _obj ) {}
-
- protected:
- virtual void execute()
- {
- myObj->studyChanged( myStudy );
- }
-
- private:
- SUIT_Study* myStudy;
- SALOME_PYQT_Module* myObj;
- };
-
- // post request
- PyInterp_Dispatcher::Get()->Exec( new StudyChangedReq( application()->activeStudy(), this ) );
-}
-
-/*!
- \brief Process GUI action (from main menu, toolbar or
- context popup menu action).
-*/
-void SALOME_PYQT_Module::onGUIEvent()
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::onGUIEvent()" );
-
- // get sender action
- QAction* action = qobject_cast<QAction*>( sender() );
- if ( !action )
- return;
-
- // get action ID
- int id = actionId( action );
- fmsg.message( QString( "action id = %1" ).arg( id ) );
-
- // perform synchronous request to Python event dispatcher
- class GUIEvent : public PyInterp_LockRequest
- {
- public:
- GUIEvent( PyInterp_Interp* _py_interp,
- SALOME_PYQT_Module* _obj,
- int _id )
- : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
- myId ( _id ),
- myObj ( _obj ) {}
-
- protected:
- virtual void execute()
- {
- myObj->guiEvent( myId );
- }
-
- private:
- int myId;
- SALOME_PYQT_Module* myObj;
- };
-
- // post request
- PyInterp_Dispatcher::Get()->Exec( new GUIEvent( myInterp, this, id ) );
-}
-
-/*!
- \brief Process context popup menu request.
-
- Called when user activates popup menu in some window
- (view, object browser, etc).
-
- \param theContext popup menu context (e.g. "ObjectBrowser")
- \param thePopupMenu popup menu
- \param title popup menu title (not used)
-*/
-void SALOME_PYQT_Module::contextMenuPopup( const QString& theContext,
- QMenu* thePopupMenu,
- QString& /*title*/ )
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::contextMenuPopup()" );
- fmsg.message( QString( "context: %1" ).arg( theContext ) );
-
- // perform synchronous request to Python event dispatcher
- class PopupMenuEvent : public PyInterp_LockRequest
- {
- public:
- PopupMenuEvent( PyInterp_Interp* _py_interp,
- SALOME_PYQT_Module* _obj,
- const QString& _context,
- QMenu* _popup )
- : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
- myContext( _context ),
- myPopup ( _popup ),
- myObj ( _obj ) {}
-
- protected:
- virtual void execute()
- {
- myObj->contextMenu( myContext, myPopup );
- }
-
- private:
- SALOME_PYQT_Module* myObj;
- QString myContext;
- QMenu* myPopup;
- };
-
- // post request only if dispatcher is not busy!
- // execute request synchronously
- if ( !PyInterp_Dispatcher::Get()->IsBusy() )
- PyInterp_Dispatcher::Get()->Exec( new PopupMenuEvent( myInterp, this, theContext, thePopupMenu ) );
-}
-
-/*!
- \brief Export preferences for the Python module.
-
- Called only once when the first instance of the module is created.
-*/
-void SALOME_PYQT_Module::createPreferences()
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::createPreferences()" );
-
- // perform synchronous request to Python event dispatcher
- class Event : public PyInterp_LockRequest
- {
- public:
- Event( PyInterp_Interp* _py_interp,
- SALOME_PYQT_Module* _obj )
- : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
- myObj ( _obj ) {}
-
- protected:
- virtual void execute()
- {
- myObj->initPreferences();
- }
-
- private:
- SALOME_PYQT_Module* myObj;
- };
-
- // post request only if dispatcher is not busy!
- // execute request synchronously
- if ( !PyInterp_Dispatcher::Get()->IsBusy() )
- PyInterp_Dispatcher::Get()->Exec( new Event( myInterp, this ) );
-}
-
-/*!
- \brief Define the dockable windows associated with the module.
-
- To fill the list of windows the correspondind Python module's windows()
- method is called from SALOME_PYQT_Module::init() method.
-
- By default, ObjectBrowser, PythonConsole and LogWindow windows are
- associated to the module.
-
- Allowed dockable windows:
- - SalomeApp_Application::WT_ObjectBrowser : object browser
- - SalomeApp_Application::WT_PyConsole : python console
- - SalomeApp_Application::WT_LogWindow : log messages output window
-
- Dock area is defined by Qt::DockWidgetArea enumeration:
- - Qt::TopDockWidgetArea : top dock area
- - Qt::BottomDockWidgetArea : bottom dock area
- - Qt::LeftDockWidgetArea : left dock area
- - Qt::RightDockWidgetArea : right dock area
-
- \param mappa map of dockable windows: { <window_type> : <dock_area> }
-*/
-void SALOME_PYQT_Module::windows( QMap<int, int>& mappa ) const
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::windows()" );
-
- mappa = myWindowsMap;
-}
-
-/*!
- \brief Define the compatible view windows associated with the module.
-
- The associated view windows are opened automatically when the module
- is activated.
-
- To fill the list of views the correspondind Python module's views()
- method is called from SALOME_PYQT_Module::init() method.
- By default, the list is empty.
-
- \param listik list of view windows types
-*/
-void SALOME_PYQT_Module::viewManagers( QStringList& lst ) const
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::viewManagers()" );
-
- lst = myViewMgrList;
-}
-
-/*!
- \brief Process module's preferences changing.
-
- Called when the module's preferences are changed.
-
- \param section setting section
- \param setting setting name
-*/
-void SALOME_PYQT_Module::preferencesChanged( const QString& section, const QString& setting )
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::preferencesChanged()" );
-
- // perform synchronous request to Python event dispatcher
- class Event : public PyInterp_LockRequest
- {
- public:
- Event( PyInterp_Interp* _py_interp,
- SALOME_PYQT_Module* _obj,
- const QString& _section,
- const QString& _setting )
- : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
- myObj ( _obj ),
- mySection( _section ),
- mySetting( _setting ) {}
-
- protected:
- virtual void execute()
- {
- myObj->prefChanged( mySection, mySetting );
- }
-
- private:
- SALOME_PYQT_Module* myObj;
- QString mySection, mySetting;
- };
-
- // post request only if dispatcher is not busy!
- // execut request synchronously
- if ( !PyInterp_Dispatcher::Get()->IsBusy() )
- PyInterp_Dispatcher::Get()->Exec( new Event( myInterp, this, section, setting ) );
-}
-
-/*!
- \brief Internal module initialization:
-
- Performs the following actions:
- - initialize or get the Python interpreter (one per study)
- - import the Python module
- - pass the workspace widget to the Python module
- - call Python module's initialize() method
- - call Python module's windows() method
- - call Python module's views() method
-
- \param app parent application object
-*/
-void SALOME_PYQT_Module::init( CAM_Application* app )
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::init()" );
-
- // reset interpreter to NULL
- myInterp = NULL;
-
- // get study Id
- SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( app );
- if ( !anApp )
- return;
- SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
- if ( !aStudy )
- return;
- int aStudyId = aStudy ? aStudy->studyDS()->StudyId() : 0;
-
- // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
- initInterp( aStudyId );
- if ( !myInterp )
- return; // Error
-
- // import Python GUI module
- importModule();
- if ( !myModule )
- return; // Error
-
- // this module is being activated now!
- myInitModule = this;
-
- // then call Python module's initialize() method
- // ... first get python lock
- PyLockWrapper aLock = myInterp->GetLockWrapper();
- // ... (the Python module is already imported)
- // ... finally call Python module's initialize() method
- if ( PyObject_HasAttrString( myModule , "initialize" ) ) {
- PyObjWrapper res( PyObject_CallMethod( myModule, "initialize", "" ) );
- if ( !res ) {
- PyErr_Print();
- }
- }
-
- // get required dockable windows list from the Python module
- // by calling windows() method
- // ... first put default values
- myWindowsMap.insert( SalomeApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
- myWindowsMap.insert( SalomeApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
- myWindowsMap.insert( SalomeApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
-
- if ( PyObject_HasAttrString( myModule , "windows" ) ) {
- PyObjWrapper res1( PyObject_CallMethod( myModule, "windows", "" ) );
- if ( !res1 ) {
- PyErr_Print();
- }
- else {
- myWindowsMap.clear();
- if ( PyDict_Check( res1 ) ) {
- PyObject* key;
- PyObject* value;
- Py_ssize_t pos = 0;
- while ( PyDict_Next( res1, &pos, &key, &value ) ) {
- // parse the return value
- // it should be a map: {integer:integer}
- int aKey, aValue;
- if( key && PyInt_Check( key ) && value && PyInt_Check( value ) ) {
- aKey = PyInt_AsLong( key );
- aValue = PyInt_AsLong( value );
- myWindowsMap[ aKey ] = aValue;
- }
- }
- }
- }
- }
-
- // get compatible view windows types from the Python module
- // by calling views() method
- if ( PyObject_HasAttrString( myModule , "views" ) ) {
- PyObjWrapper res2( PyObject_CallMethod( myModule, "views", "" ) );
- if ( !res2 ) {
- PyErr_Print();
- }
- else {
- // parse the return value
- // result can be one string...
- if ( PyString_Check( res2 ) ) {
- myViewMgrList.append( PyString_AsString( res2 ) );
- }
- // ... or list of strings
- else if ( PyList_Check( res2 ) ) {
- int size = PyList_Size( res2 );
- for ( int i = 0; i < size; i++ ) {
- PyObject* value = PyList_GetItem( res2, i );
- if( value && PyString_Check( value ) ) {
- myViewMgrList.append( PyString_AsString( value ) );
- }
- }
- }
- }
- }
- // module is already activated!
- myInitModule = 0;
+ SALOME_PYQT_ModuleLight::preferenceChanged(module,section,setting);
}
/*!
- \brief Internal activation:
-
- Performs the following actions:
- - initialize or get the Python interpreter (one per study)
- - import the Python GUI module
- - call Python module's activate() method
-
- \param theStudy parent study object
+ \brief Signal handler windowActivated(SUIT_ViewWindow*) of SUIT_Desktop
+ \param pview view being activated
*/
-void SALOME_PYQT_Module::activate( SUIT_Study* theStudy )
+void SALOME_PYQT_Module::onActiveViewChanged( SUIT_ViewWindow* pview )
{
- FuncMsg fmsg( "SALOME_PYQT_Module::activate()" );
-
- // get study Id
- SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( theStudy );
- int aStudyId = aStudy ? aStudy->studyDS()->StudyId() : 0;
-
- // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
- initInterp( aStudyId );
- if ( !myInterp )
- return; // Error
-
- // import Python GUI module
- importModule();
- if ( !myModule )
- return; // Error
-
- // get python lock
- PyLockWrapper aLock = myInterp->GetLockWrapper();
-
- // call Python module's activate() method (for the new modules)
- if ( PyObject_HasAttrString( myModule , "activate" ) ) {
- PyObject* res1 = PyObject_CallMethod( myModule, "activate", "" );
- if ( !res1 || !PyBool_Check( res1 ) ) {
- PyErr_Print();
- // always true for old modules (no return value)
- myLastActivateStatus = true;
- }
- else {
- // detect return status
- myLastActivateStatus = PyObject_IsTrue( res1 );
- }
- }
-
- // Connect the SUIT_Desktop signal windowActivated() to this->onActiveViewChanged()
- SUIT_Desktop* aDesk = theStudy->application()->desktop();
- if ( aDesk )
- {
- connect( aDesk, SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
- this, SLOT( onActiveViewChanged( SUIT_ViewWindow* ) ) );
- // If a active window exists send activeViewChanged
- // If a getActiveView() in SalomePyQt available we no longer need this
- SUIT_ViewWindow* aView = aDesk->activeWindow();
- if ( aView )
- activeViewChanged( aView );
-
- // get all view currently opened in the study and connect their signals to
- // the corresponding slots of the class.
- QList<SUIT_ViewWindow*> wndList = aDesk->windows();
- SUIT_ViewWindow* wnd;
- foreach ( wnd, wndList )
- connectView( wnd );
- }
+ SALOME_PYQT_ModuleLight::onActiveViewChanged(pview);
}
/*!
- \brief Additional customization after module is activated:
-
- Performs the following actions:
- - get the Python interpreter (one per study)
- - import the Python GUI module
- - call Python module's setSettings() method (obsolete function,
- used for compatibility with old code)
-
- \param theStudy parent study object
+ \brief Signal handler cloneView() of OCCViewer_ViewWindow
+ \param pview view being cloned
*/
-void SALOME_PYQT_Module::customize( SUIT_Study* theStudy )
+void SALOME_PYQT_Module::onViewCloned( SUIT_ViewWindow* pview )
{
- FuncMsg fmsg( "SALOME_PYQT_Module::customize()" );
-
- // get study Id
- SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( theStudy );
- int aStudyId = aStudy ? aStudy->studyDS()->StudyId() : 0;
-
- // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
- initInterp( aStudyId );
- if ( !myInterp )
- return; // Error
-
- // import Python GUI module
- importModule();
- if ( !myModule )
- return; // Error
-
- if ( IsCallOldMethods ) {
- // call Python module's setWorkspace() method
- setWorkSpace();
- }
-
- // get python lock
- PyLockWrapper aLock = myInterp->GetLockWrapper();
-
- if ( IsCallOldMethods ) {
- // call Python module's setSettings() method (obsolete)
- if ( PyObject_HasAttrString( myModule , "setSettings" ) ) {
- PyObjWrapper res( PyObject_CallMethod( myModule, "setSettings", "" ) );
- if( !res ) {
- PyErr_Print();
- }
- }
- }
-}
-
-/*!
- \brief Internal deactivation:
-
- Performs the following actions:
- - call Python module's deactivate() method
-
- \param theStudy parent study object
-*/
-void SALOME_PYQT_Module::deactivate( SUIT_Study* theStudy )
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::deactivate()" );
-
- // check if the subinterpreter is initialized and Python module is imported
- if ( !myInterp || !myModule ) {
- // Error! Python subinterpreter should be initialized and module should be imported first!
- return;
- }
- // then call Python module's deactivate() method
- if ( PyObject_HasAttrString( myModule , "deactivate" ) ) {
- PyObjWrapper res( PyObject_CallMethod( myModule, "deactivate", "" ) );
- if( !res ) {
- PyErr_Print();
- }
- }
-
- // Disconnect the SUIT_Desktop signal windowActivated()
- SUIT_Desktop* aDesk = theStudy->application()->desktop();
- if ( aDesk )
- {
- disconnect( aDesk, SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
- this, SLOT( onActiveViewChanged( SUIT_ViewWindow* ) ) );
- }
-}
-
-/*!
- \brief Perform internal actions when active study is changed.
-
- Called when active the study is actived (user brings its
- desktop to top):
- - initialize or get the Python interpreter (one per study)
- - import the Python GUI module
- - call Python module's activeStudyChanged() method
-
- \param theStudy study being activated
-*/
-void SALOME_PYQT_Module::studyChanged( SUIT_Study* theStudy )
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::studyChanged()" );
-
- // get study Id
- SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( theStudy );
- int aStudyId = aStudy ? aStudy->studyDS()->StudyId() : 0;
-
- // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
- initInterp( aStudyId );
- if ( !myInterp )
- return; // Error
-
- // import Python GUI module
- importModule();
- if ( !myModule )
- return; // Error
-
- if ( IsCallOldMethods ) {
- // call Python module's setWorkspace() method
- setWorkSpace();
- }
-
- // get python lock
- PyLockWrapper aLock = myInterp->GetLockWrapper();
-
- // call Python module's activeStudyChanged() method
- if ( PyObject_HasAttrString( myModule , "activeStudyChanged" ) ) {
- PyObjWrapper res( PyObject_CallMethod( myModule, "activeStudyChanged", "i", aStudyId ) );
- if( !res ) {
- PyErr_Print();
- }
- }
-}
-
-/*!
- \brief Get module engine.
-
- Returns nil var if engine is not found in LifeCycleCORBA.
-
- \return module's engine reference
-*/
-Engines::Component_var SALOME_PYQT_Module::getEngine() const
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::getEngine()" );
-
- Engines::Component_var comp;
- try {
- comp = getApp()->lcc()->FindOrLoad_Component( "FactoryServerPy", name().toLatin1() );
- }
- catch ( CORBA::Exception& ) {
- }
- return comp;
-}
-
-/*!
- \birief Get module engine IOR.
-
- Returns empty string if engine is not found in LifeCycleCORBA.
-
- \return module's engine IOR
-*/
-QString SALOME_PYQT_Module::engineIOR() const
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::engineIOR()" );
-
- QString anIOR = "";
- if ( !CORBA::is_nil( getEngine() ) )
- anIOR = getApp()->orb()->object_to_string( getEngine() );
- return anIOR;
-}
-
-/*!
- \brief Process (internally) context popup menu request.
-
- Performs the following actions:
- - calls Python module's definePopup(...) method (obsolete function,
- used for compatibility with old code) to define the popup menu context
- - parses XML resourses file (if exists) and fills the popup menu with the items)
- - calls Python module's customPopup(...) method (obsolete function,
- used for compatibility with old code) to allow module to customize the popup menu
- - for new modules calls createPopupMenu() function to allow the
- modules to build the popup menu by using insertItem(...) Qt functions.
-
- \param theContext popup menu context
- \param thePopupMenu popup menu
-*/
-void SALOME_PYQT_Module::contextMenu( const QString& theContext, QMenu* thePopupMenu )
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::contextMenu()" );
-
- // Python interpreter should be initialized and Python module should be
- // import first
- if ( !myInterp || !myModule )
- return;
-
- QString aContext( "" ), aObject( "" ), aParent( theContext );
-
- if ( IsCallOldMethods && PyObject_HasAttrString( myModule , "definePopup" ) ) {
- // call definePopup() Python module's function
- // this is obsolete function, used only for compatibility reasons
- PyObjWrapper res( PyObject_CallMethod( myModule,
- "definePopup",
- "sss",
- aContext.toLatin1().constData(),
- aObject.toLatin1().constData(),
- aParent.toLatin1().constData() ) );
- if( !res ) {
- PyErr_Print();
- }
- else {
- // parse return value
- char *co, *ob, *pa;
- if( PyArg_ParseTuple( res, "sss", &co, &ob, &pa ) ) {
- aContext = co;
- aObject = ob;
- aParent = pa;
- }
- }
- } // if ( IsCallOldMethods ... )
-
- // first try to create menu via XML parser:
- // we create popup menus without help of QtxPopupMgr
- if ( myXmlHandler )
- myXmlHandler->createPopup( thePopupMenu, aContext, aParent, aObject );
-
- PyObjWrapper sipPopup( sipBuildResult( 0, "M", thePopupMenu, sipClass_QMenu ) );
-
- // then call Python module's createPopupMenu() method (for new modules)
- if ( PyObject_HasAttrString( myModule , "createPopupMenu" ) ) {
- PyObjWrapper res1( PyObject_CallMethod( myModule,
- "createPopupMenu",
- "Os",
- sipPopup.get(),
- aContext.toLatin1().constData() ) );
- if( !res1 ) {
- PyErr_Print();
- }
- }
-
- if ( IsCallOldMethods && PyObject_HasAttrString( myModule , "customPopup" ) ) {
- // call customPopup() Python module's function
- // this is obsolete function, used only for compatibility reasons
- PyObjWrapper res2( PyObject_CallMethod( myModule,
- "customPopup",
- "Osss",
- sipPopup.get(),
- aContext.toLatin1().constData(),
- aObject.toLatin1().constData(),
- aParent.toLatin1().constData() ) );
- if( !res2 ) {
- PyErr_Print();
- }
- }
-}
-
-/*!
- \brief Internal GUI event handling.
-
- Performs the following actions:
- - calls Python module's OnGUIEvent() method
-
- \param theId GUI action ID
-*/
-void SALOME_PYQT_Module::guiEvent( const int theId )
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::guiEvent()" );
-
- // Python interpreter should be initialized and Python module should be
- // import first
- if ( !myInterp || !myModule )
- return;
-
- if ( PyObject_HasAttrString( myModule , "OnGUIEvent" ) ) {
- PyObjWrapper res( PyObject_CallMethod( myModule, "OnGUIEvent", "i", theId ) );
- if( !res ) {
- PyErr_Print();
- }
- }
-}
-
-/*!
- \brief Initialize (internally) preferences for the module.
-
- Performs the following actions:
- - calls Python module's createPreferences() method
-*/
-void SALOME_PYQT_Module::initPreferences()
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::initPreferences()" );
-
- // Python interpreter should be initialized and Python module should be
- // import first
- if ( !myInterp || !myModule )
- return;
-
- // temporary set myInitModule because createPreferences() method
- // might be called during the module intialization process
- myInitModule = this;
-
- if ( PyObject_HasAttrString( myModule , "createPreferences" ) ) {
- PyObjWrapper res( PyObject_CallMethod( myModule, "createPreferences", "" ) );
- if( !res ) {
- PyErr_Print();
- }
- }
-
- myInitModule = 0;
-}
-
-/*!
- \brief Initialize python subinterpreter (one per study).
- \param theStudyId study ID
-*/
-void SALOME_PYQT_Module::initInterp( int theStudyId )
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::initInterp()" );
-
- // check study Id
- if ( !theStudyId ) {
- // Error! Study Id must not be 0!
- myInterp = NULL;
- return;
- }
- // try to find the subinterpreter
- if( myInterpMap.contains( theStudyId ) ) {
- // found!
- myInterp = myInterpMap[ theStudyId ];
- return;
- }
- // not found - create a new one!
- ///////////////////////////////////////////////////////////////////
- // Attention: the creation of Python interpretor must be protected
- // by a C++ Lock because of C threads
- ///////////////////////////////////////////////////////////////////
- myInterp = new SALOME_PYQT_PyInterp();
- myInterp->initialize();
- myInterpMap[ theStudyId ] = myInterp;
-
- // import 'salome' module and call 'salome_init' method;
- // do it only once on interpreter creation
- // ... first get python lock
- PyLockWrapper aLock = myInterp->GetLockWrapper();
- // ... then import a module
- PyObjWrapper aMod = PyImport_ImportModule( "salome" );
- if( !aMod ) {
- // Error!
- PyErr_Print();
- return;
- }
- // ... then call a method
- int embedded = 1;
- PyObjWrapper aRes( PyObject_CallMethod( aMod, "salome_init", "ii", theStudyId, embedded ) );
- if( !aRes ) {
- // Error!
- PyErr_Print();
- return;
- }
-}
-
-/*!
- \brief Import Python GUI module and remember the reference to the module.
-
- Attention! initInterp() should be called first!!!
-*/
-void SALOME_PYQT_Module::importModule()
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::importModule()" );
-
- // check if the subinterpreter is initialized
- if ( !myInterp ) {
- // Error! Python subinterpreter should be initialized first!
- myModule = 0;
- return;
- }
- // import Python GUI module and puts it in <myModule> attribute
- // ... first get python lock
- PyLockWrapper aLock = myInterp->GetLockWrapper();
- // ... then import a module
- QString aMod = name() + "GUI";
- myModule = PyImport_ImportModule( aMod.toLatin1().data() );
- if( !myModule ) {
- // Error!
- PyErr_Print();
- return;
- }
-}
-
-/*!
- \brief Set study workspace to the Python module.
-
- Calls setWorkSpace() method of the Pythohn module with
- PyQt QWidget object to use with interpreter.
-
- Attention! initInterp() and importModule() should be called first!!!
-*/
-void SALOME_PYQT_Module::setWorkSpace()
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::setWorkSpace()" );
-
- // check if the subinterpreter is initialized and Python module is imported
- if ( !myInterp || !myModule ) {
- // Error! Python subinterpreter should be initialized and module should be imported first!
- return;
- }
-
- // call setWorkspace() method
- // ... first get python lock
- PyLockWrapper aLock = myInterp->GetLockWrapper();
-
- // ... then try to import SalomePyQt module. If it's not possible don't go on.
- PyObjWrapper aQtModule( PyImport_ImportModule( "SalomePyQt" ) );
- if( !aQtModule ) {
- // Error!
- PyErr_Print();
- return;
- }
-
- if ( IsCallOldMethods ) {
- // ... then get workspace object
- QWidget* aWorkspace = 0;
- if ( getApp()->desktop()->inherits( "STD_MDIDesktop" ) ) {
- STD_MDIDesktop* aDesktop = dynamic_cast<STD_MDIDesktop*>( getApp()->desktop() );
- if ( aDesktop )
- aWorkspace = aDesktop->workspace();
- }
- else if ( getApp()->desktop()->inherits( "STD_TabDesktop" ) ) {
- STD_TabDesktop* aDesktop = dynamic_cast<STD_TabDesktop*>( getApp()->desktop() );
- if ( aDesktop )
- aWorkspace = aDesktop->workstack();
- }
- PyObjWrapper pyws( sipBuildResult( 0, "M", aWorkspace, sipClass_QWidget ) );
- // ... and finally call Python module's setWorkspace() method (obsolete)
- if ( PyObject_HasAttrString( myModule , "setWorkSpace" ) ) {
- PyObjWrapper res( PyObject_CallMethod( myModule, "setWorkSpace", "O", pyws.get() ) );
- if( !res ) {
- PyErr_Print();
- }
- }
- }
-}
-
-/*!
- \brief Preference changing callback function (internal).
-
- Performs the following actions:
- - call Python module's preferenceChanged() method
-
- \param section setting section name
- \param setting setting name
-*/
-void SALOME_PYQT_Module::prefChanged( const QString& section, const QString& setting )
-{
- FuncMsg fmsg( "SALOME_PYQT_Module::prefChanged()" );
-
- // Python interpreter should be initialized and Python module should be
- // import first
- if ( !myInterp || !myModule )
- return;
-
- if ( PyObject_HasAttrString( myModule , "preferenceChanged" ) ) {
- PyObjWrapper res( PyObject_CallMethod( myModule,
- "preferenceChanged",
- "ss",
- section.toLatin1().constData(),
- setting.toLatin1().constData() ) );
- if( !res ) {
- PyErr_Print();
- }
- }
-}
-
-/*!
- \brief Get default menu group identifier
- \return menu group ID (40 by default)
-*/
-int SALOME_PYQT_Module::defaultMenuGroup()
-{
- return DEFAULT_GROUP;
-}
-
-//
-// The next methods call the parent implementation.
-// This is done to open protected methods from CAM_Module class.
-//
-
-/*!
- \brief Create toolbar with specified \a name.
- \param name toolbar name
- \return toolbar ID or -1 if toolbar creation is failed
-*/
-int SALOME_PYQT_Module::createTool( const QString& name )
-{
- return SalomeApp_Module::createTool( name );
-}
-
-/*!
- \brief Insert action with specified \a id to the toolbar.
- \param id action ID
- \param tBar toolbar ID
- \param idx required index in the toolbar
- \return action ID or -1 if action could not be added
-*/
-int SALOME_PYQT_Module::createTool( const int id, const int tBar, const int idx )
-{
- return SalomeApp_Module::createTool( id, tBar, idx );
-}
-
-/*!
- \brief Insert action with specified \a id to the toolbar.
- \param id action ID
- \param tBar toolbar name
- \param idx required index in the toolbar
- \return action ID or -1 if action could not be added
-*/
-int SALOME_PYQT_Module::createTool( const int id, const QString& tBar, const int idx )
-{
- return SalomeApp_Module::createTool( id, tBar, idx );
-}
-
-/*!
- \brief Insert action to the toolbar.
- \param a action
- \param tBar toolbar ID
- \param id required action ID
- \param idx required index in the toolbar
- \return action ID or -1 if action could not be added
-*/
-int SALOME_PYQT_Module::createTool( QAction* a, const int tBar, const int id, const int idx )
-{
- return SalomeApp_Module::createTool( a, tBar, id, idx );
-}
-
-/*!
- \brief Insert action to the toolbar.
- \param a action
- \param tBar toolbar name
- \param id required action ID
- \param idx required index in the toolbar
- \return action ID or -1 if action could not be added
-*/
-int SALOME_PYQT_Module::createTool( QAction* a, const QString& tBar, const int id, const int idx )
-{
- return SalomeApp_Module::createTool( a, tBar, id, idx );
-}
-
-/*!
- \brief Create main menu.
- \param subMenu menu name
- \param menu parent menu ID
- \param id required menu ID
- \param group menu group ID
- \param idx required index in the menu
- \return menu ID or -1 if menu could not be added
-*/
-int SALOME_PYQT_Module::createMenu( const QString& subMenu, const int menu, const int id, const int group, const int idx )
-{
- return SalomeApp_Module::createMenu( subMenu, menu, id, group, idx );
-}
-
-/*!
- \brief Create main menu.
- \param subMenu menu name
- \param menu parent menu name (list of menu names separated by "|")
- \param id required menu ID
- \param group menu group ID
- \param idx required index in the menu
- \return menu ID or -1 if menu could not be added
-*/
-int SALOME_PYQT_Module::createMenu( const QString& subMenu, const QString& menu, const int id, const int group, const int idx )
-{
- return SalomeApp_Module::createMenu( subMenu, menu, id, group, idx );
-}
-
-/*!
- \brief Insert action to the main menu.
- \param id action ID
- \param menu parent menu ID
- \param group menu group ID
- \param idx required index in the menu
- \return action ID or -1 if action could not be added
-*/
-int SALOME_PYQT_Module::createMenu( const int id, const int menu, const int group, const int idx )
-{
- return SalomeApp_Module::createMenu( id, menu, group, idx );
-}
-
-/*!
- \brief Insert action to the main menu.
- \param id action ID
- \param menu parent menu name (list of menu names separated by "|")
- \param group menu group ID
- \param idx required index in the menu
- \return action ID or -1 if action could not be added
-*/
-int SALOME_PYQT_Module::createMenu( const int id, const QString& menu, const int group, const int idx )
-{
- return SalomeApp_Module::createMenu( id, menu, group, idx );
-}
-
-/*!
- \brief Insert action to the main menu.
- \param a action
- \param menu parent menu ID
- \param group menu group ID
- \param idx required index in the menu
- \return action ID or -1 if action could not be added
-*/
-int SALOME_PYQT_Module::createMenu( QAction* a, const int menu, const int id, const int group, const int idx )
-{
- return SalomeApp_Module::createMenu( a, menu, id, group, idx );
-}
-
-/*!
- \brief Insert action to the main menu.
- \param a action
- \param menu parent menu name (list of menu names separated by "|")
- \param group menu group ID
- \param idx required index in the menu
- \return action ID or -1 if action could not be added
-*/
-int SALOME_PYQT_Module::createMenu( QAction* a, const QString& menu, const int id, const int group, const int idx )
-{
- return SalomeApp_Module::createMenu( a, menu, id, group, idx );
-}
-
-/*!
- \brief Create separator action which can be used in the menu or toolbar.
- \return new separator action
-*/
-QAction* SALOME_PYQT_Module::separator()
-{
- return SalomeApp_Module::separator();
-}
-
-/*!
- \brief Get action by specified \a id.
- \return action or 0 if it is not found
-*/
-QAction* SALOME_PYQT_Module::action( const int id ) const
-{
- QAction* a = SalomeApp_Module::action( id );
- if ( !a ) {
- // try menu
- QMenu* m = menuMgr()->findMenu( id );
- if ( m ) a = m->menuAction();
- }
- return a;
-}
-
-/*!
- \brief Get action identifier.
- \return action ID or -1 if action is not registered
-*/
-int SALOME_PYQT_Module::actionId( const QAction* a ) const
-{
- return SalomeApp_Module::actionId( a );
-}
-
-/*!
- \brief Create new action.
-
- If the action with specified identifier already registered
- it is not created, but its attributes are only modified.
-
- \param id action ID
- \param text tooltip text
- \param icon icon
- \param menu menu text
- \param tip status tip
- \param key keyboard shortcut
- \param toggle \c true for checkable action
- \return created action
-*/
-QAction* SALOME_PYQT_Module::createAction( const int id, const QString& text, const QString& icon,
- const QString& menu, const QString& tip, const int key,
- const bool toggle, QObject* parent )
-{
- QIcon anIcon = loadIcon( icon );
- QAction* a = action( id );
- if ( a ) {
- if ( a->toolTip().isEmpty() && !text.isEmpty() ) a->setToolTip( text );
- if ( a->text().isEmpty() && !menu.isEmpty() ) a->setText( menu );
- if ( a->icon().isNull() && !anIcon.isNull() ) a->setIcon( anIcon );
- if ( a->statusTip().isEmpty() && !tip.isEmpty() ) a->setStatusTip( tip );
- if ( a->shortcut().isEmpty() && key ) a->setShortcut( key );
- if ( a->isCheckable() != toggle ) a->setCheckable( toggle );
- disconnect( a, SIGNAL( triggered( bool ) ), this, SLOT( onGUIEvent() ) );
- connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onGUIEvent() ) );
- }
- else {
- a = SalomeApp_Module::createAction( id,
- text,
- anIcon,
- menu,
- tip,
- key,
- parent ? parent : this,
- toggle,
- this,
- SLOT( onGUIEvent() ) );
- }
- return a;
-}
-
-/*!
- \brief Create new action group.
-
- If the action with specified identifier already registered
- it is not created, but its attributes are only modified.
-
- \param id action ID
- \param text tooltip text
- \param icon icon
- \param menu menu text
- \param tip status tip
- \param key keyboard shortcut
- \param toggle \c true for checkable action
- \return created action
-*/
-QtxActionGroup* SALOME_PYQT_Module::createActionGroup(const int id, const bool exclusive)
-{
- QtxActionGroup* a = qobject_cast<QtxActionGroup*>( action( id ) );
- if ( !a ) {
- a = new QtxActionGroup( this );
- SalomeApp_Module::registerAction( id, a );
- }
- a->setExclusive( exclusive );
- return a;
-}
-
-/*!
- \brief Load icon from resource file.
- \param fileName icon file name
- \return icon (null icon if loading failed)
-*/
-QIcon SALOME_PYQT_Module::loadIcon( const QString& fileName )
-{
- QIcon anIcon;
- if ( !fileName.isEmpty() ) {
- QPixmap pixmap = getApp()->resourceMgr()->loadPixmap( name(), tr( fileName.toLatin1() ) );
- if ( !pixmap.isNull() )
- anIcon = QIcon( pixmap );
- }
- return anIcon;
-}
-
-/*!
- \brief Add global application preference (for example,
- application specific section).
- \param label preference name
- \return preference ID
-*/
-int SALOME_PYQT_Module::addGlobalPreference( const QString& label )
-{
- LightApp_Preferences* pref = preferences();
- if ( !pref )
- return -1;
-
- return pref->addPreference( label, -1 );
-}
-
-/*!
- \brief Add preference.
- \param label preference name
- \return preference ID
-*/
-int SALOME_PYQT_Module::addPreference( const QString& label )
-{
- return SalomeApp_Module::addPreference( label );
-}
-
-/*!
- \brief Add preference.
- \param label preference name
- \param pId parent preference ID
- \param type preference type
- \param section resource file section name
- \param param resource file setting name
- \return preference ID
-*/
-int SALOME_PYQT_Module::addPreference( const QString& label,
- const int pId, const int type,
- const QString& section,
- const QString& param )
-{
- return SalomeApp_Module::addPreference( label, pId, type, section, param );
-}
-
-/*!
- \brief Get the preference property.
- \param id preference ID
- \param prop property name
- \return property value (invalid QVariant() if property is not found)
-*/
-QVariant SALOME_PYQT_Module::preferenceProperty( const int id,
- const QString& prop ) const
-{
- QVariant v = SalomeApp_Module::preferenceProperty( id, prop );
- return v;
-}
-
-/*!
- \brief Set the preference property.
- \param id preference ID
- \param prop property name
- \param var property value
-*/
-void SALOME_PYQT_Module::setPreferenceProperty( const int id,
- const QString& prop,
- const QVariant& var )
-{
- SalomeApp_Module::setPreferenceProperty( id, prop, var );
-}
-
-
-/*!
- \brief Signal handler windowActivated(SUIT_ViewWindow*) of SUIT_Desktop
- \param pview view being activated
-*/
-void SALOME_PYQT_Module::onActiveViewChanged( SUIT_ViewWindow* pview )
-{
- class ActiveViewChange : public PyInterp_LockRequest
- {
- public:
- ActiveViewChange( PyInterp_Interp* _py_interp, SALOME_PYQT_Module* _obj, const SUIT_ViewWindow* _pview )
- : PyInterp_LockRequest( _py_interp, 0, true ),
- myObj(_obj),myView(_pview) {}
-
- protected:
- virtual void execute()
- {
- myObj->activeViewChanged( myView );
- }
-
- private:
- SALOME_PYQT_Module* myObj;
- const SUIT_ViewWindow * myView;
- };
-
- PyInterp_Dispatcher::Get()->Exec( new ActiveViewChange( myInterp, this, pview ) );
-}
-
-/*!
- \brief Processes the view changing, calls Python module's activeViewChanged() method
- \param pview view being activated
-*/
-void SALOME_PYQT_Module::activeViewChanged( const SUIT_ViewWindow* pview )
-{
- if ( !myInterp || !myModule )
- return;
-
- // Do not use SUIT_ViewWindow::closing() signal here. View manager reacts on
- // this signal and deletes view. So our slot does not works if it is connected
- // on this signal. SUIT_ViewManager::deleteView(SUIT_ViewWindow*) is used here
-
- connectView( pview );
-
- if ( PyObject_HasAttrString( myModule, "activeViewChanged" ) )
- {
- if ( !pview )
- return;
-
- PyObjWrapper res( PyObject_CallMethod( myModule, "activeViewChanged", "i" , pview->getId() ) );
- if( !res )
- PyErr_Print();
- }
-}
-
-/*!
- \brief Signal handler cloneView() of OCCViewer_ViewWindow
- \param pview view being cloned
-*/
-void SALOME_PYQT_Module::onViewCloned( SUIT_ViewWindow* pview )
-{
- class ViewClone : public PyInterp_LockRequest
- {
- public:
- ViewClone( PyInterp_Interp* _py_interp, SALOME_PYQT_Module* _obj, const SUIT_ViewWindow* _pview )
- : PyInterp_LockRequest( _py_interp, 0, true ),
- myObj(_obj), myView(_pview) {}
-
- protected:
- virtual void execute()
- {
- myObj->viewCloned( myView );
- }
-
- private:
- SALOME_PYQT_Module* myObj;
- const SUIT_ViewWindow* myView;
- };
-
- PyInterp_Dispatcher::Get()->Exec( new ViewClone( myInterp, this, pview ) );
-}
-
-/*!
- \brief Processes the view cloning, calls Python module's activeViewCloned() method
- \param pview view being cloned
-*/
-void SALOME_PYQT_Module::viewCloned( const SUIT_ViewWindow* pview )
-{
- if ( !myInterp || !myModule || !pview )
- return;
-
- if ( PyObject_HasAttrString( myModule, "viewCloned" ) )
- {
- PyObjWrapper res( PyObject_CallMethod( myModule, "viewCloned", "i", pview->getId() ) );
- if( !res )
- PyErr_Print();
- }
-}
-
-/*!
- \brief Signal handler closing(SUIT_ViewWindow*) of a view
- \param pview view being closed
-*/
-void SALOME_PYQT_Module::onViewClosed( SUIT_ViewWindow* pview )
-{
- class ViewClose : public PyInterp_LockRequest
- {
- public:
- ViewClose( PyInterp_Interp* _py_interp, SALOME_PYQT_Module* _obj, const SUIT_ViewWindow* _pview )
- : PyInterp_LockRequest( _py_interp, 0, true ),
- myObj(_obj),myView(_pview) {}
-
- protected:
- virtual void execute()
- {
- myObj->viewClosed( myView );
- }
-
- private:
- SALOME_PYQT_Module* myObj;
- const SUIT_ViewWindow * myView;
- };
-
- PyInterp_Dispatcher::Get()->Exec( new ViewClose( myInterp, this, pview ) );
-}
-
-/*!
- \brief Processes the view closing, calls Python module's viewClosed() method
- \param pview view being closed
-*/
-void SALOME_PYQT_Module::viewClosed( const SUIT_ViewWindow* pview )
-{
- if ( !myInterp || !myModule )
- return;
-
- if ( PyObject_HasAttrString( myModule, "viewClosed" ) )
- {
- PyObjWrapper res( PyObject_CallMethod( myModule, "viewClosed", "i", pview->getId() ) );
- if ( !res )
- {
- PyErr_Print();
- }
- }
-}
-
-/*!
- \brief Connects or disconnects signals about activating and cloning view on the module slots
- \param pview view which is connected/disconnected
-*/
-void SALOME_PYQT_Module::connectView( const SUIT_ViewWindow* pview )
-{
- SUIT_ViewManager* viewMgr = pview->getViewManager();
- SUIT_ViewModel* viewModel = viewMgr ? viewMgr->getViewModel() : 0;
-
- if ( viewMgr )
- {
- disconnect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
- this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) );
-
- connect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
- this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) );
- }
-
- // Connect cloneView() signal of an OCC View
- if ( pview->inherits( "OCCViewer_ViewWindow" ) )
- {
- disconnect( pview, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
- this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
- connect( pview, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
- this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
- }
- // Connect cloneView() signal of Plot2d View manager
- else if ( viewModel && viewModel->inherits( "Plot2d_Viewer" ) )
- {
- disconnect( viewModel, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
- this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
- connect( viewModel, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
- this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
- }
-}
-
-/*!
- \brief Get tag name for the DOM element.
- \param element DOM element
- \return empty string if the element does not have tag name
- \internal
-*/
-static QString tagName( const QDomElement& element )
-{
- return element.tagName().trimmed();
-}
-
-/*!
- \brief Get DOM element's attribute by its name.
- \param element DOM element
- \param attName attribute name
- \return empty string if the element does not have such attribute
- \internal
-*/
-static QString attribute( const QDomElement& element, const QString& attName )
-{
- return element.attribute( attName ).trimmed();
-}
-
-/*!
- \brief Inspect specified string for the boolean value.
-
- This function returns \c true if string represents boolean value:
- - "true", "yes" or "1" for \c true
- - "false", "no" or "0" for \c false
- Second parameter allows to specify what boolean value is expected:
- - 1: \c true
- - 0: \c false
- - other value is not taken into account (return represented value)
-
- \param value inspected string
- \param check expected boolean value
- \return boolean value represented by the string (\a check is not 1 or 0)
- or \c true if value correspond to the specified \a check
-*/
-static bool checkBool( const QString& value, const int check = -1 )
-{
- QString v = value.toLower();
- if ( ( v == "true" || v == "yes" || v == "1" ) && ( check != 0 ) )
- return true;
- if ( ( v == "false" || v == "no" || v == "0" ) && ( check == 0 ) )
- return true;
- return false;
-}
-
-/*!
- \brief Inspect specified string for the integer value.
-
- This function returns returns -1 if item is empty or represents
- an invalid number.
- \param value inspected string
- \param def default value
- \param shift shift value (it is added to the integer value to produce shifted result)
-*/
-static int checkInt( const QString& value, const int def = -1, const int shift = -1 )
-{
- bool bOk;
- int val = value.toInt( &bOk );
- if ( !bOk ) val = def;
- if ( shift > 0 && bOk && val < 0 )
- val += shift;
- return val;
-}
-
-/*!
- \brief Constructor
- \internal
- \param module parent module pointer
- \param fileName XML file path
-*/
-SALOME_PYQT_Module::XmlHandler::XmlHandler( SALOME_PYQT_Module* module,
- const QString& fileName )
-: myModule( module )
-{
- if ( fileName.isEmpty() )
- return;
- QFile aFile( fileName );
- if ( !aFile.open( QIODevice::ReadOnly ) )
- return;
- myDoc.setContent( &aFile );
- aFile.close();
-}
-
-/*!
- \brief Parse XML file and create actions.
- \internal
-
- Called by SALOME_PYQT_Module::activate() in order to create actions
- (menus, toolbars).
-*/
-void SALOME_PYQT_Module::XmlHandler::createActions()
-{
- // get document element
- QDomElement aDocElem = myDoc.documentElement();
-
- // create main menu actions
- QDomNodeList aMenuList = aDocElem.elementsByTagName( "menu-item" );
- for ( int i = 0; i < aMenuList.count(); i++ ) {
- QDomNode n = aMenuList.item( i );
- createMenu( n );
- }
-
- // create toolbars actions
- QDomNodeList aToolsList = aDocElem.elementsByTagName( "toolbar" );
- for ( int i = 0; i < aToolsList.count(); i++ ) {
- QDomNode n = aToolsList.item( i );
- createToolBar( n );
- }
-}
-
-/*!
- \brief Create popup menu.
- \internal
- \param menu popup menu
- \param context popup menu context
- \param context popup menu parent object name
- \param context popup menu object name
-*/
-void SALOME_PYQT_Module::XmlHandler::createPopup( QMenu* menu,
- const QString& context,
- const QString& parent,
- const QString& object )
-{
- // get document element
- QDomElement aDocElem = myDoc.documentElement();
-
- // get popup menus actions
- QDomNodeList aPopupList = aDocElem.elementsByTagName( "popupmenu" );
- for ( int i = 0; i < aPopupList.count(); i++ ) {
- QDomNode n = aPopupList.item( i );
- if ( !n.isNull() && n.isElement() ) {
- QDomElement e = n.toElement();
- // QString lab = attribute( e, "label-id" ); // not used //
- QString ctx = attribute( e, "context-id" );
- QString prt = attribute( e, "parent-id" );
- QString obj = attribute( e, "object-id" );
- if ( ctx == context && prt == parent && obj == object ) {
- insertPopupItems( n, menu );
- break;
- }
- }
- }
-}
-
-/*!
- \brief Activate menus
- \internal
- \param enable if \c true menus are activated, otherwise menus are deactivated
-*/
-void SALOME_PYQT_Module::XmlHandler::activateMenus( bool enable )
-{
- if ( !myModule )
- return;
-
- QtxActionMenuMgr* mgr = myModule->menuMgr();
- int id;
- foreach( id, myMenuItems ) mgr->setEmptyEnabled( id, enable );
-}
-
-/*!
- \brief Create main menu item and insert actions to it.
- \internal
- \param parentNode XML node with menu description
- \param parentMenuId parent menu ID (-1 for top-level menu)
- \param parentPopup parent popup menu (0 for top-level menu)
-*/
-void SALOME_PYQT_Module::XmlHandler::createMenu( QDomNode& parentNode,
- const int parentMenuId,
- QMenu* parentPopup )
-{
- if ( !myModule || parentNode.isNull() )
- return;
-
- QDomElement parentElement = parentNode.toElement();
- if ( !parentElement.isNull() ) {
- QString plabel = attribute( parentElement, "label-id" );
- int pid = checkInt( attribute( parentElement, "item-id" ) );
- int ppos = checkInt( attribute( parentElement, "pos-id" ) );
- int group = checkInt( attribute( parentElement, "group-id" ),
- myModule->defaultMenuGroup() );
- if ( !plabel.isEmpty() ) {
- QMenu* popup = 0;
- int menuId = -1;
- // create menu
- menuId = myModule->createMenu( plabel, // label
- parentMenuId, // parent menu ID, -1 for top-level menu
- pid, // ID
- group, // group ID
- ppos ); // position
- myMenuItems.append( menuId );
- QDomNode node = parentNode.firstChild();
- while ( !node.isNull() ) {
- if ( node.isElement() ) {
- QDomElement elem = node.toElement();
- QString aTagName = tagName( elem );
- if ( aTagName == "popup-item" ) {
- int id = checkInt( attribute( elem, "item-id" ) );
- int pos = checkInt( attribute( elem, "pos-id" ) );
- int group = checkInt( attribute( elem, "group-id" ),
- myModule->defaultMenuGroup() );
- QString label = attribute( elem, "label-id" );
- QString icon = attribute( elem, "icon-id" );
- QString tooltip = attribute( elem, "tooltip-id" );
- QString accel = attribute( elem, "accel-id" );
- bool toggle = checkBool( attribute( elem, "toggle-id" ) );
-
- // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
- // also check if the action with given ID is already created
- if ( id != -1 ) {
- // create menu action
- QAction* action = myModule->createAction( id, // ID
- tooltip, // tooltip
- icon, // icon
- label, // menu text
- tooltip, // status-bar text
- QKeySequence( accel ), // keyboard accelerator
- toggle ); // toogled action
- myModule->createMenu( action, // action
- menuId, // parent menu ID
- id, // ID (same as for createAction())
- group, // group ID
- pos ); // position
- }
- }
- else if ( aTagName == "submenu" ) {
- // create sub-menu
- createMenu( node, menuId, popup );
- }
- else if ( aTagName == "separator" ) {
- // create menu separator
- int id = checkInt( attribute( elem, "item-id" ) ); // separator can have ID
- int pos = checkInt( attribute( elem, "pos-id" ) );
- int group = checkInt( attribute( elem, "group-id" ),
- myModule->defaultMenuGroup() );
- QAction* action = myModule->separator();
- myModule->createMenu( action, // separator action
- menuId, // parent menu ID
- id, // ID
- group, // group ID
- pos ); // position
- }
- }
- node = node.nextSibling();
- }
- }
- }
-}
-
-/*!
- \brief Create a toolbar and insert actions to it.
- \param parentNode XML node with toolbar description
-*/
-void SALOME_PYQT_Module::XmlHandler::createToolBar( QDomNode& parentNode )
-{
- if ( !myModule || parentNode.isNull() )
- return;
-
- QDomElement parentElement = parentNode.toElement();
- if ( !parentElement.isNull() ) {
- QString aLabel = attribute( parentElement, "label-id" );
- if ( !aLabel.isEmpty() ) {
- // create toolbar
- int tbId = myModule->createTool( aLabel );
- QDomNode node = parentNode.firstChild();
- while ( !node.isNull() ) {
- if ( node.isElement() ) {
- QDomElement elem = node.toElement();
- QString aTagName = tagName( elem );
- if ( aTagName == "toolbutton-item" ) {
- int id = checkInt( attribute( elem, "item-id" ) );
- int pos = checkInt( attribute( elem, "pos-id" ) );
- QString label = attribute( elem, "label-id" );
- QString icon = attribute( elem, "icon-id" );
- QString tooltip = attribute( elem, "tooltip-id" );
- QString accel = attribute( elem, "accel-id" );
- bool toggle = checkBool( attribute( elem, "toggle-id" ) );
-
- // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
- // also check if the action with given ID is already created
- if ( id != -1 ) {
- // create toolbar action
- QAction* action = myModule->createAction( id, // ID
- tooltip, // tooltip
- icon, // icon
- label, // menu text
- tooltip, // status-bar text
- QKeySequence( accel ), // keyboard accelerator
- toggle ); // toogled action
- myModule->createTool( action, tbId, -1, pos );
- }
- }
- else if ( aTagName == "separatorTB" || aTagName == "separator" ) {
- // create toolbar separator
- int pos = checkInt( attribute( elem, "pos-id" ) );
- QAction* action = myModule->separator();
- myModule->createTool( action, tbId, -1, pos );
- }
- }
- node = node.nextSibling();
- }
- }
- }
-}
-
-/*!
- \brief Fill popup menu with the items.
- \param parentNode XML node with popup menu description
- \param menu popup menu
-*/
-void SALOME_PYQT_Module::XmlHandler::insertPopupItems( QDomNode& parentNode, QMenu* menu )
-{
- if ( !myModule && parentNode.isNull() )
- return;
-
- // we create popup menus without help of QtxPopupMgr
- QDomNode node = parentNode.firstChild();
- while ( !node.isNull() ) {
- if ( node.isElement() ) {
- QDomElement elem = node.toElement();
- QString aTagName = tagName( elem );
- QList<QAction*> actions = menu->actions();
- if ( aTagName == "popup-item" ) {
- // insert a command item
- int id = checkInt( attribute( elem, "item-id" ) );
- int pos = checkInt( attribute( elem, "pos-id" ) );
- QString label = attribute( elem, "label-id" );
- QString icon = attribute( elem, "icon-id" );
- QString tooltip = attribute( elem, "tooltip-id" );
- QString accel = attribute( elem, "accel-id" );
- bool toggle = checkBool( attribute( elem, "toggle-id" ) );
-
- // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
- // also check if the action with given ID is already created
- if ( id != -1 ) {
- QAction* action = myModule->createAction( id, // ID
- tooltip, // tooltip
- icon, // icon
- label, // menu text
- tooltip, // status-bar text
- QKeySequence( accel ), // keyboard accelerator
- toggle ); // toogled action
- QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
- menu->insertAction( before, action );
- }
- }
- else if ( aTagName == "submenu" ) {
- // create sub-menu
- ////int id = checkInt( attribute( elem, "item-id" ) ); // not used //
- int pos = checkInt( attribute( elem, "pos-id" ) );
- QString label = attribute( elem, "label-id" );
- QString icon = attribute( elem, "icon-id" );
-
- QIcon anIcon;
- if ( !icon.isEmpty() ) {
- QPixmap pixmap = myModule->getApp()->resourceMgr()->loadPixmap( myModule->name(), icon );
- if ( !pixmap.isNull() )
- anIcon = QIcon( pixmap );
- }
-
- QMenu* newPopup = menu->addMenu( anIcon, label );
- QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
- menu->insertMenu( before, newPopup );
- insertPopupItems( node, newPopup );
- }
- else if ( aTagName == "separator" ) {
- // create menu separator
- int pos = checkInt( attribute( elem, "pos-id" ) );
- QAction* action = myModule->separator();
- QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
- menu->insertAction( before, action );
- }
- }
- node = node.nextSibling();
- }
+ SALOME_PYQT_ModuleLight::onViewCloned(pview);
}
#ifndef SALOME_PYQT_MODULE_H
#define SALOME_PYQT_MODULE_H
-#include "SALOME_PYQT_GUI.h"
-#include "SALOME_PYQT_PyInterp.h" // this include must be first (see PyInterp_Interp.h)!
-
-#include <SalomeApp_Module.h>
-
-#include <QStringList>
-#include <QList>
-#include <QMap>
-#include <QIcon>
-
+#include "SALOME_PYQT_PyInterp.h" // this include must be first (see PyInterp_base.h)!*/
+#include "SALOME_PYQT_ModuleLight.h"
+#include "SalomeApp_Module.h"
#include <SALOMEconfig.h>
#include CORBA_CLIENT_HEADER(SALOME_Component)
-class SALOME_PYQT_PyInterp;
-class SUIT_ViewWindow;
-class QAction;
-class QtxActionGroup;
-class QMenu;
-class SALOME_PYQT_EXPORT SALOME_PYQT_Module: public SalomeApp_Module
+
+class SALOME_PYQT_EXPORT SALOME_PYQT_Module: public SalomeApp_Module,
+ public SALOME_PYQT_ModuleLight
{
Q_OBJECT;
-private:
- class XmlHandler;
-
- //! study to Python subinterpreter map
- typedef QMap<int, SALOME_PYQT_PyInterp*> InterpMap;
-
- static InterpMap myInterpMap; //!< study to Python subinterpreter map
- SALOME_PYQT_PyInterp* myInterp; //!< current Python subinterpreter
- PyObjWrapper myModule; //!< Python GUI module
- static SALOME_PYQT_Module* myInitModule; //!< Python GUI being initialized (not zero only during the initialization)
-
- XmlHandler* myXmlHandler; //!< XML resource file parser
- QMap<int, int> myWindowsMap; //!< windows map
- QStringList myViewMgrList;//!< compatible view managers list
-
- bool myLastActivateStatus; //!< latest module activation status
-
-public:
+ public:
SALOME_PYQT_Module();
~SALOME_PYQT_Module();
-public:
- static SALOME_PYQT_Module* getInitModule();
-
- void initialize( CAM_Application* );
- void windows( QMap<int, int>& ) const;
- void viewManagers( QStringList& ) const;
- void contextMenuPopup( const QString&, QMenu*, QString& );
- void createPreferences();
- QString engineIOR() const;
- void studyActivated();
- void preferencesChanged( const QString&, const QString& );
-
- static int defaultMenuGroup();
+ /* get module engine IOR */
+ virtual QString engineIOR() const;
- int createTool( const QString& );
- int createTool( const int, const int, const int = -1 );
- int createTool( const int, const QString&, const int = -1 );
- int createTool( QAction*, const int,
- const int = -1, const int = -1 );
- int createTool( QAction*, const QString&,
- const int = -1, const int = -1 );
-
- int createMenu( const QString&, const int,
- const int = -1, const int = -1, const int = -1 );
- int createMenu( const QString&, const QString&,
- const int = -1, const int = -1, const int = -1 );
- int createMenu( const int, const int,
- const int = -1, const int = -1 );
- int createMenu( const int, const QString&,
- const int = -1, const int = -1 );
- int createMenu( QAction*, const int,
- const int = -1, const int = -1, const int = -1 );
- int createMenu( QAction*, const QString&,
- const int = -1, const int = -1, const int = -1 );
-
- QAction* separator();
-
- QAction* action( const int ) const;
- int actionId( const QAction* ) const;
- QAction* createAction( const int, const QString&, const QString&,
- const QString&, const QString&, const int,
- const bool = false, QObject* = 0 );
- QtxActionGroup* createActionGroup( const int, const bool );
-
-
- QIcon loadIcon( const QString& fileName );
-
- int addGlobalPreference( const QString& );
- int addPreference( const QString& );
- int addPreference( const QString&, const int, const int = LightApp_Preferences::Auto,
- const QString& = QString(),
- const QString& = QString() );
- QVariant preferenceProperty( const int, const QString& ) const;
- void setPreferenceProperty( const int, const QString&,
- const QVariant& );
-
-public slots:
- virtual bool activateModule( SUIT_Study* );
- virtual bool deactivateModule( SUIT_Study* );
+ public slots:
void preferenceChanged( const QString&,
const QString&,
const QString& );
void onGUIEvent();
-
void onActiveViewChanged( SUIT_ViewWindow* );
void onViewClosed( SUIT_ViewWindow* );
void onViewCloned( SUIT_ViewWindow* );
-protected:
- Engines::Component_var getEngine() const;
+ protected:
+ /* create data model */
+ virtual CAM_DataModel* createDataModel();
-private:
- void init( CAM_Application* );
- void activate( SUIT_Study* );
- void deactivate( SUIT_Study* );
- bool lastActivationStatus() const;
- void customize( SUIT_Study* );
- void studyChanged( SUIT_Study* );
- void contextMenu( const QString&, QMenu* );
- void guiEvent( const int );
- void initPreferences();
- void prefChanged( const QString&, const QString& );
-
- void initInterp ( int );
- void importModule();
- void setWorkSpace();
-
- void activeViewChanged( const SUIT_ViewWindow* );
- void viewClosed( const SUIT_ViewWindow* );
- void viewCloned( const SUIT_ViewWindow* );
- void connectView( const SUIT_ViewWindow* );
+ Engines::Component_var getEngine() const;
- friend class XmlHandler;
};
#endif // SALOME_PYQT_MODULE_H
--- /dev/null
+# Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+#
+# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+#
+# File : Makefile.am
+# Author : Roman NIKOLAEV Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+
+
+include $(top_srcdir)/adm_local/unix/make_common_starter.am
+
+# Library target
+lib_LTLIBRARIES = libSalomePyQtGUILight.la
+
+
+# extra source files (generated by sip)
+SIP_SRC = sipAPISalomePyQtGUILight.h \
+ sipSalomePyQtGUILightcmodule.cc
+
+# Sip definition file
+SIP_FILES = SALOME_PYQT_GUILight.sip
+
+# extra dist files
+EXTRA_DIST += $(SIP_FILES)
+
+
+# extra clean files
+CLEANFILES = $(SIP_SRC)
+
+# moc files (generated my moc)
+MOC_FILES = \
+ SALOME_PYQT_ModuleLight_moc.cxx \
+ SALOME_PYQT_DataModelLight_moc.cxx
+
+
+# exported header files
+salomeinclude_HEADERS = \
+ SALOME_PYQT_GUILight.h \
+ SALOME_PYQT_ModuleLight.h \
+ SALOME_PYQT_DataObjectLight.h \
+ SALOME_PYQT_DataModelLight.h \
+ SALOME_PYQT_PyInterp.h
+
+# library sources
+dist_libSalomePyQtGUILight_la_SOURCES = \
+ SALOME_PYQT_ModuleLight.cxx \
+ SALOME_PYQT_DataObjectLight.cxx \
+ SALOME_PYQT_DataModelLight.cxx \
+ SALOME_PYQT_PyInterp.cxx
+
+nodist_libSalomePyQtGUILight_la_SOURCES = $(MOC_FILES) $(SIP_SRC)
+
+
+libSalomePyQtGUILight_la_CPPFLAGS = $(QT_INCLUDES) $(SIP_INCLUDES) $(PYTHON_INCLUDES) \
+ $(CAS_CPPFLAGS) $(VTK_INCLUDES) $(OGL_INCLUDES) $(BOOST_CPPFLAGS) \
+ -DHAVE_CONFIG_H @KERNEL_CXXFLAGS@ -DCALL_OLD_METHODS \
+ -I@builddir@ -I$(srcdir)/../../PyInterp -I$(srcdir)/../../PyConsole \
+ -I$(srcdir)/../../SUIT -I$(srcdir)/../../Qtx -I$(srcdir)/../../LightApp \
+ -I$(srcdir)/../../Plot2d -I$(srcdir)/../../OCCViewer \
+ -I$(srcdir)/../../CAM -I$(srcdir)/../../STD \
+ -I$(srcdir)/../../SUITApp \
+ -I$(srcdir)/../../CAM -I$(srcdir)/../../STD
+
+if GUI_ENABLE_CORBA
+libSalomePyQtGUILight_la_CPPFLAGS += -I$(srcdir)/../../SalomeApp \
+ -I$(top_builddir)/salome_adm/unix \
+ @CORBA_CXXFLAGS@ @CORBA_INCLUDES@
+endif
+
+
+if !GUI_ENABLE_CORBA
+ libSalomePyQtGUILight_la_CPPFLAGS += -DGUI_DISABLE_CORBA
+endif
+
+# linkage flags
+libSalomePyQtGUILight_la_LIBADD = $(PYTHON_LIBS) $(SIP_LIBS) $(PYQT_LIBS) $(VTK_LIBS) \
+ $(OGL_LIBS) ../../PyInterp/libPyInterp.la
+
+if GUI_ENABLE_CORBA
+ libSalomePyQtGUILight_la_LIBADD +=../../SalomeApp/libSalomeApp.la
+endif
+
+
+
+# Custom build step: generate C++ wrapping according to $(SIP_FILES)
+$(SIP_SRC): $(SIP_FILES)
+ $(SIP) $(PYQT_SIPFLAGS) $<
+
+# extra dependency (SALOME_PYQT_Module.cxx depends on header files generated by sip)
+$(dist_libSalomePyQtGUILight_la_SOURCES): $(SIP_SRC)
+
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 22/06/2007
+
+#include "PyInterp_Interp.h" // // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
+
+#include "SALOME_PYQT_DataModelLight.h"
+#include "SALOME_PYQT_DataObjectLight.h"
+#include "SALOME_PYQT_ModuleLight.h"
+#include <utilities.h>
+
+#include <LightApp_Study.h>
+#include <CAM_Module.h>
+#include <CAM_Application.h>
+#include <CAM_Study.h>
+
+
+//=================================================================================
+// function : SALOME_PYQT_DataModelLight()
+// purpose : constructor
+//=================================================================================
+SALOME_PYQT_DataModelLight::SALOME_PYQT_DataModelLight(CAM_Module * theModule)
+ : LightApp_DataModel( theModule ),
+ myFileName( "" ),
+ myStudyURL( "" )
+{
+
+}
+
+//=================================================================================
+// function : ~SALOME_PYQT_DataModelLight()
+// purpose : destructor
+//=================================================================================
+SALOME_PYQT_DataModelLight::~SALOME_PYQT_DataModelLight()
+{
+}
+
+//=================================================================================
+// function : open()
+// purpose : Open data model operation
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::open( const QString& theURL, CAM_Study* study, QStringList theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_DataModelLight::open()");
+ LightApp_Study* aDoc = dynamic_cast<LightApp_Study*>( study );
+ SALOME_PYQT_ModuleLight* aModule = dynamic_cast<SALOME_PYQT_ModuleLight*>(module());
+ if ( !aDoc || !aModule)
+ return false;
+
+ LightApp_DataModel::open( theURL, aDoc, theListOfFiles );
+
+ return aModule->open(theListOfFiles);
+
+}
+
+//=================================================================================
+// function : save()
+// purpose : Save data model operation
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::save( QStringList& theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_DataModelLight::save()");
+ bool isMultiFile = false; // temporary solution
+
+ LightApp_DataModel::save(theListOfFiles);
+ LightApp_Study* study = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy() );
+ SALOME_PYQT_ModuleLight* aModule = dynamic_cast<SALOME_PYQT_ModuleLight*>(module());
+
+ if(!aModule || !study)
+ return false;
+
+
+ std::string aTmpDir = study->GetTmpDir(myStudyURL.toLatin1().constData(), isMultiFile );
+
+ theListOfFiles.append(QString(aTmpDir.c_str()));
+ int listSize = theListOfFiles.size();
+ aModule->save(theListOfFiles);
+ //Return true if in the List of files was added item(s)
+ //else return false
+ return theListOfFiles.size() > listSize;
+}
+
+//=================================================================================
+// function : saveAs()
+// purpose : SaveAs data model operation
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::saveAs ( const QString& theURL, CAM_Study* theStudy, QStringList& theListOfFiles)
+{
+ myStudyURL = theURL;
+ return save(theListOfFiles);
+}
+
+
+
+bool SALOME_PYQT_DataModelLight::create( CAM_Study* study )
+{
+ return true;
+}
+
+//=================================================================================
+// function : isModified()
+// purpose : default implementation, always returns false so as not to mask study's isModified()
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::isModified() const
+{
+ return false;
+}
+
+//=================================================================================
+// function : isSaved()
+// purpose : default implementation, always returns true so as not to mask study's isSaved()
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::isSaved() const
+{
+ return true;
+}
+
+
+//=================================================================================
+// function : close()
+// purpose : Close data model operation
+//=================================================================================
+bool SALOME_PYQT_DataModelLight::close()
+{
+ LightApp_DataModel::close();
+ return true;
+}
+
+
+void SALOME_PYQT_DataModelLight::update ( LightApp_DataObject* theObj, LightApp_Study* theStudy )
+{
+ // Nothing to do here: we always keep the data tree in the up-to-date state
+ // The only goal of this method is to hide default behavior from LightApp_DataModel
+ return;
+}
+
+LightApp_ModuleObject* SALOME_PYQT_DataModelLight::getRoot()
+{
+ LightApp_Study* study = dynamic_cast<LightApp_Study*>( module()->application()->activeStudy() );
+ LightApp_ModuleObject *aModelRoot = dynamic_cast<LightApp_ModuleObject*>(root());
+ if(aModelRoot == NULL) {
+ aModelRoot = new LightApp_ModuleObject(this,study->root());
+ aModelRoot->setDataModel( this );
+ setRoot(aModelRoot);
+ }
+ return aModelRoot;
+}
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 22/06/2007
+
+#ifndef SALOME_PYQT_DATAMODELLIGHT_H
+#define SALOME_PYQT_DATAMODELLIGHT_H
+
+#include "SALOME_PYQT_GUILight.h"
+#include <LightApp_DataModel.h>
+
+#include <CAM_Module.h>
+#include "SALOME_PYQT_DataObjectLight.h"
+
+class SALOME_PYQT_RootObjectLight;
+
+
+
+class SALOME_PYQT_EXPORT SALOME_PYQT_DataModelLight : public LightApp_DataModel
+{
+ Q_OBJECT
+
+public:
+ SALOME_PYQT_DataModelLight( CAM_Module* theModule );
+ virtual ~SALOME_PYQT_DataModelLight();
+
+ virtual bool open ( const QString&, CAM_Study*, QStringList );
+ virtual bool save ( QStringList& );
+ virtual bool saveAs ( const QString&, CAM_Study*, QStringList& );
+ virtual bool close ();
+ virtual bool create ( CAM_Study* );
+
+ virtual bool isModified () const;
+ virtual bool isSaved () const;
+
+ virtual void update ( LightApp_DataObject* = 0, LightApp_Study* = 0 );
+
+ LightApp_ModuleObject* getRoot();
+
+ private:
+ QString myFileName;
+ QString myStudyURL;
+};
+
+#endif // SALOME_PYQT_DATAMODELLIGHT_H
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 22/06/2007
+
+
+#include "SALOME_PYQT_DataObjectLight.h"
+#include <LightApp_Application.h>
+#include <SUIT_Session.h>
+#include <utilities.h>
+#include <SUIT_ResourceMgr.h>
+
+
+#include <CAM_DataModel.h>
+#include <CAM_Module.h>
+
+
+/*!
+ * Class: SALOME_PYQT_DataObjectLight
+ * Description: LIGHT PYTHON module's data object
+ */
+
+static int _ID = 0;
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight()
+// purpose : constructor
+//=================================================================================
+SALOME_PYQT_DataObjectLight::SALOME_PYQT_DataObjectLight ( SUIT_DataObject* parent )
+ : CAM_DataObject(parent),
+ LightApp_DataObject( parent )
+
+{
+ _ID++;
+ myEntry = QString("PYLIGHT_OBJ_%1").arg(_ID);
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight()
+// purpose : destructor
+//=================================================================================
+SALOME_PYQT_DataObjectLight::~SALOME_PYQT_DataObjectLight()
+{
+
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::entry()
+// purpose : return entry of object
+//=================================================================================
+QString SALOME_PYQT_DataObjectLight::entry() const
+{
+ return myEntry;
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::name()
+// purpose : return name of object
+//=================================================================================
+QString SALOME_PYQT_DataObjectLight::name() const
+{
+ return myName;
+}
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::icon()
+// purpose : return icon of object
+//=================================================================================
+QPixmap SALOME_PYQT_DataObjectLight::icon(const int index) const
+{
+ if(index == NameId)
+ return myIcon;
+ else
+ return LightApp_DataObject::icon( index );
+}
+
+
+//=================================================================================
+// function : SALOME_PYQT_DataObjectLight::toolTip()
+// purpose : return toolTip of object
+//=================================================================================
+QString SALOME_PYQT_DataObjectLight::toolTip(const int index) const
+{
+ return myToolTip;
+}
+
+
+void SALOME_PYQT_DataObjectLight::setName(const QString& name)
+{
+ myName = name;
+}
+
+void SALOME_PYQT_DataObjectLight::setIcon(const QString& iconname)
+{
+ if(!iconname.isEmpty()) {
+ LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
+ if(anApp) {
+ QString modulename = anApp->activeModule()->name();
+ if(!modulename.isEmpty())
+ {
+ myIcon = SUIT_Session::session()->resourceMgr()->loadPixmap(modulename,
+ QObject::tr(iconname.toLatin1()));
+ }
+ }
+ }
+}
+
+void SALOME_PYQT_DataObjectLight::setToolTip(const QString& tooltip)
+{
+ myToolTip = tooltip;
+}
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 22/06/2007
+
+
+#ifndef SALOME_PYQT_DATAOBJECTLIGHT_H
+#define SALOME_PYQT_DATAOBJECTLIGHT_H
+
+
+#include "SALOME_PYQT_GUILight.h"
+#include <LightApp_DataObject.h>
+#include <LightApp_Study.h>
+
+#include <qstring.h>
+
+/*!
+ * SALOME_PYQT_DataObjectLight - PYTHON LIGHT module's data object class
+ */
+class SALOME_PYQT_EXPORT SALOME_PYQT_DataObjectLight : public virtual LightApp_DataObject
+{
+
+ public:
+ SALOME_PYQT_DataObjectLight( SUIT_DataObject* = 0 );
+
+ virtual ~SALOME_PYQT_DataObjectLight();
+
+ virtual QString entry() const;
+
+ virtual QString name() const;
+ QPixmap icon(const int = NameId) const;
+ QString toolTip(const int = NameId) const;
+
+ void setName(const QString& name);
+ void setIcon(const QString& icon);
+ void setToolTip(const QString& tooltip);
+
+ private:
+ QString myEntry;
+ QString myName;
+ QString myToolTip;
+ QPixmap myIcon;
+};
+
+#endif // SALOME_PYQT_DATAOBJECTLIGHT_H
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : SALOME_PYQT_GUI.h
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+
+#if !defined ( SALOME_PYQT_GUILIGHT_H )
+#define SALOME_PYQT_GUIILIGHT_H
+
+// ========================================================
+// set dllexport type for Win platform
+#ifdef WNT
+
+#ifdef SALOME_PYQT_EXPORTS
+#define SALOME_PYQT_EXPORT __declspec(dllexport)
+#else
+#define SALOME_PYQT_EXPORT __declspec(dllimport)
+#endif
+
+#else // WNT
+
+#define SALOME_PYQT_EXPORT
+
+#endif // WNT
+
+// ========================================================
+// avoid warning messages
+#ifdef WNT
+#pragma warning (disable : 4786)
+#pragma warning (disable : 4251)
+#endif
+
+#endif // SALOME_PYQT_GUIILIGHT_H
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : SALOME_PYQT_GUI.sip
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+
+%Module SalomePyQtGUILight
+
+%Import QtGuimod.sip
+%Import QtXmlmod.sip
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : SALOME_PYQT_Module.cxx
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+
+#include <SALOME_PYQT_PyInterp.h>
+#include <SUITApp_init_python.hxx>
+#include <PyInterp_Interp.h>
+#include <PyConsole_Interp.h>
+#include <PyConsole_Console.h>
+#include <PyInterp_Dispatcher.h>
+
+#include "SALOME_PYQT_ModuleLight.h"
+#include "SALOME_PYQT_DataModelLight.h"
+
+#ifndef GUI_DISABLE_CORBA
+#include <Container_init_python.hxx>
+#endif
+
+#include <SUIT_ResourceMgr.h>
+#include <SUIT_DataObjectIterator.h>
+#include <SUIT_Desktop.h>
+#include <SUIT_ViewModel.h>
+#include <SUIT_ViewWindow.h>
+#include <SUIT_ViewManager.h>
+#include <STD_MDIDesktop.h>
+#include <STD_TabDesktop.h>
+#include <LightApp_Preferences.h>
+#include <LightApp_Application.h>
+#include <LightApp_Study.h>
+
+#include <QtxWorkstack.h>
+#include <QtxWorkspace.h>
+#include <QtxActionGroup.h>
+#include <QtxActionMenuMgr.h>
+#include <QtxActionToolMgr.h>
+
+#include <QFile>
+#include <QDomDocument>
+#include <QDomNode>
+#include <QDomElement>
+#include <QMenuBar>
+#include <QMenu>
+#include <QAction>
+
+
+#include "sipAPISalomePyQtGUILight.h"
+
+#include <sip.h>
+#if SIP_VERSION < 0x040700
+#include "sipQtGuiQWidget.h"
+#include "sipQtGuiQMenu.h"
+#endif
+
+#include <utilities.h>
+
+/*!
+ \brief Default name of the module, replaced at the moment
+ of module creation.
+ \internal
+*/
+const char* DEFAULT_NAME = "SALOME_PYQT_ModuleLight";
+
+/*!
+ \brief Default menu group number.
+ \internal
+*/
+const int DEFAULT_GROUP = 40;
+
+/*!
+ \var IsCallOldMethods
+ \brief Allow calling obsolete callback methods.
+ \internal
+
+ If the macro CALL_OLD_METHODS is not defined, the invoking
+ of obsolete Python module's methods like setSetting(), definePopup(),
+ etc. is blocked.
+
+ CALL_OLD_METHODS macro can be defined for example by adding
+ -DCALL_OLD_METHODS compilation option to the Makefile.
+*/
+#ifdef CALL_OLD_METHODS
+const bool IsCallOldMethods = true;
+#else
+const bool IsCallOldMethods = false;
+#endif
+
+/* Py_ssize_t for old Pythons */
+/* This code is as recommended by: */
+/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */
+#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN)
+typedef int Py_ssize_t;
+# define PY_SSIZE_T_MAX INT_MAX
+# define PY_SSIZE_T_MIN INT_MIN
+#endif
+
+//
+// NB: Python requests.
+// General rule for Python requests created by SALOME_PYQT_Module:
+// all requests should be executed SYNCHRONOUSLY within the main GUI thread.
+// However, it is obligatory that ANY Python call is wrapped with a request object,
+// so that ALL Python API calls are serialized with PyInterp_Dispatcher.
+//
+
+/*!
+ \class SALOME_PYQT_Module::XmlHandler
+ \brief XML resource files parser.
+ \internal
+
+ This class is used to provide backward compatibility with
+ existing Python modules in which obsolete menu definition system
+ (via XML files) is used.
+*/
+
+class SALOME_PYQT_ModuleLight::XmlHandler
+{
+public:
+ XmlHandler( SALOME_PYQT_ModuleLight* module, const QString& fileName );
+ void createActions();
+ void createPopup ( QMenu* menu,
+ const QString& context,
+ const QString& parent,
+ const QString& object );
+ void activateMenus( bool );
+
+protected:
+ void createToolBar ( QDomNode& parentNode );
+ void createMenu ( QDomNode& parentNode,
+ const int parentMenuId = -1,
+ QMenu* parentPopup = 0 );
+
+ void insertPopupItems( QDomNode& parentNode,
+ QMenu* menu );
+
+private:
+ SALOME_PYQT_ModuleLight* myModule;
+ QDomDocument myDoc;
+ QList<int> myMenuItems;
+};
+
+//
+// NB: Library initialization
+// Since the SalomePyQtGUILight library is not imported in Python it's initialization function
+// should be called manually (and only once) in order to initialize global sip data
+// and to get C API from sip : sipBuildResult for example
+//
+
+#define INIT_FUNCTION initSalomePyQtGUILight
+#if defined(SIP_STATIC_MODULE)
+extern "C" void INIT_FUNCTION();
+#else
+PyMODINIT_FUNC INIT_FUNCTION();
+#endif
+
+/*!
+ \fn CAM_Module* createModule()
+ \brief Module factory function.
+ \internal
+
+ Creates an instance of SALOME_PYQT_Module object by request
+ of an application when the module is loaded and initialized.
+
+ \return new module object
+*/
+
+extern "C" {
+ SALOME_PYQT_EXPORT CAM_Module* createModule() {
+
+ static bool alreadyInitialized = false;
+ if ( !alreadyInitialized ) {
+ // call only once (see comment above) !
+ static PyThreadState *gtstate = 0;
+#ifndef GUI_DISABLE_CORBA
+ if(SUIT_PYTHON::initialized)
+ gtstate = SUIT_PYTHON::_gtstate;
+ else
+ gtstate = KERNEL_PYTHON::_gtstate;
+#else
+ gtstate = SUIT_PYTHON::_gtstate;
+#endif
+ PyEval_RestoreThread( gtstate );
+ INIT_FUNCTION();
+ PyEval_ReleaseThread( gtstate );
+ alreadyInitialized = !alreadyInitialized;
+ }
+ return new SALOME_PYQT_ModuleLight();
+ }
+}
+
+/*!
+ \class FuncMsg
+ \brief Function call in/out tracer.
+ \internal
+*/
+
+class FuncMsg
+{
+public:
+ FuncMsg( const QString& funcName )
+ {
+ myName = funcName;
+ MESSAGE( myName.toLatin1().constData() << " [ begin ]" );
+ }
+ ~FuncMsg()
+ {
+ MESSAGE( myName.toLatin1().constData() << " [ end ]" );
+ }
+ void message( const QString& msg )
+ {
+ MESSAGE( myName.toLatin1().constData() << " : " << msg.toLatin1().constData() );
+ }
+private:
+ QString myName;
+};
+
+/*!
+ \class SALOME_PYQT_ModuleLight
+ \brief This class implements module API for all the Python-based
+ SALOME modules.
+*/
+
+//
+// Static variables definition
+//
+SALOME_PYQT_ModuleLight::InterpMap SALOME_PYQT_ModuleLight::myInterpMap;
+SALOME_PYQT_ModuleLight* SALOME_PYQT_ModuleLight::myInitModule = 0;
+
+/*!
+ \brief Get the module being initialized.
+
+ This is a little trick :) needed to provide an access from Python
+ (SalomePyQt) to the module being currently activated. The problem
+ that during the process of module initialization (initialize()
+ function) it is not yet available via application->activeModule()
+ call.
+
+ This method returns valid pointer only if called in scope of
+ initialize() function.
+
+ \return the module being currently initialized
+*/
+SALOME_PYQT_ModuleLight* SALOME_PYQT_ModuleLight::getInitModule()
+{
+ return myInitModule;
+}
+
+/*!
+ \brief Constructor
+*/
+SALOME_PYQT_ModuleLight::SALOME_PYQT_ModuleLight()
+: LightApp_Module( DEFAULT_NAME ),
+ myInterp( 0 ),
+ myModule( 0 ),
+ myXmlHandler ( 0 ),
+ myLastActivateStatus( true )
+{
+}
+
+/*!
+ \brief Destructor
+*/
+SALOME_PYQT_ModuleLight::~SALOME_PYQT_ModuleLight()
+{
+ if ( myXmlHandler )
+ delete myXmlHandler;
+}
+
+/*!
+ \brief Initialization of the module.
+
+ This method can be used for creation of the menus, toolbars and
+ other such staff.
+
+ There are two ways to do this:
+ - for obsolete modules this method first tries to read
+ <module>_<language>.xml resource file which contains a menu,
+ toolbars and popup menus description;
+ - new modules can create menus by direct calling of the
+ corresponding methods of SalomePyQt Python API in the Python
+ module's initialize() method which is called from here.
+
+ NOTE: SALOME supports two modes of modules loading:
+ - immediate (all the modules are created and initialized
+ immediately when the application object is created;
+ - postponed modules loading (used currently); in this mode
+ the module is loaded only be request.
+ If postponed modules loading is not used, the active
+ study might be not yet defined at this stage, so initialize()
+ method should not perform any study-based initialization.
+
+ \param app parent application object
+*/
+void SALOME_PYQT_ModuleLight::initialize( CAM_Application* app )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::initialize()" );
+
+ // call base implementation
+ LightApp_Module::initialize( app );
+
+ // try to get XML resource file name
+ SUIT_ResourceMgr* aResMgr = getApp()->resourceMgr();
+ if ( !myXmlHandler && aResMgr ) {
+ // get current language
+ QString aLang = aResMgr->stringValue( "language", "language", QString() );
+ if ( aLang.isEmpty() )
+ aLang = "en";
+ // define resource file name
+ QString aFileName = name() + "_" + aLang + ".xml";
+ aFileName = aResMgr->path( "resources", name(), aFileName );
+ // create XML handler instance
+ if ( !aFileName.isEmpty() && QFile::exists( aFileName ) )
+ myXmlHandler = new SALOME_PYQT_ModuleLight::XmlHandler( this, aFileName );
+ // create menus & toolbars from XML file if required
+ if ( myXmlHandler )
+ myXmlHandler->createActions();
+ }
+
+ // perform internal initialization and call module's initialize() funtion
+ // InitializeReq: request class for internal init() operation
+ class InitializeReq : public PyInterp_Request
+ {
+ public:
+ InitializeReq( CAM_Application* _app,
+ SALOME_PYQT_ModuleLight* _obj )
+ : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+ myApp( _app ),
+ myObj( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->init( myApp );
+ }
+
+ private:
+ CAM_Application* myApp;
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request
+ PyInterp_Dispatcher::Get()->Exec( new InitializeReq( app, this ) );
+}
+
+/*!
+ \brief Activation of the module.
+
+ This function is usually used in order to show the module's
+ specific menus and toolbars, update actions state and perform
+ other such actions required when the module is activated.
+
+ Note, that returning \c false in this function prevents the
+ module activation.
+
+ \param theStudy parent study
+ \return \c true if activation is successful and \c false otherwise
+*/
+bool SALOME_PYQT_ModuleLight::activateModule( SUIT_Study* theStudy )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::activateModule()" );
+
+ // call base implementation
+ bool res = LightApp_Module::activateModule( theStudy );
+
+ if ( !res )
+ return res;
+
+ // reset the activation status to the default value
+ myLastActivateStatus = true;
+
+ // perform internal activation
+ // ActivateReq: request class for internal activate() operation
+ class ActivateReq : public PyInterp_Request
+ {
+ public:
+ ActivateReq( SUIT_Study* _study,
+ SALOME_PYQT_ModuleLight* _obj )
+ : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+ myStudy ( _study ),
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->activate( myStudy );
+ }
+
+ private:
+ SUIT_Study* myStudy;
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request
+ PyInterp_Dispatcher::Get()->Exec( new ActivateReq( theStudy, this ) );
+
+ // check activation status (set by activate())
+ if ( !lastActivationStatus() )
+ return false;
+
+ // activate menus, toolbars, etc
+ if ( myXmlHandler ) myXmlHandler->activateMenus( true );
+ setMenuShown( true );
+ setToolShown( true );
+
+ // connect preferences changing signal
+ connect( getApp(), SIGNAL( preferenceChanged( const QString&, const QString&, const QString& ) ),
+ this, SLOT( preferenceChanged( const QString&, const QString&, const QString& ) ) );
+
+ // perform custom activation actions
+ // CustomizeReq: request class for internal customize() operation
+ class CustomizeReq : public PyInterp_Request
+ {
+ public:
+ CustomizeReq( SUIT_Study* _study,
+ SALOME_PYQT_ModuleLight* _obj )
+ : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+ myStudy ( _study ),
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->customize( myStudy );
+ }
+
+ private:
+ SUIT_Study* myStudy;
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request
+ PyInterp_Dispatcher::Get()->Exec( new CustomizeReq( theStudy, this ) );
+
+ return true;
+}
+
+/*!
+ \brief Deactivation of the module.
+
+ This function is usually used in order to hide the module's
+ specific menus and toolbars and perform other such actions
+ required when the module is deactivated.
+
+ \param theStudy parent study
+ \return \c true if deactivation is successful and \c false otherwise
+*/
+bool SALOME_PYQT_ModuleLight::deactivateModule( SUIT_Study* theStudy )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::deactivateModule()" );
+
+ // disconnect preferences changing signal
+ disconnect( getApp(), SIGNAL( preferenceChanged( const QString&, const QString&, const QString& ) ),
+ this, SLOT( preferenceChanged( const QString&, const QString&, const QString& ) ) );
+
+ // perform internal deactivation
+ // DeactivateReq: request class for internal deactivate() operation
+ class DeactivateReq : public PyInterp_LockRequest
+ {
+ public:
+ DeactivateReq( PyInterp_Interp* _py_interp,
+ SUIT_Study* _study,
+ SALOME_PYQT_ModuleLight* _obj )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myStudy ( _study ),
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->deactivate( myStudy );
+ }
+
+ private:
+ SUIT_Study* myStudy;
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request
+ PyInterp_Dispatcher::Get()->Exec( new DeactivateReq( myInterp, theStudy, this ) );
+
+ // deactivate menus, toolbars, etc
+ if ( myXmlHandler ) myXmlHandler->activateMenus( false );
+ setMenuShown( false );
+ setToolShown( false );
+
+ // call base implementation
+ return LightApp_Module::deactivateModule( theStudy );
+}
+
+/*!
+ \brief Get last activation status.
+ \return status of last module activation operation
+ \sa activateModule()
+*/
+bool SALOME_PYQT_ModuleLight::lastActivationStatus() const
+{
+ return myLastActivateStatus;
+}
+
+/*!
+ \breif Process application preferences changing.
+
+ Called when any application setting is changed.
+
+ \param module preference module
+ \param section preference resource file section
+ \param setting preference resource name
+*/
+void SALOME_PYQT_ModuleLight::preferenceChanged( const QString& module,
+ const QString& section,
+ const QString& setting )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::preferenceChanged()" );
+
+ // perform synchronous request to Python event dispatcher
+ class Event : public PyInterp_LockRequest
+ {
+ public:
+ Event( PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ const QString& _section,
+ const QString& _setting )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj ( _obj ),
+ mySection( _section ),
+ mySetting( _setting ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->prefChanged( mySection, mySetting );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ QString mySection, mySetting;
+ };
+
+ if ( module != moduleName() ) {
+ // module's own preferences are processed by preferencesChanged() method
+ // ...
+ // post the request only if dispatcher is not busy!
+ // execute request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new Event( myInterp, this, section, setting ) );
+ }
+}
+
+/*!
+ \brief Process study activation.
+
+ Called when study desktop is activated. Used for notifying the Python
+ module about changing of the active study.
+*/
+void SALOME_PYQT_ModuleLight::studyActivated()
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::studyActivated()" );
+
+ // StudyChangedReq: request class for internal studyChanged() operation
+ class StudyChangedReq : public PyInterp_Request
+ {
+ public:
+ StudyChangedReq( SUIT_Study* _study,
+ SALOME_PYQT_ModuleLight* _obj )
+ : PyInterp_Request( 0, true ), // this request should be processed synchronously (sync == true)
+ myStudy ( _study ),
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->studyChanged( myStudy );
+ }
+
+ private:
+ SUIT_Study* myStudy;
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request
+ PyInterp_Dispatcher::Get()->Exec( new StudyChangedReq( application()->activeStudy(), this ) );
+}
+
+/*!
+ \brief Process GUI action (from main menu, toolbar or
+ context popup menu action).
+*/
+void SALOME_PYQT_ModuleLight::onGUIEvent()
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::onGUIEvent()" );
+
+ // get sender action
+ QAction* action = qobject_cast<QAction*>( sender() );
+ if ( !action )
+ return;
+
+ // get action ID
+ int id = actionId( action );
+ fmsg.message( QString( "action id = %1" ).arg( id ) );
+
+ // perform synchronous request to Python event dispatcher
+ class GUIEvent : public PyInterp_LockRequest
+ {
+ public:
+ GUIEvent( PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ int _id )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myId ( _id ),
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->guiEvent( myId );
+ }
+
+ private:
+ int myId;
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request
+ PyInterp_Dispatcher::Get()->Exec( new GUIEvent( myInterp, this, id ) );
+}
+
+/*!
+ \brief Process context popup menu request.
+
+ Called when user activates popup menu in some window
+ (view, object browser, etc).
+
+ \param theContext popup menu context (e.g. "ObjectBrowser")
+ \param thePopupMenu popup menu
+ \param title popup menu title (not used)
+*/
+void SALOME_PYQT_ModuleLight::contextMenuPopup( const QString& theContext,
+ QMenu* thePopupMenu,
+ QString& /*title*/ )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::contextMenuPopup()" );
+ fmsg.message( QString( "context: %1" ).arg( theContext ) );
+
+ // perform synchronous request to Python event dispatcher
+ class PopupMenuEvent : public PyInterp_LockRequest
+ {
+ public:
+ PopupMenuEvent( PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ const QString& _context,
+ QMenu* _popup )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myContext( _context ),
+ myPopup ( _popup ),
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->contextMenu( myContext, myPopup );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ QString myContext;
+ QMenu* myPopup;
+ };
+
+ // post request only if dispatcher is not busy!
+ // execute request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new PopupMenuEvent( myInterp, this, theContext, thePopupMenu ) );
+}
+
+/*!
+ \brief Export preferences for the Python module.
+
+ Called only once when the first instance of the module is created.
+*/
+void SALOME_PYQT_ModuleLight::createPreferences()
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::createPreferences()" );
+
+ // perform synchronous request to Python event dispatcher
+ class Event : public PyInterp_LockRequest
+ {
+ public:
+ Event( PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj ( _obj ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->initPreferences();
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ };
+
+ // post request only if dispatcher is not busy!
+ // execute request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new Event( myInterp, this ) );
+}
+
+/*!
+ \brief Define the dockable windows associated with the module.
+
+ To fill the list of windows the correspondind Python module's windows()
+ method is called from SALOME_PYQT_ModuleLight::init() method.
+
+ By default, ObjectBrowser, PythonConsole and LogWindow windows are
+ associated to the module.
+
+ Allowed dockable windows:
+ - LightApp_Application::WT_ObjectBrowser : object browser
+ - LightApp_Application::WT_PyConsole : python console
+ - LightApp_Application::WT_LogWindow : log messages output window
+
+ Dock area is defined by Qt::DockWidgetArea enumeration:
+ - Qt::TopDockWidgetArea : top dock area
+ - Qt::BottomDockWidgetArea : bottom dock area
+ - Qt::LeftDockWidgetArea : left dock area
+ - Qt::RightDockWidgetArea : right dock area
+
+ \param mappa map of dockable windows: { <window_type> : <dock_area> }
+*/
+void SALOME_PYQT_ModuleLight::windows( QMap<int, int>& mappa ) const
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::windows()" );
+
+ mappa = myWindowsMap;
+}
+
+/*!
+ \brief Define the compatible view windows associated with the module.
+
+ The associated view windows are opened automatically when the module
+ is activated.
+
+ To fill the list of views the correspondind Python module's views()
+ method is called from SALOME_PYQT_ModuleLight::init() method.
+ By default, the list is empty.
+
+ \param listik list of view windows types
+*/
+void SALOME_PYQT_ModuleLight::viewManagers( QStringList& lst ) const
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::viewManagers()" );
+
+ lst = myViewMgrList;
+}
+
+/*!
+ \brief Process module's preferences changing.
+
+ Called when the module's preferences are changed.
+
+ \param section setting section
+ \param setting setting name
+*/
+void SALOME_PYQT_ModuleLight::preferencesChanged( const QString& section, const QString& setting )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::preferencesChanged()" );
+
+ // perform synchronous request to Python event dispatcher
+ class Event : public PyInterp_LockRequest
+ {
+ public:
+ Event( PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ const QString& _section,
+ const QString& _setting )
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj ( _obj ),
+ mySection( _section ),
+ mySetting( _setting ) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->prefChanged( mySection, mySetting );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ QString mySection, mySetting;
+ };
+
+ // post request only if dispatcher is not busy!
+ // execut request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new Event( myInterp, this, section, setting ) );
+}
+
+/*!
+ \brief Internal module initialization:
+
+ Performs the following actions:
+ - initialize or get the Python interpreter (one per study)
+ - import the Python module
+ - pass the workspace widget to the Python module
+ - call Python module's initialize() method
+ - call Python module's windows() method
+ - call Python module's views() method
+
+ \param app parent application object
+*/
+void SALOME_PYQT_ModuleLight::init( CAM_Application* app )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::init()" );
+
+ // reset interpreter to NULL
+ myInterp = NULL;
+
+ // get study Id
+ LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( app );
+ if ( !anApp )
+ return;
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( app->activeStudy() );
+ if ( !aStudy )
+ return;
+ int aStudyId = aStudy ? aStudy->id() : 0;
+
+ // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
+ initInterp( aStudyId );
+ if ( !myInterp )
+ return; // Error
+
+ // import Python GUI module
+ importModule();
+ if ( !myModule )
+ return; // Error
+
+ // this module is being activated now!
+ myInitModule = this;
+
+ // then call Python module's initialize() method
+ // ... first get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+ // ... (the Python module is already imported)
+ // ... finally call Python module's initialize() method
+ if ( PyObject_HasAttrString( myModule , "initialize" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "initialize", "" ) );
+ if ( !res ) {
+ PyErr_Print();
+ }
+ }
+
+ // get required dockable windows list from the Python module
+ // by calling windows() method
+ // ... first put default values
+ myWindowsMap.insert( LightApp_Application::WT_ObjectBrowser, Qt::LeftDockWidgetArea );
+ myWindowsMap.insert( LightApp_Application::WT_PyConsole, Qt::BottomDockWidgetArea );
+ myWindowsMap.insert( LightApp_Application::WT_LogWindow, Qt::BottomDockWidgetArea );
+
+ if ( PyObject_HasAttrString( myModule , "windows" ) ) {
+ PyObjWrapper res1( PyObject_CallMethod( myModule, "windows", "" ) );
+ if ( !res1 ) {
+ PyErr_Print();
+ }
+ else {
+ myWindowsMap.clear();
+ if ( PyDict_Check( res1 ) ) {
+ PyObject* key;
+ PyObject* value;
+ Py_ssize_t pos = 0;
+ while ( PyDict_Next( res1, &pos, &key, &value ) ) {
+ // parse the return value
+ // it should be a map: {integer:integer}
+ int aKey, aValue;
+ if( key && PyInt_Check( key ) && value && PyInt_Check( value ) ) {
+ aKey = PyInt_AsLong( key );
+ aValue = PyInt_AsLong( value );
+ myWindowsMap[ aKey ] = aValue;
+ }
+ }
+ }
+ }
+ }
+
+ // get compatible view windows types from the Python module
+ // by calling views() method
+ if ( PyObject_HasAttrString( myModule , "views" ) ) {
+ PyObjWrapper res2( PyObject_CallMethod( myModule, "views", "" ) );
+ if ( !res2 ) {
+ PyErr_Print();
+ }
+ else {
+ // parse the return value
+ // result can be one string...
+ if ( PyString_Check( res2 ) ) {
+ myViewMgrList.append( PyString_AsString( res2 ) );
+ }
+ // ... or list of strings
+ else if ( PyList_Check( res2 ) ) {
+ int size = PyList_Size( res2 );
+ for ( int i = 0; i < size; i++ ) {
+ PyObject* value = PyList_GetItem( res2, i );
+ if( value && PyString_Check( value ) ) {
+ myViewMgrList.append( PyString_AsString( value ) );
+ }
+ }
+ }
+ }
+ }
+ // module is already activated!
+ myInitModule = 0;
+}
+
+/*!
+ \brief Internal activation:
+
+ Performs the following actions:
+ - initialize or get the Python interpreter (one per study)
+ - import the Python GUI module
+ - call Python module's activate() method
+
+ \param theStudy parent study object
+*/
+void SALOME_PYQT_ModuleLight::activate( SUIT_Study* theStudy )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::activate()" );
+
+ // get study Id
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( theStudy );
+ int aStudyId = aStudy ? aStudy->id() : 0;
+
+ // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
+ initInterp( aStudyId );
+ if ( !myInterp )
+ return; // Error
+
+ // import Python GUI module
+ importModule();
+ if ( !myModule )
+ return; // Error
+
+ // get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+ // call Python module's activate() method (for the new modules)
+ if ( PyObject_HasAttrString( myModule , "activate" ) ) {
+ PyObject* res1 = PyObject_CallMethod( myModule, "activate", "" );
+ if ( !res1 || !PyBool_Check( res1 ) ) {
+ PyErr_Print();
+ // always true for old modules (no return value)
+ myLastActivateStatus = true;
+ }
+ else {
+ // detect return status
+ myLastActivateStatus = PyObject_IsTrue( res1 );
+ }
+ }
+
+ // Connect the SUIT_Desktop signal windowActivated() to this->onActiveViewChanged()
+ SUIT_Desktop* aDesk = theStudy->application()->desktop();
+ if ( aDesk )
+ {
+ connect( aDesk, SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
+ this, SLOT( onActiveViewChanged( SUIT_ViewWindow* ) ) );
+ // If a active window exists send activeViewChanged
+ // If a getActiveView() in SalomePyQt available we no longer need this
+ SUIT_ViewWindow* aView = aDesk->activeWindow();
+ if ( aView )
+ activeViewChanged( aView );
+
+ // get all view currently opened in the study and connect their signals to
+ // the corresponding slots of the class.
+ QList<SUIT_ViewWindow*> wndList = aDesk->windows();
+ SUIT_ViewWindow* wnd;
+ foreach ( wnd, wndList )
+ connectView( wnd );
+ }
+}
+
+/*!
+ \brief Additional customization after module is activated:
+
+ Performs the following actions:
+ - get the Python interpreter (one per study)
+ - import the Python GUI module
+ - call Python module's setSettings() method (obsolete function,
+ used for compatibility with old code)
+
+ \param theStudy parent study object
+*/
+void SALOME_PYQT_ModuleLight::customize( SUIT_Study* theStudy )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::customize()" );
+
+ // get study Id
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( theStudy );
+ int aStudyId = aStudy ? aStudy->id() : 0;
+
+ // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
+ initInterp( aStudyId );
+ if ( !myInterp )
+ return; // Error
+
+ // import Python GUI module
+ importModule();
+ if ( !myModule )
+ return; // Error
+
+ if ( IsCallOldMethods ) {
+ // call Python module's setWorkspace() method
+ setWorkSpace();
+ }
+
+ // get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+ if ( IsCallOldMethods ) {
+ // call Python module's setSettings() method (obsolete)
+ if ( PyObject_HasAttrString( myModule , "setSettings" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "setSettings", "" ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+ }
+}
+
+/*!
+ \brief Internal deactivation:
+
+ Performs the following actions:
+ - call Python module's deactivate() method
+
+ \param theStudy parent study object
+*/
+void SALOME_PYQT_ModuleLight::deactivate( SUIT_Study* theStudy )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::deactivate()" );
+
+ // check if the subinterpreter is initialized and Python module is imported
+ if ( !myInterp || !myModule ) {
+ // Error! Python subinterpreter should be initialized and module should be imported first!
+ return;
+ }
+ // then call Python module's deactivate() method
+ if ( PyObject_HasAttrString( myModule , "deactivate" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "deactivate", "" ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+
+ // Disconnect the SUIT_Desktop signal windowActivated()
+ SUIT_Desktop* aDesk = theStudy->application()->desktop();
+ if ( aDesk )
+ {
+ disconnect( aDesk, SIGNAL( windowActivated( SUIT_ViewWindow* ) ),
+ this, SLOT( onActiveViewChanged( SUIT_ViewWindow* ) ) );
+ }
+}
+
+/*!
+ \brief Perform internal actions when active study is changed.
+
+ Called when active the study is actived (user brings its
+ desktop to top):
+ - initialize or get the Python interpreter (one per study)
+ - import the Python GUI module
+ - call Python module's activeStudyChanged() method
+
+ \param theStudy study being activated
+*/
+void SALOME_PYQT_ModuleLight::studyChanged( SUIT_Study* theStudy )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::studyChanged()" );
+
+ // get study Id
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( theStudy );
+ int aStudyId = aStudy ? aStudy->id() : 0;
+
+ // initialize Python subinterpreter (on per study) and put it in <myInterp> variable
+ initInterp( aStudyId );
+ if ( !myInterp )
+ return; // Error
+
+ // import Python GUI module
+ importModule();
+ if ( !myModule )
+ return; // Error
+
+ if ( IsCallOldMethods ) {
+ // call Python module's setWorkspace() method
+ setWorkSpace();
+ }
+
+ // get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+ // call Python module's activeStudyChanged() method
+ if ( PyObject_HasAttrString( myModule , "activeStudyChanged" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "activeStudyChanged", "i", aStudyId ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+}
+
+/*!
+ \brief Process (internally) context popup menu request.
+
+ Performs the following actions:
+ - calls Python module's definePopup(...) method (obsolete function,
+ used for compatibility with old code) to define the popup menu context
+ - parses XML resourses file (if exists) and fills the popup menu with the items)
+ - calls Python module's customPopup(...) method (obsolete function,
+ used for compatibility with old code) to allow module to customize the popup menu
+ - for new modules calls createPopupMenu() function to allow the
+ modules to build the popup menu by using insertItem(...) Qt functions.
+
+ \param theContext popup menu context
+ \param thePopupMenu popup menu
+*/
+void SALOME_PYQT_ModuleLight::contextMenu( const QString& theContext, QMenu* thePopupMenu )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::contextMenu()" );
+
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule )
+ return;
+
+ QString aContext( "" ), aObject( "" ), aParent( theContext );
+
+ if ( IsCallOldMethods && PyObject_HasAttrString( myModule , "definePopup" ) ) {
+ // call definePopup() Python module's function
+ // this is obsolete function, used only for compatibility reasons
+ PyObjWrapper res( PyObject_CallMethod( myModule,
+ "definePopup",
+ "sss",
+ theContext.toLatin1().constData(),
+ aObject.toLatin1().constData(),
+ aParent.toLatin1().constData() ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ else {
+ // parse return value
+ char *co, *ob, *pa;
+ if( PyArg_ParseTuple( res, "sss", &co, &ob, &pa ) ) {
+ aContext = co;
+ aObject = ob;
+ aParent = pa;
+ }
+ }
+ } // if ( IsCallOldMethods ... )
+
+ // first try to create menu via XML parser:
+ // we create popup menus without help of QtxPopupMgr
+ if ( myXmlHandler )
+ myXmlHandler->createPopup( thePopupMenu, aContext, aParent, aObject );
+
+ PyObjWrapper sipPopup( sipBuildResult( 0, "M", thePopupMenu, sipClass_QMenu ) );
+
+ // then call Python module's createPopupMenu() method (for new modules)
+ if ( PyObject_HasAttrString( myModule , "createPopupMenu" ) ) {
+ PyObjWrapper res1( PyObject_CallMethod( myModule,
+ "createPopupMenu",
+ "Os",
+ sipPopup.get(),
+ theContext.toLatin1().constData() ) );
+ if( !res1 ) {
+ PyErr_Print();
+ }
+ }
+
+ if ( IsCallOldMethods && PyObject_HasAttrString( myModule , "customPopup" ) ) {
+ // call customPopup() Python module's function
+ // this is obsolete function, used only for compatibility reasons
+ PyObjWrapper res2( PyObject_CallMethod( myModule,
+ "customPopup",
+ "Osss",
+ sipPopup.get(),
+ aContext.toLatin1().constData(),
+ aObject.toLatin1().constData(),
+ aParent.toLatin1().constData() ) );
+ if( !res2 ) {
+ PyErr_Print();
+ }
+ }
+}
+
+/*!
+ \brief Internal GUI event handling.
+
+ Performs the following actions:
+ - calls Python module's OnGUIEvent() method
+
+ \param theId GUI action ID
+*/
+void SALOME_PYQT_ModuleLight::guiEvent( const int theId )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::guiEvent()" );
+
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule )
+ return;
+
+ if ( PyObject_HasAttrString( myModule , "OnGUIEvent" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "OnGUIEvent", "i", theId ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+}
+
+/*!
+ \brief Initialize (internally) preferences for the module.
+
+ Performs the following actions:
+ - calls Python module's createPreferences() method
+*/
+void SALOME_PYQT_ModuleLight::initPreferences()
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::initPreferences()" );
+
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule )
+ return;
+
+ // temporary set myInitModule because createPreferences() method
+ // might be called during the module intialization process
+ myInitModule = this;
+
+ if ( PyObject_HasAttrString( myModule , "createPreferences" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "createPreferences", "" ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+
+ myInitModule = 0;
+}
+
+/*!
+ \brief Initialize python subinterpreter (one per study).
+ \param theStudyId study ID
+*/
+void SALOME_PYQT_ModuleLight::initInterp( int theStudyId )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::initInterp()" );
+
+ // check study Id
+ if ( !theStudyId ) {
+ // Error! Study Id must not be 0!
+ myInterp = NULL;
+ return;
+ }
+ // try to find the subinterpreter
+ if( myInterpMap.contains( theStudyId ) ) {
+ // found!
+ myInterp = myInterpMap[ theStudyId ];
+ return;
+ }
+
+ myInterp = new SALOME_PYQT_PyInterp();
+ if(!myInterp)
+ return;
+
+ myInterp->initialize();
+ myInterpMap[ theStudyId ] = myInterp;
+
+#ifndef GUI_DISABLE_CORBA
+ if(!SUIT_PYTHON::initialized) {
+ // import 'salome' module and call 'salome_init' method;
+ // do it only once on interpreter creation
+ // ... first get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+ // ... then import a module
+ PyObjWrapper aMod = PyImport_ImportModule( "salome" );
+ if( !aMod ) {
+ // Error!
+ PyErr_Print();
+ return;
+ }
+ // ... then call a method
+ int embedded = 1;
+ PyObjWrapper aRes( PyObject_CallMethod( aMod, "salome_init", "ii", theStudyId, embedded ) );
+ if( !aRes ) {
+ // Error!
+ PyErr_Print();
+ return;
+ }
+ }
+#endif
+}
+
+/*!
+ \brief Import Python GUI module and remember the reference to the module.
+
+ Attention! initInterp() should be called first!!!
+*/
+void SALOME_PYQT_ModuleLight::importModule()
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::importModule()" );
+
+ // check if the subinterpreter is initialized
+ if ( !myInterp ) {
+ // Error! Python subinterpreter should be initialized first!
+ myModule = 0;
+ return;
+ }
+ // import Python GUI module and puts it in <myModule> attribute
+ // ... first get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+ // ... then import a module
+ QString aMod = name() + "GUI";
+ myModule = PyImport_ImportModule( aMod.toLatin1().data() );
+ if( !myModule ) {
+ // Error!
+ PyErr_Print();
+ return;
+ }
+}
+
+/*!
+ \brief Set study workspace to the Python module.
+
+ Calls setWorkSpace() method of the Pythohn module with
+ PyQt QWidget object to use with interpreter.
+
+ Attention! initInterp() and importModule() should be called first!!!
+*/
+void SALOME_PYQT_ModuleLight::setWorkSpace()
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::setWorkSpace()" );
+
+ // check if the subinterpreter is initialized and Python module is imported
+ if ( !myInterp || !myModule ) {
+ // Error! Python subinterpreter should be initialized and module should be imported first!
+ return;
+ }
+
+ // call setWorkspace() method
+ // ... first get python lock
+ PyLockWrapper aLock = myInterp->GetLockWrapper();
+
+ // ... then try to import SalomePyQt module. If it's not possible don't go on.
+ PyObjWrapper aQtModule( PyImport_ImportModule( "SalomePyQt" ) );
+ if( !aQtModule ) {
+ // Error!
+ PyErr_Print();
+ return;
+ }
+
+ if ( IsCallOldMethods ) {
+ // ... then get workspace object
+ QWidget* aWorkspace = 0;
+ if ( getApp()->desktop()->inherits( "STD_MDIDesktop" ) ) {
+ STD_MDIDesktop* aDesktop = dynamic_cast<STD_MDIDesktop*>( getApp()->desktop() );
+ if ( aDesktop )
+ aWorkspace = aDesktop->workspace();
+ }
+ else if ( getApp()->desktop()->inherits( "STD_TabDesktop" ) ) {
+ STD_TabDesktop* aDesktop = dynamic_cast<STD_TabDesktop*>( getApp()->desktop() );
+ if ( aDesktop )
+ aWorkspace = aDesktop->workstack();
+ }
+ PyObjWrapper pyws( sipBuildResult( 0, "M", aWorkspace, sipClass_QWidget ) );
+ // ... and finally call Python module's setWorkspace() method (obsolete)
+ if ( PyObject_HasAttrString( myModule , "setWorkSpace" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "setWorkSpace", "O", pyws.get() ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+ }
+}
+
+/*!
+ \brief Preference changing callback function (internal).
+
+ Performs the following actions:
+ - call Python module's preferenceChanged() method
+
+ \param section setting section name
+ \param setting setting name
+*/
+void SALOME_PYQT_ModuleLight::prefChanged( const QString& section, const QString& setting )
+{
+ FuncMsg fmsg( "SALOME_PYQT_ModuleLight::prefChanged()" );
+
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule )
+ return;
+
+ if ( PyObject_HasAttrString( myModule , "preferenceChanged" ) ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule,
+ "preferenceChanged",
+ "ss",
+ section.toLatin1().constData(),
+ setting.toLatin1().constData() ) );
+ if( !res ) {
+ PyErr_Print();
+ }
+ }
+}
+
+/*!
+ \brief Get default menu group identifier
+ \return menu group ID (40 by default)
+*/
+int SALOME_PYQT_ModuleLight::defaultMenuGroup()
+{
+ return DEFAULT_GROUP;
+}
+
+//
+// The next methods call the parent implementation.
+// This is done to open protected methods from CAM_Module class.
+//
+
+/*!
+ \brief Create toolbar with specified \a name.
+ \param name toolbar name
+ \return toolbar ID or -1 if toolbar creation is failed
+*/
+int SALOME_PYQT_ModuleLight::createTool( const QString& name )
+{
+ return LightApp_Module::createTool( name );
+}
+
+/*!
+ \brief Insert action with specified \a id to the toolbar.
+ \param id action ID
+ \param tBar toolbar ID
+ \param idx required index in the toolbar
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createTool( const int id, const int tBar, const int idx )
+{
+ return LightApp_Module::createTool( id, tBar, idx );
+}
+
+/*!
+ \brief Insert action with specified \a id to the toolbar.
+ \param id action ID
+ \param tBar toolbar name
+ \param idx required index in the toolbar
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createTool( const int id, const QString& tBar, const int idx )
+{
+ return LightApp_Module::createTool( id, tBar, idx );
+}
+
+/*!
+ \brief Insert action to the toolbar.
+ \param a action
+ \param tBar toolbar ID
+ \param id required action ID
+ \param idx required index in the toolbar
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createTool( QAction* a, const int tBar, const int id, const int idx )
+{
+ return LightApp_Module::createTool( a, tBar, id, idx );
+}
+
+/*!
+ \brief Insert action to the toolbar.
+ \param a action
+ \param tBar toolbar name
+ \param id required action ID
+ \param idx required index in the toolbar
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createTool( QAction* a, const QString& tBar, const int id, const int idx )
+{
+ return LightApp_Module::createTool( a, tBar, id, idx );
+}
+
+/*!
+ \brief Create main menu.
+ \param subMenu menu name
+ \param menu parent menu ID
+ \param id required menu ID
+ \param group menu group ID
+ \param idx required index in the menu
+ \return menu ID or -1 if menu could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( const QString& subMenu, const int menu, const int id, const int group, const int idx )
+{
+ return LightApp_Module::createMenu( subMenu, menu, id, group, idx );
+}
+
+/*!
+ \brief Create main menu.
+ \param subMenu menu name
+ \param menu parent menu name (list of menu names separated by "|")
+ \param id required menu ID
+ \param group menu group ID
+ \param idx required index in the menu
+ \return menu ID or -1 if menu could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( const QString& subMenu, const QString& menu, const int id, const int group, const int idx )
+{
+ return LightApp_Module::createMenu( subMenu, menu, id, group, idx );
+}
+
+/*!
+ \brief Insert action to the main menu.
+ \param id action ID
+ \param menu parent menu ID
+ \param group menu group ID
+ \param idx required index in the menu
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( const int id, const int menu, const int group, const int idx )
+{
+ return LightApp_Module::createMenu( id, menu, group, idx );
+}
+
+/*!
+ \brief Insert action to the main menu.
+ \param id action ID
+ \param menu parent menu name (list of menu names separated by "|")
+ \param group menu group ID
+ \param idx required index in the menu
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( const int id, const QString& menu, const int group, const int idx )
+{
+ return LightApp_Module::createMenu( id, menu, group, idx );
+}
+
+/*!
+ \brief Insert action to the main menu.
+ \param a action
+ \param menu parent menu ID
+ \param group menu group ID
+ \param idx required index in the menu
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( QAction* a, const int menu, const int id, const int group, const int idx )
+{
+ return LightApp_Module::createMenu( a, menu, id, group, idx );
+}
+
+/*!
+ \brief Insert action to the main menu.
+ \param a action
+ \param menu parent menu name (list of menu names separated by "|")
+ \param group menu group ID
+ \param idx required index in the menu
+ \return action ID or -1 if action could not be added
+*/
+int SALOME_PYQT_ModuleLight::createMenu( QAction* a, const QString& menu, const int id, const int group, const int idx )
+{
+ return LightApp_Module::createMenu( a, menu, id, group, idx );
+}
+
+/*!
+ \brief Create separator action which can be used in the menu or toolbar.
+ \return new separator action
+*/
+QAction* SALOME_PYQT_ModuleLight::separator()
+{
+ return LightApp_Module::separator();
+}
+
+/*!
+ \brief Get action by specified \a id.
+ \return action or 0 if it is not found
+*/
+QAction* SALOME_PYQT_ModuleLight::action( const int id ) const
+{
+ QAction* a = LightApp_Module::action( id );
+ if ( !a ) {
+ // try menu
+ QMenu* m = menuMgr()->findMenu( id );
+ if ( m ) a = m->menuAction();
+ }
+ return a;
+}
+
+/*!
+ \brief Get action identifier.
+ \return action ID or -1 if action is not registered
+*/
+int SALOME_PYQT_ModuleLight::actionId( const QAction* a ) const
+{
+ return LightApp_Module::actionId( a );
+}
+
+/*!
+ \brief Create new action.
+
+ If the action with specified identifier already registered
+ it is not created, but its attributes are only modified.
+
+ \param id action ID
+ \param text tooltip text
+ \param icon icon
+ \param menu menu text
+ \param tip status tip
+ \param key keyboard shortcut
+ \param toggle \c true for checkable action
+ \return created action
+*/
+QAction* SALOME_PYQT_ModuleLight::createAction( const int id, const QString& text, const QString& icon,
+ const QString& menu, const QString& tip, const int key,
+ const bool toggle, QObject* parent )
+{
+ QIcon anIcon = loadIcon( icon );
+ QAction* a = action( id );
+ if ( a ) {
+ if ( a->toolTip().isEmpty() && !text.isEmpty() ) a->setToolTip( text );
+ if ( a->text().isEmpty() && !menu.isEmpty() ) a->setText( menu );
+ if ( a->icon().isNull() && !anIcon.isNull() ) a->setIcon( anIcon );
+ if ( a->statusTip().isEmpty() && !tip.isEmpty() ) a->setStatusTip( tip );
+ if ( a->shortcut().isEmpty() && key ) a->setShortcut( key );
+ if ( a->isCheckable() != toggle ) a->setCheckable( toggle );
+ disconnect( a, SIGNAL( triggered( bool ) ), this, SLOT( onGUIEvent() ) );
+ connect( a, SIGNAL( triggered( bool ) ), this, SLOT( onGUIEvent() ) );
+ }
+ else {
+ a = LightApp_Module::createAction( id,
+ text,
+ anIcon,
+ menu,
+ tip,
+ key,
+ parent ? parent : this,
+ toggle,
+ this,
+ SLOT( onGUIEvent() ) );
+ }
+ return a;
+}
+
+/*!
+ \brief Create new action group.
+
+ If the action with specified identifier already registered
+ it is not created, but its attributes are only modified.
+
+ \param id action ID
+ \param text tooltip text
+ \param icon icon
+ \param menu menu text
+ \param tip status tip
+ \param key keyboard shortcut
+ \param toggle \c true for checkable action
+ \return created action
+*/
+QtxActionGroup* SALOME_PYQT_ModuleLight::createActionGroup(const int id, const bool exclusive)
+{
+ QtxActionGroup* a = qobject_cast<QtxActionGroup*>( action( id ) );
+ if ( !a ) {
+ a = new QtxActionGroup( this );
+ LightApp_Module::registerAction( id, a );
+ }
+ a->setExclusive( exclusive );
+ return a;
+}
+
+/*!
+ \brief Load icon from resource file.
+ \param fileName icon file name
+ \return icon (null icon if loading failed)
+*/
+QIcon SALOME_PYQT_ModuleLight::loadIcon( const QString& fileName )
+{
+ QIcon anIcon;
+ if ( !fileName.isEmpty() ) {
+ QPixmap pixmap = getApp()->resourceMgr()->loadPixmap( name(), tr( fileName.toLatin1() ) );
+ if ( !pixmap.isNull() )
+ anIcon = QIcon( pixmap );
+ }
+ return anIcon;
+}
+
+/*!
+ \brief Add global application preference (for example,
+ application specific section).
+ \param label preference name
+ \return preference ID
+*/
+int SALOME_PYQT_ModuleLight::addGlobalPreference( const QString& label )
+{
+ LightApp_Preferences* pref = preferences();
+ if ( !pref )
+ return -1;
+
+ return pref->addPreference( label, -1 );
+}
+
+/*!
+ \brief Add preference.
+ \param label preference name
+ \return preference ID
+*/
+int SALOME_PYQT_ModuleLight::addPreference( const QString& label )
+{
+ return LightApp_Module::addPreference( label );
+}
+
+/*!
+ \brief Add preference.
+ \param label preference name
+ \param pId parent preference ID
+ \param type preference type
+ \param section resource file section name
+ \param param resource file setting name
+ \return preference ID
+*/
+int SALOME_PYQT_ModuleLight::addPreference( const QString& label,
+ const int pId, const int type,
+ const QString& section,
+ const QString& param )
+{
+ return LightApp_Module::addPreference( label, pId, type, section, param );
+}
+
+/*!
+ \brief Get the preference property.
+ \param id preference ID
+ \param prop property name
+ \return property value (invalid QVariant() if property is not found)
+*/
+QVariant SALOME_PYQT_ModuleLight::preferenceProperty( const int id,
+ const QString& prop ) const
+{
+ QVariant v = LightApp_Module::preferenceProperty( id, prop );
+ return v;
+}
+
+/*!
+ \brief Set the preference property.
+ \param id preference ID
+ \param prop property name
+ \param var property value
+*/
+void SALOME_PYQT_ModuleLight::setPreferenceProperty( const int id,
+ const QString& prop,
+ const QVariant& var )
+{
+ LightApp_Module::setPreferenceProperty( id, prop, var );
+}
+
+
+/*!
+ \brief Signal handler windowActivated(SUIT_ViewWindow*) of SUIT_Desktop
+ \param pview view being activated
+*/
+void SALOME_PYQT_ModuleLight::onActiveViewChanged( SUIT_ViewWindow* pview )
+{
+ class ActiveViewChange : public PyInterp_LockRequest
+ {
+ public:
+ ActiveViewChange( PyInterp_Interp* _py_interp, SALOME_PYQT_ModuleLight* _obj, const SUIT_ViewWindow* _pview )
+ : PyInterp_LockRequest( _py_interp, 0, true ),
+ myObj(_obj),myView(_pview) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->activeViewChanged( myView );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ const SUIT_ViewWindow * myView;
+ };
+
+ PyInterp_Dispatcher::Get()->Exec( new ActiveViewChange( myInterp, this, pview ) );
+}
+
+/*!
+ \brief Processes the view changing, calls Python module's activeViewChanged() method
+ \param pview view being activated
+*/
+void SALOME_PYQT_ModuleLight::activeViewChanged( const SUIT_ViewWindow* pview )
+{
+ if ( !myInterp || !myModule )
+ return;
+
+ // Do not use SUIT_ViewWindow::closing() signal here. View manager reacts on
+ // this signal and deletes view. So our slot does not works if it is connected
+ // on this signal. SUIT_ViewManager::deleteView(SUIT_ViewWindow*) is used here
+
+ connectView( pview );
+
+ if ( PyObject_HasAttrString( myModule, "activeViewChanged" ) )
+ {
+ if ( !pview )
+ return;
+
+ PyObjWrapper res( PyObject_CallMethod( myModule, "activeViewChanged", "i" , pview->getId() ) );
+ if( !res )
+ PyErr_Print();
+ }
+}
+
+/*!
+ \brief Signal handler cloneView() of OCCViewer_ViewWindow
+ \param pview view being cloned
+*/
+void SALOME_PYQT_ModuleLight::onViewCloned( SUIT_ViewWindow* pview )
+{
+ class ViewClone : public PyInterp_LockRequest
+ {
+ public:
+ ViewClone( PyInterp_Interp* _py_interp, SALOME_PYQT_ModuleLight* _obj, const SUIT_ViewWindow* _pview )
+ : PyInterp_LockRequest( _py_interp, 0, true ),
+ myObj(_obj), myView(_pview) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->viewCloned( myView );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ const SUIT_ViewWindow* myView;
+ };
+
+ PyInterp_Dispatcher::Get()->Exec( new ViewClone( myInterp, this, pview ) );
+}
+
+/*!
+ \brief Processes the view cloning, calls Python module's activeViewCloned() method
+ \param pview view being cloned
+*/
+void SALOME_PYQT_ModuleLight::viewCloned( const SUIT_ViewWindow* pview )
+{
+ if ( !myInterp || !myModule || !pview )
+ return;
+
+ if ( PyObject_HasAttrString( myModule, "viewCloned" ) )
+ {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "viewCloned", "i", pview->getId() ) );
+ if( !res )
+ PyErr_Print();
+ }
+}
+
+/*!
+ \brief Signal handler closing(SUIT_ViewWindow*) of a view
+ \param pview view being closed
+*/
+void SALOME_PYQT_ModuleLight::onViewClosed( SUIT_ViewWindow* pview )
+{
+ class ViewClose : public PyInterp_LockRequest
+ {
+ public:
+ ViewClose( PyInterp_Interp* _py_interp, SALOME_PYQT_ModuleLight* _obj, const SUIT_ViewWindow* _pview )
+ : PyInterp_LockRequest( _py_interp, 0, true ),
+ myObj(_obj),myView(_pview) {}
+
+ protected:
+ virtual void execute()
+ {
+ myObj->viewClosed( myView );
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ const SUIT_ViewWindow * myView;
+ };
+
+ PyInterp_Dispatcher::Get()->Exec( new ViewClose( myInterp, this, pview ) );
+}
+
+/*!
+ \brief Processes the view closing, calls Python module's viewClosed() method
+ \param pview view being closed
+*/
+void SALOME_PYQT_ModuleLight::viewClosed( const SUIT_ViewWindow* pview )
+{
+ if ( !myInterp || !myModule )
+ return;
+
+ if ( PyObject_HasAttrString( myModule, "viewClosed" ) )
+ {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "viewClosed", "i", pview->getId() ) );
+ if ( !res )
+ {
+ PyErr_Print();
+ }
+ }
+}
+
+/*!
+ \brief Connects or disconnects signals about activating and cloning view on the module slots
+ \param pview view which is connected/disconnected
+*/
+void SALOME_PYQT_ModuleLight::connectView( const SUIT_ViewWindow* pview )
+{
+ SUIT_ViewManager* viewMgr = pview->getViewManager();
+ SUIT_ViewModel* viewModel = viewMgr ? viewMgr->getViewModel() : 0;
+
+ if ( viewMgr )
+ {
+ disconnect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) );
+
+ connect( viewMgr, SIGNAL( deleteView( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewClosed( SUIT_ViewWindow* ) ) );
+ }
+
+ // Connect cloneView() signal of an OCC View
+ if ( pview->inherits( "OCCViewer_ViewWindow" ) )
+ {
+ disconnect( pview, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
+ connect( pview, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
+ }
+ // Connect cloneView() signal of Plot2d View manager
+ else if ( viewModel && viewModel->inherits( "Plot2d_Viewer" ) )
+ {
+ disconnect( viewModel, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
+ connect( viewModel, SIGNAL( viewCloned( SUIT_ViewWindow* ) ),
+ this, SLOT( onViewCloned( SUIT_ViewWindow* ) ) );
+ }
+}
+
+/*!
+ \brief Get tag name for the DOM element.
+ \param element DOM element
+ \return empty string if the element does not have tag name
+ \internal
+*/
+static QString tagName( const QDomElement& element )
+{
+ return element.tagName().trimmed();
+}
+
+/*!
+ \brief Get DOM element's attribute by its name.
+ \param element DOM element
+ \param attName attribute name
+ \return empty string if the element does not have such attribute
+ \internal
+*/
+static QString attribute( const QDomElement& element, const QString& attName )
+{
+ return element.attribute( attName ).trimmed();
+}
+
+/*!
+ \brief Inspect specified string for the boolean value.
+
+ This function returns \c true if string represents boolean value:
+ - "true", "yes" or "1" for \c true
+ - "false", "no" or "0" for \c false
+ Second parameter allows to specify what boolean value is expected:
+ - 1: \c true
+ - 0: \c false
+ - other value is not taken into account (return represented value)
+
+ \param value inspected string
+ \param check expected boolean value
+ \return boolean value represented by the string (\a check is not 1 or 0)
+ or \c true if value correspond to the specified \a check
+*/
+static bool checkBool( const QString& value, const int check = -1 )
+{
+ QString v = value.toLower();
+ if ( ( v == "true" || v == "yes" || v == "1" ) && ( check != 0 ) )
+ return true;
+ if ( ( v == "false" || v == "no" || v == "0" ) && ( check == 0 ) )
+ return true;
+ return false;
+}
+
+/*!
+ \brief Inspect specified string for the integer value.
+
+ This function returns returns -1 if item is empty or represents
+ an invalid number.
+ \param value inspected string
+ \param def default value
+ \param shift shift value (it is added to the integer value to produce shifted result)
+*/
+static int checkInt( const QString& value, const int def = -1, const int shift = -1 )
+{
+ bool bOk;
+ int val = value.toInt( &bOk );
+ if ( !bOk ) val = def;
+ if ( shift > 0 && bOk && val < 0 )
+ val += shift;
+ return val;
+}
+
+/*!
+ \brief Constructor
+ \internal
+ \param module parent module pointer
+ \param fileName XML file path
+*/
+SALOME_PYQT_ModuleLight::XmlHandler::XmlHandler( SALOME_PYQT_ModuleLight* module,
+ const QString& fileName )
+: myModule( module )
+{
+ if ( fileName.isEmpty() )
+ return;
+ QFile aFile( fileName );
+ if ( !aFile.open( QIODevice::ReadOnly ) )
+ return;
+ myDoc.setContent( &aFile );
+ aFile.close();
+}
+
+/*!
+ \brief Parse XML file and create actions.
+ \internal
+
+ Called by SALOME_PYQT_ModuleLight::activate() in order to create actions
+ (menus, toolbars).
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::createActions()
+{
+ // get document element
+ QDomElement aDocElem = myDoc.documentElement();
+
+ // create main menu actions
+ QDomNodeList aMenuList = aDocElem.elementsByTagName( "menu-item" );
+ for ( int i = 0; i < aMenuList.count(); i++ ) {
+ QDomNode n = aMenuList.item( i );
+ createMenu( n );
+ }
+
+ // create toolbars actions
+ QDomNodeList aToolsList = aDocElem.elementsByTagName( "toolbar" );
+ for ( int i = 0; i < aToolsList.count(); i++ ) {
+ QDomNode n = aToolsList.item( i );
+ createToolBar( n );
+ }
+}
+
+/*!
+ \brief Create popup menu.
+ \internal
+ \param menu popup menu
+ \param context popup menu context
+ \param context popup menu parent object name
+ \param context popup menu object name
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::createPopup( QMenu* menu,
+ const QString& context,
+ const QString& parent,
+ const QString& object )
+{
+ // get document element
+ QDomElement aDocElem = myDoc.documentElement();
+
+ // get popup menus actions
+ QDomNodeList aPopupList = aDocElem.elementsByTagName( "popupmenu" );
+ for ( int i = 0; i < aPopupList.count(); i++ ) {
+ QDomNode n = aPopupList.item( i );
+ if ( !n.isNull() && n.isElement() ) {
+ QDomElement e = n.toElement();
+ // QString lab = attribute( e, "label-id" ); // not used //
+ QString ctx = attribute( e, "context-id" );
+ QString prt = attribute( e, "parent-id" );
+ QString obj = attribute( e, "object-id" );
+ if ( ctx == context && prt == parent && obj == object ) {
+ insertPopupItems( n, menu );
+ break;
+ }
+ }
+ }
+}
+
+/*!
+ \brief Activate menus
+ \internal
+ \param enable if \c true menus are activated, otherwise menus are deactivated
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::activateMenus( bool enable )
+{
+ if ( !myModule )
+ return;
+
+ QtxActionMenuMgr* mgr = myModule->menuMgr();
+ int id;
+ foreach( id, myMenuItems ) mgr->setEmptyEnabled( id, enable );
+}
+
+/*!
+ \brief Create main menu item and insert actions to it.
+ \internal
+ \param parentNode XML node with menu description
+ \param parentMenuId parent menu ID (-1 for top-level menu)
+ \param parentPopup parent popup menu (0 for top-level menu)
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::createMenu( QDomNode& parentNode,
+ const int parentMenuId,
+ QMenu* parentPopup )
+{
+ if ( !myModule || parentNode.isNull() )
+ return;
+
+ QDomElement parentElement = parentNode.toElement();
+ if ( !parentElement.isNull() ) {
+ QString plabel = attribute( parentElement, "label-id" );
+ int pid = checkInt( attribute( parentElement, "item-id" ) );
+ int ppos = checkInt( attribute( parentElement, "pos-id" ) );
+ int group = checkInt( attribute( parentElement, "group-id" ),
+ myModule->defaultMenuGroup() );
+ if ( !plabel.isEmpty() ) {
+ QMenu* popup = 0;
+ int menuId = -1;
+ // create menu
+ menuId = myModule->createMenu( plabel, // label
+ parentMenuId, // parent menu ID, -1 for top-level menu
+ pid, // ID
+ group, // group ID
+ ppos ); // position
+ myMenuItems.append( menuId );
+ QDomNode node = parentNode.firstChild();
+ while ( !node.isNull() ) {
+ if ( node.isElement() ) {
+ QDomElement elem = node.toElement();
+ QString aTagName = tagName( elem );
+ if ( aTagName == "popup-item" ) {
+ int id = checkInt( attribute( elem, "item-id" ) );
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ int group = checkInt( attribute( elem, "group-id" ),
+ myModule->defaultMenuGroup() );
+ QString label = attribute( elem, "label-id" );
+ QString icon = attribute( elem, "icon-id" );
+ QString tooltip = attribute( elem, "tooltip-id" );
+ QString accel = attribute( elem, "accel-id" );
+ bool toggle = checkBool( attribute( elem, "toggle-id" ) );
+
+ // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
+ // also check if the action with given ID is already created
+ if ( id != -1 ) {
+ // create menu action
+ QAction* action = myModule->createAction( id, // ID
+ tooltip, // tooltip
+ icon, // icon
+ label, // menu text
+ tooltip, // status-bar text
+ QKeySequence( accel ), // keyboard accelerator
+ toggle ); // toogled action
+ myModule->createMenu( action, // action
+ menuId, // parent menu ID
+ id, // ID (same as for createAction())
+ group, // group ID
+ pos ); // position
+ }
+ }
+ else if ( aTagName == "submenu" ) {
+ // create sub-menu
+ createMenu( node, menuId, popup );
+ }
+ else if ( aTagName == "separator" ) {
+ // create menu separator
+ int id = checkInt( attribute( elem, "item-id" ) ); // separator can have ID
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ int group = checkInt( attribute( elem, "group-id" ),
+ myModule->defaultMenuGroup() );
+ QAction* action = myModule->separator();
+ myModule->createMenu( action, // separator action
+ menuId, // parent menu ID
+ id, // ID
+ group, // group ID
+ pos ); // position
+ }
+ }
+ node = node.nextSibling();
+ }
+ }
+ }
+}
+
+/*!
+ \brief Create a toolbar and insert actions to it.
+ \param parentNode XML node with toolbar description
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::createToolBar( QDomNode& parentNode )
+{
+ if ( !myModule || parentNode.isNull() )
+ return;
+
+ QDomElement parentElement = parentNode.toElement();
+ if ( !parentElement.isNull() ) {
+ QString aLabel = attribute( parentElement, "label-id" );
+ if ( !aLabel.isEmpty() ) {
+ // create toolbar
+ int tbId = myModule->createTool( aLabel );
+ QDomNode node = parentNode.firstChild();
+ while ( !node.isNull() ) {
+ if ( node.isElement() ) {
+ QDomElement elem = node.toElement();
+ QString aTagName = tagName( elem );
+ if ( aTagName == "toolbutton-item" ) {
+ int id = checkInt( attribute( elem, "item-id" ) );
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ QString label = attribute( elem, "label-id" );
+ QString icon = attribute( elem, "icon-id" );
+ QString tooltip = attribute( elem, "tooltip-id" );
+ QString accel = attribute( elem, "accel-id" );
+ bool toggle = checkBool( attribute( elem, "toggle-id" ) );
+
+ // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
+ // also check if the action with given ID is already created
+ if ( id != -1 ) {
+ // create toolbar action
+ QAction* action = myModule->createAction( id, // ID
+ tooltip, // tooltip
+ icon, // icon
+ label, // menu text
+ tooltip, // status-bar text
+ QKeySequence( accel ), // keyboard accelerator
+ toggle ); // toogled action
+ myModule->createTool( action, tbId, -1, pos );
+ }
+ }
+ else if ( aTagName == "separatorTB" || aTagName == "separator" ) {
+ // create toolbar separator
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ QAction* action = myModule->separator();
+ myModule->createTool( action, tbId, -1, pos );
+ }
+ }
+ node = node.nextSibling();
+ }
+ }
+ }
+}
+
+/*!
+ \brief Fill popup menu with the items.
+ \param parentNode XML node with popup menu description
+ \param menu popup menu
+*/
+void SALOME_PYQT_ModuleLight::XmlHandler::insertPopupItems( QDomNode& parentNode, QMenu* menu )
+{
+ if ( !myModule && parentNode.isNull() )
+ return;
+
+ // we create popup menus without help of QtxPopupMgr
+ QDomNode node = parentNode.firstChild();
+ while ( !node.isNull() ) {
+ if ( node.isElement() ) {
+ QDomElement elem = node.toElement();
+ QString aTagName = tagName( elem );
+ QList<QAction*> actions = menu->actions();
+ if ( aTagName == "popup-item" ) {
+ // insert a command item
+ int id = checkInt( attribute( elem, "item-id" ) );
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ QString label = attribute( elem, "label-id" );
+ QString icon = attribute( elem, "icon-id" );
+ QString tooltip = attribute( elem, "tooltip-id" );
+ QString accel = attribute( elem, "accel-id" );
+ bool toggle = checkBool( attribute( elem, "toggle-id" ) );
+
+ // -1 action ID is not allowed : it means that <item-id> attribute is missed in the XML file!
+ // also check if the action with given ID is already created
+ if ( id != -1 ) {
+ QAction* action = myModule->createAction( id, // ID
+ tooltip, // tooltip
+ icon, // icon
+ label, // menu text
+ tooltip, // status-bar text
+ QKeySequence( accel ), // keyboard accelerator
+ toggle ); // toogled action
+ QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
+ menu->insertAction( before, action );
+ }
+ }
+ else if ( aTagName == "submenu" ) {
+ // create sub-menu
+ ////int id = checkInt( attribute( elem, "item-id" ) ); // not used //
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ QString label = attribute( elem, "label-id" );
+ QString icon = attribute( elem, "icon-id" );
+
+ QIcon anIcon;
+ if ( !icon.isEmpty() ) {
+ QPixmap pixmap = myModule->getApp()->resourceMgr()->loadPixmap( myModule->name(), icon );
+ if ( !pixmap.isNull() )
+ anIcon = QIcon( pixmap );
+ }
+
+ QMenu* newPopup = menu->addMenu( anIcon, label );
+ QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
+ menu->insertMenu( before, newPopup );
+ insertPopupItems( node, newPopup );
+ }
+ else if ( aTagName == "separator" ) {
+ // create menu separator
+ int pos = checkInt( attribute( elem, "pos-id" ) );
+ QAction* action = myModule->separator();
+ QAction* before = ( pos >= 0 && pos < actions.count() ) ? actions[ pos ] : 0;
+ menu->insertAction( before, action );
+ }
+ }
+ node = node.nextSibling();
+ }
+}
+
+/*
+ * Save study request.
+ * Called when user save study.
+ */
+void SALOME_PYQT_ModuleLight::save(QStringList& theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::save()")
+ // perform synchronous request to Python event dispatcher
+ class SaveEvent: public PyInterp_LockRequest
+ {
+ public:
+ SaveEvent(PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ QStringList& _files_list)
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj( _obj ) ,
+ myFilesList(_files_list) {}
+ protected:
+ virtual void execute()
+ {
+ myObj->saveEvent(myFilesList);
+ }
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ QStringList& myFilesList;
+ };
+
+ // Posting the request only if dispatcher is not busy!
+ // Executing the request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new SaveEvent( myInterp, this, theListOfFiles ) );
+}
+
+void SALOME_PYQT_ModuleLight::saveEvent(QStringList& theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::saveEvent()");
+ QStringList::Iterator it = theListOfFiles.begin();
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule || (it == theListOfFiles.end()))
+ return;
+
+ if ( PyObject_HasAttrString(myModule , "saveFiles") ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "saveFiles",
+ "s", (*it).toLatin1().constData()));
+ if( !res ) {
+ PyErr_Print();
+ }
+ else{
+ // parse the return value
+ // result can be one string...
+ if ( PyString_Check( res ) ) {
+ QString astr = PyString_AsString( res );
+ //SCRUTE(astr);
+ theListOfFiles.append(astr);
+ }
+ //also result can be a list...
+ else if ( PyList_Check( res ) ) {
+ int size = PyList_Size( res );
+ for ( int i = 0; i < size; i++ ) {
+ PyObject* value = PyList_GetItem( res, i );
+ if( value && PyString_Check( value ) ) {
+ theListOfFiles.append( PyString_AsString( value ) );
+ }
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Open study request.
+ * Called when user open study.
+ */
+bool SALOME_PYQT_ModuleLight::open(QStringList theListOfFiles)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::open()");
+ // perform synchronous request to Python event dispatcher
+ bool opened = false;
+ class OpenEvent: public PyInterp_LockRequest
+ {
+ public:
+ OpenEvent(PyInterp_Interp* _py_interp,
+ SALOME_PYQT_ModuleLight* _obj,
+ QStringList _files_list,
+ bool& _opened)
+ : PyInterp_LockRequest( _py_interp, 0, true ), // this request should be processed synchronously (sync == true)
+ myObj( _obj ) ,
+ myFilesList(_files_list),
+ myOpened(_opened) {}
+ protected:
+ virtual void execute()
+ {
+ myObj->openEvent(myFilesList,myOpened);
+ }
+
+ private:
+ SALOME_PYQT_ModuleLight* myObj;
+ QStringList myFilesList;
+ bool& myOpened;
+ };
+
+ // Posting the request only if dispatcher is not busy!
+ // Executing the request synchronously
+ if ( !PyInterp_Dispatcher::Get()->IsBusy() )
+ PyInterp_Dispatcher::Get()->Exec( new OpenEvent( myInterp, this, theListOfFiles, opened) );
+ return opened;
+}
+
+
+void SALOME_PYQT_ModuleLight::openEvent(QStringList theListOfFiles, bool &opened)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::openEvent()");
+ // Python interpreter should be initialized and Python module should be
+ // import first
+ if ( !myInterp || !myModule || theListOfFiles.isEmpty())
+ return;
+ QStringList* theList = new QStringList(theListOfFiles);
+
+ PyObjWrapper sipList( sipBuildResult( 0, "M", theList, sipClass_QStringList ) );
+
+ if ( PyObject_HasAttrString(myModule , "openFiles") ) {
+ PyObjWrapper res( PyObject_CallMethod( myModule, "openFiles",
+ "O", sipList.get()));
+ if( !res || !PyBool_Check( res )) {
+ PyErr_Print();
+ opened = false;
+ }
+ else{
+ opened = PyObject_IsTrue( res );
+
+ }
+ }
+}
+
+/*
+ * Create new empty Data Object and return its entry
+ */
+QString SALOME_PYQT_ModuleLight::createObject(const QString& parent)
+{
+ SALOME_PYQT_DataObjectLight* obj=0;
+ if(!parent.isEmpty())
+ {
+ SALOME_PYQT_DataObjectLight* parentObj = findObject(parent);
+ if(parentObj)
+ {
+ obj = new SALOME_PYQT_DataObjectLight(parentObj);
+ }
+ }
+ else
+ {
+ SALOME_PYQT_DataModelLight* dm =
+ dynamic_cast<SALOME_PYQT_DataModelLight*>( dataModel());
+ if(dm)
+ {
+ obj = new SALOME_PYQT_DataObjectLight(dm->getRoot());
+ }
+ }
+ if (obj)
+ return obj->entry();
+ else
+ return QString::null;
+}
+
+/*
+ * Create new Data Object with name, icon and tooltip
+ * and return its entry
+ */
+QString SALOME_PYQT_ModuleLight::createObject(const QString& aname,
+ const QString& iconname,
+ const QString& tooltip,
+ const QString& parent)
+{
+ QString entry = createObject(parent);
+ SALOME_PYQT_DataObjectLight* obj = findObject(entry);
+
+ if(obj)
+ {
+ obj->setName(aname);
+ obj->setToolTip(tooltip);
+ obj->setIcon(iconname);
+ return obj->entry();
+ }
+ else
+ return QString::null;
+}
+
+/*
+ * Find object by entry
+ */
+SALOME_PYQT_DataObjectLight* SALOME_PYQT_ModuleLight::findObject(const QString& entry)
+{
+ SALOME_PYQT_DataObjectLight* obj = 0;
+ SALOME_PYQT_DataModelLight* dm =
+ dynamic_cast<SALOME_PYQT_DataModelLight*>( dataModel());
+ if(!entry.isEmpty() && dm ){
+ for ( SUIT_DataObjectIterator it( dm->getRoot(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
+ SALOME_PYQT_DataObjectLight* curentobj =
+ dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.current() );
+
+ if(curentobj && curentobj->entry() == entry) {
+ obj = curentobj;
+ return obj;
+ }
+ }
+ }
+ return obj;
+}
+
+/*
+ * Set Name for object
+ */
+void SALOME_PYQT_ModuleLight::setName(const QString& obj, const QString& name)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ dataObj->setName(name);
+ }
+}
+
+/*
+ * Set Icon for object
+ */
+void SALOME_PYQT_ModuleLight::setIcon(const QString& obj, const QString& iconname)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ dataObj->setIcon(iconname);
+ }
+}
+
+/*
+ * Return Name of object
+ */
+QString SALOME_PYQT_ModuleLight::getName(const QString& obj)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ return dataObj->name();
+ }
+ return QString::null;
+}
+
+/*
+ * Return Tool Tip of object
+ */
+QString SALOME_PYQT_ModuleLight::getToolTip(const QString& obj)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ return dataObj->toolTip();
+ }
+ return QString::null;
+}
+
+
+/*
+ * Set Tool Tip for object
+ */
+void SALOME_PYQT_ModuleLight::setToolTip(const QString& obj, const QString& tooltip)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ dataObj->setToolTip(tooltip);
+ }
+}
+
+/*
+ * Remove object by entry
+ */
+void SALOME_PYQT_ModuleLight::removeObject(const QString& obj)
+{
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj) {
+ dataObj->parent()->removeChild(dataObj);
+ }
+}
+
+
+/*
+ * Remove chields from object
+ */
+void SALOME_PYQT_ModuleLight::removeChild(const QString& obj)
+{
+ MESSAGE("SALOME_PYQT_ModuleLight::removeChild()");
+ DataObjectList lst;
+ if(!obj.isEmpty())
+ {
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj)
+ {
+ dataObj->children(lst);
+ QListIterator<SUIT_DataObject*> it( lst );
+ while( it.hasNext() )
+ {
+ SALOME_PYQT_DataObjectLight* sobj = dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.next() );
+ dataObj->removeChild(sobj);
+ }
+ }
+ }
+ else
+ {
+ SALOME_PYQT_DataModelLight* dm =
+ dynamic_cast<SALOME_PYQT_DataModelLight*>( dataModel());
+ if(dm)
+ {
+ dm->getRoot()->children(lst);
+ QListIterator<SUIT_DataObject*> it( lst );
+ while(it.hasNext() )
+ {
+ SALOME_PYQT_DataObjectLight* sobj = dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.next() );
+ dm->getRoot()->removeChild(sobj);
+ }
+ }
+ }
+}
+
+QStringList SALOME_PYQT_ModuleLight::getChildren(const QString& obj, const bool rec)
+{
+ DataObjectList lst;
+ QStringList entryList;
+ if(!obj.isEmpty())
+ {
+ SALOME_PYQT_DataObjectLight* dataObj = findObject(obj);
+ if(dataObj)
+ {
+ dataObj->children(lst,rec);
+ QListIterator<SUIT_DataObject*> it( lst );
+ while(it.hasNext())
+ {
+ SALOME_PYQT_DataObjectLight* sobj = dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.next() );
+ entryList.append(sobj->entry());
+ }
+ }
+ }
+ else
+ {
+ SALOME_PYQT_DataModelLight* dm =
+ dynamic_cast<SALOME_PYQT_DataModelLight*>( dataModel());
+ if(dm)
+ {
+ dm->getRoot()->children(lst);
+ QListIterator<SUIT_DataObject*> it( lst );
+ while( it.hasNext() )
+ {
+ SALOME_PYQT_DataObjectLight* sobj = dynamic_cast<SALOME_PYQT_DataObjectLight*>( it.next() );
+ entryList.append(sobj->entry());
+ }
+ }
+ }
+ return entryList;
+}
+
+/*!
+ * Create new instance of data model and return it.
+ */
+CAM_DataModel* SALOME_PYQT_ModuleLight::createDataModel()
+{
+ MESSAGE( "SALOME_PYQT_ModuleLight::createDataModel()" );
+ return new SALOME_PYQT_DataModelLight(this);
+}
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : SALOME_PYQT_Module.h
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+
+#ifndef SALOME_PYQT_MODULELIGHT_H
+#define SALOME_PYQT_MODULELIGHT_H
+
+#include "PyInterp_Interp.h" // // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
+#include "SALOME_PYQT_GUILight.h"
+#include "LightApp_Module.h"
+#include "SALOME_PYQT_DataObjectLight.h"
+#include <CAM_Module.h>
+
+#include <map>
+#include <QStringList>
+#include <QList>
+#include <QMap>
+#include <QIcon>
+
+class SALOME_PYQT_RootObjectLight;
+class SALOME_PYQT_PyInterp;
+class SUIT_ViewWindow;
+class QAction;
+class QtxActionGroup;
+class QMenu;
+
+
+class SALOME_PYQT_EXPORT SALOME_PYQT_ModuleLight: virtual public LightApp_Module
+{
+ Q_OBJECT;
+
+private:
+ class XmlHandler;
+
+ //! study to Python subinterpreter map
+ typedef QMap<int, PyInterp_Interp*> InterpMap;
+ PyObjWrapper myModule; //!< Python GUI module
+ static SALOME_PYQT_ModuleLight* myInitModule; //!< Python GUI being initialized (not zero only during the initialization)
+
+ XmlHandler* myXmlHandler; //!< XML resource file parser
+ QMap<int, int> myWindowsMap; //!< windows map
+ QStringList myViewMgrList;//!< compatible view managers list
+ bool myLastActivateStatus; //!< latest module activation status
+
+
+protected:
+ PyInterp_Interp* myInterp; //!< current Python subinterpreter
+ static InterpMap myInterpMap; //!< study to Python subinterpreter map
+
+public:
+ SALOME_PYQT_ModuleLight();
+ ~SALOME_PYQT_ModuleLight();
+
+public:
+ static SALOME_PYQT_ModuleLight* getInitModule();
+
+ void initialize( CAM_Application* );
+ void windows( QMap<int, int>& ) const;
+ void viewManagers( QStringList& ) const;
+ void contextMenuPopup( const QString&, QMenu*, QString& );
+ void createPreferences();
+ void studyActivated();
+ void preferencesChanged( const QString&, const QString& );
+
+ static int defaultMenuGroup();
+
+ int createTool( const QString& );
+ int createTool( const int, const int, const int = -1 );
+ int createTool( const int, const QString&, const int = -1 );
+ int createTool( QAction*, const int,
+ const int = -1, const int = -1 );
+ int createTool( QAction*, const QString&,
+ const int = -1, const int = -1 );
+
+ int createMenu( const QString&, const int,
+ const int = -1, const int = -1, const int = -1 );
+ int createMenu( const QString&, const QString&,
+ const int = -1, const int = -1, const int = -1 );
+ int createMenu( const int, const int,
+ const int = -1, const int = -1 );
+ int createMenu( const int, const QString&,
+ const int = -1, const int = -1 );
+ int createMenu( QAction*, const int,
+ const int = -1, const int = -1, const int = -1 );
+ int createMenu( QAction*, const QString&,
+ const int = -1, const int = -1, const int = -1 );
+
+ QAction* separator();
+
+ QAction* action( const int ) const;
+ int actionId( const QAction* ) const;
+ QAction* createAction( const int, const QString&, const QString&,
+ const QString&, const QString&, const int,
+ const bool = false, QObject* = 0 );
+ QtxActionGroup* createActionGroup( const int, const bool );
+
+
+ QIcon loadIcon( const QString& fileName );
+
+ int addGlobalPreference( const QString& );
+ int addPreference( const QString& );
+ int addPreference( const QString&, const int, const int = LightApp_Preferences::Auto,
+ const QString& = QString(),
+ const QString& = QString() );
+ QVariant preferenceProperty( const int, const QString& ) const;
+ void setPreferenceProperty( const int, const QString&,
+ const QVariant& );
+
+ void save(QStringList& theListOfFiles);
+
+ bool open(QStringList theListOfFiles);
+
+ /*create new SALOME_PYQT_DataObjectLight and return its entry*/
+ QString createObject(const QString& parent);
+ QString createObject(const QString& name,
+ const QString& iconname,
+ const QString& tooltip,
+ const QString& parent);
+ /*Sets Name, Icon and Tool Tip for object*/
+ void setName(const QString& obj,const QString& iconname);
+ void setIcon(const QString& obj,const QString& name);
+ void setToolTip(const QString& obj, const QString& name);
+
+ /*Gets Name and Tool Tip for object*/
+ QString getName(const QString& obj);
+ QString getToolTip(const QString& obj);
+ /*remove object*/
+ void removeObject(const QString& obj);
+ /*remove child*/
+ void removeChild(const QString& obj);
+ /*return list of child objets*/
+ QStringList getChildren(const QString& obj, const bool rec);
+
+
+public slots:
+ virtual bool activateModule( SUIT_Study* );
+ virtual bool deactivateModule( SUIT_Study* );
+ void preferenceChanged( const QString&,
+ const QString&,
+ const QString& );
+ void onGUIEvent();
+
+ void onActiveViewChanged( SUIT_ViewWindow* );
+ void onViewClosed( SUIT_ViewWindow* );
+ void onViewCloned( SUIT_ViewWindow* );
+
+protected:
+ /* create data model */
+ virtual CAM_DataModel* createDataModel();
+
+private:
+ void init( CAM_Application* );
+ void activate( SUIT_Study* );
+ void deactivate( SUIT_Study* );
+ bool lastActivationStatus() const;
+ void customize( SUIT_Study* );
+ void studyChanged( SUIT_Study* );
+ void contextMenu( const QString&, QMenu* );
+ void guiEvent( const int );
+ void initPreferences();
+ void prefChanged( const QString&, const QString& );
+
+ virtual void initInterp ( int );
+ void importModule();
+ void setWorkSpace();
+
+ void activeViewChanged( const SUIT_ViewWindow* );
+ void viewClosed( const SUIT_ViewWindow* );
+ void viewCloned( const SUIT_ViewWindow* );
+ void connectView( const SUIT_ViewWindow* );
+
+ void saveEvent(QStringList& theListOfFiles);
+ void openEvent(QStringList theListOfFiles, bool& opened);
+
+ SALOME_PYQT_DataObjectLight* findObject(const QString& entry);
+
+ friend class XmlHandler;
+};
+
+#endif // SALOME_PYQT_MODULELIGHT_H
--- /dev/null
+
+#include "SALOME_PYQT_PyInterp.h" // this include must be first !!
+
+#include <SUITApp_init_python.hxx>
+#include <PyInterp_Interp.h>
+#include <utilities.h>
+
+#ifndef GUI_DISABLE_CORBA
+#include <Container_init_python.hxx>
+#endif
+
+
+
+
+/*!
+ * constructor : the main SALOME Python interpreter is used for PyQt GUI.
+ * calls initialize method defined in base class, which calls virtual methods
+ * initstate & initcontext redefined here
+ */
+SALOME_PYQT_PyInterp::SALOME_PYQT_PyInterp(): PyInterp_Interp()
+{
+}
+
+SALOME_PYQT_PyInterp::~SALOME_PYQT_PyInterp()
+{
+}
+
+void SALOME_PYQT_PyInterp::initPython()
+{
+ /*
+ * Do nothing
+ * The initialization has been done in main
+ */
+ MESSAGE("SALOME_PYQT_PyInterp::initPython");
+#ifndef GUI_DISABLE_CORBA
+ if(SUIT_PYTHON::initialized) {
+ ASSERT(SUIT_PYTHON::_gtstate); // initialisation in main
+ SCRUTE(SUIT_PYTHON::_gtstate);
+ _tstate = SUIT_PYTHON::_gtstate;
+ }
+ else {
+ ASSERT(KERNEL_PYTHON::_gtstate); // initialisation in main
+ SCRUTE(KERNEL_PYTHON::_gtstate);
+ _tstate = KERNEL_PYTHON::_gtstate;
+ }
+#else
+ SCRUTE(SUIT_PYTHON::_gtstate);
+ _tstate = SUIT_PYTHON::_gtstate;
+#endif
+}
+
+bool SALOME_PYQT_PyInterp::initState()
+{
+ /*
+ * The GIL is assumed to not be held on the call
+ * The GIL is acquired in initState and will be held on initState exit
+ * It is the caller responsability to release the lock on exit if needed
+ */
+ PyEval_AcquireThread(_tstate);
+ SCRUTE(_tstate);
+ PyEval_ReleaseThread(_tstate);
+ return true;
+}
+
+
+bool SALOME_PYQT_PyInterp::initContext()
+{
+ /*
+ * The GIL is assumed to be held
+ * It is the caller responsability to acquire the GIL before calling initContext
+ * It will still be held on initContext exit
+ */
+ _g = PyDict_New(); // create interpreter dictionnary context
+ PyObject *bimod = PyImport_ImportModule("__builtin__");
+ PyDict_SetItemString(_g, "__builtins__", bimod);
+ Py_DECREF(bimod);
+ return true;
+}
+
+int SALOME_PYQT_PyInterp::run(const char *command)
+{
+ MESSAGE("compile");
+ PyObject *code = Py_CompileString((char *)command,"PyGUI",Py_file_input);
+ if(!code){
+ // Une erreur s est produite en general SyntaxError
+ PyErr_Print();
+ return -1;
+ }
+ //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+ // PyObject *r = PyEval_EvalCode(code,_g,_g);
+ //#else
+ PyObject *r = PyEval_EvalCode((PyCodeObject *)code,_g,_g);
+ //#endif
+ Py_DECREF(code);
+ if(!r){
+ // Une erreur s est produite a l execution
+ PyErr_Print();
+ return -1 ;
+ }
+ Py_DECREF(r);
+ return 0;
+}
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// File : SALOME_PYQT_Module.h
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 13/04/2009
+
+
+#ifndef SALOME_PYQT_PYINTERP_H
+#define SALOME_PYQT_PYINTERP_H
+
+#include "SALOME_PYQT_GUILight.h"
+
+#include "PyInterp_Interp.h" // this include must be first !!!
+
+class SALOME_PYQT_EXPORT SALOME_PYQT_PyInterp : public PyInterp_Interp
+{
+ public:
+ SALOME_PYQT_PyInterp();
+ ~SALOME_PYQT_PyInterp();
+
+ int run(const char *command);
+
+ protected:
+ virtual void initPython();
+ virtual bool initState();
+ virtual bool initContext();
+};
+
+#endif // SALOME_PYQT_PYINTERP_H
MOC_FILES = SalomePyQt_moc.cxx
# compilation flags
-COMMON_CPP_FLAGS = $(QT_INCLUDES) $(QWT_INCLUDES) $(SIP_INCLUDES) $(PYTHON_INCLUDES) \
- $(CAS_CPPFLAGS) $(VTK_INCLUDES) $(OGL_INCLUDES) $(BOOST_CPPFLAGS) \
- -DHAVE_CONFIG_H @KERNEL_CXXFLAGS@ -I$(top_builddir)/salomeadn/unix \
- -I$(srcdir) -I$(top_builddir)/idl \
- -I$(srcdir)/../../SUIT -I$(srcdir)/../../CAM -I$(srcdir)/../../STD \
- -I$(srcdir)/../../Qtx -I$(srcdir)/../../SalomeApp -I$(srcdir)/../../Event \
- -I$(srcdir)/../../SalomeSession -I$(srcdir)/../../LogWindow \
- -I$(srcdir)/../../VTKViewer -I$(srcdir)/../../TOOLSGUI \
- -I$(srcdir)/../../OCCViewer -I$(srcdir)/../../Plot2d \
- -I$(srcdir)/../SALOME_PYQT_GUI -I$(srcdir)/../../PyInterp \
- -I$(srcdir)/../../LightApp -I$(srcdir)/../../ObjBrowser \
- -I$(srcdir)/../../OBJECT \
- -I$(top_builddir)/salome_adm/unix @CORBA_CXXFLAGS@ @CORBA_INCLUDES@
+COMMON_CPP_FLAGS = $(QT_INCLUDES) $(QWT_INCLUDES) $(SIP_INCLUDES) $(PYTHON_INCLUDES) \
+ $(CAS_CPPFLAGS) $(VTK_INCLUDES) $(OGL_INCLUDES) $(BOOST_CPPFLAGS) \
+ -DHAVE_CONFIG_H @KERNEL_CXXFLAGS@ -I$(top_builddir)/salomeadn/unix \
+ -I$(srcdir) -I$(top_builddir)/idl \
+ -I$(srcdir)/../../SUIT -I$(srcdir)/../../CAM -I$(srcdir)/../../STD \
+ -I$(srcdir)/../../Qtx -I$(srcdir)/../../Event \
+ -I$(srcdir)/../../LogWindow \
+ -I$(srcdir)/../../VTKViewer \
+ -I$(srcdir)/../../OCCViewer -I$(srcdir)/../../Plot2d \
+ -I$(srcdir)/../SALOME_PYQT_GUILight -I$(srcdir)/../../PyInterp \
+ -I$(srcdir)/../../LightApp -I$(srcdir)/../../ObjBrowser \
+ -I$(srcdir)/../../OBJECT
# linkage flags
-COMMON_LIBS = $(PYTHON_LIBS) $(SIP_LIBS) $(PYQT_LIBS) $(VTK_LIBS) $(QWT_LIBS) \
- $(OGL_LIBS) ../../SUIT/libsuit.la ../../CAM/libCAM.la ../../STD/libstd.la \
- ../../Qtx/libqtx.la ../../SalomeApp/libSalomeApp.la ../../Event/libEvent.la \
- ../../Session/libSalomeSession.la ../../LogWindow/libLogWindow.la \
- ../../VTKViewer/libVTKViewer.la ../../TOOLSGUI/libToolsGUI.la \
- ../SALOME_PYQT_GUI/libSalomePyQtGUI.la ../../OCCViewer/libOCCViewer.la \
+COMMON_LIBS = $(PYTHON_LIBS) $(SIP_LIBS) $(PYQT_LIBS) $(VTK_LIBS) $(QWT_LIBS) \
+ $(OGL_LIBS) ../../SUIT/libsuit.la ../../CAM/libCAM.la ../../STD/libstd.la \
+ ../../Qtx/libqtx.la ../../Event/libEvent.la \
+ ../../LogWindow/libLogWindow.la \
+ ../../VTKViewer/libVTKViewer.la \
+ ../SALOME_PYQT_GUILight/libSalomePyQtGUILight.la ../../OCCViewer/libOCCViewer.la \
../../Plot2d/libPlot2d.la
# libraries targets
// File : SalomePyQt.cxx
// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
//
-#include <SALOME_PYQT_Module.h> // this include must be first!!!
+#include <SALOME_PYQT_ModuleLight.h> // this include must be first!!!
#include "SalomePyQt.h"
#include <QApplication>
#include <SUIT_ViewManager.h>
#include <SUIT_ViewWindow.h>
#include <STD_TabDesktop.h>
-#include <SalomeApp_Application.h>
-#include <SalomeApp_Study.h>
+#include <LightApp_Application.h>
+#include <LightApp_Study.h>
#include <LightApp_SelectionMgr.h>
#include <LogWindow.h>
#include <OCCViewer_ViewWindow.h>
\internal
\return active application object or 0 if there is no any
*/
-static SalomeApp_Application* getApplication()
+static LightApp_Application* getApplication()
{
if ( SUIT_Session::session() )
- return dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+ return dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
return 0;
}
\internal
\return active study or 0 if there is no study opened
*/
-static SalomeApp_Study* getActiveStudy()
+static LightApp_Study* getActiveStudy()
{
if ( getApplication() )
- return dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
+ return dynamic_cast<LightApp_Study*>( getApplication()->activeStudy() );
return 0;
}
This function returns correct result only if Python-based
module is currently active. Otherwize, 0 is returned.
*/
-static SALOME_PYQT_Module* getActiveModule()
+static SALOME_PYQT_ModuleLight* getActiveModule()
{
- SALOME_PYQT_Module* module = 0;
- if ( SalomeApp_Application* anApp = getApplication() ) {
- module = SALOME_PYQT_Module::getInitModule();
+ SALOME_PYQT_ModuleLight* module = 0;
+ if ( LightApp_Application* anApp = getApplication() ) {
+ module = SALOME_PYQT_ModuleLight::getInitModule();
if ( !module )
- module = dynamic_cast<SALOME_PYQT_Module*>( anApp->activeModule() );
+ module = dynamic_cast<SALOME_PYQT_ModuleLight*>( anApp->activeModule() );
}
return module;
}
\brief Map of created selection objects.
\internal
*/
-static QMap<SalomeApp_Application*, SALOME_Selection*> SelMap;
+static QMap<LightApp_Application*, SALOME_Selection*> SelMap;
/*!
\brief Get the selection object for the specified application.
\param app application object
\return selection object or 0 if \a app is invalid
*/
-SALOME_Selection* SALOME_Selection::GetSelection( SalomeApp_Application* app )
+SALOME_Selection* SALOME_Selection::GetSelection( LightApp_Application* app )
{
SALOME_Selection* sel = 0;
if ( app && SelMap.find( app ) != SelMap.end() )
*/
SALOME_Selection::SALOME_Selection( QObject* p ) : QObject( 0 ), mySelMgr( 0 )
{
- SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>( p );
+ LightApp_Application* app = dynamic_cast<LightApp_Application*>( p );
if ( app ) {
mySelMgr = app->selectionMgr();
connect( mySelMgr, SIGNAL( selectionChanged() ), this, SIGNAL( currentSelectionChanged() ) );
*/
SALOME_Selection::~SALOME_Selection()
{
- SalomeApp_Application* app = 0;
- QMap<SalomeApp_Application*, SALOME_Selection*>::Iterator it;
+ LightApp_Application* app = 0;
+ QMap<LightApp_Application*, SALOME_Selection*>::Iterator it;
for ( it = SelMap.begin(); it != SelMap.end() && !app; ++it ) {
if ( it.value() == this ) app = it.key();
}
TGetMainMenuBarEvent() : myResult( 0 ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
myResult = anApp->desktop()->menuBar();
}
}
TGetPopupMenuEvent( const QString& menu ) : myResult( 0 ), myMenuName( menu ) {}
virtual void Execute()
{
- SalomeApp_Application* anApp = getApplication();
+ LightApp_Application* anApp = getApplication();
if ( anApp && !myMenuName.isEmpty() ) {
QtxActionMenuMgr* mgr = anApp->desktop()->menuMgr();
myResult = mgr->findMenu( myMenuName, -1, false ); // search only top menu
TGetStudyIdEvent() : myResult( 0 ) {}
virtual void Execute()
{
- if ( SalomeApp_Study* aStudy = getActiveStudy() ) {
- myResult = aStudy->studyDS()->StudyId();
+ if ( LightApp_Study* aStudy = getActiveStudy() ) {
+ myResult = aStudy->id();
}
}
};
TPutInfoEvent( const QString& msg, const int sec = 0 ) : myMsg( msg ), mySecs( sec ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
anApp->putInfo( myMsg, mySecs * 1000 );
}
}
TGetActiveComponentEvent() {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
if ( CAM_Module* mod = anApp->activeModule() ) {
myResult = mod->name();
}
QList<SUIT_Application*> apps = SUIT_Session::session()->applications();
QList<SUIT_Application*>::Iterator it;
for( it = apps.begin(); it != apps.end(); ++it ) {
- SalomeApp_Application* anApp = dynamic_cast<SalomeApp_Application*>( *it );
+ LightApp_Application* anApp = dynamic_cast<LightApp_Application*>( *it );
if ( anApp && anApp->activeStudy() && anApp->activeStudy()->id() == myStudyId ) {
anApp->updateObjectBrowser();
return;
myOpen ( open ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
myResult = anApp->getFileName( myOpen, myInitial, myFilters.join(";;"),
myCaption, myParent );
}
myCaption( caption ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
myResult = anApp->getOpenFileNames( myInitial, myFilters.join(";;"), myCaption, myParent );
}
}
myCaption( caption ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
myResult = anApp->getDirectory( myInitial, myCaption, myParent );
}
}
: mySource( source ), myContext( context ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
anApp->onHelpContextModule( "", mySource, myContext );
}
}
: myResult ( false ), myFileName( filename ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
SUIT_ViewManager* vm = anApp->activeViewManager();
if ( vm ) {
SUIT_ViewWindow* vw = vm->getActiveView();
TDefMenuGroupEvent() : myResult( -1 ) {}
virtual void Execute()
{
- myResult = SALOME_PYQT_Module::defaultMenuGroup();
+ myResult = SALOME_PYQT_ModuleLight::defaultMenuGroup();
}
};
int SalomePyQt::defaultMenuGroup()
CrTool( QAction* action, const QString& tBar, const int id, const int idx )
: myCase( 4 ), myAction( action ), myTbName( tBar ), myId( id ), myIndex( idx ) {}
- int execute( SALOME_PYQT_Module* module ) const
+ int execute( SALOME_PYQT_ModuleLight* module ) const
{
if ( module ) {
switch ( myCase ) {
: myResult( -1 ), myCrTool( crTool ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module )
myResult = myCrTool.execute( module );
}
CrMenu( QAction* action, const QString& menu, const int id, const int group, const int idx )
: myCase( 5 ), myAction( action ), myMenuName( menu ), myId( id ), myGroup( group ), myIndex( idx ) {}
- int execute( SALOME_PYQT_Module* module ) const
+ int execute( SALOME_PYQT_ModuleLight* module ) const
{
if ( module ) {
switch ( myCase ) {
: myResult( -1 ), myCrMenu( crMenu ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module )
myResult = myCrMenu.execute( module );
}
: myResult( 0 ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module )
myResult = (QAction*)module->separator();
}
myStatusText( statusText ), myIcon( icon ), myKey( key ), myToggle( toggle ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module )
myResult = (QAction*)module->createAction( myId, myTipText, myIcon, myMenuText, myStatusText, myKey, myToggle );
}
: myId( id ), myExclusive( exclusive ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module )
myResult = module->createActionGroup( myId, myExclusive );
}
: myResult( 0 ), myId( id ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module )
myResult = (QAction*)module->action( myId );
}
: myResult( -1 ), myAction( action ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module )
myResult = module->actionId( myAction );
}
: myResult( -1 ), myLabel( label ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module )
myResult = module->addGlobalPreference( myLabel );
}
: myResult( -1 ), myLabel( label ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module )
myResult = module->addPreference( myLabel );
}
mySection( section ), myParam ( param ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module )
myResult = module->addPreference( myLabel, myPId, myType, mySection, myParam );
}
: myId( id ), myProp( prop ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module )
myResult = module->preferenceProperty( myId, myProp );
}
: myId( id ), myProp( prop ), myVar( var ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module )
module->setPreferenceProperty( myId, myProp, myVar );
}
: myId( id ), myProp( prop ), myIdx( idx), myVar( var ) {}
virtual void Execute()
{
- SALOME_PYQT_Module* module = getActiveModule();
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
if ( module ) {
QVariant var = module->preferenceProperty( myId, myProp );
if ( var.isValid() ) {
: myMsg( msg ), myAddSep( addSeparator ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
LogWindow* lw = anApp->logWindow();
if ( lw )
lw->putMessage( myMsg, myAddSep );
TEvent() {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
LogWindow* lw = anApp->logWindow();
if ( lw )
lw->clear();
{
SUIT_ViewWindow* resWnd = 0;
- SalomeApp_Application* app = getApplication();
+ LightApp_Application* app = getApplication();
if ( app )
{
STD_TabDesktop* tabDesk = dynamic_cast<STD_TabDesktop*>( app->desktop() );
virtual void Execute()
{
myResult.clear();
- SalomeApp_Application* app = getApplication();
+ LightApp_Application* app = getApplication();
if ( app )
{
STD_TabDesktop* tabDesk = dynamic_cast<STD_TabDesktop*>( app->desktop() );
: myResult( -1 ) {}
virtual void Execute()
{
- SalomeApp_Application* app = getApplication();
+ LightApp_Application* app = getApplication();
if ( app )
{
SUIT_ViewManager* viewMgr = app->activeViewManager();
virtual void Execute()
{
myResult.clear();
- SalomeApp_Application* app = getApplication();
+ LightApp_Application* app = getApplication();
if ( app )
{
ViewManagerList vmList;
myType( theType ) {}
virtual void Execute()
{
- SalomeApp_Application* app = getApplication();
+ LightApp_Application* app = getApplication();
if ( app )
{
SUIT_ViewManager* viewMgr = app->createViewManager( myType );
: myResult( false ) {}
virtual void Execute()
{
- SalomeApp_Application* app = getApplication();
+ LightApp_Application* app = getApplication();
if ( app )
{
STD_TabDesktop* tabDesk = dynamic_cast<STD_TabDesktop*>( app->desktop() );
{
return ProcessEvent( new TNeighbourViews( id ) );
}
+
+
+/*!
+ SalomePyQt::createObject(parent)
+ Create empty data object
+*/
+class TCreateEmptyObjectEvent: public SALOME_Event {
+public:
+ typedef QString TResult;
+ TResult myResult;
+ QString myParent;
+ TCreateEmptyObjectEvent(const QString& parent) : myParent( parent ) {}
+ virtual void Execute() {
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
+ if ( module )
+ myResult = (QString)module->createObject(myParent);
+ }
+};
+QString SalomePyQt::createObject(const QString& parent)
+{
+ return ProcessEvent( new TCreateEmptyObjectEvent(parent) );
+}
+
+/*!
+ SalomePyQt::createObject( name, icon, tooltip, parent )
+ Create data object with name, icon and tooltip
+*/
+class TCreateObjectEvent: public SALOME_Event {
+public:
+ typedef QString TResult;
+ TResult myResult;
+ QString myParent;
+ QString myName;
+ QString myIconName;
+ QString myToolTip;
+ TCreateObjectEvent(const QString& name,
+ const QString& iconname,
+ const QString& tooltip,
+ const QString& parent) : myName(name),
+ myIconName(iconname),
+ myToolTip(tooltip),
+ myParent( parent ){}
+ virtual void Execute() {
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
+ if ( module )
+ myResult = (QString)module->createObject(myName, myIconName,
+ myToolTip, myParent);
+ }
+};
+QString SalomePyQt::createObject(const QString& name,
+ const QString& iconname,
+ const QString& tooltip,
+ const QString& parent)
+{
+ return ProcessEvent( new TCreateObjectEvent(name, iconname, tooltip, parent) );
+}
+
+
+/*!
+ SalomePyQt::setName(obj,name)
+ Set object name
+*/
+class TSetNameEvent: public SALOME_Event
+{
+public:
+ QString myObj;
+ QString myName;
+ TSetNameEvent( const QString& obj,
+ const QString& name) : myObj(obj),
+ myName(name) {}
+ virtual void Execute() {
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
+ if ( module )
+ module->setName(myObj,myName);
+ }
+};
+void SalomePyQt::setName(const QString& obj,const QString& name)
+{
+ ProcessVoidEvent(new TSetNameEvent(obj,name));
+}
+
+
+/*!
+ SalomePyQt::setIcon(obj,icon)
+ Set object icon
+*/
+class TSetIconEvent: public SALOME_Event
+{
+public:
+ QString myObj;
+ QString myIconName;
+ TSetIconEvent( const QString& obj,
+ const QString& iconname) : myObj(obj),
+ myIconName(iconname) {}
+ virtual void Execute() {
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
+ if ( module )
+ module->setIcon(myObj,myIconName);
+ }
+};
+
+void SalomePyQt::setIcon(const QString& obj,const QString& iconname)
+{
+ ProcessVoidEvent(new TSetIconEvent(obj,iconname));
+}
+
+/*!
+ SalomePyQt::setToolTip(obj,tooltip)
+ Set object tool tip
+*/
+class TSetToolTipEvent: public SALOME_Event
+{
+public:
+ QString myObj;
+ QString myToolTip;
+ TSetToolTipEvent( const QString& obj,
+ const QString& tooltip) : myObj(obj),
+ myToolTip(tooltip) {}
+ virtual void Execute() {
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
+ if ( module )
+ module->setToolTip(myObj,myToolTip);
+ }
+};
+void SalomePyQt::setToolTip(const QString& obj,const QString& tooltip)
+{
+ ProcessVoidEvent(new TSetToolTipEvent(obj,tooltip));
+}
+
+/*!
+ SalomePyQt::getName(obj)
+ Return name of object
+*/
+class TGetNameEvent: public SALOME_Event
+{
+public:
+ typedef QString TResult;
+ TResult myResult;
+ QString myObj;
+ TGetNameEvent( const QString& obj ) : myObj(obj) {}
+ virtual void Execute() {
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
+ if ( module )
+ myResult = (QString) module->getName(myObj);
+ }
+};
+
+QString SalomePyQt::getName(const QString& obj)
+{
+ return ProcessEvent(new TGetNameEvent(obj));
+}
+
+/*!
+ SalomePyQt::getToolTip(obj)
+ Return tool tip of object
+*/
+class TGetToolTipEvent: public SALOME_Event
+{
+public:
+ typedef QString TResult;
+ TResult myResult;
+ QString myObj;
+ TGetToolTipEvent( const QString& obj ) : myObj(obj) {}
+ virtual void Execute() {
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
+ if ( module )
+ myResult = (QString)module->getToolTip(myObj);
+ }
+};
+QString SalomePyQt::getToolTip(const QString& obj)
+{
+ return ProcessEvent(new TGetToolTipEvent(obj));
+}
+
+
+/*!
+ SalomePyQt::removeChild(obj)
+ Remove childrens from object
+*/
+class TRemoveChildEvent: public SALOME_Event
+{
+public:
+ QString myObj;
+ TRemoveChildEvent(const QString& obj) : myObj(obj) {}
+
+ virtual void Execute() {
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
+ if ( module )
+ module->removeChild(myObj);
+ }
+};
+void SalomePyQt::removeChild(const QString& obj)
+{
+ ProcessVoidEvent(new TRemoveChildEvent(obj));
+}
+
+
+/*!
+ SalomePyQt::removeObject(obj)
+ Remove object
+*/
+class TRemoveObjectEvent: public SALOME_Event
+{
+public:
+ QString myObj;
+
+ TRemoveObjectEvent( const QString& obj) : myObj(obj) {}
+ virtual void Execute() {
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
+ if ( module )
+ module->removeObject(myObj);
+ }
+};
+void SalomePyQt::removeObject(const QString& obj)
+{
+ ProcessVoidEvent(new TRemoveObjectEvent(obj));
+}
+
+/*!
+ SalomePyQt::getChildren(obj)
+ Return the list of the child objects
+ if rec == true then function get all sub children.
+*/
+
+class TGetChildrenEvent: public SALOME_Event
+{
+public:
+ typedef QStringList TResult;
+ TResult myResult;
+ QString myObj;
+ bool myRec;
+ TGetChildrenEvent(const QString& obj, const bool rec) : myObj(obj),
+ myRec(rec) {}
+ virtual void Execute() {
+ SALOME_PYQT_ModuleLight* module = getActiveModule();
+ if ( module )
+ myResult = (QStringList)module->getChildren(myObj,myRec);
+ }
+};
+QStringList SalomePyQt::getChildren(const QString& obj, const bool rec)
+{
+ return ProcessEvent( new TGetChildrenEvent(obj,rec) );
+}
#include <LightApp_Preferences.h>
class LightApp_SelectionMgr;
-class SalomeApp_Application;
+class LightApp_Application;
class QMenuBar;
class QMenu;
class QWidget;
public:
~SALOME_Selection();
- static SALOME_Selection* GetSelection( SalomeApp_Application* );
+ static SALOME_Selection* GetSelection( LightApp_Application* );
void Clear();
void ClearIObjects();
static QStringList getOpenFileNames ( QWidget*, const QString&, const QStringList&, const QString& );
static QString getExistingDirectory( QWidget*, const QString&, const QString& );
+ static QString createObject(const QString& parent = QString(""));
+ static QString createObject(const QString& name,
+ const QString& iconname,
+ const QString& tooltip,
+ const QString& parent = QString(""));
+
+ static void removeObject( const QString& obj);
+ static void removeChild( const QString& obj = QString(""));
+ static QStringList getChildren(const QString& obj = QString(""), const bool rec = false);
+ static void setName(const QString& obj,const QString& name);
+ static void setIcon(const QString& obj,const QString& iconname);
+ static void setToolTip(const QString& obj,const QString& tooltip);
+ static QString getName(const QString& obj);
+ static QString getToolTip(const QString& obj);
+
static void helpContext( const QString&, const QString& );
static bool dumpView( const QString& );
static QString getFileName ( QWidget*, const QString&, const QStringList&, const QString&, bool ) /ReleaseGIL/ ;
static QStringList getOpenFileNames ( QWidget*, const QString&, const QStringList&, const QString& ) /ReleaseGIL/ ;
- static QString getExistingDirectory( QWidget*, const QString&, const QString& ) /ReleaseGIL/ ;
+ static QString getExistingDirectory( QWidget*, const
+ QString&, const QString& ) /ReleaseGIL/ ;
+
+
+
+ static QString createObject( const QString& = QString("") ) /ReleaseGIL/ ;
+ static QString createObject( const QString&,
+ const QString&,
+ const QString&,
+ const QString& = QString("") ) /ReleaseGIL/ ;
+
+ static void setName(const QString& ,const QString& ) /ReleaseGIL/ ;
+ static void setIcon(const QString& ,const QString& ) /ReleaseGIL/ ;
+ static void setToolTip(const QString& ,const QString& ) /ReleaseGIL/ ;
+ static QString getName(const QString& ) /ReleaseGIL/ ;
+ static QString getToolTip(const QString& ) /ReleaseGIL/ ;
+
+ static void removeObject(const QString& ) /ReleaseGIL/ ;
+ static void removeChild(const QString& = QString("") ) /ReleaseGIL/ ;
+ static QStringList getChildren(const QString&=QString("") , const bool = false) /ReleaseGIL/ ;
static void helpContext( const QString&, const QString& ) /ReleaseGIL/ ;
$(QT_INCLUDES) $(QWT_INCLUDES) $(PYTHON_INCLUDES) $(CAS_CPPFLAGS) $(VTK_INCLUDES) \
$(OGL_INCLUDES) $(BOOST_CPPFLAGS) -DHAVE_CONFIG_H @KERNEL_CXXFLAGS@ \
-I$(top_builddir)/salome_adm/unix -I$(top_builddir)/idl -I$(srcdir) \
- -I$(srcdir)/../SalomeApp -I$(srcdir)/../Qtx -I$(srcdir)/../SUIT \
+ -I$(srcdir)/../LightApp -I$(srcdir)/../Qtx -I$(srcdir)/../SUIT \
-I$(srcdir)/../ObjBrowser -I$(srcdir)/../LightApp -I$(srcdir)/../SOCC \
-I$(srcdir)/../SVTK -I$(srcdir)/../Event -I$(srcdir)/../OBJECT \
-I$(srcdir)/../CAM -I$(srcdir)/../STD -I$(srcdir)/../OCCViewer \
-I$(srcdir)/../Prs -I$(srcdir)/../VTKViewer -I$(srcdir)/../SPlot2d \
- -I$(srcdir)/../Plot2d \
- @CORBA_CXXFLAGS@ @CORBA_INCLUDES@
+ -I$(srcdir)/../Plot2d
_libSALOME_Swig_la_LDFLAGS = -module
_libSALOME_Swig_la_LIBADD = \
- ../SalomeApp/libSalomeApp.la \
+ ../LightApp/libLightApp.la \
@PYTHON_LIBS@
swig_wrap.cpp : $(SWIG_SOURCES)
#include <SUIT_ViewManager.h>
#include <SUIT_DataObjectIterator.h>
#include <CAM_DataModel.h>
-#include <SalomeApp_Application.h>
-#include <SalomeApp_Study.h>
-#include <SalomeApp_Module.h>
-#include <SalomeApp_DataObject.h>
+#include <LightApp_Application.h>
+#include <LightApp_Study.h>
+#include <LightApp_Module.h>
+#include <LightApp_DataObject.h>
#include <LightApp_SelectionMgr.h>
#include <LightApp_DataOwner.h>
#include <SALOME_Prs.h>
\internal
\return active application or 0 if there is no any
*/
-static SalomeApp_Application* getApplication()
+static LightApp_Application* getApplication()
{
if ( SUIT_Session::session() )
- return dynamic_cast<SalomeApp_Application*>( SUIT_Session::session()->activeApplication() );
+ return dynamic_cast<LightApp_Application*>( SUIT_Session::session()->activeApplication() );
return 0;
}
\internal
\return active study or 0 if there is no study opened
*/
-static SalomeApp_Study* getActiveStudy()
+static LightApp_Study* getActiveStudy()
{
if ( getApplication() )
- return dynamic_cast<SalomeApp_Study*>( getApplication()->activeStudy() );
+ return dynamic_cast<LightApp_Study*>( getApplication()->activeStudy() );
return 0;
}
TEvent() {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
anApp->updateObjectBrowser();
anApp->updateActions(); //SRN: added in order to update the toolbar
}
TGetActiveStudyIdEvent() : myResult( 0 ) {}
virtual void Execute()
{
- if ( SalomeApp_Study* aStudy = getActiveStudy() ) {
- myResult = aStudy->studyDS()->StudyId();
+ if ( LightApp_Study* aStudy = getActiveStudy() ) {
+ myResult = aStudy->id();
}
}
};
TGetActiveStudyNameEvent() {}
virtual void Execute()
{
- if ( SalomeApp_Study* aStudy = getActiveStudy() ) {
- myResult = aStudy->studyDS()->Name();
+ if ( LightApp_Study* aStudy = getActiveStudy() ) {
+ myResult = aStudy->id();
}
}
};
: myName( name ), myIsUserName( isUserName ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* app = getApplication() ) {
+ if ( LightApp_Application* app = getApplication() ) {
myResult = myIsUserName ? app->moduleTitle( myName ) : app->moduleName( myName );
}
}
TGetSelectedEvent() {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
- SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
+ if ( LightApp_Application* anApp = getApplication() ) {
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
if ( aStudy && aSelMgr ) {
SUIT_DataOwnerPtrList aList;
TEvent( const char* theEntry ) : myEntry( theEntry ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
- SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
+ if ( LightApp_Application* anApp = getApplication() ) {
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
if ( aStudy && aSelMgr ) {
SALOME_ListIO anIOList;
TEvent( const char* theEntry ) : myEntry( theEntry ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
- SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
+ if ( LightApp_Application* anApp = getApplication() ) {
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
if ( aStudy && aSelMgr ) {
SALOME_ListIO anIOList;
TEvent() {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
- SalomeApp_Study* aStudy = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
+ if ( LightApp_Application* anApp = getApplication() ) {
+ LightApp_Study* aStudy = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
LightApp_SelectionMgr* aSelMgr = anApp->selectionMgr();
if ( aStudy && aSelMgr )
aSelMgr->clearSelected();
public:
TEvent( const char* theEntry ) : myEntry( theEntry ) {}
virtual void Execute() {
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
if ( window ) {
SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
TEvent( const char* theEntry ) : myEntry( theEntry ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
if ( window ) {
SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
TEvent( const char* theEntry ) : myEntry( theEntry ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
if ( window ) {
SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
TEvent() {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
- SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( anApp->activeStudy() ); // for sure!
+ if ( LightApp_Application* anApp = getApplication() ) {
+ LightApp_Study* study = dynamic_cast<LightApp_Study*>( anApp->activeStudy() ); // for sure!
SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
- SalomeApp_Module* activeModule = dynamic_cast<SalomeApp_Module*>( anApp->activeModule() );
+ LightApp_Module* activeModule = dynamic_cast<LightApp_Module*>( anApp->activeModule() );
if ( study && window && activeModule ) {
SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
if ( view ) {
for ( SUIT_DataObjectIterator it( activeModule->dataModel()->root(), SUIT_DataObjectIterator::DepthLeft ); it.current(); ++it ) {
- SalomeApp_DataObject* obj = dynamic_cast<SalomeApp_DataObject*>( it.current() );
+ LightApp_DataObject* obj = dynamic_cast<LightApp_DataObject*>( it.current() );
if ( obj && !obj->entry().isEmpty() )
view->Display( view->CreatePrs( obj->entry().toLatin1() ) );
}
TEvent() {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
if ( window ) {
SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
TIsInViewerEvent( const char* theEntry ) : myEntry( theEntry ), myResult( false ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
if ( window ) {
SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
TEvent() {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
if ( window ) {
SALOME_View* view = dynamic_cast<SALOME_View*>( window->getViewManager()->getViewModel() );
TEvent() {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
if ( window ) {
if ( dynamic_cast<SVTK_ViewWindow*>( window ) )
TEvent() {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
if ( window ) {
if ( dynamic_cast<SVTK_ViewWindow*>( window ) )
TEvent( int view ) : myView( view ) {}
virtual void Execute()
{
- if ( SalomeApp_Application* anApp = getApplication() ) {
+ if ( LightApp_Application* anApp = getApplication() ) {
SUIT_ViewWindow* window = anApp->desktop()->activeWindow();
if ( window ) {
if ( dynamic_cast<SVTK_ViewWindow*>( window ) ) {
"""
-import SALOME_Session_idl
+try:
+ import SALOME_Session_idl
+except:
+ pass
from import_hook import register_name
register_name("SalomePyQt")
lib_LTLIBRARIES = libSUITApp.la
salomeinclude_HEADERS = \
- SUITApp_Application.h
+ SUITApp_Application.h \
+ SUITApp_init_python.hxx
dist_libSUITApp_la_SOURCES = \
SUITApp.cxx \
- SUITApp_Application.cxx
+ SUITApp_Application.cxx \
+ SUITApp_init_python.cxx
MOC_FILES = \
SUITApp_Application_moc.cxx
if ENABLE_PYCONSOLE
libSUITApp_la_LDFLAGS += -Xlinker -export-dynamic $(PYTHON_LIBS)
+CPPFLAGS+=-DSUIT_ENABLE_PYTHON
endif
# Executable
#include <Python.h>
#endif
+#ifdef SUIT_ENABLE_PYTHON
+#include <SUITApp_init_python.hxx>
+#endif
+
#endif //#if defined WIN32
#include "SUITApp_Application.h"
int main( int argc, char* argv[] )
{
-#ifdef SUIT_ENABLE_PYTHON
- // First of all initialize Python, as in complex multi-component applications
- // someone else might initialize it some way unsuitable for light SALOME!
- Py_SetProgramName( argv[0] );
- Py_Initialize(); // Initialize the interpreter
- PySys_SetArgv( argc, argv );
- PyEval_InitThreads(); // Create (and acquire) the interpreter lock
- PyEval_ReleaseLock(); // Let the others use Python API until we need it again
-#endif
+ //#ifdef SUIT_ENABLE_PYTHON
+ // // First of all initialize Python, as in complex multi-component applications
+ // // someone else might initialize it some way unsuitable for light SALOME!
+ // Py_SetProgramName( argv[0] );
+ // Py_Initialize(); // Initialize the interpreter
+ // PySys_SetArgv( argc, argv );
+ // PyEval_InitThreads(); // Create (and acquire) the interpreter lock
+ // PyEval_ReleaseLock(); // Let the others use Python API until we need it again
+ //#endif
//qInstallMsgHandler( MessageOutput );
}
}
+#ifdef SUIT_ENABLE_PYTHON
+ //...Initialize python
+ int _argc = 1;
+ char* _argv[] = {""};
+ SUIT_PYTHON::init_python(_argc,_argv);
+
+ PyEval_RestoreThread( SUIT_PYTHON::_gtstate );
+
+ if ( !SUIT_PYTHON::salome_shared_modules_module ) // import only once
+ SUIT_PYTHON::salome_shared_modules_module = PyImport_ImportModule( "salome_shared_modules" );
+ if ( !SUIT_PYTHON::salome_shared_modules_module )
+ PyErr_Print();
+
+ PyEval_ReleaseThread( SUIT_PYTHON::_gtstate );
+
+#endif
+
SUIT_Application* theApp = aSession->startApplication( argList.first() );
if ( theApp )
{
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 22/06/2007
+
+
+#include "SUITApp_init_python.hxx"
+
+
+PyThreadState* SUIT_PYTHON::_gtstate = NULL;
+PyObject *SUIT_PYTHON::salome_shared_modules_module = NULL;
+PyInterpreterState* SUIT_PYTHON::_interp = NULL;
+bool SUIT_PYTHON::initialized = false;
+
+void SUIT_PYTHON::init_python(int argc, char **argv)
+{
+ if (Py_IsInitialized())
+ {
+ return;
+ }
+ Py_SetProgramName(argv[0]);
+ Py_Initialize(); // Initialize the interpreter
+ PySys_SetArgv(argc, argv);
+ SUIT_PYTHON::_interp = PyThreadState_Get()->interp;
+ PyEval_InitThreads(); // Create (and acquire) the interpreter lock
+ SUIT_PYTHON::_gtstate = PyEval_SaveThread(); // Release global thread state
+ SUIT_PYTHON::initialized = true;
+}
+
--- /dev/null
+// Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
+//
+// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+// Author : Roman NIKOLAEV, Open CASCADE S.A.S. (roman.nikolaev@opencascade.com)
+// Date : 22/06/2007
+
+
+#ifndef _SUITAPP_INIT_PYTHON_
+#define _SUITAPP_INIT_PYTHON_
+
+#include <pthread.h>
+#include <Python.h>
+
+struct SUIT_PYTHON
+{
+ static PyThreadState *_gtstate;
+ static PyInterpreterState *_interp;
+ static PyObject *salome_shared_modules_module;
+ static bool initialized;
+ static void init_python(int argc, char **argv);
+
+};
+
+#endif // _SUITAPP_INIT_PYTHON_
/*!
* \brief Base class for all salome modules
*/
-class SALOMEAPP_EXPORT SalomeApp_Module : public LightApp_Module
+class SALOMEAPP_EXPORT SalomeApp_Module : virtual public LightApp_Module
{
Q_OBJECT