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 PyConsole_Interp* anInterp = interp ? interp : new PyConsole_Interp();
57 // initialize Python interpretator
58 anInterp->initialize();
60 // create editor console
61 QVBoxLayout* lay = new QVBoxLayout( this );
63 myEditor = new PyConsole_Editor( anInterp, this );
64 char* synchronous = getenv("PYTHON_CONSOLE_SYNC");
65 if (synchronous && atoi(synchronous))
67 myEditor->setIsSync(true);
69 myEditor->viewport()->installEventFilter( this );
70 lay->addWidget( myEditor );
76 * Protected constructor.
78 PyConsole_Console::PyConsole_Console( QWidget* parent, PyConsole_Interp* /*i*/, PyConsole_Editor* e )
79 : QWidget (parent), myEditor(e)
85 Does nothing for the moment.
87 PyConsole_Console::~PyConsole_Console()
91 PyConsole_Interp* PyConsole_Console::getInterp() const
93 return myEditor ? myEditor->getInterp() : 0;
97 \brief Execute python command in the interpreter.
98 \param command string with command and arguments
100 void PyConsole_Console::exec( const QString& command )
103 myEditor->exec( command );
107 \brief Execute python command in the interpreter
108 and wait until it is finished.
110 Block execution of main application until the python command is executed.
111 \param command string with command and arguments
113 void PyConsole_Console::execAndWait( const QString& command )
116 myEditor->execAndWait( command );
120 \brief Get synchronous mode flag value.
123 \return True if python console works in synchronous mode
125 bool PyConsole_Console::isSync() const
127 return myEditor->isSync();
131 \brief Set synchronous mode flag value.
133 In synhronous mode the Python commands are executed in the GUI thread
134 and the GUI is blocked until the command is finished. In the asynchronous
135 mode each Python command is executed in the separate thread that does not
136 block the main GUI loop.
138 \param on synhronous mode flag
140 void PyConsole_Console::setIsSync( const bool on )
142 myEditor->setIsSync( on );
146 \brief Get suppress output flag value.
148 \sa setIsSuppressOutput()
149 \return True if python console output is suppressed.
151 bool PyConsole_Console::isSuppressOutput() const
153 return myEditor->isSuppressOutput();
157 \brief Set suppress output flag value.
159 In case if suppress output flag is true, the python
160 console output suppressed.
162 \param on suppress output flag
164 void PyConsole_Console::setIsSuppressOutput( const bool on )
166 myEditor->setIsSuppressOutput(on);
170 \brief Get 'show banner' flag value.
172 \sa setIsShowBanner()
173 \return \c true if python console shows banner
175 bool PyConsole_Console::isShowBanner() const
177 return myEditor->isShowBanner();
181 \brief Set 'show banner' flag value.
183 The banner is shown in the top of the python console window.
186 \param on 'show banner' flag
188 void PyConsole_Console::setIsShowBanner( const bool on )
190 myEditor->setIsShowBanner( on );
194 \brief Change the python console's font.
197 void PyConsole_Console::setFont( const QFont& f )
200 myEditor->setFont( f );
204 \brief Get python console font.
205 \return current python console's font
207 QFont PyConsole_Console::font() const
211 res = myEditor->font();
216 \brief Event handler.
218 Handles context menu request event.
222 \return True if the event is processed and further processing should be stopped
224 bool PyConsole_Console::eventFilter( QObject* o, QEvent* e )
226 if ( o == myEditor->viewport() && e->type() == QEvent::ContextMenu )
228 contextMenuRequest( (QContextMenuEvent*)e );
231 return QWidget::eventFilter( o, e );
235 \brief Create the context popup menu.
237 Fill in the popup menu with the commands.
239 \param menu context popup menu
241 void PyConsole_Console::contextMenuPopup( QMenu* menu )
243 if ( myEditor->isReadOnly() )
246 menu->addAction( myActions[CopyId] );
247 menu->addAction( myActions[PasteId] );
248 menu->addAction( myActions[ClearId] );
249 menu->addSeparator();
250 menu->addAction( myActions[SelectAllId] );
251 menu->addSeparator();
252 menu->addAction( myActions[DumpCommandsId] );
253 if ( !myEditor->isLogging() )
254 menu->addAction( myActions[StartLogId] );
256 menu->addAction( myActions[StopLogId] );
258 Qtx::simplifySeparators( menu );
264 \brief Set actions to be visible in the context popup menu.
266 Actions, which IDs are set in \a flags parameter, will be shown in the
267 context popup menu. Other actions will not be shown.
269 \param flags ORed together actions flags
271 void PyConsole_Console::setMenuActions( const int flags )
273 myActions[CopyId]->setVisible( flags & CopyId );
274 myActions[PasteId]->setVisible( flags & PasteId );
275 myActions[ClearId]->setVisible( flags & ClearId );
276 myActions[SelectAllId]->setVisible( flags & SelectAllId );
277 myActions[DumpCommandsId]->setVisible( flags & DumpCommandsId );
278 myActions[StartLogId]->setVisible( flags & StartLogId );
279 myActions[StopLogId]->setVisible( flags & StopLogId );
283 \brief Get menu actions which are currently visible in the context popup menu.
284 \return ORed together actions flags
287 int PyConsole_Console::menuActions() const
290 ret = ret | ( myActions[CopyId]->isVisible() ? CopyId : 0 );
291 ret = ret | ( myActions[PasteId]->isVisible() ? PasteId : 0 );
292 ret = ret | ( myActions[ClearId]->isVisible() ? ClearId : 0 );
293 ret = ret | ( myActions[SelectAllId]->isVisible() ? SelectAllId : 0 );
294 ret = ret | ( myActions[DumpCommandsId]->isVisible() ? DumpCommandsId : 0 );
295 ret = ret | ( myActions[StartLogId]->isVisible() ? StartLogId : 0 );
296 ret = ret | ( myActions[StopLogId]->isVisible() ? StopLogId : 0 );
301 \brief Create menu actions.
303 Create context popup menu actions.
305 void PyConsole_Console::createActions()
307 QAction* a = new QAction( tr( "EDIT_COPY_CMD" ), this );
308 a->setStatusTip( tr( "EDIT_COPY_CMD" ) );
309 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) );
310 myActions.insert( CopyId, a );
312 a = new QAction( tr( "EDIT_PASTE_CMD" ), this );
313 a->setStatusTip( tr( "EDIT_PASTE_CMD" ) );
314 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) );
315 myActions.insert( PasteId, a );
317 a = new QAction( tr( "EDIT_CLEAR_CMD" ), this );
318 a->setStatusTip( tr( "EDIT_CLEAR_CMD" ) );
319 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( clear() ) );
320 myActions.insert( ClearId, a );
322 a = new QAction( tr( "EDIT_SELECTALL_CMD" ), this );
323 a->setStatusTip( tr( "EDIT_SELECTALL_CMD" ) );
324 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) );
325 myActions.insert( SelectAllId, a );
327 a = new QAction( tr( "EDIT_DUMPCOMMANDS_CMD" ), this );
328 a->setStatusTip( tr( "EDIT_DUMPCOMMANDS_CMD" ) );
329 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( dump() ) );
330 myActions.insert( DumpCommandsId, a );
332 a = new QAction( tr( "EDIT_STARTLOG_CMD" ), this );
333 a->setStatusTip( tr( "EDIT_STARTLOG_CMD" ) );
334 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( startLog() ) );
335 myActions.insert( StartLogId, a );
337 a = new QAction( tr( "EDIT_STOPLOG_CMD" ), this );
338 a->setStatusTip( tr( "EDIT_STOPLOG_CMD" ) );
339 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( stopLog() ) );
340 myActions.insert( StopLogId, a );
344 \brief Update menu actions.
346 Update context popup menu action state.
348 void PyConsole_Console::updateActions()
350 myActions[CopyId]->setEnabled( myEditor->textCursor().hasSelection() );
351 myActions[PasteId]->setEnabled( !myEditor->isReadOnly() && !QApplication::clipboard()->text().isEmpty() );
352 myActions[SelectAllId]->setEnabled( !myEditor->document()->isEmpty() );
356 \brief Start python trace logging
357 \param fileName the path to the log file
359 void PyConsole_Console::startLog( const QString& fileName )
361 myEditor->startLog( fileName );
365 \brief Stop python trace logging
367 void PyConsole_Console::stopLog()
373 * Similar to constructor of the base class but using enhanced objects.
374 * TODO: this should really be done in a factory to avoid code duplication.
378 PyConsole_EnhConsole::PyConsole_EnhConsole( QWidget* parent, PyConsole_Interp* interp )
379 : PyConsole_Console( parent, interp, 0 )
381 PyConsole_Interp* anInterp = interp ? interp : new PyConsole_EnhInterp();
383 // initialize Python interpretator
384 anInterp->initialize();
386 // create editor console
387 QVBoxLayout* lay = new QVBoxLayout( this );
389 myEditor = new PyConsole_EnhEditor( anInterp, this );
390 char* synchronous = getenv("PYTHON_CONSOLE_SYNC");
391 if (synchronous && atoi(synchronous))
393 myEditor->setIsSync(true);
395 myEditor->viewport()->installEventFilter( this );
396 lay->addWidget( myEditor );