1 // Copyright (C) 2007-2016 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
22 // File : PyConsole_Console.cxx
23 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
25 #include "PyConsole_Console.h"
26 #include "PyConsole_Interp.h"
27 #include "PyConsole_Editor.h"
30 #include <QApplication>
32 #include <QContextMenuEvent>
34 #include <QVBoxLayout>
37 \class PyConsole_Console
38 \brief Python console widget.
40 To create a Python console, just use default contstructor, specifying only a parent widget:
42 PyConsole_Console c(myWindow);
45 This will create a console with default editor and interpreter.
47 To use custom editor with the console, you can use alternative constructor:
49 PyConsole_Console c(myWindow, new MyEditor());
54 \brief Default constructor.
56 Creates new python console widget.
57 \param parent parent widget
59 PyConsole_Console::PyConsole_Console( QWidget* parent )
68 Creates new python console widget.
69 \param parent parent widget
70 \param editor python editor
72 PyConsole_Console::PyConsole_Console( QWidget* parent, PyConsole_Editor* editor )
79 \brief Initialize console widget.
80 \param editor python editor
82 void PyConsole_Console::init( PyConsole_Editor* editor )
84 // initialize Python interpretator
85 PyConsole_Interp* interp = editor ? editor->getInterp() : new PyConsole_Interp();
88 // create editor console
89 QVBoxLayout* lay = new QVBoxLayout( this );
91 myEditor = editor ? editor : new PyConsole_Editor( this, interp );
92 myEditor->setContextMenuPolicy( Qt::NoContextMenu );
93 lay->addWidget( myEditor );
95 // force synchronous mode
96 QString synchronous = qgetenv( "PYTHON_CONSOLE_SYNC" );
97 if ( !synchronous.isEmpty() && synchronous.toInt() > 0 )
107 PyConsole_Console::~PyConsole_Console()
112 \brief Get Python interpreter
113 \return pointer to Python interpreter
115 PyConsole_Interp* PyConsole_Console::getInterp() const
117 return myEditor ? myEditor->getInterp() : 0;
121 \brief Execute python command in the interpreter.
122 \param command string with command and arguments
124 void PyConsole_Console::exec( const QString& command )
127 myEditor->exec( command );
131 \brief Execute python command in the interpreter
132 and wait until it is finished.
134 Block execution of main application until the python command is executed.
135 \param command string with command and arguments
137 void PyConsole_Console::execAndWait( const QString& command )
140 myEditor->execAndWait( command );
144 \brief Get synchronous mode flag value.
147 \return \c true if python console works in synchronous mode
149 bool PyConsole_Console::isSync() const
151 return myEditor ? myEditor->isSync() : false;
155 \brief Set synchronous mode flag value.
157 In synhronous mode the Python commands are executed in the GUI thread
158 and the GUI is blocked until the command is finished. In the asynchronous
159 mode each Python command is executed in the separate thread that does not
160 block the main GUI loop.
162 \param on synhronous mode flag
164 void PyConsole_Console::setIsSync( const bool on )
167 myEditor->setIsSync( on );
171 \brief Get suppress output flag value.
173 \sa setIsSuppressOutput()
174 \return \c true if python console output is suppressed.
176 bool PyConsole_Console::isSuppressOutput() const
178 return myEditor ? myEditor->isSuppressOutput() : false;
182 \brief Set suppress output flag value.
184 In case if suppress output flag is \c true, the python
185 console output suppressed.
187 \param on suppress output flag
189 void PyConsole_Console::setIsSuppressOutput( const bool on )
192 myEditor->setIsSuppressOutput( on );
196 \brief Get 'show banner' flag value.
198 \sa setIsShowBanner()
199 \return \c true if python console shows banner
201 bool PyConsole_Console::isShowBanner() const
203 return myEditor ? myEditor->isShowBanner() : false;
207 \brief Set 'show banner' flag value.
209 The banner is shown in the top of the python console window.
212 \param on 'show banner' flag
214 void PyConsole_Console::setIsShowBanner( const bool on )
217 myEditor->setIsShowBanner( on );
221 \brief Returns \c true if auto-completion feature is switched on
222 or \c false otherwise
223 \sa setAutoCompletion()
225 bool PyConsole_Console::autoCompletion() const
227 return myEditor ? myEditor->autoCompletion() : false;
231 \brief Switch on/off commands auto-completion feature
234 void PyConsole_Console::setAutoCompletion( const bool on )
237 myEditor->setAutoCompletion( on );
241 \brief Change the python console's font.
244 void PyConsole_Console::setFont( const QFont& f )
247 myEditor->setFont( f );
251 \brief Get python console font.
252 \return current python console font
254 QFont PyConsole_Console::font() const
256 return myEditor ? myEditor->font() : QFont();
260 \brief Set actions to be visible in the context popup menu.
262 Actions, which IDs are set in \a flags parameter, will be shown in the
263 context popup menu. Other actions will not be shown.
265 \param flags ORed together actions flags
267 void PyConsole_Console::setMenuActions( const int flags )
269 myActions[CopyId]->setVisible( flags & CopyId );
270 myActions[PasteId]->setVisible( flags & PasteId );
271 myActions[ClearId]->setVisible( flags & ClearId );
272 myActions[SelectAllId]->setVisible( flags & SelectAllId );
273 myActions[DumpCommandsId]->setVisible( flags & DumpCommandsId );
274 myActions[StartLogId]->setVisible( flags & StartLogId );
275 myActions[StopLogId]->setVisible( flags & StopLogId );
279 \brief Get menu actions which are currently visible in the context popup menu.
280 \return ORed together actions flags
283 int PyConsole_Console::menuActions() const
286 ret = ret | ( myActions[CopyId]->isVisible() ? CopyId : 0 );
287 ret = ret | ( myActions[PasteId]->isVisible() ? PasteId : 0 );
288 ret = ret | ( myActions[ClearId]->isVisible() ? ClearId : 0 );
289 ret = ret | ( myActions[SelectAllId]->isVisible() ? SelectAllId : 0 );
290 ret = ret | ( myActions[DumpCommandsId]->isVisible() ? DumpCommandsId : 0 );
291 ret = ret | ( myActions[StartLogId]->isVisible() ? StartLogId : 0 );
292 ret = ret | ( myActions[StopLogId]->isVisible() ? StopLogId : 0 );
297 \brief Create menu actions.
299 Create context popup menu actions.
301 void PyConsole_Console::createActions()
303 QAction* a = new QAction( tr( "EDIT_COPY_CMD" ), this );
304 a->setStatusTip( tr( "EDIT_COPY_CMD" ) );
305 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) );
306 myActions.insert( CopyId, a );
308 a = new QAction( tr( "EDIT_PASTE_CMD" ), this );
309 a->setStatusTip( tr( "EDIT_PASTE_CMD" ) );
310 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) );
311 myActions.insert( PasteId, a );
313 a = new QAction( tr( "EDIT_CLEAR_CMD" ), this );
314 a->setStatusTip( tr( "EDIT_CLEAR_CMD" ) );
315 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( clear() ) );
316 myActions.insert( ClearId, a );
318 a = new QAction( tr( "EDIT_SELECTALL_CMD" ), this );
319 a->setStatusTip( tr( "EDIT_SELECTALL_CMD" ) );
320 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) );
321 myActions.insert( SelectAllId, a );
323 a = new QAction( tr( "EDIT_DUMPCOMMANDS_CMD" ), this );
324 a->setStatusTip( tr( "EDIT_DUMPCOMMANDS_CMD" ) );
325 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( dump() ) );
326 myActions.insert( DumpCommandsId, a );
328 a = new QAction( tr( "EDIT_STARTLOG_CMD" ), this );
329 a->setStatusTip( tr( "EDIT_STARTLOG_CMD" ) );
330 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( startLog() ) );
331 myActions.insert( StartLogId, a );
333 a = new QAction( tr( "EDIT_STOPLOG_CMD" ), this );
334 a->setStatusTip( tr( "EDIT_STOPLOG_CMD" ) );
335 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( stopLog() ) );
336 myActions.insert( StopLogId, a );
340 \brief Update menu actions.
342 Update context popup menu action state.
344 void PyConsole_Console::updateActions()
346 myActions[CopyId]->setEnabled( myEditor && myEditor->textCursor().hasSelection() );
347 myActions[PasteId]->setEnabled( myEditor && !myEditor->isReadOnly() && !QApplication::clipboard()->text().isEmpty() );
348 myActions[SelectAllId]->setEnabled( myEditor && !myEditor->document()->isEmpty() );
352 \brief Start python trace logging
353 \param fileName the path to the log file
355 void PyConsole_Console::startLog( const QString& fileName )
358 myEditor->startLog( fileName );
362 \brief Stop python trace logging
364 void PyConsole_Console::stopLog()
371 \brief Process context popup menu request
373 Show the context popup menu.
375 \param event context popup menu event
377 void PyConsole_Console::contextMenuEvent( QContextMenuEvent* event )
379 if ( !myEditor || myEditor->isReadOnly() )
382 QMenu* menu = new QMenu( this );
384 menu->addAction( myActions[CopyId] );
385 menu->addAction( myActions[PasteId] );
386 menu->addAction( myActions[ClearId] );
387 menu->addSeparator();
388 menu->addAction( myActions[SelectAllId] );
389 menu->addSeparator();
390 menu->addAction( myActions[DumpCommandsId] );
391 if ( !myEditor->isLogging() )
392 menu->addAction( myActions[StartLogId] );
394 menu->addAction( myActions[StopLogId] );
398 menu->exec( event->globalPos());