Salome HOME
04e244ed08eaad1334fed75719df2ba992c41d0c
[modules/shaper.git] / src / PyConsole / PyConsole_Console.cxx
1
2 /*!
3   \class PyConsole_Console
4   \brief Python console widget.
5 */  
6
7 #include "PyConsole_Interp.h"   /// !!! WARNING !!! THIS INCLUDE MUST BE VERY FIRST !!!
8 #include "PyConsole_Console.h"
9 #include "PyConsole_EnhEditor.h"
10 #include "PyConsole_EnhInterp.h"
11
12 //#include <Qtx.h>
13
14 #include <QAction>
15 #include <QApplication>
16 #include <QClipboard>
17 #include <QEvent>
18 #include <QMenu>
19 #include <QVBoxLayout>
20
21 /*!
22   \brief Constructor.
23
24   Creates new python console widget.
25   \param parent parent widget
26   \param interp python interpreter
27 */
28 PyConsole_Console::PyConsole_Console( QWidget* parent, PyConsole_Interp* interp )
29 : QWidget( parent )
30 {
31   // create python interpreter
32   myInterp = interp;
33   if ( !myInterp )
34     myInterp = new PyConsole_Interp();
35   
36   // initialize Python interpretator
37   myInterp->initialize();
38   
39   // create editor console
40   QVBoxLayout* lay = new QVBoxLayout( this );
41   lay->setMargin( 0 );
42   myEditor = new PyConsole_Editor( myInterp, this );
43   char* synchronous = getenv("PYTHON_CONSOLE_SYNC");
44   if (synchronous && atoi(synchronous))
45   {
46       myEditor->setIsSync(true);
47   }
48   myEditor->viewport()->installEventFilter( this );
49   lay->addWidget( myEditor );
50
51   createActions();
52 }
53
54 /**
55  * Protected constructor.
56  */
57 PyConsole_Console::PyConsole_Console( QWidget* parent, PyConsole_Interp* i,  PyConsole_Editor* e)
58   : QWidget (parent), myEditor(e), myInterp(i)
59 {}
60
61 /*!
62   \brief Destructor.
63
64   Does nothing for the moment.
65 */
66 PyConsole_Console::~PyConsole_Console()
67 {
68 }
69
70 /*!
71   \brief Execute python command in the interpreter.
72   \param command string with command and arguments
73 */
74 void PyConsole_Console::exec( const QString& command )
75 {
76   if ( myEditor )
77     myEditor->exec( command );
78 }
79
80 /*!
81   \brief Execute python command in the interpreter 
82          and wait until it is finished.
83   
84   Block execution of main application until the python command is executed.
85   \param command string with command and arguments
86 */
87 void PyConsole_Console::execAndWait( const QString& command )
88 {
89   if ( myEditor )
90     myEditor->execAndWait( command );
91 }
92
93 /*!
94   \brief Get synchronous mode flag value.
95   
96   \sa setIsSync()
97   \return True if python console works in synchronous mode
98 */
99 bool PyConsole_Console::isSync() const
100 {
101   return myEditor->isSync();
102 }
103
104 /*!
105   \brief Set synchronous mode flag value.
106
107   In synhronous mode the Python commands are executed in the GUI thread
108   and the GUI is blocked until the command is finished. In the asynchronous
109   mode each Python command is executed in the separate thread that does not
110   block the main GUI loop.
111
112   \param on synhronous mode flag
113 */
114 void PyConsole_Console::setIsSync( const bool on )
115 {
116   myEditor->setIsSync( on );
117 }
118
119 /*!
120   \brief Get suppress output flag value.
121   
122   \sa setIsSuppressOutput()
123   \return True if python console output is suppressed.
124 */
125 bool PyConsole_Console::isSuppressOutput() const
126 {
127   return myEditor->isSuppressOutput();
128 }
129
130 /*!
131   \brief Set suppress output flag value.
132
133   In case if suppress output flag is true, the python 
134   console output suppressed.
135
136   \param on suppress output flag
137 */
138 void PyConsole_Console::setIsSuppressOutput( const bool on )
139 {
140   myEditor->setIsSuppressOutput(on);
141 }
142
143 /*!
144   \brief Get 'show banner' flag value.
145   
146   \sa setIsShowBanner()
147   \return \c true if python console shows banner
148 */
149 bool PyConsole_Console::isShowBanner() const
150 {
151   return myEditor->isShowBanner();
152 }
153
154 /*!
155   \brief Set 'show banner' flag value.
156
157   The banner is shown in the top of the python console window.
158
159   \sa isShowBanner()
160   \param on 'show banner' flag
161 */
162 void PyConsole_Console::setIsShowBanner( const bool on )
163 {
164   myEditor->setIsShowBanner( on );
165 }
166
167 /*!
168   \brief Change the python console's font.
169   \param f new font
170 */
171 void PyConsole_Console::setFont( const QFont& f )
172 {
173   if( myEditor )
174     myEditor->setFont( f );
175 }
176
177 /*!
178   \brief Get python console font.
179   \return current python console's font
180 */
181 QFont PyConsole_Console::font() const
182 {
183   QFont res;
184   if( myEditor )
185     res = myEditor->font();
186   return res;
187 }
188
189 /*!
190   \brief Event handler.
191
192   Handles context menu request event.
193
194   \param o object
195   \param e event
196   \return True if the event is processed and further processing should be stopped
197 */
198 bool PyConsole_Console::eventFilter( QObject* o, QEvent* e )
199 {
200   if ( o == myEditor->viewport() && e->type() == QEvent::ContextMenu )
201   {
202     //contextMenuRequest( (QContextMenuEvent*)e );
203     return true;
204   }
205   return QWidget::eventFilter( o, e );
206 }
207
208 /*!
209   \brief Create the context popup menu.
210
211   Fill in the popup menu with the commands.
212
213   \param menu context popup menu
214 */
215 void PyConsole_Console::contextMenuPopup( QMenu* menu )
216 {
217   if ( myEditor->isReadOnly() )
218     return;
219
220   menu->addAction( myActions[CopyId] );
221   menu->addAction( myActions[PasteId] );
222   menu->addAction( myActions[ClearId] );
223   menu->addSeparator();
224   menu->addAction( myActions[SelectAllId] );
225   menu->addSeparator();
226   menu->addAction( myActions[DumpCommandsId] );
227
228   //Qtx::simplifySeparators( menu );
229
230   updateActions();
231 }
232
233 /*!
234   \brief Set actions to be visible in the context popup menu.
235   
236   Actions, which IDs are set in \a flags parameter, will be shown in the 
237   context popup menu. Other actions will not be shown.
238
239   \param flags ORed together actions flags
240 */
241 void PyConsole_Console::setMenuActions( const int flags )
242 {
243   myActions[CopyId]->setVisible( flags & CopyId );
244   myActions[PasteId]->setVisible( flags & PasteId );
245   myActions[ClearId]->setVisible( flags & ClearId );
246   myActions[SelectAllId]->setVisible( flags & SelectAllId );
247   myActions[DumpCommandsId]->setVisible( flags & DumpCommandsId );
248 }
249
250 /*!
251   \brief Get menu actions which are currently visible in the context popup menu.
252   \return ORed together actions flags
253   \sa setMenuActions()
254 */
255 int PyConsole_Console::menuActions() const
256 {
257   int ret = 0;
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   return ret;
264 }
265
266 /*!
267   \brief Create menu actions.
268
269   Create context popup menu actions.
270 */
271 void PyConsole_Console::createActions()
272 {
273   QAction* a = new QAction( tr( "EDIT_COPY_CMD" ), this );
274   a->setStatusTip( tr( "EDIT_COPY_CMD" ) );
275   connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( copy() ) );
276   myActions.insert( CopyId, a );
277
278   a = new QAction( tr( "EDIT_PASTE_CMD" ), this );
279   a->setStatusTip( tr( "EDIT_PASTE_CMD" ) );
280   connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( paste() ) );
281   myActions.insert( PasteId, a );
282
283   a = new QAction( tr( "EDIT_CLEAR_CMD" ), this );
284   a->setStatusTip( tr( "EDIT_CLEAR_CMD" ) );
285   connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( clear() ) );
286   myActions.insert( ClearId, a );
287
288   a = new QAction( tr( "EDIT_SELECTALL_CMD" ), this );
289   a->setStatusTip( tr( "EDIT_SELECTALL_CMD" ) );
290   connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( selectAll() ) );
291   myActions.insert( SelectAllId, a );
292   
293   a = new QAction( tr( "EDIT_DUMPCOMMANDS_CMD" ), this );
294   a->setStatusTip( tr( "EDIT_DUMPCOMMANDS_CMD" ) );
295   connect( a, SIGNAL( triggered( bool ) ), myEditor, SLOT( dump() ) );
296   myActions.insert( DumpCommandsId, a );
297 }
298
299 /*!
300   \brief Update menu actions.
301
302   Update context popup menu action state.
303 */
304 void PyConsole_Console::updateActions()
305 {
306   myActions[CopyId]->setEnabled( myEditor->textCursor().hasSelection() );
307   myActions[PasteId]->setEnabled( !myEditor->isReadOnly() && !QApplication::clipboard()->text().isEmpty() );
308   myActions[SelectAllId]->setEnabled( !myEditor->document()->isEmpty() );
309 }
310
311 /**
312  * Similar to constructor of the base class but using enhanced objects.
313  * TODO: this should really be done in a factory to avoid code duplication.
314  * @param parent
315  * @param interp
316  */
317 PyConsole_EnhConsole::PyConsole_EnhConsole( QWidget* parent, PyConsole_EnhInterp* interp)
318   : PyConsole_Console(parent, interp, 0)
319 {
320   // create python interpreter
321   myInterp = interp;
322   if ( !myInterp )
323     myInterp = new PyConsole_EnhInterp();
324
325   // initialize Python interpretator
326   myInterp->initialize();
327
328   // create editor console
329   QVBoxLayout* lay = new QVBoxLayout( this );
330   lay->setMargin( 0 );
331   myEditor = new PyConsole_EnhEditor( static_cast<PyConsole_EnhInterp*>(myInterp), this );
332   char* synchronous = getenv("PYTHON_CONSOLE_SYNC");
333   if (synchronous && atoi(synchronous))
334   {
335       myEditor->setIsSync(true);
336   }
337   myEditor->viewport()->installEventFilter( this );
338   lay->addWidget( myEditor );
339
340   createActions();
341 }