]> SALOME platform Git repositories - modules/gui.git/commitdiff
Salome HOME
PyConsole: error messages printed in red in the console.
authorbruneton <bruneton>
Thu, 4 Apr 2013 10:41:41 +0000 (10:41 +0000)
committerbruneton <bruneton>
Thu, 4 Apr 2013 10:41:41 +0000 (10:41 +0000)
Also re-organized the code to prepare auto-completion.

15 files changed:
src/PyConsole/CMakeLists.txt
src/PyConsole/PyConsole_Editor.cxx
src/PyConsole/PyConsole_Editor.h
src/PyConsole/PyConsole_Event.cxx [new file with mode: 0644]
src/PyConsole/PyConsole_Event.h [new file with mode: 0644]
src/PyConsole/PyConsole_Request.cxx [new file with mode: 0644]
src/PyConsole/PyConsole_Request.h [new file with mode: 0644]
src/PyInterp/CMakeLists.txt
src/PyInterp/PyInterp_Dispatcher.cxx
src/PyInterp/PyInterp_Dispatcher.h
src/PyInterp/PyInterp_Event.cxx [new file with mode: 0644]
src/PyInterp/PyInterp_Event.h [new file with mode: 0644]
src/PyInterp/PyInterp_Request.cxx [new file with mode: 0644]
src/PyInterp/PyInterp_Request.h [new file with mode: 0644]
src/SALOME_PYQT/SALOME_PYQT_GUILight/CMakeLists.txt

index 2079551060a402730a67da9fb359a2f2c5a26ff0..48a250f6354239d32c5816184b066f0d36695c16 100755 (executable)
@@ -27,9 +27,10 @@ INCLUDE_DIRECTORIES(
   ${CMAKE_CURRENT_SOURCE_DIR}/../Qtx
   ${CMAKE_CURRENT_SOURCE_DIR}/../SUIT
   ${CMAKE_CURRENT_SOURCE_DIR}/../PyInterp
+  ${CMAKE_CURRENT_SOURCE_DIR}/../Event
 )
 
