]> SALOME platform Git repositories - modules/gui.git/blob - src/SalomePyConsole/SalomePyConsole_Editor.cxx
Salome HOME
f55eb7a16e92357bfe651c43557a9b82ed8f2d50
[modules/gui.git] / src / SalomePyConsole / SalomePyConsole_Editor.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  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, or (at your option) any later version.
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.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  SALOME SALOMEGUI : implementation of desktop and GUI kernel
24 // File   : PyConsole_Editor.cxx
25 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
26 //
27 /*!
28   \class PyConsole_Editor
29   \brief Python command line interpreter front-end GUI widget.
30   
31   This class provides simple GUI interface to the Python interpreter, including basic 
32   navigation operations, executing commands (both interactively and programmatically), 
33   copy-paste operations, history of the commands and so on.
34
35   Here below is the shortcut keyboard boundings used for navigation and other operations:
36   - <Enter>              : execute current command
37   - <Ctrl><Break>        : clear current command
38   - <Escape>             : clear current command
39   - <Up>                 : previous command in the history
40   - <Shift><Up>          : move cursor one row up with selection
41   - <Ctrl><Up>           : move cursor one row up without selection
42   - <Ctrl><Shift><Up>    : move cursor one row up with selection
43   - <Down>               : next command in the history
44   - <Shift><Down>        : move cursor one row down with selection
45   - <Ctrl><Down>         : move cursor one row down without selection
46   - <Ctrl><Shift><Down>  : move cursor one row down with selection
47   - <Left>               : move one symbol left without selection
48   - <Shift><Left>        : move one symbol left with selection
49   - <Ctrl><Left>         : move one word left without selection
50   - <Ctrl><Shift><Left>  : move one word left with selection
51   - <Right>              : move one symbol right without selection
52   - <Shift><Right>       : move one symbol right with selection
53   - <Ctrl><Right>        : move one word right without selection
54   - <Ctrl><Shift><Right> : move one word right with selection
55   - <PgUp>               : first command in the history
56   - <Shift><PgUp>        : move one page up with selection
57   - <Ctrl><PgUp>         : move one page up without selection
58   - <Ctrl><Shift><PgUp>  : scroll one page up
59   - <PgDn>               : last command in the history
60   - <Shift><PgDn>        : move one page down with selection
61   - <Ctrl><PgDn>         : move one page down without selection
62   - <Ctrl><Shift><PgDn>  : scroll one page down
63   - <Home>               : move to the beginning of the line without selection
64   - <Shift><Home>        : move to the beginning of the line with selection
65   - <Ctrl><Home>         : move to the very first symbol without selection
66   - <Ctrl><Shift><Home>  : move to the very first symbol with selection
67   - <End>                : move to the end of the line without selection
68   - <Shift><End>         : move to the end of the line with selection
69   - <Ctrl><End>          : move to the very last symbol without selection
70   - <Ctrl><Shift><End>   : move to the very last symbol with selection
71   - <Backspace>          : delete symbol before the cursor
72                            / remove selected text and put it to the clipboard (cut)
73   - <Shift><Backspace>   : delete previous word
74                            / remove selected text and put it to the clipboard (cut)
75   - <Ctrl><Backspace>    : delete text from the cursor to the beginning of the line 
76                            / remove selected text and put it to the clipboard (cut)
77   - <Delete>             : delete symbol after the cursor 
78                            / remove selected text and put it to the clipboard (cut)
79   - <Shift><Delete>      : delete next word
80                            / remove selected text and put it to the clipboard (cut)
81   - <Ctrl><Delete>       : delete text from the cursor to the end of the line
82                            / remove selected text and put it to the clipboard (cut)
83   - <Ctrl><Insert>       : copy
84   - <Shift><Insert>      : paste
85   - <Ctrl><V>            : paste
86   - <Ctrl><C>            : copy
87   - <Ctrl><X>            : cut
88   - <Ctrl><V>            : paste
89 */
90
91 #include "PyConsole_Interp.h"   // !!! WARNING !!! THIS INCLUDE MUST BE THE VERY FIRST !!!
92 #include "SalomePyConsole_Editor.h"
93 #include "PyConsole_Event.h"
94 #include "PyInterp_Event.h"
95 #include "PyInterp_Dispatcher.h"
96 #include "PyConsole_Request.h"
97
98 #include "SUIT_FileValidator.h"
99 #include "SUIT_MessageBox.h"
100 #include "SUIT_FileDlg.h"
101
102 #include <QApplication>
103 #include <QClipboard>
104 #include <QDropEvent>
105 #include <QEvent>
106 #include <QKeyEvent>
107 #include <QMouseEvent>
108 #include <QScrollBar>
109 #include <QTextBlock>
110 #include <QTextCursor>
111 #include <QTextDocument>
112 #include <QTextStream>
113 #include <QChar>
114 #include <QFileInfo>
115
116 class DumpCommandsFileValidator : public SUIT_FileValidator
117 {
118  public:
119   DumpCommandsFileValidator( QWidget* parent = 0 ) : SUIT_FileValidator ( parent ) {};
120   virtual ~DumpCommandsFileValidator() {};
121   virtual bool canSave( const QString& file, bool permissions );
122 };
123
124 bool DumpCommandsFileValidator::canSave(const QString& file, bool permissions)
125 {
126   QFileInfo fi( file );
127   if ( !QRegExp( "[A-Za-z_][A-Za-z0-9_]*" ).exactMatch( fi.completeBaseName() ) ) {
128     SUIT_MessageBox::critical( parent(),
129                                QObject::tr("WRN_WARNING"),
130                                QObject::tr("WRN_FILE_NAME_BAD") );
131     return false;
132   }
133   return SUIT_FileValidator::canSave( file, permissions);
134 }
135
136 /*!
137   \brief Constructor. 
138   
139   Creates python editor window.
140   \param theInterp python interper
141   \param theParent parent widget
142 */
143 SalomePyConsole_Editor::SalomePyConsole_Editor( PyConsole_Interp* theInterp, 
144                                                 QWidget*          theParent )
145   : PyConsole_EditorBase(theInterp,theParent)
146 {
147 }
148
149 /*!
150   \brief Destructor.
151 */
152 SalomePyConsole_Editor::~SalomePyConsole_Editor()
153 {
154 }
155
156
157 void SalomePyConsole_Editor::StaticDumpSlot(PyConsole_EditorBase *base)
158 {
159   QStringList aFilters;
160   aFilters.append( tr( "PYTHON_FILES_FILTER" ) );
161   
162   QString fileName = SUIT_FileDlg::getFileName( base, QString(),
163                                                 aFilters, tr( "TOT_DUMP_PYCOMMANDS" ),
164                                                 false, true, new DumpCommandsFileValidator( base ) );
165   base->dumpImpl(fileName);
166 }
167
168 /*!
169   \brief "Dump commands" operation.
170  */
171 void SalomePyConsole_Editor::dumpSlot()
172 {
173   SalomePyConsole_Editor::StaticDumpSlot(this);
174 }
175
176 void SalomePyConsole_Editor::StaticStartLogSlot(PyConsole_EditorBase *base)
177 {
178   QStringList aFilters;
179   aFilters.append( tr( "LOG_FILES_FILTER" ) );
180
181   while (1) {
182     QString fileName = SUIT_FileDlg::getFileName( base, QString(),
183                                                   aFilters, tr( "TOT_SAVE_PYLOG" ),
184                                                   false, true );
185     if ( !fileName.isEmpty() ) {
186       if ( base->startLogImpl( fileName ) ) {
187         break;
188       }
189       else {
190         SUIT_MessageBox::critical( base,
191                                    QObject::tr("ERR_ERROR"),
192                                    QObject::tr("ERR_FILE_NOT_WRITABLE") );
193       }
194     }
195     else {
196       break;
197     }
198   }
199 }
200
201 /*!
202   \brief "Start log" operation.
203  */
204 void SalomePyConsole_Editor::startLogSlot()
205 {
206   StaticStartLogSlot(this);
207 }