Salome HOME
SMH: Fix for compilation with correct CASCADE
[modules/gui.git] / src / PythonConsole / PythonConsole_PyEditor.cxx
1 //  SALOME SALOMEGUI : implementation of desktop and GUI kernel
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
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. 
10 // 
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. 
15 // 
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 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : PythonConsole_PyEditor.cxx
25 //  Author : Nicolas REJNERI
26 //  Module : SALOME
27 //  $Header$
28
29 #include <PythonConsole_PyEditor.h> // this include must be first (see PyInterp_base.h)!
30 #include <PyInterp_Dispatcher.h>
31 #include <SUIT_Tools.h>
32
33 #include <qapplication.h>
34 #include <qmap.h>
35 #include <qclipboard.h>
36 #include <qdragobject.h>
37
38 //#include "utilities.h"
39 using namespace std;
40
41
42 //#ifdef _DEBUG_
43 //static int MYDEBUG = 1;
44 //#else
45 //static int MYDEBUG = 0;
46 //#endif
47
48
49 enum { IdCopy, IdPaste, IdClear, IdSelectAll };
50
51
52 static QString READY_PROMPT = ">>> ";
53 static QString DOTS_PROMPT  = "... ";
54 #define PROMPT_SIZE _currentPrompt.length()
55
56 class ExecCommand : public PyInterp_LockRequest
57 {
58 public:
59   ExecCommand(PyInterp_base* theInterp, const char* theCommand, PythonConsole_PyEditor* theListener)
60 : PyInterp_LockRequest( theInterp, theListener ), myCommand(theCommand), myState( PyInterp_Event::OK )
61   {}
62
63 protected:
64   virtual void execute(){
65     if(myCommand != ""){
66 //      if(MYDEBUG) MESSAGE("*** ExecCommand::execute() started");
67       int ret = getInterp()->run( myCommand.latin1() );
68 //      if(MYDEBUG) MESSAGE("ExecCommand::execute() - myInterp = "<<getInterp()<<"; myCommand = '"<<myCommand.latin1()<<"' - "<<ret);
69       if(ret < 0)
70         myState = PyInterp_Event::ERROR;
71       else if(ret > 0)
72         myState = PyInterp_Event::INCOMPLETE;
73       myError  = getInterp()->getverr().c_str();
74       myOutput = getInterp()->getvout().c_str();
75 //      if(MYDEBUG) MESSAGE("*** ExecCommand::execute() finished");
76     }else{
77       myError = "";
78       myOutput = "";
79     }
80   }
81
82   virtual QEvent* createEvent() const
83   {
84     return new PyInterp_Event( myState, (PyInterp_Request*)this );    
85   }
86
87 public:
88   QString myError;
89   QString myOutput;
90
91 private:
92   QString myCommand;
93   int myState;
94 };
95
96
97 /*!
98     Constructor
99 */
100 PythonConsole_PyEditor::PythonConsole_PyEditor(PyInterp_base* theInterp, QWidget *theParent, const char* theName): 
101   QTextEdit(theParent,theName),
102   myInterp( 0 )
103 {
104   QString fntSet( "" );
105   QFont aFont = SUIT_Tools::stringToFont( fntSet );
106   setFont(aFont);
107   setTextFormat(QTextEdit::PlainText);
108
109   _currentPrompt = READY_PROMPT;
110   setWordWrap(NoWrap);
111
112   connect(this,SIGNAL(returnPressed()),this,SLOT(handleReturn()) );
113
114   // san - This is necessary for troubleless initialization
115   onPyInterpChanged( theInterp );
116 }
117
118 /*!
119     Destructor
120 */
121 PythonConsole_PyEditor::~PythonConsole_PyEditor()
122 {
123 //  if(MYDEBUG) MESSAGE("PythonConsole_PyEditor::~PythonConsole_PyEditor()");
124 }
125
126 /*!
127     Called to insert a string s 
128 */
129 void PythonConsole_PyEditor::setText(QString s)
130 {
131   int para=paragraphs()-1;
132   int col=paragraphLength(para);
133   insertAt(s,para,col);
134   int n = paragraphs()-1;  
135   setCursorPosition( n, paragraphLength(n)); 
136 }
137
138 /*!
139     Called when an handleReturn
140 */
141 void PythonConsole_PyEditor::handleReturn()
142 {
143   int para=paragraphs()-2;
144   _buf.append(text(para).remove(0,PROMPT_SIZE));
145   _buf.truncate( _buf.length() - 1 );
146   setReadOnly( true );
147   viewport()->setCursor( waitCursor );
148   
149   // Post a request to execute Python command
150   // Editor will be informed via a custom event that execution has been completed
151   PyInterp_Dispatcher::Get()->Exec( new ExecCommand( myInterp, _buf.latin1(), this ) );
152 }
153
154 /*
155    Processes drop event: paste dragged text
156 */
157 void PythonConsole_PyEditor::contentsDropEvent( QDropEvent* event )
158 {
159   event->acceptAction();
160   QString text;
161   if ( QTextDrag::decode( event, text ) ) {
162     int par, col;
163     int endLine = paragraphs() -1;
164     col = charAt( event->pos(), &par );
165     
166     if ( col >= 0 && par >= 0 ) {
167       if ( par != endLine || col < PROMPT_SIZE ) {
168         par = endLine;
169         col = paragraphLength( endLine );
170       }
171       setCursorPosition( par, col );
172       insertAt( text, par, col );
173       removeSelection();
174     }
175   }
176 }
177
178 /*
179    Processes middle button release event - paste clipboard's contents
180 */
181 void PythonConsole_PyEditor::contentsMouseReleaseEvent( QMouseEvent* event )
182 {
183   if ( event->button() == LeftButton ) {
184     QTextEdit::contentsMouseReleaseEvent(event);
185     copy();
186   }
187   if ( event->button() == MidButton ) {
188     if (QApplication::clipboard()->supportsSelection()) {
189       int par, col;
190       int endLine = paragraphs() -1;
191       col = charAt( event->pos(), &par );
192       if ( col >= 0 && par >= 0 ) {
193         if ( par != endLine || col < PROMPT_SIZE )
194           setCursorPosition( endLine, paragraphLength( endLine ) );
195         else
196           setCursorPosition( par, col );
197         QApplication::clipboard()->setSelectionMode(TRUE);
198         paste();
199         QApplication::clipboard()->setSelectionMode(FALSE);
200       }
201     }
202   }
203   else {
204     QTextEdit::contentsMouseReleaseEvent(event);
205   }
206 }
207
208 /*
209    Processes own popup menu
210 */
211 void PythonConsole_PyEditor::mousePressEvent (QMouseEvent* event)
212 {
213   if ( event->button() == RightButton ) {
214     QPopupMenu *popup = new QPopupMenu( this );
215     QMap<int, int> idMap;
216
217     int para1, col1, para2, col2;
218     getSelection(&para1, &col1, &para2, &col2);
219     bool allSelected = hasSelectedText() &&
220       para1 == 0 && para2 == paragraphs()-1 && col1 == 0 && para2 == paragraphLength(para2);
221     int id;
222     id = popup->insertItem( tr( "EDIT_COPY_CMD" ) );
223     idMap.insert(IdCopy, id);
224     id = popup->insertItem( tr( "EDIT_PASTE_CMD" ) );
225     idMap.insert(IdPaste, id);
226     id = popup->insertItem( tr( "EDIT_CLEAR_CMD" ) );
227     idMap.insert(IdClear, id);
228     popup->insertSeparator();
229     id = popup->insertItem( tr( "EDIT_SELECTALL_CMD" ) );
230     idMap.insert(IdSelectAll, id);
231     popup->setItemEnabled( idMap[ IdCopy ],  hasSelectedText() );
232     popup->setItemEnabled( idMap[ IdPaste ],
233                           !isReadOnly() && (bool)QApplication::clipboard()->text().length() );
234     popup->setItemEnabled( idMap[ IdSelectAll ],
235                           (bool)text().length() && !allSelected );
236     
237     int r = popup->exec( event->globalPos() );
238     delete popup;
239     
240     if ( r == idMap[ IdCopy ] ) {
241       copy();
242     }
243     else if ( r == idMap[ IdPaste ] ) {
244       paste();
245     }
246     else if ( r == idMap[ IdClear ] ) {
247       clear();
248       setText(myBanner);
249       _currentPrompt = READY_PROMPT;
250       setText(_currentPrompt);
251     }
252     else if ( r == idMap[ IdSelectAll ] ) {
253       selectAll();
254     }
255   }
256   else {
257     QTextEdit::mousePressEvent(event);
258   }
259 }
260
261 /*!
262    Checks, is the string a command line or not.
263 */
264
265 bool PythonConsole_PyEditor::isCommand( const QString& str) const
266 {
267   // prompt may be '>>> ' or for '... '
268   return ( str.find( READY_PROMPT ) == 0 || str.find( DOTS_PROMPT ) == 0 );
269 }
270
271
272 /*!
273     Called when a keyPress event
274 */
275 void PythonConsole_PyEditor::keyPressEvent( QKeyEvent* e )
276 {
277   // get cursor position
278   int curLine, curCol;
279   getCursorPosition(&curLine, &curCol);
280
281   // get last edited line
282   int endLine = paragraphs() -1;
283
284   // get pressed key code
285   int aKey = e->key();
286
287   // check if <Ctrl> is pressed
288   bool ctrlPressed = e->state() & ControlButton;
289   // check if <Shift> is pressed
290   bool shftPressed = e->state() & ShiftButton;
291   // check if <Alt> is pressed
292   bool altPressed = e->state() & AltButton;
293
294   // process <Ctrl>+<C> key-bindings
295   if ( aKey == Key_C && ctrlPressed ) {
296     _buf.truncate(0);
297     setText("\n");
298     _currentPrompt = READY_PROMPT;
299     setText(_currentPrompt);
300     return;
301   }
302
303   // check for printed key
304   aKey = ( aKey < Key_Space || aKey > Key_ydiaeresis ) ? aKey : 0;
305
306   switch ( aKey ) {
307   case 0 :
308     // any printed key
309     {
310       if ( curLine < endLine || curCol < PROMPT_SIZE )
311         moveCursor( QTextEdit::MoveEnd, false );
312       QTextEdit::keyPressEvent( e );
313       break;
314     }
315   case Key_Return:
316   case Key_Enter:
317     // <Enter> key
318     {
319       moveCursor( QTextEdit::MoveEnd, false );
320       QTextEdit::keyPressEvent( e );
321       break;
322     }
323   case Key_Up:
324     // <Up> arrow key: process as follows:
325     // - without <Ctrl>, <Shift> modifiers: previous command in history
326     // - with <Ctrl> modifier key pressed:  move cursor one row up without selection
327     // - with <Shift> modifier key pressed: move cursor one row up with selection
328     // - with <Ctrl>+<Shift> modifier keys pressed: scroll one row up
329     {
330       if ( ctrlPressed && shftPressed ) {
331         scrollBy( 0, -QFontMetrics( font() ).lineSpacing() );
332       }
333       else if ( shftPressed ) {
334         if ( curLine > 0 )
335           moveCursor( QTextEdit::MoveUp, true );
336       }
337       else if ( ctrlPressed ) {
338         moveCursor( QTextEdit::MoveUp, false );
339       }
340       else { 
341         QString histLine = _currentPrompt;
342         if ( ! _isInHistory ) {
343           _isInHistory = true;
344           _currentCommand = text( endLine ).remove( 0, PROMPT_SIZE );
345           _currentCommand.truncate( _currentCommand.length() - 1 );
346         }
347         QString previousCommand = myInterp->getPrevious();
348         if ( previousCommand.compare( BEGIN_HISTORY_PY ) != 0 )
349   {
350     removeParagraph( endLine );
351           histLine.append( previousCommand );
352     append( histLine );
353         }
354         moveCursor( QTextEdit::MoveEnd, false );
355       }
356       break;
357     }
358   case Key_Down:
359     // <Down> arrow key: process as follows:
360     // - without <Ctrl>, <Shift> modifiers: next command in history
361     // - with <Ctrl> modifier key pressed:  move cursor one row down without selection
362     // - with <Shift> modifier key pressed: move cursor one row down with selection
363     // - with <Ctrl>+<Shift> modifier keys pressed: scroll one row down
364     {
365       if ( ctrlPressed && shftPressed ) {
366         scrollBy( 0, QFontMetrics( font() ).lineSpacing() );
367       }
368       else if ( shftPressed ) {
369         if ( curLine < endLine )
370           moveCursor( QTextEdit::MoveDown, true );
371       }
372       else if ( ctrlPressed ) {
373         moveCursor( QTextEdit::MoveDown, false );
374       }
375       else { 
376         QString histLine = _currentPrompt;
377         QString nextCommand = myInterp->getNext();
378         if ( nextCommand.compare( TOP_HISTORY_PY ) != 0 ) {
379           removeParagraph( endLine );
380           histLine.append( nextCommand );
381           append( histLine );
382         }
383         else {
384           if (_isInHistory) {
385             _isInHistory = false;
386             removeParagraph( endLine );
387             histLine.append( _currentCommand );
388             append( histLine );
389           }
390         }
391         moveCursor( QTextEdit::MoveEnd, false );
392       }
393       break;
394     }
395   case Key_Left:
396     // <Left> arrow key: process as follows:
397     // - without <Ctrl>, <Shift> modifiers: move one symbol left (taking into account prompt)
398     // - with <Ctrl> modifier key pressed:  move one word left (taking into account prompt)
399     // - with <Shift> modifier key pressed: move one symbol left with selection
400     // - with <Ctrl>+<Shift> modifier keys pressed: move one word left with selection
401     {
402       if ( !shftPressed && isCommand( text( curLine ) ) && curCol <= PROMPT_SIZE ) {
403         setCursorPosition( curLine-1, 0 );
404         moveCursor( QTextEdit::MoveLineEnd, false );
405       }
406       else {
407         QTextEdit::keyPressEvent( e );
408       }
409       break;
410     }
411   case Key_Right:
412     // <Right> arrow key: process as follows:
413     // - without <Ctrl>, <Shift> modifiers: move one symbol right (taking into account prompt)
414     // - with <Ctrl> modifier key pressed:  move one word right (taking into account prompt)
415     // - with <Shift> modifier key pressed: move one symbol right with selection
416     // - with <Ctrl>+<Shift> modifier keys pressed: move one word right with selection
417     {
418       if ( !shftPressed ) {
419         if ( curCol < paragraphLength( curLine ) ) {
420           if ( isCommand( text( curLine ) ) && curCol < PROMPT_SIZE ) {
421             setCursorPosition( curLine, PROMPT_SIZE );
422             break;
423           }
424         }
425         else {
426           if ( curLine < endLine && isCommand( text( curLine+1 ) ) ) {
427             setCursorPosition( curLine+1, PROMPT_SIZE );
428             break;
429           }
430         }
431       }
432       QTextEdit::keyPressEvent( e );
433       break;
434     }
435   case Key_PageUp:
436     // <PageUp> key: process as follows:
437     // - without <Ctrl>, <Shift> modifiers: first command in history
438     // - with <Ctrl> modifier key pressed:  move cursor one page up without selection
439     // - with <Shift> modifier key pressed: move cursor one page up with selection
440     // - with <Ctrl>+<Shift> modifier keys pressed: scroll one page up
441     {
442       if ( ctrlPressed && shftPressed ) {
443         scrollBy( 0, -visibleHeight() );
444       }
445       else if ( shftPressed ) {
446         if ( curLine > 0 )
447           moveCursor( QTextEdit::MovePgUp, true );
448       }
449       else if ( ctrlPressed ) {
450         moveCursor( QTextEdit::MovePgUp, false );
451       }
452       else { 
453         QString histLine = _currentPrompt;
454         if ( ! _isInHistory ) {
455           _isInHistory = true;
456           _currentCommand = text( endLine ).remove( 0, PROMPT_SIZE );
457           _currentCommand.truncate( _currentCommand.length() - 1 );
458         }
459         QString firstCommand = myInterp->getPrevious();
460         QString pcmd;
461         while ( ( pcmd = QString( myInterp->getPrevious() ) ).compare( BEGIN_HISTORY_PY ) != 0 )
462           firstCommand = pcmd;
463         if ( firstCommand.compare( BEGIN_HISTORY_PY ) != 0 ) {
464           removeParagraph( endLine );
465           histLine.append( firstCommand );
466           insertParagraph( histLine, -1 );
467         }
468         moveCursor( QTextEdit::MoveEnd, false );
469       }
470       break;
471     }
472   case Key_PageDown:
473     // <PageDown> key: process as follows:
474     // - without <Ctrl>, <Shift> modifiers: last command in history
475     // - with <Ctrl> modifier key pressed:  move cursor one page down without selection
476     // - with <Shift> modifier key pressed: move cursor one page down with selection
477     // - with <Ctrl>+<Shift> modifier keys pressed: scroll one page down
478     {
479       if ( ctrlPressed && shftPressed ) {
480         scrollBy( 0, visibleHeight() );
481       }
482       else if ( shftPressed ) {
483         if ( curLine < endLine )
484           moveCursor( QTextEdit::MovePgDown, true );
485       }
486       else if ( ctrlPressed ) {
487         moveCursor( QTextEdit::MovePgDown, false );
488       }
489       else { 
490         if ( _isInHistory ) {
491           QString histLine = _currentPrompt;
492           while ( QString( myInterp->getNext() ).compare( TOP_HISTORY_PY ) != 0 );
493           _isInHistory = false;
494           removeParagraph( endLine );
495           histLine.append( _currentCommand );
496           insertParagraph( histLine, -1 );
497         }
498         moveCursor( QTextEdit::MoveEnd, false );
499       }
500       break;
501     }
502   case Key_Home: 
503     // <Home> key: process as follows:
504     // - without <Ctrl>, <Shift> modifiers: move cursor to the beginning of the current line without selection
505     // - with <Ctrl> modifier key pressed:  move cursor to the very first symbol without selection
506     // - with <Shift> modifier key pressed: move cursor to the beginning of the current line with selection
507     // - with <Ctrl>+<Shift> modifier keys pressed: move cursor to the very first symbol with selection
508     {
509       if ( ctrlPressed ) { 
510         moveCursor( QTextEdit::MoveHome, shftPressed );
511       }
512       else {
513         if ( isCommand( text( curLine ) ) ) {
514           int ps1, ps2, cs1, cs2;
515           bool hasSelection = hasSelectedText();
516           if ( hasSelection )
517             getSelection( &ps1, &cs1, &ps2, &cs2 );
518           removeSelection();
519           horizontalScrollBar()->setValue( horizontalScrollBar()->minValue() );
520           if ( curCol > PROMPT_SIZE && shftPressed ) 
521             setSelection( curLine, PROMPT_SIZE, curLine, ( hasSelection && ps1 == ps2 && ps1 == curLine && cs2 > PROMPT_SIZE ) ? cs2 : curCol );
522           setCursorPosition( curLine, PROMPT_SIZE );
523         }
524         else {
525           moveCursor( QTextEdit::MoveLineStart, shftPressed );
526         }
527       }
528       break;
529     }
530   case Key_End:
531     // <End> key: process as follows:
532     // - without <Ctrl>, <Shift> modifiers: move cursor to the end of the current line without selection
533     // - with <Ctrl> modifier key pressed:  move cursor to the very last symbol without selection
534     // - with <Shift> modifier key pressed: move cursor to the end of the current line with selection
535     // - with <Ctrl>+<Shift> modifier keys pressed: move cursor to the very last symbol with selection
536     {
537       if ( ctrlPressed ) { 
538         moveCursor( QTextEdit::MoveEnd, shftPressed );
539       }
540       else {
541         moveCursor( QTextEdit::MoveLineEnd, shftPressed );
542       }
543       break;
544     }  
545   case Key_Backspace :
546     // <Backspace> key: process as follows
547     // - without any modifiers : delete symbol before the cursor / selection (taking into account prompt)
548     // - with <Ctrl> modifier key pressed: delete previous word
549     // works only for last (command) line
550     {
551       if ( curLine == endLine && ( curCol > PROMPT_SIZE || curCol >= PROMPT_SIZE && hasSelectedText() ) ) {
552         if ( ctrlPressed && !hasSelectedText() ) {
553           QString txt = text( curLine );
554           int ind = curCol-1;
555           while ( ind > 0 && txt[ ind ] == ' ' ) ind--;
556           ind = txt.findRev( ' ', ind ) + 1;
557           if ( ind > PROMPT_SIZE-1 ) {
558             setSelection( curLine, ind, curLine, curCol );
559             removeSelectedText();
560           }
561           else {
562             QTextEdit::keyPressEvent( e );
563           }
564         }
565         else {
566           QTextEdit::keyPressEvent( e );
567         }
568       }
569       break;
570     }
571   case Key_Delete :
572     // <Delete> key: process as follows
573     // - without any modifiers : delete symbol after the cursor / selection (taking into account prompt)
574     // - with <Ctrl> modifier key pressed: delete next word
575     // works only for last (command) line
576     {
577       if ( curLine == endLine && curCol > PROMPT_SIZE-1 ) {
578         if ( ctrlPressed && !hasSelectedText() ) {
579           QString txt = text( curLine );
580           int ind = curCol;
581           while ( ind < txt.length()-1 && txt[ ind ] == ' ' ) ind++;
582           ind = txt.find( ' ', ind );
583           while ( ind < txt.length()-1 && txt[ ind ] == ' ' ) ind++;
584           if ( ind > PROMPT_SIZE-1 ) {
585             setSelection( curLine, curCol, curLine, ind );
586             removeSelectedText();
587           }
588           else {
589             QTextEdit::keyPressEvent( e );
590           }
591         }
592         else {
593           QTextEdit::keyPressEvent( e );
594         }
595       }
596       break;
597     }
598   case Key_Insert :
599     // <Insert> key: process as follows
600     // - with <Ctrl> modifier key pressed:  copy()
601     // - with <Shift> modifier key pressed: paste() to the command line
602     {
603       if ( ctrlPressed ) {
604         copy();
605       }
606       else if ( shftPressed ) {
607         if ( curLine != endLine || curCol < PROMPT_SIZE )
608           moveCursor( QTextEdit::MoveEnd, false );
609         paste();
610       }
611       else
612         QTextEdit::keyPressEvent( e );
613       break;
614     }
615   }
616 }
617
618 /*!
619     Handles notifications coming from Python dispatcher
620 */
621 void PythonConsole_PyEditor::customEvent(QCustomEvent* e)
622 {
623   switch( e->type() ) {
624   case PyInterp_Event::OK:
625   case PyInterp_Event::ERROR:
626     {
627       PyInterp_Event* pe = dynamic_cast<PyInterp_Event*>( e );
628       if ( pe ){
629         ExecCommand* ec = dynamic_cast<ExecCommand*>( pe->GetRequest() );
630         if ( ec ){
631           // The next line has appeared dangerous in case if
632           // Python command execution has produced very large output.
633           // A more clever approach is needed...
634           setText(ec->myOutput);
635           setText(ec->myError);
636         }
637       }
638       _buf.truncate(0);
639       _currentPrompt = READY_PROMPT;
640       setText(_currentPrompt);
641       viewport()->unsetCursor();
642       break;
643     }
644   case PyInterp_Event::INCOMPLETE:
645     {
646       _buf.append("\n");
647       _currentPrompt = DOTS_PROMPT;
648       setText(_currentPrompt);
649       viewport()->unsetCursor();
650       break;
651     }
652   default:
653     QTextEdit::customEvent( e );
654   }
655
656   setReadOnly( false );
657   _isInHistory = false;
658 }
659
660 /*!
661    Handles Python interpreter change
662 */
663 void PythonConsole_PyEditor::onPyInterpChanged( PyInterp_base* interp )
664 {
665   if ( myInterp != interp 
666        // Force read-only state and wait cursor when myInterp is NULL
667       || !myInterp ){
668     myInterp = interp;
669     if ( myInterp ){
670       myBanner = myInterp->getbanner().c_str();
671       setText(myBanner);
672       _buf.truncate(0);
673       setReadOnly( false );
674       _isInHistory = false;
675       setText(_currentPrompt);
676       viewport()->unsetCursor();
677     }
678     else {
679       clear();
680       setReadOnly( true );
681       viewport()->setCursor( waitCursor );
682     }
683   }
684 }