1 // Copyright (C) 2007-2015 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_ConsoleBase.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_ConsoleBase.h"
33 #include "PyConsole_EnhEditorBase.h"
34 #include "PyConsole_EnhInterp.h"
39 #include <QApplication>
43 #include <QContextMenuEvent>
44 #include <QVBoxLayout>
46 PyConsole_EditorBase *PyConsole_ConsoleBase::PyConsole_Interp_CreatorBase::createEditor( PyConsole_Interp *interp, PyConsole_ConsoleBase *console ) const
47 { return new PyConsole_EditorBase(interp,console); }
49 PyConsole_Interp *PyConsole_ConsoleBase::PyConsole_Interp_CreatorBase::createInterp( ) const
50 { return new PyConsole_Interp; }
55 Creates new python console widget.
56 \param parent parent widget
57 \param interp python interpreter
59 PyConsole_ConsoleBase::PyConsole_ConsoleBase( QWidget* parent, PyConsole_Interp* interp )
62 PyConsole_ConsoleBase::PyConsole_Interp_CreatorBase crea;
63 defaultConstructor(interp,crea);
67 * MUST BE NON VIRTUAL ! (called from constructor !!!!)
69 void PyConsole_ConsoleBase::defaultConstructor( PyConsole_Interp* interp, const PyConsole_Interp_CreatorBase& crea )
71 PyConsole_Interp *anInterp = interp ? interp : crea.createInterp();
73 // initialize Python interpretator
74 anInterp->initialize();
76 // create editor console
77 QVBoxLayout* lay = new QVBoxLayout( this );
79 myEditor = crea.createEditor( anInterp, this );
80 char* synchronous = getenv("PYTHON_CONSOLE_SYNC");
81 if (synchronous && atoi(synchronous))
83 myEditor->setIsSync(true);
85 myEditor->viewport()->installEventFilter( this );
86 lay->addWidget( myEditor );
92 * Protected constructor.
94 PyConsole_ConsoleBase::PyConsole_ConsoleBase( QWidget* parent, PyConsole_Interp* /*i*/, PyConsole_EditorBase* e )
95 : QWidget (parent), myEditor(e)
101 Does nothing for the moment.
103 PyConsole_ConsoleBase::~PyConsole_ConsoleBase()
107 PyConsole_Interp* PyConsole_ConsoleBase::getInterp() const
109 return myEditor ? myEditor->getInterp() : 0;
113 \brief Execute python command in the interpreter.
114 \param command string with command and arguments
116 void PyConsole_ConsoleBase::exec( const QString& command )
119 myEditor->exec( command );
123 \brief Execute python command in the interpreter
124 and wait until it is finished.
126 Block execution of main application until the python command is executed.
127 \param command string with command and arguments
129 void PyConsole_ConsoleBase::execAndWait( const QString& command )
132 myEditor->execAndWait( command );
136 \brief Get synchronous mode flag value.
139 \return True if python console works in synchronous mode
141 bool PyConsole_ConsoleBase::isSync() const
143 return myEditor->isSync();
147 \brief Set synchronous mode flag value.
149 In synhronous mode the Python commands are executed in the GUI thread
150 and the GUI is blocked until the command is finished. In the asynchronous
151 mode each Python command is executed in the separate thread that does not
152 block the main GUI loop.
154 \param on synhronous mode flag
156 void PyConsole_ConsoleBase::setIsSync( const bool on )
158 myEditor->setIsSync( on );
162 \brief Get suppress output flag value.
164 \sa setIsSuppressOutput()
165 \return True if python console output is suppressed.
167 bool PyConsole_ConsoleBase::isSuppressOutput() const
169 return myEditor->isSuppressOutput();
173 \brief Set suppress output flag value.
175 In case if suppress output flag is true, the python
176 console output suppressed.
178 \param on suppress output flag
180 void PyConsole_ConsoleBase::setIsSuppressOutput( const bool on )
182 myEditor->setIsSuppressOutput(on);
186 \brief Get 'show banner' flag value.
188 \sa setIsShowBanner()
189 \return \c true if python console shows banner
191 bool PyConsole_ConsoleBase::isShowBanner() const
193 return myEditor->isShowBanner();
197 \brief Set 'show banner' flag value.
199 The banner is shown in the top of the python console window.
202 \param on 'show banner' flag
204 void PyConsole_ConsoleBase::setIsShowBanner( const bool on )
206 myEditor->setIsShowBanner( on );
210 \brief Change the python console's font.
213 void PyConsole_ConsoleBase::setFont( const QFont& f )
216 myEditor->setFont( f );
220 \brief Get python console font.
221 \return current python console's font
223 QFont PyConsole_ConsoleBase::font() const
227 res = myEditor->font();
232 \brief Set actions to be visible in the context popup menu.
234 Actions, which IDs are set in \a flags parameter, will be shown in the
235 context popup menu. Other actions will not be shown.
237 \param flags ORed together actions flags
239 void PyConsole_ConsoleBase::setMenuActions( const int flags )
241 myActions[CopyId]->setVisible( flags & CopyId );
242 myActions[PasteId]->setVisible( flags & PasteId );
243 myActions[ClearId]->setVisible( flags & ClearId );
244 myActions[SelectAllId]->setVisible( flags & SelectAllId );
245 myActions[DumpCommandsId]->setVisible( flags & DumpCommandsId );
246 myActions[StartLogId]->setVisible( flags & StartLogId );
247 myActions[StopLogId]->setVisible( flags & StopLogId );
251 \brief Get menu actions which are currently visible in the context popup menu.
252 \return ORed together actions flags
255 int PyConsole_ConsoleBase::menuActions() const
258 ret = ret | ( myActions[CopyId]->isVisible() ? CopyId : 0 );
259 ret = ret | ( myActions[PasteId]->isVisible() ? PasteId : 0 );
260 ret = ret | ( myActions[ClearId]->isVisible() ? ClearId : 0 );
261 ret = ret | ( myActions[SelectAllId]->isVisible() ? SelectAllId : 0 );
262 ret = ret | ( myActions[DumpCommandsId]->isVisible() ? DumpCommandsId : 0 );
263 ret = ret | ( myActions[StartLogId]->isVisible() ? StartLogId : 0 );
264 ret = ret | ( myActions[StopLogId]->isVisible() ? StopLogId : 0 );
269 \brief Create menu actions.
271 Create context popup menu actions.
273 void PyConsole_ConsoleBase::createActions()
275 QAction* a = new QAction( tr( "EDIT_COPY_CMD" ), this );
276 a->setStatusTip( tr( "EDIT_COPY_CMD" ) );
277 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) );
278 myActions.insert( CopyId, a );
280 a = new QAction( tr( "EDIT_PASTE_CMD" ), this );
281 a->setStatusTip( tr( "EDIT_PASTE_CMD" ) );
282 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) );
283 myActions.insert( PasteId, a );
285 a = new QAction( tr( "EDIT_CLEAR_CMD" ), this );
286 a->setStatusTip( tr( "EDIT_CLEAR_CMD" ) );
287 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( clear() ) );
288 myActions.insert( ClearId, a );
290 a = new QAction( tr( "EDIT_SELECTALL_CMD" ), this );
291 a->setStatusTip( tr( "EDIT_SELECTALL_CMD" ) );
292 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) );
293 myActions.insert( SelectAllId, a );
295 a = new QAction( tr( "EDIT_DUMPCOMMANDS_CMD" ), this );
296 a->setStatusTip( tr( "EDIT_DUMPCOMMANDS_CMD" ) );
297 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( dump() ) );
298 myActions.insert( DumpCommandsId, a );
300 a = new QAction( tr( "EDIT_STARTLOG_CMD" ), this );
301 a->setStatusTip( tr( "EDIT_STARTLOG_CMD" ) );
302 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( startLog() ) );
303 myActions.insert( StartLogId, a );
305 a = new QAction( tr( "EDIT_STOPLOG_CMD" ), this );
306 a->setStatusTip( tr( "EDIT_STOPLOG_CMD" ) );
307 connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( stopLog() ) );
308 myActions.insert( StopLogId, a );
312 \brief Update menu actions.
314 Update context popup menu action state.
316 void PyConsole_ConsoleBase::updateActions()
318 myActions[CopyId]->setEnabled( myEditor->textCursor().hasSelection() );
319 myActions[PasteId]->setEnabled( !myEditor->isReadOnly() && !QApplication::clipboard()->text().isEmpty() );
320 myActions[SelectAllId]->setEnabled( !myEditor->document()->isEmpty() );
324 \brief Start python trace logging
325 \param fileName the path to the log file
327 void PyConsole_ConsoleBase::startLog( const QString& fileName )
329 myEditor->startLog( fileName );
333 \brief Stop python trace logging
335 void PyConsole_ConsoleBase::stopLog()
341 \brief Create the context popup menu.
343 Fill in the popup menu with the commands.
345 \param menu context popup menu
347 void PyConsole_ConsoleBase::contextMenuPopup( QMenu *menu )
349 if ( myEditor->isReadOnly() )
352 menu->addAction( myActions[CopyId] );
353 menu->addAction( myActions[PasteId] );
354 menu->addAction( myActions[ClearId] );
355 menu->addSeparator();
356 menu->addAction( myActions[SelectAllId] );
357 menu->addSeparator();
358 menu->addAction( myActions[DumpCommandsId] );
359 if ( !myEditor->isLogging() )
360 menu->addAction( myActions[StartLogId] );
362 menu->addAction( myActions[StopLogId] );
364 Qtx::simplifySeparators( menu );
369 PyConsole_EditorBase *PyConsole_EnhConsoleBase::PyConsole_Interp_EnhCreatorBase::createEditor( PyConsole_Interp *interp, PyConsole_ConsoleBase *console ) const
370 { return new PyConsole_EnhEditorBase(interp,console); }
372 PyConsole_Interp *PyConsole_EnhConsoleBase::PyConsole_Interp_EnhCreatorBase::createInterp( ) const
373 { return new PyConsole_EnhInterp; }
376 * Similar to constructor of the base class but using enhanced objects.
377 * TODO: this should really be done in a factory to avoid code duplication.
381 PyConsole_EnhConsoleBase::PyConsole_EnhConsoleBase( QWidget* parent, PyConsole_Interp* interp )
382 : PyConsole_ConsoleBase( parent, interp, 0 )
384 PyConsole_Interp_EnhCreatorBase crea;
385 defaultConstructor(interp,crea);
389 \brief Event handler.
391 Handles context menu request event.
395 \return True if the event is processed and further processing should be stopped
397 bool PyConsole_EnhConsoleBase::eventFilter( QObject* o, QEvent* e )
399 if ( o == myEditor->viewport() && e->type() == QEvent::ContextMenu )
401 contextMenuRequest( (QContextMenuEvent*)e );
404 return QWidget::eventFilter( o, e );
407 void PyConsole_EnhConsoleBase::contextMenuRequest( QContextMenuEvent * e )
409 QMenu *menu(new QMenu(this));
410 contextMenuPopup(menu);
411 menu->move(e->globalPos());