-SET(COMMON_LIBS ${PYTHON_LIBRARIES} ${QT_LIBRARIES} ${SALOMELocalTrace} qtx suit PyInterp)
+SET(COMMON_LIBS ${PYTHON_LIBRARIES} ${QT_LIBRARIES} ${SALOMELocalTrace} qtx suit PyInterp Event)
 
 SET(GUI_HEADERS   
   PyConsole_Editor.h
@@ -41,6 +42,8 @@ SET(PyConsole_SOURCES
   PyConsole_Console.cxx
   PyConsole_Editor.cxx
   PyConsole_Interp.cxx
+  PyConsole_Event.cxx
+  PyConsole_Request.cxx
 )
 
 SET(GUITS_SOURCES
@@ -59,6 +62,8 @@ SET(COMMON_HEADERS_H
   PyConsole_Console.h
   PyConsole_Editor.h
   PyConsole_Interp.h
+  PyConsole_Event.h
+  PyConsole_Request.h
 )
 INSTALL(FILES ${COMMON_HEADERS_H} DESTINATION ${GUI_salomeinclude_HEADERS})
 QT4_INSTALL_TS_RESOURCES("${GUITS_SOURCES}" "${GUI_salomeres_DATA}")
index 3414e26a62b56da147bc90712864a82c07231fdc..049eabb42a78f22daa4f173eb93acb11aa272742 100644 (file)
 
 #include "PyConsole_Interp.h"   // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
 #include "PyConsole_Editor.h"
-#include <PyInterp_Dispatcher.h>
+#include "PyConsole_Event.h"
+#include "PyInterp_Event.h"
+#include "PyInterp_Dispatcher.h"
+#include "PyConsole_Request.h"
 
 #include <SUIT_Tools.h>
 #include <SUIT_FileDlg.h>
 
 static QString READY_PROMPT = ">>> ";
 static QString DOTS_PROMPT  = "... ";
-#define PROMPT_SIZE myPrompt.length()
-
-#define PRINT_EVENT 65432
-
 
 class DumpCommandsFileValidator : public SUIT_FileValidator
 {
@@ -141,95 +140,19 @@ bool DumpCommandsFileValidator::canSave(const QString& file, bool permissions)
   return SUIT_FileValidator::canSave( file, permissions);
 }
 
-/*!
-  \class ExecCommand
-  \brief Python command execution request.
-  \internal
-*/
-
-class ExecCommand : public PyInterp_LockRequest
+void staticCallbackStdout( void* data, char* c )
 {
-public:
-  /*!
-    \brief Constructor.
-    
-    Creates new python command execution request.
-    \param theInterp   python interpreter
-    \param theCommand  python command
-    \param theListener widget to get the notification messages
-    \param sync        if True the request is processed synchronously 
-  */
-  ExecCommand( PyInterp_Interp*        theInterp, 
-               const QString&          theCommand,
-               PyConsole_Editor*       theListener, 
-               bool                    sync = false )
-    : PyInterp_LockRequest( theInterp, theListener, sync ),
-      myCommand( theCommand ), myState( PyInterp_Event::ES_OK )
-  {}
-
-protected:
-  /*!
-    \brief Execute the python command in the interpreter and 
-           get its execution status.
-  */
-  virtual void execute()
-  {
-    if ( myCommand != "" )
-    {
-      int ret = getInterp()->run( myCommand.toUtf8().data() );
-      if ( ret < 0 )
-        myState = PyInterp_Event::ES_ERROR;
-      else if ( ret > 0 )
-        myState = PyInterp_Event::ES_INCOMPLETE;
-    } 
-  }
-
-  /*!
-    \brief Create and return a notification event.
-    \return new notification event
-  */
-  virtual QEvent* createEvent() const
-  {
-    if ( IsSync() )
-      QCoreApplication::sendPostedEvents( listener(), PRINT_EVENT );
-    return new PyInterp_Event( myState, (PyInterp_Request*)this );    
-  }
-
-private:
-  QString myCommand;   //!< Python command
-  int     myState;     //!< Python command execution status
-};
-
-/*!
-  \class PrintEvent
-  \brief Python command output backend event.
-  \internal
-*/
-
-class PrintEvent : public QEvent
-{
-public:
-  /*!
-    \brief Constructor
-    \param c message text (python trace)
-  */
-  PrintEvent( const char* c ) : QEvent( (QEvent::Type)PRINT_EVENT ), myText( c ) {}
-  /*!
-    \brief Get message
-    \return message text (python trace)
-  */
-  QString text() const { return myText; }
-
-private:
-  QString myText; //!< Event message (python trace)
-};
+  if(!((PyConsole_Editor*)data)->isSuppressOutput())
+    QApplication::postEvent( (PyConsole_Editor*)data, new PrintEvent( c, false ) );
+}
 
-void staticCallback( void* data, char* c )
+void staticCallbackStderr( void* data, char* c )
 {
   if(!((PyConsole_Editor*)data)->isSuppressOutput())
-    QApplication::postEvent( (PyConsole_Editor*)data, new PrintEvent( c ) ); 
+    QApplication::postEvent( (PyConsole_Editor*)data, new PrintEvent( c, true ) );
 }
 
+
 /*!
   \brief Constructor. 
   
@@ -257,8 +180,8 @@ PyConsole_Editor::PyConsole_Editor( PyConsole_Interp* theInterp,
   setWordWrapMode( QTextOption::WrapAnywhere );
   setAcceptRichText( false );
 
-  theInterp->setvoutcb( staticCallback, this );
-  theInterp->setverrcb( staticCallback, this );
+  theInterp->setvoutcb( staticCallbackStdout, this );
+  theInterp->setverrcb( staticCallbackStderr, this );
 
   // san - This is necessary for troubleless initialization
   onPyInterpChanged( theInterp );
@@ -366,14 +289,23 @@ QSize PyConsole_Editor::sizeHint() const
   \brief Put the string \a str to the python editor.
   \param str string to be put in the command line of the editor
   \param newBlock if True, then the string is printed on a new line
+  \param isError if true, the text is printed in dark red
 */
 void PyConsole_Editor::addText( const QString& str, 
-                                const bool     newBlock )
+                                const bool     newBlock,
+                                const bool    isError)
 {
+  QTextCursor theCursor(textCursor());
+  QTextCharFormat cf;
+
   moveCursor( QTextCursor::End );
   if ( newBlock )
-    textCursor().insertBlock();
-  textCursor().insertText( str );
+    theCursor.insertBlock();
+  if (isError)
+      cf.setForeground(QBrush(Qt::red));
+  else
+      cf.setForeground(QBrush(Qt::black));
+  theCursor.insertText( str, cf);
   moveCursor( QTextCursor::End );
   ensureCursorVisible();
 }
@@ -467,7 +399,7 @@ void PyConsole_Editor::handleReturn()
   if ( !par.isValid() ) return;
 
   // get command
-  QString cmd = par.text().remove( 0, PROMPT_SIZE );
+  QString cmd = par.text().remove( 0, promptSize() );
   // extend the command buffer with the current command 
   myCommandBuffer.append( cmd );
   // add command to the history
@@ -499,7 +431,7 @@ void PyConsole_Editor::dropEvent( QDropEvent* event )
   QPoint pos = event->pos();
   QTextCursor cur = cursorForPosition( event->pos() );
   // if the position is not in the last line move it to the end of the command line
