Salome HOME
Add Python wrappings for Python console.
authorvsr <vsr@opencascade.com>
Fri, 7 Oct 2016 12:25:37 +0000 (15:25 +0300)
committervsr <vsr@opencascade.com>
Tue, 11 Oct 2016 14:41:16 +0000 (17:41 +0300)
12 files changed:
src/LightApp/LightApp_PyEditor.cxx
src/SalomeApp/SalomeApp_PyInterp.cxx
src/SalomeApp/SalomeApp_PyInterp.h
tools/PyConsole/CMakeLists.txt
tools/PyConsole/src/CMakeLists.txt
tools/PyConsole/src/PyConsole_Console.cxx
tools/PyConsole/src/PyConsole_Console.h
tools/PyConsole/src/PyConsole_Editor.cxx
tools/PyConsole/src/PyConsole_Editor.h
tools/PyConsole/src/python/CMakeLists.txt [new file with mode: 0644]
tools/PyConsole/src/python/PyConsolePy.sip [new file with mode: 0644]
tools/PyInterp/src/PyInterp_Interp.cxx

index 7d71b8de090e5edf8286e1cdeab481585f109222..d2072b3dcda77ba8b48acc124221d5a5c6672473 100644 (file)
@@ -29,7 +29,7 @@
   \param parent parent widget
 */
 LightApp_PyEditor::LightApp_PyEditor( PyConsole_Interp* interp, QWidget* parent )
-  : PyConsole_Editor( interp, parent )
+  : PyConsole_Editor( parent, interp )
 {
 }
 
index e79c8361320ee59144b9e24e8b788871890e92c7..0ab36f99a65cec79f76a09e3e9f14a0e24f73afb 100755 (executable)
@@ -39,6 +39,23 @@ SalomeApp_PyInterp::~SalomeApp_PyInterp()
 {
 }
  
+/*!
+ * Initialize context dictionaries. GIL is held already.
+ * The code executed in an embedded interpreter is expected to be run at the module
+ * level, in which case local and global context have to be the same dictionary.
+ * See: http://stackoverflow.com/questions/12265756/c-python-running-python-code-within-a-context
+ * for an explanation.
+ */
+bool SalomeApp_PyInterp::initContext()
+{
+  bool ok = PyConsole_Interp::initContext();
+  if ( ok ) {
+    int ret = PyRun_SimpleString( "import salome_iapp; salome_iapp.IN_SALOME_GUI = True" );
+    ok = ok && (ret == 0);
+  }
+  return ok;
+}
+
 /*!
   \brief Called before each Python command running.
 */
index 567b25235af1736ec1c25c16a1837cbe3adb6524..45bbc0178e488b242c2f4cca51623954b1aca364 100755 (executable)
@@ -39,6 +39,7 @@ public:
 
 protected:
   SalomeApp_PyInterp();
+  virtual bool initContext();
   virtual int  beforeRun();
 
 private:
index 30f21888b22d34a22d4475a6c9701393a2d53ad8..57cb1e4ca40ca03adfa97a6f0b7f91097726a2bc 100644 (file)
@@ -45,6 +45,7 @@ INCLUDE(SalomeSetupPlatform)
 # Options
 # =======
 OPTION(PYCONSOLE_BUILD_WITH_QT5 "Build PYCONSOLE with Qt 5" ON)
+OPTION(PYCONSOLE_BUILD_PYTHON "Build Python wrapping for PyConsole" ON)
 
 #
 # Set list of prerequisites
@@ -60,6 +61,20 @@ ELSE()
   FIND_PACKAGE(SalomeQt5 REQUIRED)
 ENDIF()
 
+IF(PYCONSOLE_BUILD_PYTHON)
+  # Sip
+  FIND_PACKAGE(SalomeSIP REQUIRED)  # should come after Python and before PyQt
+  SALOME_LOG_OPTIONAL_PACKAGE(SalomeSIP PYCONSOLE_BUILD_PYTHON)
+  # PyQt
+  IF (NOT PYCONSOLE_BUILD_WITH_QT5)
+    FIND_PACKAGE(SalomePyQt4 REQUIRED)
+    SALOME_LOG_OPTIONAL_PACKAGE(SalomePyQt4 PYCONSOLE_BUILD_PYTHON)
+  ELSE()
+    FIND_PACKAGE(SalomePyQt5 REQUIRED)
+    SALOME_LOG_OPTIONAL_PACKAGE(SalomePyQt5 PYCONSOLE_BUILD_PYTHON)
+  ENDIF()
+ENDIF(PYCONSOLE_BUILD_PYTHON)
+
 # Detection report
 SALOME_PACKAGE_REPORT_AND_CHECK()
 
