1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File : PyConsole_Console.cxx
24 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
27 \class PyConsole_Console
28 \brief Python console widget.
31 #include "PyConsole_Interp.h" /// !!! WARNING !!! THIS INCLUDE MUST BE VERY FIRST !!!
32 #include "PyConsole_Console.h"
33 #include "PyConsole_EnhEditor.h"
34 #include "PyConsole_EnhInterp.h"
39 #include <QApplication>
43 #include <QVBoxLayout>
48 Creates new python console widget.
49 \param parent parent widget
50 \param interp python interpreter
52 PyConsole_Console::PyConsole_Console( QWidget* parent, PyConsole_Interp* interp )
55 // create python interpreter
58 myInterp = new PyConsole_Interp();
60 // initialize Python interpretator
61 myInterp->initialize();
63 // create editor console
64 QVBoxLayout* lay = new QVBoxLayout( this );
66 myEditor = new PyConsole_Editor( myInterp, this );
67 char* synchronous = getenv("PYTHON_CONSOLE_SYNC");
68 if (synchronous && atoi(synchronous))
70 myEditor->setIsSync(true);
72 myEditor->viewport()->installEventFilter( this );
73 lay->addWidget( myEditor );
79 * Protected constructor.
81 PyConsole_Console::PyConsole_Console( QWidget* parent, PyConsole_Interp* i, PyConsole_Editor* e)
82 : QWidget (parent), myEditor(e), myInterp(i)
88 Does nothing for the moment.
90 PyConsole_Console::~PyConsole_Console()
95 \brief Execute python command in the interpreter.
96 \param command string with command and arguments
98 void PyConsole_Console::exec( const QString& command )
101 myEditor->exec( command );
105 \brief Execute python command in the interpreter
106 and wait until it is finished.
108 Block execution of main application until the python command is executed.
109 \param command string with command and arguments
111 void PyConsole_Console::execAndWait( const QString& command )
114 myEditor->execAndWait( command );
118 \brief Get synchronous mode flag value.
121 \return True if python console works in synchronous mode
123 bool PyConsole_Console::isSync() const
125 return myEditor->isSync();
129 \brief Set synchronous mode flag value.
131 In synhronous mode the Python commands are executed in the GUI thread
132 and the GUI is blocked until the command is finished. In the asynchronous
133 mode each Python command is executed in the separate thread that does not
134 block the main GUI loop.
136 \param on synhronous mode flag
138 void PyConsole_Console::setIsSync( const bool on )
140 myEditor->setIsSync( on );
144 \brief Get suppress output flag value.
146 \sa setIsSuppressOutput()
147 \return True if python console output is suppressed.
149 bool PyConsole_Console::isSuppressOutput() const
151 return myEditor->isSuppressOutput();
155 \brief Set suppress output flag value.
157 In case if suppress output flag is true, the python
158 console output suppressed.
160 \param on suppress output flag
162 void PyConsole_Console::setIsSuppressOutput( const bool on )
164 myEditor->setIsSuppressOutput(on);
168 \brief Get 'show banner' flag value.
170 \sa setIsShowBanner()
171 \return \c true if python console shows banner
173 bool PyConsole_Console::isShowBanner() const
175 return myEditor->isShowBanner();
179 \brief Set 'show banner' flag value.
181 The banner is shown in the top of the python console window.
184 \param on 'show banner' flag
186 void PyConsole_Console::setIsShowBanner( const bool on )
188 myEditor->setIsShowBanner( on );
192 \brief Change the python console's font.
195 void PyConsole_Console::setFont( const QFont& f )
198 myEditor->setFont( f );
202 \brief Get python console font.
203 \return current python console's font
205 QFont PyConsole_Console::font() const
209 res = myEditor->font();
214 \brief Event handler.
216 Handles context menu request event.
220 \return True if the event is processed and further processing should be stopped
222 bool PyConsole_Console::eventFilter( QObject* o, QEvent* e )
224 if ( o == myEditor->viewport() && e->type() == QEvent::ContextMenu )
226 contextMenuRequest( (QContextMenuEvent*)e );
229 return QWidget::eventFilter( o, e );
233 \brief Create the context popup menu.
235 Fill in the popup menu with the commands.
237 \param menu context popup menu
239 void PyConsole_Console::contextMenuPopup( QMenu* menu )
241 if ( myEditor->isReadOnly() )
244 menu->addAction( myActions[CopyId] );
245 menu->addAction( myActions[PasteId] );
246 menu->addAction( myActions[ClearId] );
247 menu->addSeparator();
248 menu->addAction( myActions[SelectAllId] );
249 menu->addSeparator();
250 menu->addAction( myActions[DumpCommandsId] );
251 if ( !myEditor->isLogging() )
252 menu->addAction( myActions[StartLogId] );
254 menu->addAction( myActions[StopLogId] );
256 Qtx::simplifySeparators( menu );
262 \brief Set actions to be visible in the context popup menu.
264 Actions, which IDs are set in \a flags parameter, will be shown in the
265 context popup menu. Other actions will not be shown.
267 \param flags ORed together actions flags
269 void PyConsole_Console::setMenuActions( const int flags )
271 myActions[CopyId]->setVisible( flags & CopyId );
272 myActions[PasteId]->setVisible( flags & PasteId );
273 myActions[ClearId]->setVisible( flags & ClearId );
274 myActions[SelectAllId]->setVisible( flags & SelectAllId );
275 myActions[DumpCommandsId]->setVisible( flags & DumpCommandsId );
276 myActions[StartLogId]->setVisible( flags & StartLogId );
277 myActions[StopLogId]->setVisible( flags & StopLogId );
281 \brief Get menu actions which are currently visible in the context popup menu.
282 \return ORed together actions flags
285 int PyConsole_Console::menuActions() const
288 ret = ret | ( myActions[CopyId]->isVisible() ? CopyId : 0 );
289 ret = ret | ( myActions[PasteId]->isVisible() ? PasteId : 0 );
290 ret = ret | ( myActions[ClearId]->isVisible() ? ClearId : 0 );
291 ret = ret | ( myActions[SelectAllId]->isVisible() ? SelectAllId : 0 );
292 ret = ret | ( myActions[DumpCommandsId]->isVisible() ? DumpCommandsId : 0 );
293 ret = ret | ( myActions[StartLogId]->isVisible() ? StartLogId : 0 );
294 ret = ret | ( myActions[StopLogId]->isVisible() ? StopLogId : 0 );
299 \brief Create menu actions.
301 Create context popup menu actions.
303 void PyConsole_Console::createActions()
305 QAction* a = new QAction( tr( "EDIT_COPY_CMD" ), this );
306 a->setStatusTip( tr( "EDIT_COPY_CMD" ) );
307 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) );
308 myActions.insert( CopyId, a );
310 a = new QAction( tr( "EDIT_PASTE_CMD" ), this );
311 a->setStatusTip( tr( "EDIT_PASTE_CMD" ) );
312 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) );
313 myActions.insert( PasteId, a );
315 a = new QAction( tr( "EDIT_CLEAR_CMD" ), this );
316 a->setStatusTip( tr( "EDIT_CLEAR_CMD" ) );
317 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( clear() ) );
318 myActions.insert( ClearId, a );
320 a = new QAction( tr( "EDIT_SELECTALL_CMD" ), this );
321 a->setStatusTip( tr( "EDIT_SELECTALL_CMD" ) );
322 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) );
323 myActions.insert( SelectAllId, a );
325 a = new QAction( tr( "EDIT_DUMPCOMMANDS_CMD" ), this );
326 a->setStatusTip( tr( "EDIT_DUMPCOMMANDS_CMD" ) );
327 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( dump() ) );
328 myActions.insert( DumpCommandsId, a );
330 a = new QAction( tr( "EDIT_STARTLOG_CMD" ), this );
331 a->setStatusTip( tr( "EDIT_STARTLOG_CMD" ) );
332 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( startLog() ) );
333 myActions.insert( StartLogId, a );
335 a = new QAction( tr( "EDIT_STOPLOG_CMD" ), this );
336 a->setStatusTip( tr( "EDIT_STOPLOG_CMD" ) );
337 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( stopLog() ) );
338 myActions.insert( StopLogId, a );
342 \brief Update menu actions.
344 Update context popup menu action state.
346 void PyConsole_Console::updateActions()
348 myActions[CopyId]->setEnabled( myEditor->textCursor().hasSelection() );
349 myActions[PasteId]->setEnabled( !myEditor->isReadOnly() && !QApplication::clipboard()->text().isEmpty() );
350 myActions[SelectAllId]->setEnabled( !myEditor->document()->isEmpty() );
354 \brief Start python trace logging
355 \param fileName the path to the log file
357 void PyConsole_Console::startLog( const QString& fileName )
359 myEditor->startLog( fileName );
363 \brief Stop python trace logging
365 void PyConsole_Console::stopLog()
371 * Similar to constructor of the base class but using enhanced objects.
372 * TODO: this should really be done in a factory to avoid code duplication.
376 PyConsole_EnhConsole::PyConsole_EnhConsole( QWidget* parent, PyConsole_EnhInterp* interp)
377 : PyConsole_Console(parent, interp, 0)
379 // create python interpreter
382 myInterp = new PyConsole_EnhInterp();
384 // initialize Python interpretator
385 myInterp->initialize();
387 // create editor console
388 QVBoxLayout* lay = new QVBoxLayout( this );
390 myEditor = new PyConsole_EnhEditor( static_cast<PyConsole_EnhInterp*>(myInterp), this );
391 char* synchronous = getenv("PYTHON_CONSOLE_SYNC");
392 if (synchronous && atoi(synchronous))
394 myEditor->setIsSync(true);
396 myEditor->viewport()->installEventFilter( this );
397 lay->addWidget( myEditor );