From: bruneton Date: Thu, 4 Apr 2013 10:41:41 +0000 (+0000) Subject: PyConsole: error messages printed in red in the console. X-Git-Tag: V6_main_FINAL~11 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=09e5432ca6312573ec75e70d582ced1d6b52109b;p=modules%2Fgui.git PyConsole: error messages printed in red in the console. Also re-organized the code to prepare auto-completion. --- diff --git a/src/PyConsole/CMakeLists.txt b/src/PyConsole/CMakeLists.txt index 207955106..48a250f63 100755 --- a/src/PyConsole/CMakeLists.txt +++ b/src/PyConsole/CMakeLists.txt @@ -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}") diff --git a/src/PyConsole/PyConsole_Editor.cxx b/src/PyConsole/PyConsole_Editor.cxx index 3414e26a6..049eabb42 100644 --- a/src/PyConsole/PyConsole_Editor.cxx +++ b/src/PyConsole/PyConsole_Editor.cxx @@ -95,7 +95,10 @@ #include "PyConsole_Interp.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! #include "PyConsole_Editor.h" -#include +#include "PyConsole_Event.h" +#include "PyInterp_Event.h" +#include "PyInterp_Dispatcher.h" +#include "PyConsole_Request.h" #include #include @@ -116,10 +119,6 @@ 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 + 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(); } diff --git a/src/PyConsole/PyConsole_Editor.h b/src/PyConsole/PyConsole_Editor.h index 6bcc53a55..2e1c80630 100644 --- a/src/PyConsole/PyConsole_Editor.h +++ b/src/PyConsole/PyConsole_Editor.h @@ -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 index 000000000..ae0b66594 --- /dev/null +++ b/src/PyConsole/PyConsole_Event.cxx @@ -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 index 000000000..b99a58d58 --- /dev/null +++ b/src/PyConsole/PyConsole_Event.h @@ -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 +#include + +/*! + \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 index 000000000..7b0095862 --- /dev/null +++ b/src/PyConsole/PyConsole_Request.cxx @@ -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 + +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 index 000000000..e4f20801f --- /dev/null +++ b/src/PyConsole/PyConsole_Request.h @@ -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 +#include + +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_ */ diff --git a/src/PyInterp/CMakeLists.txt b/src/PyInterp/CMakeLists.txt index 425fa8b05..3267a4d93 100755 --- a/src/PyInterp/CMakeLists.txt +++ b/src/PyInterp/CMakeLists.txt @@ -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}) diff --git a/src/PyInterp/PyInterp_Dispatcher.cxx b/src/PyInterp/PyInterp_Dispatcher.cxx index 5e7643547..acaeafec9 100755 --- a/src/PyInterp/PyInterp_Dispatcher.cxx +++ b/src/PyInterp/PyInterp_Dispatcher.cxx @@ -27,23 +27,11 @@ #include "PyInterp_Dispatcher.h" // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!! #include "PyInterp_Interp.h" #include "PyInterp_Watcher.h" -#include +#include "PyInterp_Request.h" #include #include -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() diff --git a/src/PyInterp/PyInterp_Dispatcher.h b/src/PyInterp/PyInterp_Dispatcher.h index 793124d2b..4cc9a55f3 100755 --- a/src/PyInterp/PyInterp_Dispatcher.h +++ b/src/PyInterp/PyInterp_Dispatcher.h @@ -22,106 +22,22 @@ // 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 #include -#include #include 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 index 000000000..7027f6e21 --- /dev/null +++ b/src/PyInterp/PyInterp_Event.cxx @@ -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 index 000000000..cab3dcd8d --- /dev/null +++ b/src/PyInterp/PyInterp_Event.h @@ -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 + +#include + +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 index 000000000..4ace03545 --- /dev/null +++ b/src/PyInterp/PyInterp_Request.cxx @@ -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 index 000000000..15310648b --- /dev/null +++ b/src/PyInterp/PyInterp_Request.h @@ -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 +#include + +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 diff --git a/src/SALOME_PYQT/SALOME_PYQT_GUILight/CMakeLists.txt b/src/SALOME_PYQT/SALOME_PYQT_GUILight/CMakeLists.txt index fd0b56ab0..8e6e6086a 100755 --- a/src/SALOME_PYQT/SALOME_PYQT_GUILight/CMakeLists.txt +++ b/src/SALOME_PYQT/SALOME_PYQT_GUILight/CMakeLists.txt @@ -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)