index 113f808b3111eb882f2c3cc0c3f3faa67774473c..f64ad21cbdc9e4ae98f2283d6070fdc7451afc52 100755 (executable)
 
 INCLUDE(UseQtExt)
 
+IF(PYCONSOLE_BUILD_PYTHON)
+  ADD_SUBDIRECTORY(python)
+ENDIF(PYCONSOLE_BUILD_PYTHON)
+
 # --- options ---
 
 # additional include directories
index 3aaa52ccb12834d64c178bb8050302fb03095dc8..26f8b1cdcde290f2e178642b4d93d7df0ec65d6e 100644 (file)
 
   This will create a console with default editor and interpreter.
 
-  To use custom editor and/or interpreter class with the console, you can use additional parameter
-  of the constructor; in this case you have to ensure that Python interpeter is initialized properly:
+  To use custom editor with the console, you can use alternative constructor:
   \code
-  PyConsole_Interp* interp = new PyConsole_Interp();
-  interp->initialize();
-  PyConsole_Console c(myWindow, new MyEditor(interp));
+  PyConsole_Console c(myWindow, new MyEditor());
   \endcode
 */  
 
+/*!
+  \brief Default constructor.
+
+  Creates new python console widget.
+  \param parent parent widget
+*/
+PyConsole_Console::PyConsole_Console( QWidget* parent )
+: QWidget( parent )
+{
+  init( 0 );
+}
+
 /*!
   \brief Constructor.
 
   Creates new python console widget.
   \param parent parent widget
-  \param interp python interpreter
+  \param editor python editor
 */
 PyConsole_Console::PyConsole_Console( QWidget* parent, PyConsole_Editor* editor )
 : QWidget( parent )
+{
+  init( editor );
+}
+
+/*!
+  \brief Initialize console widget.
+  \param editor python editor
+*/
+void PyConsole_Console::init( PyConsole_Editor* editor )
 {
   // initialize Python interpretator
   PyConsole_Interp* interp = editor ? editor->getInterp() : new PyConsole_Interp();
@@ -70,7 +88,7 @@ PyConsole_Console::PyConsole_Console( QWidget* parent, PyConsole_Editor* editor
   // create editor console
   QVBoxLayout* lay = new QVBoxLayout( this );
   lay->setMargin( 0 );
-  myEditor = editor ? editor : new PyConsole_Editor( interp, this );
+  myEditor = editor ? editor : new PyConsole_Editor( this, interp );
   myEditor->setContextMenuPolicy( Qt::NoContextMenu );
   lay->addWidget( myEditor );
 
index e0b111e53efdb8ab98f2ad4e1953baa644d4ff79..2a2becd3e94f31e7c40503c7b8fd0ae916dd3732 100644 (file)
@@ -54,7 +54,8 @@ public:
   };
 
 public:
-  PyConsole_Console( QWidget* parent, PyConsole_Editor* editor = 0 );
+  PyConsole_Console( QWidget* = 0 );
+  PyConsole_Console( QWidget*, PyConsole_Editor* );
   virtual ~PyConsole_Console();
 
   PyConsole_Interp*   getInterp() const;
@@ -89,6 +90,9 @@ protected:
 
   virtual void        contextMenuEvent( QContextMenuEvent* );
 
+private:
+  void                init( PyConsole_Editor* );
+
 protected:
   PyConsole_Editor*   myEditor;    //!< python console editor widget
   QMap<int, QAction*> myActions;   //!< menu actions list
index e177a03ef3589936ecbae07ea77665c7453fff40..7ec727292b4a936526c2f8e0883212ee54059f88 100644 (file)
@@ -147,26 +147,47 @@ void PyConsole_CallbackStderr( void* data, char* c )
 }
 
 /*!
-  \brief Constructor. 
+  \brief Default constructor. 
   
   Creates python editor window.
-  \param theInterp python interper
   \param theParent parent widget
 */
