]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
no message
authorstv <stv@opencascade.com>
Tue, 2 Oct 2007 10:51:49 +0000 (10:51 +0000)
committerstv <stv@opencascade.com>
Tue, 2 Oct 2007 10:51:49 +0000 (10:51 +0000)
src/PyConsole/PyConsole_Editor.cxx
src/PyInterp/PyInterp_base.cxx
src/PyInterp/PyInterp_base.h

index 23268097ea5860b5ca0f44fef5ef7f1e7c455865..2fee0d516f32cb5dea7baf4904e5af1de553d515 100644 (file)
 #include <QtGui/qapplication.h>
 #include <QtGui/qtextdocument.h>
 
+#include <iostream>
+
 using namespace std;
 
 static QString READY_PROMPT = ">>> ";
@@ -117,7 +119,7 @@ static QString DOTS_PROMPT  = "... ";
 /*!
   \class ExecCommand
   \brief Python command execution request [internal].
- */
+*/
 class ExecCommand : public PyInterp_LockRequest
 {
 public:
@@ -145,23 +147,16 @@ protected:
   */
   virtual void execute()
   {
-    if ( myCommand != "" )
+    if( !myCommand.trimmed().isEmpty() )
     {
 //      SUIT_Session::SetPythonExecuted( true ); // disable GUI user actions
       int ret = getInterp()->run( myCommand.toLatin1() );
 //      SUIT_Session::SetPythonExecuted(false); // enable GUI user actions
       if ( ret < 0 )
-             myState = PyInterp_Event::ERROR;
+       myState = PyInterp_Event::ERRORS;
       else if ( ret > 0 )
-             myState = PyInterp_Event::INCOMPLETE;
-      myError  = getInterp()->getverr().c_str();
-      myOutput = getInterp()->getvout().c_str();
+       myState = PyInterp_Event::INCOMPLETE;
     } 
-    else
-    {
-      myError = "";
-      myOutput = "";
-    }
   }
 
   /*!
@@ -173,15 +168,27 @@ protected:
     return new PyInterp_Event( myState, (PyInterp_Request*)this );    
   }
 
-public:
-  QString myError;     //!< Python command error message
-  QString myOutput;    //!< Python command output log
-
 private:
   QString myCommand;   //!< Python command
   int     myState;     //!< Python command execution status
 };
 
+#define PRINT_EVENT 65432
+
+class PrintEvent : public QEvent
+{
+public:
+  PrintEvent( const char* c ) : QEvent( (QEvent::Type)PRINT_EVENT ), myText( c ) {}
+  QString text() const { return myText; }
+private:
+  QString myText;
+};
+
+void staticCallback( void* data, char* c )
+{
+  QApplication::postEvent( (PyConsole_Editor*)data, new PrintEvent( c ) ); 
+}
+
 /*!
   \brief Constructor. 
   
@@ -203,10 +210,13 @@ PyConsole_Editor::PyConsole_Editor( PyInterp_base* theInterp,
   setUndoRedoEnabled( false );
 
   myPrompt = READY_PROMPT;
-  setLineWrapMode( QTextEdit::NoWrap );
-  setWordWrapMode( QTextOption::NoWrap );
+  setLineWrapMode( QTextEdit::WidgetWidth );
+  setWordWrapMode( QTextOption::WrapAnywhere );
   setAcceptRichText( false );
 
+  theInterp->setvoutcb( staticCallback, this );
+  theInterp->setverrcb( staticCallback, this );
+
   // san - This is necessary for troubleless initialization
   onPyInterpChanged( theInterp );
 }
@@ -236,7 +246,7 @@ void PyConsole_Editor::setIsSync( const bool s )
   \param newBlock if True, then the string is printed on a new line
 */
 void PyConsole_Editor::addText( const QString& str, 
-                                     const bool     newBlock )
+                               const bool     newBlock )
 {
   moveCursor( QTextCursor::End );
   if ( newBlock )
@@ -297,7 +307,7 @@ PyInterp_Request* PyConsole_Editor::createRequest( const QString& cmd )
   \brief Execute command in the python interpreter
   and wait until it is finished.
   \param command python command to be executed
- */
+*/
 void PyConsole_Editor::execAndWait( const QString& command )
 {
   // already running ?
@@ -334,6 +344,8 @@ void PyConsole_Editor::handleReturn()
   if ( !cmd.trimmed().isEmpty() )
     myHistory.push_back( cmd );
   
+  addText( "", true );
+  
   // set read-only mode
   setReadOnly( true );
   // set busy cursor
@@ -851,28 +863,40 @@ void PyConsole_Editor::customEvent( QEvent* event )
 {
   switch( event->type() )
   {
-  case PyInterp_Event::OK:
-  case PyInterp_Event::ERROR:
-  {
-    PyInterp_Event* pe = dynamic_cast<PyInterp_Event*>( event );
-    if ( pe )
+  case PRINT_EVENT:
     {
-      ExecCommand* ec = dynamic_cast<ExecCommand*>( pe->GetRequest() );
-      if ( ec )
-      {
-       // The next line has appeared dangerous in case if
-       // Python command execution has produced very large output.
-       // A more clever approach is needed...
-       // print python output
-       addText( ec->myOutput, true );
-       addText( ec->myError );
+      PrintEvent* pe=(PrintEvent*)event;
+
+      // [ BEGIN ] workaround for the synchronous mode (1.)
+      if ( isSync() ) {
+       QTextCursor cur = textCursor();
+       cur.movePosition( QTextCursor::End );
+       cur.movePosition( QTextCursor::Left, QTextCursor::KeepAnchor, PROMPT_SIZE );
+       cur.removeSelectedText();
+       setTextCursor( cur );
+      }
+      // [ END ] workaround for the synchronous mode (1.)
+
+      addText( pe->text() );
+
+      // [ BEGIN ] workaround for the synchronous mode (2.)
+      if ( isSync() ) {
+       addText( myPrompt );
       }
+      // [ END ] workaround for the synchronous mode (2.)
+
+      return;
     }
+  case PyInterp_Event::OK:
+  case PyInterp_Event::ERRORS:
+  {
     // clear command buffer
     myCommandBuffer.truncate( 0 );
     // set "ready" prompt
     myPrompt = READY_PROMPT;
-    addText( myPrompt );
+    QTextBlock par = document()->end().previous();
+    QString txt = par.text();
+    addText( myPrompt, !txt.isEmpty() );
     // unset busy cursor
     unsetCursor();
     // stop event loop (if running)
@@ -886,7 +910,9 @@ void PyConsole_Editor::customEvent( QEvent* event )
     myCommandBuffer.append( "\n" );
     // set "dot" prompt
     myPrompt = DOTS_PROMPT;
-    addText( myPrompt, true );
+    QTextBlock par = document()->end().previous();
+    QString txt = par.text();
+    addText( myPrompt, !txt.isEmpty() );
     // unset busy cursor
     unsetCursor();
     // stop event loop (if running)
@@ -958,7 +984,7 @@ void PyConsole_Editor::onPyInterpChanged( PyInterp_base* interp )
   
   Reimplemented from Qt.
   Warning! In Qt4 this method is not virtual.
- */
+*/
 void PyConsole_Editor::cut()
 {
   QTextCursor cur = textCursor();
@@ -983,7 +1009,7 @@ void PyConsole_Editor::cut()
 
   Reimplemented from Qt.
   Warning! In Qt4 this method is not virtual.
- */
+*/
 void PyConsole_Editor::paste()
 {
   QTextCursor cur = textCursor();
@@ -1010,7 +1036,7 @@ void PyConsole_Editor::paste()
 
   Reimplemented from Qt.
   Warning! In Qt4 this method is not virtual.
- */
+*/
 void PyConsole_Editor::clear()
 {
   QTextEdit::clear();
index 1ff7cd2410435654f5e2f34aed06dbcec9299720..2bd254b62b0828002208f5e87a389543332ce695 100644 (file)
 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+
 // 
+
 // 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
+
 //
+
 //  SALOME SALOMEGUI : implementation of desktop and GUI kernel
+
 //
+
 //  File   : PyInterp_base.cxx
+
 //  Author : Christian CAREMOLI, Paul RASCLE, EDF
+
 //  Module : SALOME
+
 //  $Header$
 
 
+
+
+
 #include "PyInterp_base.h" // this include must be first (see PyInterp_base.h)!
 
+
+
 #include <cStringIO.h>
 
+#include <structmember.h>
+
+
+
 #include <string>
+
 #include <vector>
 
+
+
 using namespace std;
 
+
+
 PyLockWrapper::PyLockWrapper(PyThreadState* theThreadState): 
+
   myThreadState(theThreadState),
+
   mySaveThreadState(0)
+
 {
+
 #if defined(USE_GILSTATE)
+
   if (myThreadState->interp == PyInterp_base::_interp) {
+
     _savestate = PyGILState_Ensure();
+
   } else {
+
     PyEval_AcquireThread(myThreadState);
+
   }
+
 #else 
+
   PyEval_AcquireThread(myThreadState);
+
 #endif
+
 }
 
+
+
 PyLockWrapper::~PyLockWrapper()
+
 {
+
 #if defined(USE_GILSTATE)
+
   if (myThreadState->interp == PyInterp_base::_interp) {
+
     PyGILState_Release(_savestate);
+
   } else {
+
     PyEval_ReleaseThread(myThreadState);
+
   }
+
 #else 
+
   PyEval_ReleaseThread(myThreadState);
+
 #endif
+
 }
 
+
+
 class PyReleaseLock{
+
 public:
+
   ~PyReleaseLock(){
+
     PyEval_ReleaseLock();
+
   }
+
 };
 
 
+
+
+
 PyLockWrapper PyInterp_base::GetLockWrapper(){
+
   return _tstate;
+
+}
+
+
+
+static void
+
+PyStdOut_dealloc(PyStdOut *self)
+
+{
+
+  PyObject_Del(self);
+
+}
+
+
+
+static PyObject *
+
+PyStdOut_write(PyStdOut *self, PyObject *args)
+
+{
+
+  char *c;
+
+  int l;
+
+  if (!PyArg_ParseTuple(args, "t#:write",&c, &l))
+
+    return NULL;
+
+  if(self->_cb==NULL) {
+
+    if ( self->_iscerr )
+
+      std::cerr << c ;
+
+    else
+
+      std::cout << c ;
+
+  }
+
+  else {
+
+    self->_cb(self->_data,c);
+
+  }
+
+  Py_INCREF(Py_None);
+
+  return Py_None;
+
 }
 
 
+
+static PyMethodDef PyStdOut_methods[] = {
+
+  {"write",  (PyCFunction)PyStdOut_write,  METH_VARARGS,
+
+    PyDoc_STR("write(string) -> None")},
+
+  {NULL,    NULL}   /* sentinel */
+
+};
+
+
+
+static PyMemberDef PyStdOut_memberlist[] = {
+
+  {"softspace", T_INT,  offsetof(PyStdOut, softspace), 0,
+
+   "flag indicating that a space needs to be printed; used by print"},
+
+  {NULL} /* Sentinel */
+
+};
+
+
+
+
+
+
+
+static PyTypeObject PyStdOut_Type = {
+
+  /* The ob_type field must be initialized in the module init function
+
+   * to be portable to Windows without using C++. */
+
+  PyObject_HEAD_INIT(NULL)
+
+  0,      /*ob_size*/
+
+  "PyOut",   /*tp_name*/
+
+  sizeof(PyStdOut),  /*tp_basicsize*/
+
+  0,      /*tp_itemsize*/
+
+  /* methods */
+
+  (destructor)PyStdOut_dealloc, /*tp_dealloc*/
+
+  0,      /*tp_print*/
+
+  0, /*tp_getattr*/
+
+  0, /*tp_setattr*/
+
+  0,      /*tp_compare*/
+
+  0,      /*tp_repr*/
+
+  0,      /*tp_as_number*/
+
+  0,      /*tp_as_sequence*/
+
+  0,      /*tp_as_mapping*/
+
+  0,      /*tp_hash*/
+
+        0,                      /*tp_call*/
+
+        0,                      /*tp_str*/
+
+        PyObject_GenericGetAttr,                      /*tp_getattro*/
+
+        /* softspace is writable:  we must supply tp_setattro */
+
+        PyObject_GenericSetAttr,    /* tp_setattro */
+
+        0,                      /*tp_as_buffer*/
+
+        Py_TPFLAGS_DEFAULT,     /*tp_flags*/
+
+        0,                      /*tp_doc*/
+
+        0,                      /*tp_traverse*/
+
+        0,                      /*tp_clear*/
+
+        0,                      /*tp_richcompare*/
+
+        0,                      /*tp_weaklistoffset*/
+
+        0,                      /*tp_iter*/
+
+        0,                      /*tp_iternext*/
+
+        PyStdOut_methods,                      /*tp_methods*/
+
+        PyStdOut_memberlist,                      /*tp_members*/
+
+        0,                      /*tp_getset*/
+
+        0,                      /*tp_base*/
+
+        0,                      /*tp_dict*/
+
+        0,                      /*tp_descr_get*/
+
+        0,                      /*tp_descr_set*/
+
+        0,                      /*tp_dictoffset*/
+
+        0,                      /*tp_init*/
+
+        0,                      /*tp_alloc*/
+
+        0,                      /*tp_new*/
+
+        0,                      /*tp_free*/
+
+        0,                      /*tp_is_gc*/
+
+};
+
+
+
+
+
+#define PyStdOut_Check(v)  ((v)->ob_type == &PyStdOut_Type)
+
+
+
+static PyStdOut * newPyStdOut( bool iscerr )
+
+{
+
+  PyStdOut *self;
+
+  self = PyObject_New(PyStdOut, &PyStdOut_Type);
+
+  if (self == NULL)
+
+    return NULL;
+
+  self->softspace = 0;
+
+  self->_cb = NULL;
+
+  self->_iscerr = iscerr;
+
+  return self;
+
+}
+
+
+
 // main python interpreter (static attributes)
 
+
+
 int PyInterp_base::_argc = 1;
+
 char* PyInterp_base::_argv[] = {""};
 
+
+
 PyObject *PyInterp_base::builtinmodule = NULL;
 
+
+
 PyThreadState *PyInterp_base::_gtstate = NULL;
+
 PyInterpreterState *PyInterp_base::_interp = NULL;
 
 
+
+
+
 /*!
+
  * basic constructor here : herited classes constructors must call initalize() method
+
  * defined here.
+
  */
+
 PyInterp_base::PyInterp_base(): _tstate(0), _vout(0), _verr(0), _g(0), _atFirst(true)
+
 {
+
 }
 
+
+
 PyInterp_base::~PyInterp_base()
+
 {
+
 }
 
 
+
+
+
 /*!
+
  * Must be called by herited classes constructors. initialize() calls virtuals methods
+
  * initstate & initcontext, not defined here in base class. initstate & initcontext methods
+
  * must be implemented in herited classes, following the Python interpreter policy
+
  * (mono or multi interpreter...).
+
  */
+
 void PyInterp_base::initialize()
+
 {
+
   _history.clear();       // start a new list of user's commands 
+
   _ith = _history.begin();
 
+
+
   init_python();
+
   // Here the global lock is released
 
+
+
   initState();
 
+
+
   PyLockWrapper aLock= GetLockWrapper();
 
+
+
   initContext();
 
+
+
   // used to interpret & compile commands
+
   PyObjWrapper m(PyImport_ImportModule("codeop"));
+
   if(!m){
+
     PyErr_Print();
+
     return;
-  }
 
-  // Create cStringIO to capture stdout and stderr
-  PycString_IMPORT;
-  if (PycStringIO) { // CTH11627 : additional check
-    _vout = PycStringIO->NewOutput(128);
-    _verr = PycStringIO->NewOutput(128);
   }
 
+
+
+  // Create python objects to capture stdout and stderr
+
+  _vout=(PyObject*)newPyStdOut( false ); // stdout 
+
+  _verr=(PyObject*)newPyStdOut( true );  // stderr
+
+
+
   // All the initRun outputs are redirected to the standard output (console)
+
   initRun();
+
 }
 
+
+
 void PyInterp_base::init_python()
+
 {
+
   _atFirst = false;
+
   if (Py_IsInitialized())
+
     return;
 
+
+
   // Python is not initialized
+
   Py_SetProgramName(_argv[0]);
+
   Py_Initialize(); // Initialize the interpreter
+
   PySys_SetArgv(_argc, _argv);
+
   PyEval_InitThreads(); // Create (and acquire) the interpreter lock
+
   _interp = PyThreadState_Get()->interp;
+
+  if (PyType_Ready(&PyStdOut_Type) < 0)
+
+  {
+
+    PyErr_Print();
+
+  }
+
   _gtstate = PyEval_SaveThread(); // Release global thread state
+
 }
 
+
+
 string PyInterp_base::getbanner()
+
 {
+
  // Should we take the lock ?
+
  // PyEval_RestoreThread(_tstate);
+
   string aBanner("Python ");
+
   aBanner = aBanner + Py_GetVersion() + " on " + Py_GetPlatform() ;
+
   aBanner = aBanner + "\ntype help to get general information on environment\n";
+
   //PyEval_SaveThread();
+
   return aBanner;
+
 }
 
 
-int PyInterp_base::initRun()
-{
-  PySys_SetObject("stderr",_verr);
-  PySys_SetObject("stdout",_vout);
 
-  PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
-  PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
 
-  //PyObject *m = PyImport_GetModuleDict();
-  
-  PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
-  PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
+
+int PyInterp_base::initRun()
+
+{
 
   return 0;
+
 }
 
 
+
+
+
 /*!
+
  * This function compiles a string (command) and then evaluates it in the dictionnary
+
  * context if possible.
+
  * Returns :
+
  * -1 : fatal error 
+
  *  1 : incomplete text
+
  *  0 : complete text executed with success
+
  */
+
 int compile_command(const char *command,PyObject *context)
+
 {
+
   PyObject *m = PyImport_AddModule("codeop");
+
   if(!m){ // Fatal error. No way to go on.
+
     PyErr_Print();
+
     return -1;
+
   }
+
   PyObjWrapper v(PyObject_CallMethod(m,"compile_command","s",command));
+
   if(!v){
+
     // Error encountered. It should be SyntaxError,
+
     //so we don't write out traceback
+
     PyObjWrapper exception, value, tb;
+
     PyErr_Fetch(&exception, &value, &tb);
+
     PyErr_NormalizeException(&exception, &value, &tb);
+
     PyErr_Display(exception, value, NULL);
+
     return -1;
+
   }else if (v == Py_None){
+
     // Incomplete text we return 1 : we need a complete text to execute
+
     return 1;
+
   }else{
+
     // Complete and correct text. We evaluate it.
+
     //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+
     //    PyObjWrapper r(PyEval_EvalCode(v,context,context));
+
     //#else
+
     PyObjWrapper r(PyEval_EvalCode((PyCodeObject *)(void *)v,context,context));
+
     //#endif
+
     if(!r){
+
       // Execution error. We return -1
+
       PyErr_Print();
+
       return -1;
+
     }
+
     // The command has been successfully executed. Return 0
+
     return 0;
+
   }
+
 }
 
 
+
+
+
 int PyInterp_base::run(const char *command)
+
 {
+
   if(_atFirst){
+
     int ret = 0;
+
     ret = simpleRun("from Help import *");
+
     if (ret) { 
+
       _atFirst = false;
+
       return ret;
+
     }
+
     ret = simpleRun("import salome");
+
     if (ret) { 
+
       _atFirst = false;
+
       return ret;
+
     }
+
     ret = simpleRun("salome.salome_init(0,1)");
+
     if (ret) { 
+
       _atFirst = false;
+
       return ret;
+
     }
+
     _atFirst = false;
+
   }
+
   return simpleRun(command);
+
 }
 
 
+
+
+
 int PyInterp_base::simpleRun(const char *command)
+
 {
+
   if( !_atFirst && strcmp(command,"") != 0 ) {
+
     _history.push_back(command);
+
     _ith = _history.end();
+
   }
 
+
+
   // We come from C++ to enter Python world
+
   // We need to acquire the Python global lock
+
   //PyLockWrapper aLock(_tstate); // san - lock is centralized now
 
+
+
   // Reset redirected outputs before treatment
+
   PySys_SetObject("stderr",_verr);
+
   PySys_SetObject("stdout",_vout);
 
-  PyObjWrapper verr(PyObject_CallMethod(_verr,"reset",""));
-  PyObjWrapper vout(PyObject_CallMethod(_vout,"reset",""));
+
 
   int ier = compile_command(command,_g);
 
+
+
   // Outputs are redirected on standards outputs (console)
+
   PySys_SetObject("stdout",PySys_GetObject("__stdout__"));
+
   PySys_SetObject("stderr",PySys_GetObject("__stderr__"));
 
+
+
   return ier;
+
 }
 
 
+
+
+
 const char * PyInterp_base::getPrevious()
+
 {
+
   if(_ith != _history.begin()){
+
     _ith--;
+
     return (*_ith).c_str();
+
   }
+
   else
+
     return BEGIN_HISTORY_PY;
+
 }
 
 
+
+
+
 const char * PyInterp_base::getNext()
+
 {
+
   if(_ith != _history.end()){
+
     _ith++;
+
   }
+
   if (_ith == _history.end())
+
     return TOP_HISTORY_PY;
+
   else
+
     return (*_ith).c_str();
+
 }
 
 
-string PyInterp_base::getverr(){ 
-  //PyLockWrapper aLock(_tstate);
-  PyObjWrapper v(PycStringIO->cgetvalue(_verr));
-  string aRet(PyString_AsString(v));
-  return aRet;
+
+
+
+void PyInterp_base::setvoutcb(PyOutChanged* cb, void* data)
+
+{  
+
+  ((PyStdOut*)_vout)->_cb=cb;
+
+  ((PyStdOut*)_vout)->_data=data;
+
 }
 
 
-string PyInterp_base::getvout(){  
-  //PyLockWrapper aLock(_tstate);
-  PyObjWrapper v(PycStringIO->cgetvalue(_vout));
-  string aRet(PyString_AsString(v));
-  return aRet;
+
+
+
+void PyInterp_base::setverrcb(PyOutChanged* cb, void* data)
+
+{  
+
+  ((PyStdOut*)_verr)->_cb=cb;
+
+  ((PyStdOut*)_verr)->_data=data;
+
 }
+
index a00056e868cef3ae508321a0563d2ff9b514a5f4..fd25c0b482fc917550e1dd8be5fc7703c3139cf3 100644 (file)
 // Copyright (C) 2005  OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
+
 // 
+
 // 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
+
 //
+
 //  SALOME SALOMEGUI : implementation of desktop and GUI kernel
+
 //
+
 //  File   : PyInterp_base.h
+
 //  Author : Christian CAREMOLI, Paul RASCLE, EDF
+
 //  Module : SALOME
 
+
+
 #ifndef _PYINTERP_BASE_H_
+
 #define _PYINTERP_BASE_H_
 
+
+
 #include "PyInterp.h"
 
+
+
 #include <list>
+
 #include <string>
+
 #include <iostream>
 
+
+
 // include order important!
+
 // pthread then python then qt
+
 //#include <pthread.h>  // must be before Python.h !
 
+
+
 #include <Python.h>   // must be before qt includes ...
+
 #include <compile.h>   // Python include needed for versions before 2.4. Included in Python.h now.
+
 #include <eval.h>   // Python include needed for versions before 2.4. Included in Python.h now.
 
+
+
 //#if PY_VERSION_HEX < 0x02040000 // python version earlier than 2.4.0
+
 //extern "C" PyObject * PyEval_EvalCode(PyObject *co, PyObject *g, PyObject *l);
+
 //#endif
 
+
+
 /* For 2.3, use the PyGILState_ calls */
+
 #if (PY_VERSION_HEX >= 0x02030000)
+
 #define USE_GILSTATE
+
 #endif
 
+
+
 #define TOP_HISTORY_PY "--- top of history ---"
+
 #define BEGIN_HISTORY_PY "--- begin of history ---"
 
+
+
 class PYINTERP_EXPORT PyLockWrapper
+
 {
+
   PyThreadState* myThreadState;
+
   PyThreadState* mySaveThreadState;
+
 #if defined(USE_GILSTATE)
+
   PyGILState_STATE _savestate ;
+
 #endif
+
  public:
+
   PyLockWrapper(PyThreadState* theThreadState);
+
   ~PyLockWrapper();
+
 };
 
+
+
+typedef void PyOutChanged(void* data,char * c);
+
+
+
 class PYINTERP_EXPORT PyInterp_base{
+
  public:
+
   static int _argc;
+
   static char* _argv[];
+
   static PyObject *builtinmodule;
+
   static PyThreadState *_gtstate;
+
   static PyInterpreterState *_interp;
+
   
+
   PyInterp_base();
+
   virtual ~PyInterp_base();
+
   
+
   virtual void initialize();
+
   virtual void init_python();
+
   // init_python() made virtual to:
+
   // 1. Remove dependency on KERNEL in light SALOME configuration
+
   // 2. Allow redefinition of this method in SalomeApp_PyInterp class (it should be empty there and rely on KERNEL_PYTHON)
 
+
+
   virtual int run(const char *command); 
 
+
+
   PyLockWrapper GetLockWrapper();
 
+
+
   std::string getbanner(); 
-  std::string getverr();
-  std::string getvout();  
+
+  void setverrcb(PyOutChanged*,void*);
+
+  void setvoutcb(PyOutChanged*,void*);
+
+
 
   const char * getPrevious();
+
   const char * getNext();    
 
+
+
  protected:
+
   PyThreadState * _tstate;
+
   PyObject * _vout;
+
   PyObject * _verr;
+
   PyObject * _g;
+
   PyObject * _codeop;
+
   std::list<std::string> _history;
+
   std::list<std::string>::iterator _ith;
+
   bool _atFirst;
 
+
+
   int simpleRun(const char* command);
+
   int initRun();
 
+
+
   virtual bool initState() = 0;
+
   virtual bool initContext() = 0;  
+
 };
 
 
+
+
+
 class PYINTERP_EXPORT PyObjWrapper{
+
   PyObject* myObject;
+
 public:
+
   PyObjWrapper(PyObject* theObject): myObject(theObject) {}
+
   PyObjWrapper(): myObject(0) {}
+
   operator PyObject*(){
+
     return myObject;
+
   }
+
   PyObject* operator->(){
+
     return myObject;
+
   }
+
   PyObject* get(){
+
     return myObject;
+
   }
+
   bool operator!(){
+
     return !myObject;
+
   }
+
   bool operator==(PyObject* theObject){
+
     return myObject == theObject;
+
   }
+
   PyObject** operator&(){
+
     return &myObject;
+
   }
+
   PyObjWrapper& operator=(PyObjWrapper* theObjWrapper){
+
     Py_XDECREF(myObject);
+
     myObject = theObjWrapper->myObject;
+
     return *this;
+
   }
+
   virtual ~PyObjWrapper(){ 
+
     Py_XDECREF(myObject);
+
   }
+
 };
 
+
+
+
+
+typedef struct {
+
+  PyObject_HEAD
+
+  int softspace;
+
+  PyOutChanged* _cb;
+
+  void* _data;
+
+  bool _iscerr;
+
+} PyStdOut;
+
+
+
 #endif
+