-  if ( cur.position() < document()->end().previous().position() + PROMPT_SIZE ) {
+  if ( cur.position() < document()->end().previous().position() + promptSize() ) {
     moveCursor( QTextCursor::End );
     pos = cursorRect().center();
   }
@@ -536,7 +468,7 @@ void PyConsole_Editor::mouseReleaseEvent( QMouseEvent* event )
       text = QApplication::clipboard()->text( QClipboard::Clipboard );
     QTextCursor cur = cursorForPosition( event->pos() );
     // if the position is not in the last line move it to the end of the command line
-    if ( cur.position() < document()->end().previous().position() + PROMPT_SIZE ) {
+    if ( cur.position() < document()->end().previous().position() + promptSize() ) {
       moveCursor( QTextCursor::End );
     }
     else {
@@ -618,7 +550,7 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
   case 0 :
     // any printed key: just print it
     {
-      if ( curLine < endLine || curCol < PROMPT_SIZE ) {
+      if ( curLine < endLine || curCol < promptSize() ) {
         moveCursor( QTextCursor::End );
       }
       QTextEdit::keyPressEvent( event );
@@ -654,7 +586,7 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
           myCmdInHistory = myHistory.count();
           // remember current command
           QTextBlock par = document()->end().previous();
-          myCurrentCommand = par.text().remove( 0, PROMPT_SIZE );
+          myCurrentCommand = par.text().remove( 0, promptSize() );
         }
         if ( myCmdInHistory > 0 ) {
           myCmdInHistory--;
@@ -724,7 +656,7 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
     // - with <Ctrl>+<Shift> modifier keys pressed: move one word left with selection
     {
       QString txt = textCursor().block().text();
-      if ( !shftPressed && isCommand( txt ) && curCol <= PROMPT_SIZE ) {
+      if ( !shftPressed && isCommand( txt ) && curCol <= promptSize() ) {
         moveCursor( QTextCursor::Up );
         moveCursor( QTextCursor::EndOfBlock );
       }
@@ -743,15 +675,15 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
       QString txt = textCursor().block().text();
       if ( !shftPressed ) {
         if ( curCol < txt.length() ) {
-          if ( isCommand( txt ) && curCol < PROMPT_SIZE ) {
-            cur.setPosition( cur.block().position() + PROMPT_SIZE );
+          if ( isCommand( txt ) && curCol < promptSize() ) {
+            cur.setPosition( cur.block().position() + promptSize() );
             setTextCursor( cur );
             break;
           }
         }
         else {
           if ( curLine < endLine && isCommand( textCursor().block().next().text() ) ) {
-            cur.setPosition( cur.position() + PROMPT_SIZE+1 );
+            cur.setPosition( cur.position() + promptSize()+1 );
             setTextCursor( cur );
             horizontalScrollBar()->setValue( horizontalScrollBar()->minimum() );
             break;
@@ -798,7 +730,7 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
           myCmdInHistory = myHistory.count();
           // remember current command
           QTextBlock par = document()->end().previous();
-          myCurrentCommand = par.text().remove( 0, PROMPT_SIZE );
+          myCurrentCommand = par.text().remove( 0, promptSize() );
         }
         if ( myCmdInHistory > 0 ) {
           myCmdInHistory = 0;
@@ -876,14 +808,14 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
         QString txt = textCursor().block().text();
         if ( isCommand( txt ) ) {
           if ( shftPressed ) {
-            if ( curCol > PROMPT_SIZE ) {
+            if ( curCol > promptSize() ) {
               cur.movePosition( QTextCursor::StartOfLine, QTextCursor::KeepAnchor );
-              cur.movePosition( QTextCursor::Right, QTextCursor::KeepAnchor, PROMPT_SIZE );
+              cur.movePosition( QTextCursor::Right, QTextCursor::KeepAnchor, promptSize() );
             }
           }
           else {
             cur.movePosition( QTextCursor::StartOfLine );
-            cur.movePosition( QTextCursor::Right, QTextCursor::MoveAnchor, PROMPT_SIZE );
+            cur.movePosition( QTextCursor::Right, QTextCursor::MoveAnchor, promptSize() );
           }
           setTextCursor( cur );
         }
@@ -916,13 +848,13 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
       if ( cur.hasSelection() ) {
         cut();
       }
-      else if ( cur.position() > document()->end().previous().position() + PROMPT_SIZE ) {
+      else if ( cur.position() > document()->end().previous().position() + promptSize() ) {
         if ( shftPressed ) {
           moveCursor( QTextCursor::PreviousWord, QTextCursor::KeepAnchor );
           textCursor().removeSelectedText();
         }
         else if ( ctrlPressed ) {
-          cur.setPosition( document()->end().previous().position() + PROMPT_SIZE, 
+          cur.setPosition( document()->end().previous().position() + promptSize(),
                            QTextCursor::KeepAnchor );
           setTextCursor( cur );
           textCursor().removeSelectedText();
@@ -932,7 +864,7 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
         }
       }
       else {
-        cur.setPosition( document()->end().previous().position() + PROMPT_SIZE );
+        cur.setPosition( document()->end().previous().position() + promptSize() );
         setTextCursor( cur );
         horizontalScrollBar()->setValue( horizontalScrollBar()->minimum() );
       }
@@ -948,7 +880,7 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
       if ( cur.hasSelection() ) {
         cut();
       }
-      else if ( cur.position() > document()->end().previous().position() + PROMPT_SIZE-1 ) {
+      else if ( cur.position() > document()->end().previous().position() + promptSize()-1 ) {
         if ( shftPressed ) {
           moveCursor( QTextCursor::NextWord, QTextCursor::KeepAnchor );
           textCursor().removeSelectedText();
@@ -962,7 +894,7 @@ void PyConsole_Editor::keyPressEvent( QKeyEvent* event )
         }
       }
       else {
-        cur.setPosition( document()->end().previous().position() + PROMPT_SIZE );
+        cur.setPosition( document()->end().previous().position() + promptSize() );
         setTextCursor( cur );
         horizontalScrollBar()->setValue( horizontalScrollBar()->minimum() );
       }
@@ -994,10 +926,10 @@ void PyConsole_Editor::customEvent( QEvent* event )
 {
   switch( event->type() )
   {
-  case PRINT_EVENT:
+  case PrintEvent::EVENT_ID:
     {
       PrintEvent* pe=(PrintEvent*)event;
-      addText( pe->text() );
+      addText( pe->text(), false, pe->isError());
       return;
     }
   case PyInterp_Event::ES_OK:
@@ -1115,11 +1047,11 @@ void PyConsole_Editor::cut()
   if ( cur.hasSelection() ) {
     QApplication::clipboard()->setText( cur.selectedText() );
     int startSelection = cur.selectionStart();
-    if ( startSelection < document()->end().previous().position() + PROMPT_SIZE )
-      startSelection = document()->end().previous().position() + PROMPT_SIZE;
+    if ( startSelection < document()->end().previous().position() + promptSize() )
+      startSelection = document()->end().previous().position() + promptSize();
     int endSelection = cur.selectionEnd();
-    if ( endSelection < document()->end().previous().position() + PROMPT_SIZE )
-      endSelection = document()->end().previous().position() + PROMPT_SIZE;
+    if ( endSelection < document()->end().previous().position() + promptSize() )
+      endSelection = document()->end().previous().position() + promptSize();
     cur.setPosition( startSelection );
     cur.setPosition( endSelection, QTextCursor::KeepAnchor );
     horizontalScrollBar()->setValue( horizontalScrollBar()->minimum() );
@@ -1139,18 +1071,18 @@ void PyConsole_Editor::paste()
   QTextCursor cur = textCursor();
   if ( cur.hasSelection() ) {
     int startSelection = cur.selectionStart();
-    if ( startSelection < document()->end().previous().position() + PROMPT_SIZE )
-      startSelection = document()->end().previous().position() + PROMPT_SIZE;
+    if ( startSelection < document()->end().previous().position() + promptSize() )
+      startSelection = document()->end().previous().position() + promptSize();
     int endSelection = cur.selectionEnd();
-    if ( endSelection < document()->end().previous().position() + PROMPT_SIZE )
-      endSelection = document()->end().previous().position() + PROMPT_SIZE;
+    if ( endSelection < document()->end().previous().position() + promptSize() )
+      endSelection = document()->end().previous().position() + promptSize();
     cur.setPosition( startSelection );
     cur.setPosition( endSelection, QTextCursor::KeepAnchor );
     horizontalScrollBar()->setValue( horizontalScrollBar()->minimum() );
     setTextCursor( cur );
     textCursor().removeSelectedText();
   }
-  if ( textCursor().position() < document()->end().previous().position() + PROMPT_SIZE )
+  if ( textCursor().position() < document()->end().previous().position() + promptSize() )
     moveCursor( QTextCursor::End );
   QTextEdit::paste();
 }
index 6bcc53a55445c28350ee0176736d1b427b862d62..2e1c80630a427efaee43996ca34930c93f0d61b6 100644 (file)
@@ -43,7 +43,7 @@ public:
   PyConsole_Editor( PyConsole_Interp* theInterp, QWidget *theParent = 0 );
   ~PyConsole_Editor();
   
-  virtual void   addText( const QString& str, const bool newBlock = false ); 
+  virtual void   addText( const QString& str, const bool newBlock = false, const bool isError = false );
   bool           isCommand( const QString& str ) const;
 
   virtual void   exec( const QString& command );
@@ -60,6 +60,14 @@ public:
 
   virtual QSize  sizeHint() const;
 
+public slots:
+    void           cut();
+    void           paste();
+    void           clear();
+    void           handleReturn();
+    void           onPyInterpChanged( PyConsole_Interp* );
+    void           dump();
+
 protected:
   virtual void   dropEvent( QDropEvent* event );
   virtual void   mouseReleaseEvent( QMouseEvent* event );
@@ -68,15 +76,9 @@ protected:
 
   virtual PyInterp_Request* createRequest( const QString& );
 
-public slots:
-  void           cut();
-  void           paste();
-  void           clear();
-  void           handleReturn();
-  void           onPyInterpChanged( PyConsole_Interp* );
-  void           dump();
-  
-private:
+  /** Convenience function */
+  inline int promptSize() const { return myPrompt.size(); }
+
   PyConsole_Interp* myInterp;           //!< python interpreter
 
   QString           myCommandBuffer;    //!< python command buffer
diff --git a/src/PyConsole/PyConsole_Event.cxx b/src/PyConsole/PyConsole_Event.cxx
new file mode 100644 (file)
index 0000000..ae0b665
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright (C) 2007-2013  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 : Vadim SANDLER (Open CASCADE S.A.S), Adrien Bruneton (CEA/DEN)
+
+#include "PyConsole_Event.h"
diff --git a/src/PyConsole/PyConsole_Event.h b/src/PyConsole/PyConsole_Event.h
new file mode 100644 (file)
index 0000000..b99a58d
--- /dev/null
@@ -0,0 +1,62 @@
+// Copyright (C) 2007-2013  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 : Vadim SANDLER (Open CASCADE S.A.S), Adrien Bruneton (CEA/DEN)
+
+#ifndef PYCONSOLE_EVENT_H
+#define PYCONSOLE_EVENT_H
+
+#include <QEvent>
+#include <QString>
+
+/*!
+  \class PrintEvent
+  \brief Python command output backend event.
+  \internal
+*/
+class PrintEvent : public QEvent
+{
+public:
+  static const int EVENT_ID = 65432;
+
+  /*!
+    \brief Constructor
+    \param c message text (python trace)
+  */
+  PrintEvent( const char* c, bool isError = false) :
+    QEvent( (QEvent::Type)EVENT_ID ), myText( c ), errorFlag(isError)
+  {}
+
+  /*!
+    \brief Get message
+    \return message text (python trace)
+  */
+  QString text() const { return myText; }
+  bool isError() const { return errorFlag; }
+
+protected:
+  QString myText; //!< Event message (python trace)
+
+  /** Set to true if an error msg is to be displayed */
+  bool errorFlag;
+};
+
+#endif // PYCONSOLE_EVENT_H
diff --git a/src/PyConsole/PyConsole_Request.cxx b/src/PyConsole/PyConsole_Request.cxx
new file mode 100644 (file)
index 0000000..7b00958
--- /dev/null
@@ -0,0 +1,56 @@
+// Copyright (C) 2007-2013  CEA/DEN, EDF 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
+//
+// Author : Adrien Bruneton (CEA/DEN)
+// Created on: 3 avr. 2013
+
+#include "PyConsole_Request.h"
+
+#include "PyInterp_Event.h"
+#include "PyConsole_Event.h"
+#include "PyInterp_Interp.h"
+#include "PyConsole_Editor.h"
+
+#include <QCoreApplication>
+
+ExecCommand::ExecCommand( PyInterp_Interp*        theInterp,
+               const QString&          theCommand,
+               PyConsole_Editor*       theListener,
+               bool                    sync )
+    : PyInterp_LockRequest( theInterp, theListener, sync ),
+      myCommand( theCommand ), myState( PyInterp_Event::ES_OK )
+  {}
+
+void ExecCommand::execute()
+{
+  if ( myCommand != "" )
+    {
+      int ret = getInterp()->run( myCommand.toUtf8().data() );
+      if ( ret < 0 )
+        myState = PyInterp_Event::ES_ERROR;
+      else if ( ret > 0 )
+        myState = PyInterp_Event::ES_INCOMPLETE;
+    }
+}
+
+QEvent* ExecCommand::createEvent() const
+{
+  if ( IsSync() )
+    QCoreApplication::sendPostedEvents( listener(), PrintEvent::EVENT_ID );
+  return new PyInterp_Event( myState, (PyInterp_Request*)this );
+}
diff --git a/src/PyConsole/PyConsole_Request.h b/src/PyConsole/PyConsole_Request.h
new file mode 100644 (file)
index 0000000..e4f2080
--- /dev/null
@@ -0,0 +1,75 @@
+// Copyright (C) 2007-2013  CEA/DEN, EDF 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
+//
+// Author : Adrien Bruneton (CEA/DEN)
+// Created on: 3 avr. 2013
+
+
+#ifndef PYCONSOLE_REQUEST_H_
+#define PYCONSOLE_REQUEST_H_
+
+#include "PyInterp_Request.h"
+
+#include <QString>
+#include <QEvent>
+
+class PyInterp_Interp;
+class PyConsole_Editor;
+
+/*!
+  \class ExecCommand
+  \brief Python command execution request.
+  \internal
+*/
+class ExecCommand : public PyInterp_LockRequest
+{
+public:
+  /*!
+    \brief Constructor.
+
+    Creates new python command execution request.
+    \param theInterp   python interpreter
+    \param theCommand  python command
+    \param theListener widget to get the notification messages
+    \param sync        if True the request is processed synchronously
+  */
+  ExecCommand( PyInterp_Interp*        theInterp,
+               const QString&          theCommand,
+               PyConsole_Editor*       theListener,
+               bool                    sync = false );
+
+protected:
+  /*!
+    \brief Execute the python command in the interpreter and
+           get its execution status.
+  */
+  virtual void execute();
+
+  /*!
+    \brief Create and return a notification event.
+    \return new notification event
+  */
+  virtual QEvent* createEvent() const;
+
+private:
+  QString myCommand;   //!< Python command
+  int     myState;     //!< Python command execution status
+};
+
+
+#endif /* PYCONSOLE_REQUEST_H_ */
index 425fa8b051d604b59f50145c58c5e4ce57f4e8fa..3267a4d93f30c5cecb1166d120ddd942a6caaf25 100755 (executable)
@@ -34,6 +34,8 @@ QT4_WRAP_CPP(GUI_HEADERS_MOC ${GUI_HEADERS})
 SET(PyInterp_SOURCES
   PyInterp_Interp.cxx
   PyInterp_Dispatcher.cxx
+  PyInterp_Event.cxx
+  PyInterp_Request.cxx
 )
 
 ADD_DEFINITIONS(${QT_DEFINITIONS} ${PYTHON_DEFINITIONS})
@@ -46,5 +48,7 @@ SET(COMMON_HEADERS_H
   PyInterp.h
   PyInterp_Interp.h
   PyInterp_Dispatcher.h
+  PyInterp_Event.h
+  PyInterp_Request.h
 )
 INSTALL(FILES ${COMMON_HEADERS_H} DESTINATION ${GUI_salomeinclude_HEADERS})
index 5e7643547b2589d56ec2d05c7e3b6d2608c65b3c..acaeafec9c74c7376a86386caa4bf550a1494e97 100755 (executable)
 #include "PyInterp_Dispatcher.h"   // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
 #include "PyInterp_Interp.h"
 #include "PyInterp_Watcher.h"
-#include <SALOME_Event.h>
+#include "PyInterp_Request.h"
 
 #include <QObject>
 #include <QCoreApplication>
 
-class PyInterp_ExecuteEvent: public SALOME_Event
-{
-public:
-  PyInterp_Request* myRequest;
-  PyInterp_ExecuteEvent( PyInterp_Request* r )
-    : myRequest( r ) {}
-  virtual void Execute()
-  {
-    myRequest->execute();
-  }
-};
-
 PyInterp_Dispatcher* PyInterp_Dispatcher::myInstance = 0;
 
 void PyInterp_Request::process()
index 793124d2b3c62380df9a4a6149d7e419d050ce8f..4cc9a55f3ad5deaf7f62ba84c61db4775309c03d 100755 (executable)
 
 //  File   : PyInterp_Dispatcher.h
 //  Author : Sergey Anikin, OCC
-//  Module : SALOME
+//  Module : GUI
 //
 #ifndef PYINTERP_DISPATCHER_H
 #define PYINTERP_DISPATCHER_H
 
 #include "PyInterp.h"   // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
 
+#include "PyInterp_Request.h"   // full include instead of forward declaration
+                                // everyone inc'ing the Dispatcher will get the requests for free.
+
 #include <QMutex>
 #include <QThread>
-#include <QEvent>
 #include <QQueue>
 
 class QObject;
-
-class PyInterp_Interp;
 class PyInterp_Watcher;
-class PyInterp_Dispatcher;
-class PyInterp_ExecuteEvent;
-
-class PYINTERP_EXPORT PyInterp_Request
-{
-  friend class PyInterp_Dispatcher;
-  friend class PyInterp_ExecuteEvent;
-
-  PyInterp_Request();
-  PyInterp_Request( const PyInterp_Request& );
-
-protected:
-  virtual ~PyInterp_Request() {};
-  // protected destructor - to control deletion of requests
-
-public:
-  PyInterp_Request( QObject* listener, bool sync = false )
-    : myIsSync( sync ), myListener( listener ) {};
-
-  static void     Destroy( PyInterp_Request* );
-  // Deletes a request
-
-  bool            IsSync() const { return myIsSync; }
-  // Returns true if this request should be processed synchronously,
-  // without putting it to a queue
-
-protected:
-  virtual void    safeExecute();
-
-  virtual void    execute() = 0;
-  // Should be redefined in successors, contains actual request code
-
-  virtual QEvent* createEvent() const;
-  // This method can be overridden to customize notification event creation
-
-  virtual void    processEvent( QObject* );
-
-  QObject*        listener() const { return myListener; }
-  void            setListener( QObject* );
-
-private:
-  void            process();
-
-private:
-  QMutex          myMutex;
-  bool            myIsSync;
-  QObject*        myListener;
-};
-
-class PYINTERP_EXPORT PyInterp_LockRequest : public PyInterp_Request
-{
-public:
-  PyInterp_LockRequest( PyInterp_Interp* interp, QObject* listener = 0, bool sync = false )
-    : PyInterp_Request( listener, sync ), myInterp( interp ) {}
-
-protected:
-  PyInterp_Interp*  getInterp() const { return myInterp; }
-
-  virtual void      safeExecute();
-
-private:
-  PyInterp_Interp*  myInterp;
-};
-
-class PYINTERP_EXPORT PyInterp_Event : public QEvent
-{
-  PyInterp_Event();
-  PyInterp_Event( const PyInterp_Event& );
-
-public:
-  //Execution state
-  enum { ES_NOTIFY = QEvent::User + 5000, ES_OK, ES_ERROR, ES_INCOMPLETE, ES_LAST };
-
-  PyInterp_Event( int type, PyInterp_Request* request )
-    : QEvent( (QEvent::Type)type ), myRequest( request ) {}
-
-  virtual ~PyInterp_Event();
-
-  PyInterp_Request* GetRequest() const { return myRequest; }
-  operator PyInterp_Request*() const { return myRequest; }
-
-private:
-  PyInterp_Request* myRequest;
-};
 
 class PYINTERP_EXPORT PyInterp_Dispatcher : protected QThread
 {
diff --git a/src/PyInterp/PyInterp_Event.cxx b/src/PyInterp/PyInterp_Event.cxx
new file mode 100644 (file)
index 0000000..7027f6e
--- /dev/null
@@ -0,0 +1,32 @@
+// Copyright (C) 2007-2013  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   : PyInterp_Request.h
+//  Author : Sergey Anikin, OCC, Adrien Bruneton (CEA/DEN)
+//  Module : GUI
+
+#include "PyInterp_Event.h"
+#include "PyInterp_Request.h"
+
+void PyInterp_ExecuteEvent::Execute()
+{
+  myRequest->execute();
+}
diff --git a/src/PyInterp/PyInterp_Event.h b/src/PyInterp/PyInterp_Event.h
new file mode 100644 (file)
index 0000000..cab3dcd
--- /dev/null
@@ -0,0 +1,72 @@
+
+// Copyright (C) 2007-2013  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   : PyInterp_Request.h
+//  Author : Sergey Anikin, OCC, Adrien Bruneton (CEA/DEN)
+//  Module : GUI
+
+#ifndef PYINTERP_EVENT_H
+#define PYINTERP_EVENT_H
+
+#include "PyInterp.h"
+
+#include <SALOME_Event.h>
+
+#include <QEvent>
+
+class PyInterp_Request;
+
+class PyInterp_ExecuteEvent: public SALOME_Event
+{
+public:
+  PyInterp_ExecuteEvent( PyInterp_Request* r )
+    : myRequest( r ) {}
+
+  virtual void Execute();
+
+protected:
+  PyInterp_Request* myRequest;
+};
+
+
+class PYINTERP_EXPORT PyInterp_Event : public QEvent
+{
+  PyInterp_Event();
+  PyInterp_Event( const PyInterp_Event& );
+
+public:
+  //Execution state
+  enum { ES_NOTIFY = QEvent::User + 5000, ES_OK, ES_ERROR, ES_INCOMPLETE, ES_LAST };
+
+  PyInterp_Event( int type, PyInterp_Request* request )
+    : QEvent( (QEvent::Type)type ), myRequest( request ) {}
+
+  virtual ~PyInterp_Event();
+
+  PyInterp_Request* GetRequest() const { return myRequest; }
+  operator PyInterp_Request*() const { return myRequest; }
+
+private:
+  PyInterp_Request* myRequest;
+};
+
+#endif // PYINTERP_EVENT_H
diff --git a/src/PyInterp/PyInterp_Request.cxx b/src/PyInterp/PyInterp_Request.cxx
new file mode 100644 (file)
index 0000000..4ace035
--- /dev/null
@@ -0,0 +1,66 @@
+// Copyright (C) 2007-2013  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   : PyInterp_Request.h
+//  Author : Sergey Anikin, OCC, Adrien Bruneton (CEA/DEN)
+//  Module : GUI
+
+#include "PyInterp_Request.h"
+
+/*!
+  \class ExecCommand
+  \brief Python command execution request.
+  \internal
+*/
+class ExecCommand : public PyInterp_LockRequest
+{
+public:
+  /*!
+    \brief Constructor.
+
+    Creates new python command execution request.
+    \param theInterp   python interpreter
+    \param theCommand  python command
+    \param theListener widget to get the notification messages
+    \param sync        if True the request is processed synchronously
+  */
+  ExecCommand( PyInterp_Interp*        theInterp,
+               const QString&          theCommand,
+               PyConsole_Editor*       theListener,
+               bool                    sync = false );
+
+protected:
+  /*!
+    \brief Execute the python command in the interpreter and
+           get its execution status.
+  */
+  virtual void execute();
+
+  /*!
+    \brief Create and return a notification event.
+    \return new notification event
+  */
+  virtual QEvent* createEvent() const;
+
+  QString myCommand;   //!< Python command
+  int     myState;     //!< Python command execution status
+};
+
diff --git a/src/PyInterp/PyInterp_Request.h b/src/PyInterp/PyInterp_Request.h
new file mode 100644 (file)
index 0000000..1531064
--- /dev/null
@@ -0,0 +1,104 @@
+// Copyright (C) 2007-2013  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   : PyInterp_Request.h
+//  Author : Sergey Anikin (OCC), Adrien Bruneton (CEA/DEN)
+//  Module : GUI
+
+#ifndef PYINTERP_REQUEST_H
+#define PYINTERP_REQUEST_H
+
+#include "PyInterp.h"
+#include "PyInterp_Event.h"
+
+#include <QMutex>
+#include <QObject>
+
+class PyInterp_Interp;
+class PyInterp_Watcher;
+class PyInterp_Dispatcher;
+class PyInterp_ExecuteEvent;
+class PyConsole_Editor;
+
+class PYINTERP_EXPORT PyInterp_Request
+{
+  friend class PyInterp_Dispatcher;
+  friend class PyInterp_ExecuteEvent;
+
+  PyInterp_Request();
+  PyInterp_Request( const PyInterp_Request& );
+
+protected:
+  virtual ~PyInterp_Request() {};
+  // protected destructor - to control deletion of requests
+
+public:
+  PyInterp_Request( QObject* listener, bool sync = false )
+    : myIsSync( sync ), myListener( listener ) {};
+
+  static void     Destroy( PyInterp_Request* );
+  // Deletes a request
+
+  bool            IsSync() const { return myIsSync; }
+  // Returns true if this request should be processed synchronously,
+  // without putting it to a queue
+
+protected:
+  virtual void    safeExecute();
+
+  virtual void    execute() = 0;
+  // Should be redefined in successors, contains actual request code
+
+  virtual QEvent* createEvent() const;
+  // This method can be overridden to customize notification event creation
+
+  virtual void    processEvent( QObject* );
+
+  QObject*        listener() const { return myListener; }
+  void            setListener( QObject* );
+
+private:
+  void            process();
+
+private:
+  QMutex          myMutex;
+  bool            myIsSync;
+  QObject*        myListener;
+};
+
+class PYINTERP_EXPORT PyInterp_LockRequest : public PyInterp_Request
+{
+public:
+
+  PyInterp_LockRequest( PyInterp_Interp* interp, QObject* listener = 0, bool sync = false )
+    : PyInterp_Request( listener, sync ), myInterp( interp )
+  {}
+
+protected:
+  PyInterp_Interp*  getInterp() const { return myInterp; }
+
+  virtual void      safeExecute();
+
+private:
+  PyInterp_Interp*  myInterp;
+};
+
+#endif // PYINTERP_REQUEST_H
index fd0b56ab001a0d1b94ffcb4418979c74786cdfd1..8e6e6086aabaf25621d73b4cc193374e6d9b8356 100755 (executable)
@@ -39,6 +39,7 @@ INCLUDE_DIRECTORIES(
   ${CMAKE_CURRENT_SOURCE_DIR}/../../SUITApp
   ${CMAKE_CURRENT_SOURCE_DIR}/../../CAM
   ${CMAKE_CURRENT_SOURCE_DIR}/../../STD
+  ${CMAKE_CURRENT_SOURCE_DIR}/../../Event
 )
 
 SET(COMMON_LIBS ${PYTHON_LIBRARIES} ${PYQT_LIBRARIES} ${VTK_LIBRARIES} ${OPENGL_LIBRARIES} PyInterp LightApp)