-PyConsole_Editor::PyConsole_Editor( PyConsole_Interp* theInterp, 
-                                    QWidget*          theParent )
-: QTextEdit( theParent ),
-  myInterp( theInterp ),
-  myCmdInHistory( -1 ),
-  myEventLoop( 0 ),
-  myShowBanner( true ),
-  myIsSync( true ),
-  myIsSuppressOutput( false ),
-  myMultiLinePaste( false ),
-  myAutoCompletion( false ),
-  myTabMode( false ),
-  myComplCursorPos( -1 )
+PyConsole_Editor::PyConsole_Editor( QWidget* parent )
+  : QTextEdit( parent )
+{
+  PyConsole_Interp* interp = new PyConsole_Interp();
+  interp->initialize();
+  init( interp );
+}
+
+/*!
+  \brief Constructor. 
+  
+  Creates python editor window.
+  \param parent parent widget
+  \param interp python interper
+*/
+PyConsole_Editor::PyConsole_Editor( QWidget*          parent,
+                                    PyConsole_Interp* interp )
+  : QTextEdit( parent )
 {
+  init( interp );
+}
+
+
+void PyConsole_Editor::init( PyConsole_Interp* interp )
+{
+  myInterp = interp;
+  myCmdInHistory = -1;
+  myEventLoop = 0;
+  myShowBanner = true;
+  myIsSync = true;
+  myIsSuppressOutput = false;
+  myMultiLinePaste = false;
+  myAutoCompletion = false;
+  myTabMode = false;
+  myComplCursorPos = -1;
+
   setFont( QFont( "Courier", 11 ) ); // default font
   setUndoRedoEnabled( false );
 
index a63e8fcd12fc1672c86e1e4e50d65fe4c3c52f06..01c35c92ec1d0a8c3d69757c924cebb6044558a1 100644 (file)
@@ -39,7 +39,8 @@ class PYCONSOLE_EXPORT PyConsole_Editor : public QTextEdit
   Q_OBJECT;
 
 public:
-  PyConsole_Editor( PyConsole_Interp*, QWidget* = 0 );
+  PyConsole_Editor( QWidget* = 0 );
+  PyConsole_Editor( QWidget*, PyConsole_Interp* );
   ~PyConsole_Editor();
 
   PyConsole_Interp* getInterp() const;
@@ -95,6 +96,8 @@ protected:
   virtual QString getLogFileName();
 
 private:
+  void           init( PyConsole_Interp* );
+
   void           multilinePaste( const QString& );
   void           multiLineProcessNextLine();
 
diff --git a/tools/PyConsole/src/python/CMakeLists.txt b/tools/PyConsole/src/python/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1d2ee21
--- /dev/null
@@ -0,0 +1,63 @@
+# Copyright (C) 2015-2016  OPEN CASCADE
+#
+# 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, or (at your option) any later version.
+#
+# 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 : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+#
+
+INCLUDE(UseQtExt)
+INCLUDE(UsePyQt)
+
+# --- options ---
+
+# additional include directories
+INCLUDE_DIRECTORIES(
+  $(QT_INCLUDES)
+  ${PYTHON_INCLUDE_DIRS}
+  ${SIP_INCLUDE_DIR}
+  ${PROJECT_BINARY_DIR}
+  ${CMAKE_CURRENT_SOURCE_DIR}/..
+)
+
+# additional preprocessor / compiler flags
+ADD_DEFINITIONS(${QT_DEFINITIONS})
+
+# libraries to link to
+SET(_link_LIBRARIES ${QT_LIBRARIES} ${PYTHON_LIBRARIES} PyConsole)
+
+# --- sources ---
+
+# sip files / to be processed by sip
+SET(_sip_files PyConsolePy.sip)
+
+# sources / sip wrappings
+PYQT_WRAP_SIP(_sip_SOURCES ${_sip_files})
+
+# sources / to compile
+SET(PyConsolePy_SOURCES ${_sip_SOURCES})
+message("PyConsolePy_SOURCES = ${PyConsolePy_SOURCES}")
+
+# --- rules ---
+
+ADD_LIBRARY(PyConsolePy ${PyConsolePy_SOURCES})
+IF(WIN32)
+  SET_TARGET_PROPERTIES(PyConsolePy PROPERTIES SUFFIX ".pyd" DEBUG_OUTPUT_NAME PyConsolePy_d RELEASE_OUTPUT_NAME PyConsolePy)
+ELSE()
+  SET_TARGET_PROPERTIES(PyConsolePy PROPERTIES PREFIX "")
+ENDIF()
+TARGET_LINK_LIBRARIES(PyConsolePy ${_link_LIBRARIES})
+INSTALL(TARGETS PyConsolePy EXPORT ${TOOLS_EXPORT_NAME}TargetGroup DESTINATION ${PYCONSOLE_INSTALL_LIBS})
diff --git a/tools/PyConsole/src/python/PyConsolePy.sip b/tools/PyConsole/src/python/PyConsolePy.sip
new file mode 100644 (file)
index 0000000..67645c8
--- /dev/null
@@ -0,0 +1,137 @@
+// Copyright (C) 2007-2016  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, or (at your option) any later version.
+//
+// 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   : PyConsolePy.sip
+// Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
+//
+
+%Module PyConsolePy
+
+%Import QtCore/QtCoremod.sip
+%Import QtGui/QtGuimod.sip
+%If (Qt_5_0_0 -)
+%Import QtWidgets/QtWidgetsmod.sip
+%End
+
+class PyConsole_Editor : QTextEdit
+{ 
+%TypeHeaderCode
+#include <PyConsole_Editor.h>
+%End
+
+public:
+  explicit PyConsole_Editor( QWidget* /TransferThis/ = 0 );
+  virtual ~PyConsole_Editor();
+
+  virtual void   addText( const QString&, const bool = false, const bool = false );
+  bool           isCommand( const QString& ) const;
+
+  virtual void   exec( const QString& );
+  void           execAndWait( const QString& );
+
+  bool           isSync() const;
+  void           setIsSync( const bool );
+
+  bool           isSuppressOutput() const;
+  void           setIsSuppressOutput( const bool );
+
+  bool           isShowBanner() const;
+  void           setIsShowBanner( const bool );
+
+  void           setAutoCompletion( bool );
+  bool           autoCompletion() const;
+
+  bool           isLogging() const;
+
+  virtual QSize  sizeHint() const;
+
+  bool           startLog( const QString& );
+  bool           dump( const QString& );
+
+signals:
+  void updateDoc( const QString& );
+
+public slots:
+  void           cut();
+  void           paste();
+  void           clear();
+  void           dump();
+  void           startLog();
+  void           stopLog();
+
+protected:
+  virtual void   dropEvent( QDropEvent* );
+  virtual void   mousePressEvent( QMouseEvent* );
+  virtual void   mouseReleaseEvent( QMouseEvent* );
+  virtual void   keyPressEvent ( QKeyEvent* );
+  virtual void   customEvent( QEvent* );
+  virtual void   insertFromMimeData( const QMimeData* );
+  void           putLog( const QString& );
+
+  virtual QString getDumpFileName();
+  virtual QString getLogFileName();
+
+private:
+  PyConsole_Editor( const PyConsole_Editor& );
+  PyConsole_Editor& operator=( const PyConsole_Editor& );
+};
+
+class PyConsole_Console : QWidget
+{ 
+%TypeHeaderCode
+#include <PyConsole_Console.h>
+%End
+
+public:
+  explicit PyConsole_Console( QWidget* /TransferThis/ = 0 );
+  virtual ~PyConsole_Console();
+
+  QFont               font() const;
+  virtual void        setFont( const QFont& );
+
+  bool                isSync() const;
+  void                setIsSync( const bool );
+
+  bool                isSuppressOutput() const;
+  void                setIsSuppressOutput( const bool );
+
+  bool                isShowBanner() const;
+  void                setIsShowBanner( const bool );
+
+  void                setAutoCompletion( bool );
+  bool                autoCompletion() const;
+
+  void                exec( const QString& );
+  void                execAndWait( const QString& );
+
+  void                setMenuActions( const int );
+  int                 menuActions() const;
+
+  void                startLog( const QString& );
+  void                stopLog();
+
+protected:
+  virtual void        contextMenuEvent( QContextMenuEvent* );
+
+private:
+  PyConsole_Console( const PyConsole_Console& );
+  PyConsole_Console& operator=( const PyConsole_Console& );
+};
index 5946e8d7f65c74ee48e5ee29acf717ca49553d1a..ebee5fda2592327efb1e5629bbcd6fddbb88c945 100644 (file)
@@ -295,9 +295,7 @@ bool PyInterp_Interp::initContext()
   Py_INCREF(_global_context);
   _local_context = _global_context;
 
-  int ret = PyRun_SimpleString("import salome_iapp;salome_iapp.IN_SALOME_GUI=True");
-
-  return ret == 0;
+  return true;
 }
 
 /*!