Salome HOME
NRI : Temporary modification for reading catalog of modules.
[modules/kernel.git] / src / SALOMEGUI / QAD_PyEditor.cxx
1 using namespace std;
2 //  File      : QAD_PyEditor.cxx
3 //  Created   : Thu Jun 14 16:04:59 2001
4 //  Author    : Nicolas REJNERI
5 //  Project   : SALOME
6 //  Module    : SALOMEGUI
7 //  Copyright : Open CASCADE
8 //  $Header$
9
10 #include "QAD_PyEditor.h"
11 #include "QAD_PyInterp.h"
12 #include "QAD_Application.h"
13 #include "QAD_Desktop.h"
14 #include "QAD_Config.h"
15 #include "QAD_Tools.h"
16 #include "QAD_MessageBox.h"
17 //#include "QAD_RightFrame.h"
18
19 #include <qapplication.h>
20 #include <qmap.h>
21 #include <qclipboard.h>
22
23 // NRI : Temporary added
24 // IDL Headers
25 #include <SALOMEconfig.h>
26 #include CORBA_SERVER_HEADER(SALOMEDS)
27 #include CORBA_SERVER_HEADER(SALOMEDS_Attributes)
28 //NRI
29
30 #define SIZEPR 4
31 enum { IdCopy, IdPaste, IdClear, IdSelectAll };
32
33 /*!
34     Constructor
35 */
36 QAD_PyEditor::QAD_PyEditor(QAD_PyInterp* interp, 
37                            QWidget *parent, const char *name)
38   : QMultiLineEdit(parent,name)
39 {
40   QString fntSet = QAD_CONFIG->getSetting("Viewer:ConsoleFont");
41   QFont myFont = QAD_Tools::stringToFont( fntSet );
42 //  QFont myFont("Courier",11);
43   setFont(myFont);
44   _interp = interp;
45   string banner = _interp->getbanner();
46   setText(banner.c_str());
47   _isInHistory = false;
48   _currentPrompt = ">>> ";
49   // put error messages of interpreter if they exist.
50   _buf.truncate(0);
51   setText(_interp->getverr());
52   setText(_currentPrompt);
53   setPalette( QAD_Application::getPalette(true) );
54   setWordWrap(NoWrap);
55   connect(this,SIGNAL(returnPressed()),this,SLOT(handleReturn()) );
56 }
57
58 /*!
59     Destructor
60 */
61 QAD_PyEditor::~QAD_PyEditor()
62 {
63 }
64
65 /*!
66     Called to insert a string s 
67 */
68 void QAD_PyEditor::setText(QString s)
69 {
70 //   MESSAGE("setText");
71   int line=numLines()-1;
72   int col=lineLength(line);
73   insertAt(s,line,col);
74   int n = numLines()-1;  
75   setCursorPosition( n, textLine(n).length()); 
76 }
77
78 /*!
79     Called when an handleReturn
80 */
81 void QAD_PyEditor::handleReturn()
82 {
83   QApplication::setOverrideCursor( Qt::waitCursor );
84   int ret;
85   int line=numLines()-2;
86
87   // NRI : Temporary added
88   SALOMEDS::Study_var aStudy = QAD_Application::getDesktop()->getActiveStudy()->getStudyDocument();
89   
90   if ( aStudy->GetProperties()->IsLocked() ) {
91     QApplication::restoreOverrideCursor();
92     QAD_MessageBox::warn1 ( (QWidget*)QAD_Application::getDesktop(),
93                             QObject::tr("WARNING"), 
94                             QObject::tr("WRN_STUDY_LOCKED"),
95                             QObject::tr("BUT_OK") );
96
97     _currentPrompt = ">>> ";
98     setText(_currentPrompt);
99     
100     return;
101   }  
102   // NRI
103
104   _buf.append(textLine(line).remove(0,SIZEPR));
105   ret = _interp->run(_buf);
106   if(ret <= 0)
107     {
108       _buf.truncate(0);
109       setText(_interp->getvout());
110       setText(_interp->getverr());
111       _currentPrompt = ">>> ";
112       setText(_currentPrompt);
113     }
114   if(ret == 1)
115     {
116       _buf.append("\n");
117       _currentPrompt = "... ";
118       setText(_currentPrompt);
119     }
120   _isInHistory = false;
121   QApplication::restoreOverrideCursor();
122 }
123
124 /*
125    Processes own popup menu
126 */
127 void QAD_PyEditor::mousePressEvent (QMouseEvent * event)
128 {
129   if ( event->button() == RightButton ) {
130     QPopupMenu *popup = new QPopupMenu( this );
131     QMap<int, int> idMap;
132
133     int line1, col1, line2, col2;
134     getMarkedRegion(&line1, &col1, &line2, &col2);
135     bool allSelected = getMarkedRegion(&line1, &col1, &line2, &col2) &&
136       line1 == 0 && line2 == numLines()-1 && col1 == 0 && col2 == lineLength(line2);
137     int id;
138     id = popup->insertItem( tr( "EDIT_COPY_CMD" ) );
139     idMap.insert(IdCopy, id);
140     id = popup->insertItem( tr( "EDIT_PASTE_CMD" ) );
141     idMap.insert(IdPaste, id);
142     id = popup->insertItem( tr( "EDIT_CLEAR_CMD" ) );
143     idMap.insert(IdClear, id);
144     popup->insertSeparator();
145     id = popup->insertItem( tr( "EDIT_SELECTALL_CMD" ) );
146     idMap.insert(IdSelectAll, id);
147     popup->setItemEnabled( idMap[ IdCopy ],  hasMarkedText() );
148     popup->setItemEnabled( idMap[ IdPaste ],
149                           !isReadOnly() && (bool)QApplication::clipboard()->text().length() );
150     popup->setItemEnabled( idMap[ IdSelectAll ],
151                           (bool)text().length() && !allSelected );
152     
153     int r = popup->exec( event->globalPos() );
154     delete popup;
155     
156     if ( r == idMap[ IdCopy ] ) {
157       copy();
158     }
159     else if ( r == idMap[ IdPaste ] ) {
160       paste();
161     }
162     else if ( r == idMap[ IdClear ] ) {
163       clear();
164       string banner = _interp->getbanner();
165       setText(banner.c_str());
166       setText(_currentPrompt);
167     }
168     else if ( r == idMap[ IdSelectAll ] ) {
169       selectAll();
170     }
171     return;
172   }
173   else {
174     QMultiLineEdit::mousePressEvent(event);
175   }
176 }
177
178 /*!
179     Called when a Mouse release event
180 */
181 void QAD_PyEditor::mouseReleaseEvent ( QMouseEvent * e )
182 {
183   //  MESSAGE("mouseReleaseEvent");
184   int curLine, curCol; // for cursor position
185   int endLine, endCol; // for last edited line
186   getCursorPosition(&curLine, &curCol);
187   endLine = numLines() -1;
188   if (e->button() != MidButton)
189     QMultiLineEdit::mouseReleaseEvent(e);
190   else if ((curLine == endLine) && (curCol >= SIZEPR))
191     QMultiLineEdit::mouseReleaseEvent(e);
192 }
193
194 /*!
195     Called when a drop event (Drag & Drop)
196 */
197   void QAD_PyEditor::dropEvent (QDropEvent *e)
198 {
199   INFOS("dropEvent : not handled");
200 }
201
202 /*!
203    Checks, is the string a command line or not.
204 */
205
206 bool QAD_PyEditor::isCommand( const QString& str) const
207 {
208   if (str.find(_currentPrompt)==0)
209     return true;
210   return false;
211 }
212
213
214 /*!
215     Called when a keyPress event
216 */
217 void QAD_PyEditor::keyPressEvent( QKeyEvent *e )
218 {
219   int curLine, curCol; // for cursor position
220   int endLine, endCol; // for last edited line
221   getCursorPosition(&curLine, &curCol);
222   endLine = numLines() -1;
223   //MESSAGE("current position " << curLine << ", " << curCol);
224   //MESSAGE("last line " << endLine);
225   //MESSAGE(e->key());
226   int aKey=e->key();
227   int keyRange=0;
228   if ((aKey >= Key_Space) && (aKey <= Key_ydiaeresis))
229     keyRange = 0;
230   else
231     keyRange = aKey;
232
233   bool ctrlPressed = ( (e->state() & ControlButton) == ControlButton );
234   bool shftPressed = ( (e->state() & ShiftButton) ==  ShiftButton );
235
236   switch (keyRange)
237     {
238     case 0 :
239       {
240         if (curLine <endLine)
241           {
242             setCursorPosition(endLine, SIZEPR);
243             end();
244           }
245         QMultiLineEdit::keyPressEvent( e );
246         break;
247       }
248     case Key_Return:
249     case Key_Enter:
250       {
251         if (curLine <endLine)
252           {
253             setCursorPosition(endLine, SIZEPR);
254           }
255         end();
256         QMultiLineEdit::keyPressEvent( e );
257         break;
258       }
259     case Key_Up:
260       {
261         // if Cntr+Key_Up event then scroll the commands stack up
262         if (ctrlPressed) {
263           QString histLine = _currentPrompt;
264           if (! _isInHistory)
265             {
266               _isInHistory = true;
267               _currentCommand = textLine(endLine).remove(0,SIZEPR);
268               SCRUTE(_currentCommand);
269             }
270           QString previousCommand = _interp->getPrevious();
271           if (previousCommand.compare(BEGIN_HISTORY_PY) != 0)
272             {
273               removeLine(endLine);
274               histLine.append(previousCommand);
275               insertLine(histLine);
276             }
277           endLine = numLines() -1;
278           setCursorPosition(endLine, lineLength(endLine));
279         }
280         // if Shift+Key_Up event then move cursor up and select the text
281         else if ( shftPressed && curLine > 0 ){
282            setCursorPosition(curLine-1, curCol, true);
283         }
284         // move cursor up
285         else { QMultiLineEdit::keyPressEvent( e ); }
286         break;
287       }
288     case Key_Down:
289       {
290         // if Cntr+Key_Down event then scroll the commands stack down
291         if (ctrlPressed) {
292           QString histLine = _currentPrompt;
293           QString nextCommand = _interp->getNext();
294           if (nextCommand.compare(TOP_HISTORY_PY) != 0)
295             {
296               removeLine(endLine);
297               histLine.append(nextCommand);
298               insertLine(histLine);
299             }
300           else
301             if (_isInHistory)
302               {
303                 _isInHistory = false;
304                 removeLine(endLine);
305                 histLine.append(_currentCommand);
306                 insertLine(histLine);
307               }
308           endLine = numLines() -1;
309           setCursorPosition(endLine, lineLength(endLine));
310         }
311         // if Shift+Key_Down event then move cursor down and select the text
312         else if ( shftPressed && curLine < endLine ) {
313            setCursorPosition(curLine+1, curCol, true);
314         }
315         //move cursor down
316         else { QMultiLineEdit::keyPressEvent( e ); }
317
318         break;
319       }
320     case Key_Left:
321       {
322         if (!shftPressed && isCommand(textLine(curLine)) && curCol <= SIZEPR )
323           {
324             setCursorPosition((curLine -1), SIZEPR);
325             end();
326           }
327         else QMultiLineEdit::keyPressEvent( e );
328         break;
329       }
330     case Key_Right:
331       {
332         if (!shftPressed && isCommand(textLine(curLine)) 
333             && curCol < SIZEPR) setCursorPosition(curLine, SIZEPR-1);
334         QMultiLineEdit::keyPressEvent( e );
335         break;
336       }
337     case Key_Home: 
338       {
339         if (isCommand(textLine(curLine)) && curCol <= SIZEPR)
340           setCursorPosition(curLine, SIZEPR, shftPressed);
341         else setCursorPosition(curLine, 0, shftPressed);
342         break;
343       }
344     case Key_End:
345       {
346         setCursorPosition(curLine, textLine(curLine).length(), shftPressed);
347         break;
348       }  
349     case Key_Backspace :
350       {
351         if ((curLine == endLine) && (curCol > SIZEPR))
352           QMultiLineEdit::keyPressEvent( e );
353         break;
354       }
355     case Key_Delete :
356       {
357         if ((curLine == endLine) && (curCol > SIZEPR-1))
358           QMultiLineEdit::keyPressEvent( e );
359         break;
360       }
361     }
362   if ( e->key() == Key_C && ( e->state() & ControlButton ) )
363     {
364       _buf.truncate(0);
365       setText("\n");
366       _currentPrompt = ">>> ";
367       setText(_currentPrompt);
368     }
369
370   // NRI : DEBUG PAS TERRIBLE //
371   if (( e->key() == Key_F3) || 
372       ( e->key() == Key_F4) ||
373       ( e->key() == Key_Return) ||
374       ( e->key() == Key_Escape))
375     QAD_Application::getDesktop()->onKeyPress( e );
376   // NRI //
377 }