52 @type bool |
59 @type bool |
53 @param parent parent widget |
60 @param parent parent widget |
54 @type QWidget |
61 @type QWidget |
55 """ |
62 """ |
56 super().__init__(parent) |
63 super().__init__(parent) |
57 |
64 |
58 self.__shell = Shell(dbs, vm, project, False, self) |
65 self.__shell = Shell(dbs, vm, project, False, self) |
59 |
66 |
60 from UI.SearchWidget import SearchWidget |
67 from UI.SearchWidget import SearchWidget |
|
68 |
61 self.__searchWidget = SearchWidget(self.__shell, self, horizontal) |
69 self.__searchWidget = SearchWidget(self.__shell, self, horizontal) |
62 self.__searchWidget.setSizePolicy(QSizePolicy.Policy.Fixed, |
70 self.__searchWidget.setSizePolicy( |
63 QSizePolicy.Policy.Preferred) |
71 QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred |
|
72 ) |
64 self.__searchWidget.hide() |
73 self.__searchWidget.hide() |
65 |
74 |
66 if horizontal: |
75 if horizontal: |
67 self.__layout = QHBoxLayout(self) |
76 self.__layout = QHBoxLayout(self) |
68 else: |
77 else: |
69 self.__layout = QVBoxLayout(self) |
78 self.__layout = QVBoxLayout(self) |
70 self.__layout.setContentsMargins(1, 1, 1, 1) |
79 self.__layout.setContentsMargins(1, 1, 1, 1) |
71 self.__layout.addWidget(self.__shell) |
80 self.__layout.addWidget(self.__shell) |
72 self.__layout.addWidget(self.__searchWidget) |
81 self.__layout.addWidget(self.__searchWidget) |
73 |
82 |
74 self.__searchWidget.searchNext.connect(self.__shell.searchNext) |
83 self.__searchWidget.searchNext.connect(self.__shell.searchNext) |
75 self.__searchWidget.searchPrevious.connect(self.__shell.searchPrev) |
84 self.__searchWidget.searchPrevious.connect(self.__shell.searchPrev) |
76 self.__shell.searchStringFound.connect( |
85 self.__shell.searchStringFound.connect(self.__searchWidget.searchStringFound) |
77 self.__searchWidget.searchStringFound) |
86 |
78 |
|
79 def showFind(self, txt=""): |
87 def showFind(self, txt=""): |
80 """ |
88 """ |
81 Public method to display the search widget. |
89 Public method to display the search widget. |
82 |
90 |
83 @param txt text to be shown in the combo (string) |
91 @param txt text to be shown in the combo (string) |
84 """ |
92 """ |
85 self.__searchWidget.showFind(txt) |
93 self.__searchWidget.showFind(txt) |
86 |
94 |
87 def shell(self): |
95 def shell(self): |
88 """ |
96 """ |
89 Public method to get a reference to the shell widget. |
97 Public method to get a reference to the shell widget. |
90 |
98 |
91 @return reference to the shell widget (Shell) |
99 @return reference to the shell widget (Shell) |
92 """ |
100 """ |
93 return self.__shell |
101 return self.__shell |
94 |
102 |
95 |
103 |
96 class ShellHistoryStyle(enum.Enum): |
104 class ShellHistoryStyle(enum.Enum): |
97 """ |
105 """ |
98 Class defining the shell history styles. |
106 Class defining the shell history styles. |
99 """ |
107 """ |
|
108 |
100 DISABLED = 0 |
109 DISABLED = 0 |
101 LINUXSTYLE = 1 |
110 LINUXSTYLE = 1 |
102 WINDOWSSTYLE = 2 |
111 WINDOWSSTYLE = 2 |
103 |
112 |
104 |
113 |
105 class Shell(QsciScintillaCompat): |
114 class Shell(QsciScintillaCompat): |
106 """ |
115 """ |
107 Class implementing a graphical Python shell. |
116 Class implementing a graphical Python shell. |
108 |
117 |
109 A user can enter commands that are executed in the remote |
118 A user can enter commands that are executed in the remote |
110 Python interpreter. |
119 Python interpreter. |
111 |
120 |
112 @signal searchStringFound(bool) emitted to indicate the search |
121 @signal searchStringFound(bool) emitted to indicate the search |
113 result |
122 result |
114 @signal historyStyleChanged(ShellHistoryStyle) emitted to indicate a |
123 @signal historyStyleChanged(ShellHistoryStyle) emitted to indicate a |
115 change of the history style |
124 change of the history style |
116 @signal queueText(str) emitted to queue some text for processing |
125 @signal queueText(str) emitted to queue some text for processing |
117 @signal virtualEnvironmentChanged(str) emitted to signal the new virtual |
126 @signal virtualEnvironmentChanged(str) emitted to signal the new virtual |
118 environment of the shell |
127 environment of the shell |
119 """ |
128 """ |
|
129 |
120 searchStringFound = pyqtSignal(bool) |
130 searchStringFound = pyqtSignal(bool) |
121 historyStyleChanged = pyqtSignal(ShellHistoryStyle) |
131 historyStyleChanged = pyqtSignal(ShellHistoryStyle) |
122 queueText = pyqtSignal(str) |
132 queueText = pyqtSignal(str) |
123 virtualEnvironmentChanged = pyqtSignal(str) |
133 virtualEnvironmentChanged = pyqtSignal(str) |
124 |
134 |
125 def __init__(self, dbs, vm, project, windowedVariant, parent=None): |
135 def __init__(self, dbs, vm, project, windowedVariant, parent=None): |
126 """ |
136 """ |
127 Constructor |
137 Constructor |
128 |
138 |
129 @param dbs reference to the debug server object |
139 @param dbs reference to the debug server object |
130 @type DebugServer |
140 @type DebugServer |
131 @param vm reference to the viewmanager object |
141 @param vm reference to the viewmanager object |
132 @type ViewManager |
142 @type ViewManager |
133 @param project reference to the project object |
143 @param project reference to the project object |
137 @param parent parent widget |
147 @param parent parent widget |
138 @type QWidget |
148 @type QWidget |
139 """ |
149 """ |
140 super().__init__(parent) |
150 super().__init__(parent) |
141 self.setUtf8(True) |
151 self.setUtf8(True) |
142 |
152 |
143 self.vm = vm |
153 self.vm = vm |
144 self.__mainWindow = parent |
154 self.__mainWindow = parent |
145 self.__lastSearch = () |
155 self.__lastSearch = () |
146 self.__windowed = windowedVariant |
156 self.__windowed = windowedVariant |
147 self.__currentVenv = "" |
157 self.__currentVenv = "" |
148 self.__currentWorkingDirectory = "" |
158 self.__currentWorkingDirectory = "" |
149 |
159 |
150 self.linesepRegExp = r"\r\n|\n|\r" |
160 self.linesepRegExp = r"\r\n|\n|\r" |
151 |
161 |
152 self.passive = ((not self.__windowed) and |
162 self.passive = (not self.__windowed) and Preferences.getDebugger( |
153 Preferences.getDebugger("PassiveDbgEnabled")) |
163 "PassiveDbgEnabled" |
|
164 ) |
154 if self.passive: |
165 if self.passive: |
155 self.setWindowTitle(self.tr('Shell - Passive')) |
166 self.setWindowTitle(self.tr("Shell - Passive")) |
156 else: |
167 else: |
157 self.setWindowTitle(self.tr('Shell')) |
168 self.setWindowTitle(self.tr("Shell")) |
158 |
169 |
159 if self.__windowed: |
170 if self.__windowed: |
160 self.setWhatsThis(self.tr( |
171 self.setWhatsThis( |
161 """<b>The Shell Window</b>""" |
172 self.tr( |
162 """<p>You can use the cursor keys while entering commands.""" |
173 """<b>The Shell Window</b>""" |
163 """ There is also a history of commands that can be recalled""" |
174 """<p>You can use the cursor keys while entering commands.""" |
164 """ using the up and down cursor keys while holding down the""" |
175 """ There is also a history of commands that can be recalled""" |
165 """ Ctrl-key. This can be switched to just the up and down""" |
176 """ using the up and down cursor keys while holding down the""" |
166 """ cursor keys on the Shell page of the configuration""" |
177 """ Ctrl-key. This can be switched to just the up and down""" |
167 """ dialog. Pressing these keys after some text has been""" |
178 """ cursor keys on the Shell page of the configuration""" |
168 """ entered will start an incremental search.</p>""" |
179 """ dialog. Pressing these keys after some text has been""" |
169 """<p>The shell has some special commands. '%restart' kills""" |
180 """ entered will start an incremental search.</p>""" |
170 """ the shell and starts a new one. '%clear' clears the""" |
181 """<p>The shell has some special commands. '%restart' kills""" |
171 """ display of the shell window. '%start' is used to start a""" |
182 """ the shell and starts a new one. '%clear' clears the""" |
172 """ shell for a virtual environment and should be followed""" |
183 """ display of the shell window. '%start' is used to start a""" |
173 """ by a virtual environment name. '%start' without a""" |
184 """ shell for a virtual environment and should be followed""" |
174 """ virtual environment name starts the default shell.""" |
185 """ by a virtual environment name. '%start' without a""" |
175 """ Available virtual environments may be listed with the""" |
186 """ virtual environment name starts the default shell.""" |
176 """ '%envs' or '%environments' commands. The active virtual""" |
187 """ Available virtual environments may be listed with the""" |
177 """ environment can be questioned by the '%which' command.""" |
188 """ '%envs' or '%environments' commands. The active virtual""" |
178 """ '%quit' or '%exit' is used to exit the application.""" |
189 """ environment can be questioned by the '%which' command.""" |
179 """ These commands (except '%environments', '%envs' and""" |
190 """ '%quit' or '%exit' is used to exit the application.""" |
180 """ '%which') are available through the window menus as""" |
191 """ These commands (except '%environments', '%envs' and""" |
181 """ well.</p>""" |
192 """ '%which') are available through the window menus as""" |
182 """<p>Pressing the Tab key after some text has been entered""" |
193 """ well.</p>""" |
183 """ will show a list of possible completions. The relevant""" |
194 """<p>Pressing the Tab key after some text has been entered""" |
184 """ entry may be selected from this list. If only one entry""" |
195 """ will show a list of possible completions. The relevant""" |
185 """ is available, this will be inserted automatically.</p>""" |
196 """ entry may be selected from this list. If only one entry""" |
186 )) |
197 """ is available, this will be inserted automatically.</p>""" |
187 else: |
198 ) |
188 self.setWhatsThis(self.tr( |
199 ) |
189 """<b>The Shell Window</b>""" |
200 else: |
190 """<p>This is simply an interpreter running in a window. The""" |
201 self.setWhatsThis( |
191 """ interpreter is the one that is used to run the program""" |
202 self.tr( |
192 """ being debugged. This means that you can execute any""" |
203 """<b>The Shell Window</b>""" |
193 """ command while the program being debugged is running.</p>""" |
204 """<p>This is simply an interpreter running in a window. The""" |
194 """<p>You can use the cursor keys while entering commands.""" |
205 """ interpreter is the one that is used to run the program""" |
195 """ There is also a history of commands that can be recalled""" |
206 """ being debugged. This means that you can execute any""" |
196 """ using the up and down cursor keys while holding down the""" |
207 """ command while the program being debugged is running.</p>""" |
197 """ Ctrl-key. This can be switched to just the up and down""" |
208 """<p>You can use the cursor keys while entering commands.""" |
198 """ cursor keys on the Shell page of the configuration""" |
209 """ There is also a history of commands that can be recalled""" |
199 """ dialog. Pressing these keys after some text has been""" |
210 """ using the up and down cursor keys while holding down the""" |
200 """ entered will start an incremental search.</p>""" |
211 """ Ctrl-key. This can be switched to just the up and down""" |
201 """<p>The shell has some special commands. '%restart' kills""" |
212 """ cursor keys on the Shell page of the configuration""" |
202 """ the shell and starts a new one. '%clear' clears the""" |
213 """ dialog. Pressing these keys after some text has been""" |
203 """ display of the shell window. '%start' is used to start a""" |
214 """ entered will start an incremental search.</p>""" |
204 """ shell for a virtual environment and should be followed""" |
215 """<p>The shell has some special commands. '%restart' kills""" |
205 """ by a virtual environment name. '%start' without a""" |
216 """ the shell and starts a new one. '%clear' clears the""" |
206 """ virtual environment name starts the default shell.""" |
217 """ display of the shell window. '%start' is used to start a""" |
207 """ Available virtual environments may be listed with the""" |
218 """ shell for a virtual environment and should be followed""" |
208 """ '%envs' or '%environments' commands. The active virtual""" |
219 """ by a virtual environment name. '%start' without a""" |
209 """ environment can be questioned by the '%which' command.""" |
220 """ virtual environment name starts the default shell.""" |
210 """ These commands (except '%environments' and '%envs') are""" |
221 """ Available virtual environments may be listed with the""" |
211 """ available through the context menu as well.</p>""" |
222 """ '%envs' or '%environments' commands. The active virtual""" |
212 """<p>Pressing the Tab key after some text has been entered""" |
223 """ environment can be questioned by the '%which' command.""" |
213 """ will show a list of possible completions. The relevant""" |
224 """ These commands (except '%environments' and '%envs') are""" |
214 """ entry may be selected from this list. If only one entry""" |
225 """ available through the context menu as well.</p>""" |
215 """ is available, this will be inserted automatically.</p>""" |
226 """<p>Pressing the Tab key after some text has been entered""" |
216 """<p>In passive debugging mode the shell is only available""" |
227 """ will show a list of possible completions. The relevant""" |
217 """ after the program to be debugged has connected to the""" |
228 """ entry may be selected from this list. If only one entry""" |
218 """ IDE until it has finished. This is indicated by a""" |
229 """ is available, this will be inserted automatically.</p>""" |
219 """ different prompt and by an indication in the window""" |
230 """<p>In passive debugging mode the shell is only available""" |
220 """ caption.</p>""" |
231 """ after the program to be debugged has connected to the""" |
221 )) |
232 """ IDE until it has finished. This is indicated by a""" |
222 |
233 """ different prompt and by an indication in the window""" |
|
234 """ caption.</p>""" |
|
235 ) |
|
236 ) |
|
237 |
223 self.userListActivated.connect(self.__completionListSelected) |
238 self.userListActivated.connect(self.__completionListSelected) |
224 self.linesChanged.connect(self.__resizeLinenoMargin) |
239 self.linesChanged.connect(self.__resizeLinenoMargin) |
225 |
240 |
226 if self.__windowed: |
241 if self.__windowed: |
227 self.__showStdOutErr = True |
242 self.__showStdOutErr = True |
228 else: |
243 else: |
229 self.__showStdOutErr = Preferences.getShell("ShowStdOutErr") |
244 self.__showStdOutErr = Preferences.getShell("ShowStdOutErr") |
230 if self.__showStdOutErr: |
245 if self.__showStdOutErr: |
256 sys.ps1 = ">>> " |
271 sys.ps1 = ">>> " |
257 try: |
272 try: |
258 sys.ps2 |
273 sys.ps2 |
259 except AttributeError: |
274 except AttributeError: |
260 sys.ps2 = "... " |
275 sys.ps2 = "... " |
261 |
276 |
262 # Initialize instance variables. |
277 # Initialize instance variables. |
263 self.__initialise() |
278 self.__initialise() |
264 self.prline = 0 |
279 self.prline = 0 |
265 self.prcol = 0 |
280 self.prcol = 0 |
266 self.inDragDrop = False |
281 self.inDragDrop = False |
267 self.lexer_ = None |
282 self.lexer_ = None |
268 self.completionText = "" |
283 self.completionText = "" |
269 |
284 |
270 self.clientType = '' |
285 self.clientType = "" |
271 |
286 |
272 # Initialize history |
287 # Initialize history |
273 self.__historyLists = {} |
288 self.__historyLists = {} |
274 self.__maxHistoryEntries = Preferences.getShell("MaxHistoryEntries") |
289 self.__maxHistoryEntries = Preferences.getShell("MaxHistoryEntries") |
275 self.__historyStyle = Preferences.getShell("HistoryStyle") |
290 self.__historyStyle = Preferences.getShell("HistoryStyle") |
276 self.__historyWrap = Preferences.getShell("HistoryWrap") |
291 self.__historyWrap = Preferences.getShell("HistoryWrap") |
277 self.__history = [] |
292 self.__history = [] |
278 self.__setHistoryIndex() |
293 self.__setHistoryIndex() |
279 # remove obsolete shell histories (Python and Ruby) |
294 # remove obsolete shell histories (Python and Ruby) |
280 for clientType in ["Python", "Ruby"]: |
295 for clientType in ["Python", "Ruby"]: |
281 Preferences.getSettings().remove("Shell/Histories/" + clientType) |
296 Preferences.getSettings().remove("Shell/Histories/" + clientType) |
282 |
297 |
283 # clear QScintilla defined keyboard commands |
298 # clear QScintilla defined keyboard commands |
284 # we do our own handling through the view manager |
299 # we do our own handling through the view manager |
285 self.clearAlternateKeys() |
300 self.clearAlternateKeys() |
286 self.clearKeys() |
301 self.clearKeys() |
287 self.__actionsAdded = False |
302 self.__actionsAdded = False |
288 |
303 |
289 if self.passive: |
304 if self.passive: |
290 self.__getBanner() |
305 self.__getBanner() |
291 |
306 |
292 if not self.__windowed: |
307 if not self.__windowed: |
293 # Create a little language context menu |
308 # Create a little language context menu |
294 self.lmenu = QMenu(self.tr('Start')) |
309 self.lmenu = QMenu(self.tr("Start")) |
295 self.lmenu.aboutToShow.connect(self.__showStartMenu) |
310 self.lmenu.aboutToShow.connect(self.__showStartMenu) |
296 self.lmenu.triggered.connect(self.__startDebugClient) |
311 self.lmenu.triggered.connect(self.__startDebugClient) |
297 |
312 |
298 # Create the history context menu |
313 # Create the history context menu |
299 self.hmenu = QMenu(self.tr('History')) |
314 self.hmenu = QMenu(self.tr("History")) |
300 self.hmenu.addAction(self.tr('Select entry'), self.selectHistory) |
315 self.hmenu.addAction(self.tr("Select entry"), self.selectHistory) |
301 self.hmenu.addAction(self.tr('Show'), self.showHistory) |
316 self.hmenu.addAction(self.tr("Show"), self.showHistory) |
302 self.hmenu.addAction(self.tr('Clear'), self.clearHistory) |
317 self.hmenu.addAction(self.tr("Clear"), self.clearHistory) |
303 |
318 |
304 # Create a little context menu |
319 # Create a little context menu |
305 self.menu = QMenu(self) |
320 self.menu = QMenu(self) |
306 self.menu.addAction(self.tr('Cut'), self.cut) |
321 self.menu.addAction(self.tr("Cut"), self.cut) |
307 self.menu.addAction(self.tr('Copy'), self.copy) |
322 self.menu.addAction(self.tr("Copy"), self.copy) |
308 self.menu.addAction(self.tr('Paste'), self.paste) |
323 self.menu.addAction(self.tr("Paste"), self.paste) |
309 self.menu.addMenu(self.hmenu).setEnabled(self.isHistoryEnabled()) |
324 self.menu.addMenu(self.hmenu).setEnabled(self.isHistoryEnabled()) |
310 |
325 |
311 self.menu.addSeparator() |
326 self.menu.addSeparator() |
312 self.menu.addAction(self.tr('Find'), self.__find) |
327 self.menu.addAction(self.tr("Find"), self.__find) |
313 self.menu.addSeparator() |
328 self.menu.addSeparator() |
314 self.menu.addAction(self.tr('Clear'), self.clear) |
329 self.menu.addAction(self.tr("Clear"), self.clear) |
315 self.menu.addAction(self.tr('Restart'), self.doRestart) |
330 self.menu.addAction(self.tr("Restart"), self.doRestart) |
316 self.menu.addAction( |
331 self.menu.addAction(self.tr("Restart and Clear"), self.doClearRestart) |
317 self.tr('Restart and Clear'), self.doClearRestart) |
|
318 self.menu.addSeparator() |
332 self.menu.addSeparator() |
319 self.menu.addMenu(self.lmenu) |
333 self.menu.addMenu(self.lmenu) |
320 self.menu.addAction(self.tr('Active Name'), self.__showVenvName) |
334 self.menu.addAction(self.tr("Active Name"), self.__showVenvName) |
321 self.menu.addSeparator() |
335 self.menu.addSeparator() |
322 self.menu.addAction(self.tr("Save Contents..."), self.saveContents) |
336 self.menu.addAction(self.tr("Save Contents..."), self.saveContents) |
323 self.menu.addSeparator() |
337 self.menu.addSeparator() |
324 self.menu.addAction(self.tr("Configure..."), self.__configure) |
338 self.menu.addAction(self.tr("Configure..."), self.__configure) |
325 |
339 |
326 self.__bindLexer() |
340 self.__bindLexer() |
327 self.__setTextDisplay() |
341 self.__setTextDisplay() |
328 self.__setMargin0() |
342 self.__setMargin0() |
329 |
343 |
330 # set the autocompletion and calltips function |
344 # set the autocompletion and calltips function |
331 self.__setAutoCompletion() |
345 self.__setAutoCompletion() |
332 self.__setCallTips() |
346 self.__setCallTips() |
333 |
347 |
334 self.setWindowIcon(UI.PixmapCache.getIcon("eric")) |
348 self.setWindowIcon(UI.PixmapCache.getIcon("eric")) |
335 |
349 |
336 self.incrementalSearchString = "" |
350 self.incrementalSearchString = "" |
337 self.incrementalSearchActive = False |
351 self.incrementalSearchActive = False |
338 |
352 |
339 self.supportedEditorCommands = { |
353 self.supportedEditorCommands = { |
340 QsciScintilla.SCI_LINEDELETE: self.__clearCurrentLine, |
354 QsciScintilla.SCI_LINEDELETE: self.__clearCurrentLine, |
341 QsciScintilla.SCI_TAB: self.__QScintillaTab, |
355 QsciScintilla.SCI_TAB: self.__QScintillaTab, |
342 QsciScintilla.SCI_NEWLINE: self.__QScintillaNewline, |
356 QsciScintilla.SCI_NEWLINE: self.__QScintillaNewline, |
343 |
|
344 QsciScintilla.SCI_DELETEBACK: self.__QScintillaDeleteBack, |
357 QsciScintilla.SCI_DELETEBACK: self.__QScintillaDeleteBack, |
345 QsciScintilla.SCI_CLEAR: self.__QScintillaDelete, |
358 QsciScintilla.SCI_CLEAR: self.__QScintillaDelete, |
346 QsciScintilla.SCI_DELWORDLEFT: self.__QScintillaDeleteWordLeft, |
359 QsciScintilla.SCI_DELWORDLEFT: self.__QScintillaDeleteWordLeft, |
347 QsciScintilla.SCI_DELWORDRIGHT: self.__QScintillaDeleteWordRight, |
360 QsciScintilla.SCI_DELWORDRIGHT: self.__QScintillaDeleteWordRight, |
348 QsciScintilla.SCI_DELLINELEFT: self.__QScintillaDeleteLineLeft, |
361 QsciScintilla.SCI_DELLINELEFT: self.__QScintillaDeleteLineLeft, |
349 QsciScintilla.SCI_DELLINERIGHT: self.__QScintillaDeleteLineRight, |
362 QsciScintilla.SCI_DELLINERIGHT: self.__QScintillaDeleteLineRight, |
350 |
|
351 QsciScintilla.SCI_CHARLEFT: self.__QScintillaCharLeft, |
363 QsciScintilla.SCI_CHARLEFT: self.__QScintillaCharLeft, |
352 QsciScintilla.SCI_CHARRIGHT: self.__QScintillaCharRight, |
364 QsciScintilla.SCI_CHARRIGHT: self.__QScintillaCharRight, |
353 QsciScintilla.SCI_WORDLEFT: self.__QScintillaWordLeft, |
365 QsciScintilla.SCI_WORDLEFT: self.__QScintillaWordLeft, |
354 QsciScintilla.SCI_WORDRIGHT: self.__QScintillaWordRight, |
366 QsciScintilla.SCI_WORDRIGHT: self.__QScintillaWordRight, |
355 QsciScintilla.SCI_VCHOME: self.__QScintillaVCHome, |
367 QsciScintilla.SCI_VCHOME: self.__QScintillaVCHome, |
356 QsciScintilla.SCI_LINEEND: self.__QScintillaLineEnd, |
368 QsciScintilla.SCI_LINEEND: self.__QScintillaLineEnd, |
357 |
|
358 QsciScintilla.SCI_LINEUP: self.__QScintillaCursorCommand, |
369 QsciScintilla.SCI_LINEUP: self.__QScintillaCursorCommand, |
359 QsciScintilla.SCI_LINEDOWN: self.__QScintillaCursorCommand, |
370 QsciScintilla.SCI_LINEDOWN: self.__QScintillaCursorCommand, |
360 QsciScintilla.SCI_LINESCROLLUP: self.__QScintillaCursorCommand, |
371 QsciScintilla.SCI_LINESCROLLUP: self.__QScintillaCursorCommand, |
361 QsciScintilla.SCI_LINESCROLLDOWN: self.__QScintillaCursorCommand, |
372 QsciScintilla.SCI_LINESCROLLDOWN: self.__QScintillaCursorCommand, |
362 |
|
363 QsciScintilla.SCI_PAGEUP: self.__QScintillaAutoCompletionCommand, |
373 QsciScintilla.SCI_PAGEUP: self.__QScintillaAutoCompletionCommand, |
364 QsciScintilla.SCI_PAGEDOWN: self.__QScintillaAutoCompletionCommand, |
374 QsciScintilla.SCI_PAGEDOWN: self.__QScintillaAutoCompletionCommand, |
365 |
|
366 QsciScintilla.SCI_CHARLEFTEXTEND: self.__QScintillaCharLeftExtend, |
375 QsciScintilla.SCI_CHARLEFTEXTEND: self.__QScintillaCharLeftExtend, |
367 QsciScintilla.SCI_CHARRIGHTEXTEND: self.extendSelectionRight, |
376 QsciScintilla.SCI_CHARRIGHTEXTEND: self.extendSelectionRight, |
368 QsciScintilla.SCI_WORDLEFTEXTEND: self.__QScintillaWordLeftExtend, |
377 QsciScintilla.SCI_WORDLEFTEXTEND: self.__QScintillaWordLeftExtend, |
369 QsciScintilla.SCI_WORDRIGHTEXTEND: self.extendSelectionWordRight, |
378 QsciScintilla.SCI_WORDRIGHTEXTEND: self.extendSelectionWordRight, |
370 QsciScintilla.SCI_VCHOMEEXTEND: self.__QScintillaVCHomeExtend, |
379 QsciScintilla.SCI_VCHOMEEXTEND: self.__QScintillaVCHomeExtend, |
371 QsciScintilla.SCI_LINEENDEXTEND: self.extendSelectionToEOL, |
380 QsciScintilla.SCI_LINEENDEXTEND: self.extendSelectionToEOL, |
372 |
|
373 QsciScintilla.SCI_CANCEL: self.__QScintillaCancel, |
381 QsciScintilla.SCI_CANCEL: self.__QScintillaCancel, |
374 } |
382 } |
375 |
383 |
376 self.__historyNavigateByCursor = ( |
384 self.__historyNavigateByCursor = Preferences.getShell("HistoryNavigateByCursor") |
377 Preferences.getShell("HistoryNavigateByCursor") |
385 |
|
386 self.__queuedText = "" |
|
387 self.__blockTextProcessing = False |
|
388 self.queueText.connect( |
|
389 self.__concatenateText, Qt.ConnectionType.QueuedConnection |
378 ) |
390 ) |
379 |
391 |
380 self.__queuedText = '' |
|
381 self.__blockTextProcessing = False |
|
382 self.queueText.connect(self.__concatenateText, |
|
383 Qt.ConnectionType.QueuedConnection) |
|
384 |
|
385 self.__project = project |
392 self.__project = project |
386 if self.__project: |
393 if self.__project: |
387 self.__project.projectOpened.connect(self.__projectOpened) |
394 self.__project.projectOpened.connect(self.__projectOpened) |
388 self.__project.projectClosed.connect(self.__projectClosed) |
395 self.__project.projectClosed.connect(self.__projectClosed) |
389 |
396 |
390 self.grabGesture(Qt.GestureType.PinchGesture) |
397 self.grabGesture(Qt.GestureType.PinchGesture) |
391 |
398 |
392 def __showStartMenu(self): |
399 def __showStartMenu(self): |
393 """ |
400 """ |
394 Private slot to prepare the start submenu. |
401 Private slot to prepare the start submenu. |
395 """ |
402 """ |
396 self.lmenu.clear() |
403 self.lmenu.clear() |
398 for venvName in sorted(venvManager.getVirtualenvNames()): |
405 for venvName in sorted(venvManager.getVirtualenvNames()): |
399 self.lmenu.addAction(venvName) |
406 self.lmenu.addAction(venvName) |
400 if self.__project.isOpen(): |
407 if self.__project.isOpen(): |
401 self.lmenu.addSeparator() |
408 self.lmenu.addSeparator() |
402 self.lmenu.addAction(self.tr("Project")) |
409 self.lmenu.addAction(self.tr("Project")) |
403 |
410 |
404 def __resizeLinenoMargin(self): |
411 def __resizeLinenoMargin(self): |
405 """ |
412 """ |
406 Private slot to resize the line numbers margin. |
413 Private slot to resize the line numbers margin. |
407 """ |
414 """ |
408 linenoMargin = Preferences.getShell("LinenoMargin") |
415 linenoMargin = Preferences.getShell("LinenoMargin") |
409 if linenoMargin: |
416 if linenoMargin: |
410 self.setMarginWidth(0, '8' * (len(str(self.lines())) + 1)) |
417 self.setMarginWidth(0, "8" * (len(str(self.lines())) + 1)) |
411 |
418 |
412 def closeShell(self): |
419 def closeShell(self): |
413 """ |
420 """ |
414 Public method to shutdown the shell. |
421 Public method to shutdown the shell. |
415 """ |
422 """ |
416 for clientType in self.__historyLists: |
423 for clientType in self.__historyLists: |
417 self.saveHistory(clientType) |
424 self.saveHistory(clientType) |
418 |
425 |
419 def __bindLexer(self, language='Python3'): |
426 def __bindLexer(self, language="Python3"): |
420 """ |
427 """ |
421 Private slot to set the lexer. |
428 Private slot to set the lexer. |
422 |
429 |
423 @param language lexer language to set (string) |
430 @param language lexer language to set (string) |
424 """ |
431 """ |
425 self.language = language |
432 self.language = language |
426 if Preferences.getShell("SyntaxHighlightingEnabled"): |
433 if Preferences.getShell("SyntaxHighlightingEnabled"): |
427 from . import Lexers |
434 from . import Lexers |
|
435 |
428 self.lexer_ = Lexers.getLexer(self.language, self) |
436 self.lexer_ = Lexers.getLexer(self.language, self) |
429 else: |
437 else: |
430 self.lexer_ = None |
438 self.lexer_ = None |
431 |
439 |
432 if self.lexer_ is None: |
440 if self.lexer_ is None: |
433 self.setLexer(None) |
441 self.setLexer(None) |
434 font = Preferences.getShell("MonospacedFont") |
442 font = Preferences.getShell("MonospacedFont") |
435 self.monospacedStyles(font) |
443 self.monospacedStyles(font) |
436 return |
444 return |
437 |
445 |
438 # get the font for style 0 and set it as the default font |
446 # get the font for style 0 and set it as the default font |
439 key = 'Scintilla/{0}/style0/font'.format(self.lexer_.language()) |
447 key = "Scintilla/{0}/style0/font".format(self.lexer_.language()) |
440 fdesc = Preferences.getSettings().value(key) |
448 fdesc = Preferences.getSettings().value(key) |
441 if fdesc is not None: |
449 if fdesc is not None: |
442 font = QFont([fdesc[0]], int(fdesc[1])) |
450 font = QFont([fdesc[0]], int(fdesc[1])) |
443 self.lexer_.setDefaultFont(font) |
451 self.lexer_.setDefaultFont(font) |
444 self.setLexer(self.lexer_) |
452 self.setLexer(self.lexer_) |
445 self.lexer_.readSettings(Preferences.getSettings(), "Scintilla") |
453 self.lexer_.readSettings(Preferences.getSettings(), "Scintilla") |
446 if self.lexer_.hasSubstyles(): |
454 if self.lexer_.hasSubstyles(): |
447 self.lexer_.readSubstyles(self) |
455 self.lexer_.readSubstyles(self) |
448 |
456 |
449 # initialize the lexer APIs settings |
457 # initialize the lexer APIs settings |
450 api = self.vm.getAPIsManager().getAPIs(self.language) |
458 api = self.vm.getAPIsManager().getAPIs(self.language) |
451 if api is not None: |
459 if api is not None: |
452 api = api.getQsciAPIs() |
460 api = api.getQsciAPIs() |
453 if api is not None: |
461 if api is not None: |
454 self.lexer_.setAPIs(api) |
462 self.lexer_.setAPIs(api) |
455 |
463 |
456 self.lexer_.setDefaultColor(self.lexer_.color(0)) |
464 self.lexer_.setDefaultColor(self.lexer_.color(0)) |
457 self.lexer_.setDefaultPaper(self.lexer_.paper(0)) |
465 self.lexer_.setDefaultPaper(self.lexer_.paper(0)) |
458 |
466 |
459 def __setMargin0(self): |
467 def __setMargin0(self): |
460 """ |
468 """ |
461 Private method to configure margin 0. |
469 Private method to configure margin 0. |
462 """ |
470 """ |
463 # set the settings for all margins |
471 # set the settings for all margins |
464 self.setMarginsFont(Preferences.getShell("MarginsFont")) |
472 self.setMarginsFont(Preferences.getShell("MarginsFont")) |
465 self.setMarginsForegroundColor( |
473 self.setMarginsForegroundColor(Preferences.getEditorColour("MarginsForeground")) |
466 Preferences.getEditorColour("MarginsForeground")) |
474 self.setMarginsBackgroundColor(Preferences.getEditorColour("MarginsBackground")) |
467 self.setMarginsBackgroundColor( |
475 |
468 Preferences.getEditorColour("MarginsBackground")) |
|
469 |
|
470 # set margin 0 settings |
476 # set margin 0 settings |
471 linenoMargin = Preferences.getShell("LinenoMargin") |
477 linenoMargin = Preferences.getShell("LinenoMargin") |
472 self.setMarginLineNumbers(0, linenoMargin) |
478 self.setMarginLineNumbers(0, linenoMargin) |
473 if linenoMargin: |
479 if linenoMargin: |
474 self.__resizeLinenoMargin() |
480 self.__resizeLinenoMargin() |
475 else: |
481 else: |
476 self.setMarginWidth(0, 0) |
482 self.setMarginWidth(0, 0) |
477 |
483 |
478 # disable margins 1 and 2 |
484 # disable margins 1 and 2 |
479 self.setMarginWidth(1, 0) |
485 self.setMarginWidth(1, 0) |
480 self.setMarginWidth(2, 0) |
486 self.setMarginWidth(2, 0) |
481 |
487 |
482 def __setTextDisplay(self): |
488 def __setTextDisplay(self): |
483 """ |
489 """ |
484 Private method to configure the text display. |
490 Private method to configure the text display. |
485 """ |
491 """ |
486 self.setTabWidth(Preferences.getEditor("TabWidth")) |
492 self.setTabWidth(Preferences.getEditor("TabWidth")) |
487 if Preferences.getEditor("ShowWhitespace"): |
493 if Preferences.getEditor("ShowWhitespace"): |
488 self.setWhitespaceVisibility( |
494 self.setWhitespaceVisibility(QsciScintilla.WhitespaceVisibility.WsVisible) |
489 QsciScintilla.WhitespaceVisibility.WsVisible) |
|
490 with contextlib.suppress(AttributeError): |
495 with contextlib.suppress(AttributeError): |
491 self.setWhitespaceForegroundColor( |
496 self.setWhitespaceForegroundColor( |
492 Preferences.getEditorColour("WhitespaceForeground")) |
497 Preferences.getEditorColour("WhitespaceForeground") |
|
498 ) |
493 self.setWhitespaceBackgroundColor( |
499 self.setWhitespaceBackgroundColor( |
494 Preferences.getEditorColour("WhitespaceBackground")) |
500 Preferences.getEditorColour("WhitespaceBackground") |
495 self.setWhitespaceSize( |
501 ) |
496 Preferences.getEditor("WhitespaceSize")) |
502 self.setWhitespaceSize(Preferences.getEditor("WhitespaceSize")) |
497 else: |
503 else: |
498 self.setWhitespaceVisibility( |
504 self.setWhitespaceVisibility(QsciScintilla.WhitespaceVisibility.WsInvisible) |
499 QsciScintilla.WhitespaceVisibility.WsInvisible) |
|
500 self.setEolVisibility(Preferences.getEditor("ShowEOL")) |
505 self.setEolVisibility(Preferences.getEditor("ShowEOL")) |
501 if Preferences.getEditor("BraceHighlighting"): |
506 if Preferences.getEditor("BraceHighlighting"): |
502 self.setBraceMatching(QsciScintilla.BraceMatch.SloppyBraceMatch) |
507 self.setBraceMatching(QsciScintilla.BraceMatch.SloppyBraceMatch) |
503 else: |
508 else: |
504 self.setBraceMatching(QsciScintilla.BraceMatch.NoBraceMatch) |
509 self.setBraceMatching(QsciScintilla.BraceMatch.NoBraceMatch) |
505 self.setMatchedBraceForegroundColor( |
510 self.setMatchedBraceForegroundColor( |
506 Preferences.getEditorColour("MatchingBrace")) |
511 Preferences.getEditorColour("MatchingBrace") |
|
512 ) |
507 self.setMatchedBraceBackgroundColor( |
513 self.setMatchedBraceBackgroundColor( |
508 Preferences.getEditorColour("MatchingBraceBack")) |
514 Preferences.getEditorColour("MatchingBraceBack") |
|
515 ) |
509 self.setUnmatchedBraceForegroundColor( |
516 self.setUnmatchedBraceForegroundColor( |
510 Preferences.getEditorColour("NonmatchingBrace")) |
517 Preferences.getEditorColour("NonmatchingBrace") |
|
518 ) |
511 self.setUnmatchedBraceBackgroundColor( |
519 self.setUnmatchedBraceBackgroundColor( |
512 Preferences.getEditorColour("NonmatchingBraceBack")) |
520 Preferences.getEditorColour("NonmatchingBraceBack") |
|
521 ) |
513 if Preferences.getEditor("CustomSelectionColours"): |
522 if Preferences.getEditor("CustomSelectionColours"): |
514 self.setSelectionBackgroundColor( |
523 self.setSelectionBackgroundColor( |
515 Preferences.getEditorColour("SelectionBackground")) |
524 Preferences.getEditorColour("SelectionBackground") |
|
525 ) |
516 else: |
526 else: |
517 self.setSelectionBackgroundColor( |
527 self.setSelectionBackgroundColor( |
518 QApplication.palette().color(QPalette.ColorRole.Highlight)) |
528 QApplication.palette().color(QPalette.ColorRole.Highlight) |
|
529 ) |
519 if Preferences.getEditor("ColourizeSelText"): |
530 if Preferences.getEditor("ColourizeSelText"): |
520 self.resetSelectionForegroundColor() |
531 self.resetSelectionForegroundColor() |
521 elif Preferences.getEditor("CustomSelectionColours"): |
532 elif Preferences.getEditor("CustomSelectionColours"): |
522 self.setSelectionForegroundColor( |
533 self.setSelectionForegroundColor( |
523 Preferences.getEditorColour("SelectionForeground")) |
534 Preferences.getEditorColour("SelectionForeground") |
|
535 ) |
524 else: |
536 else: |
525 self.setSelectionForegroundColor( |
537 self.setSelectionForegroundColor( |
526 QApplication.palette().color( |
538 QApplication.palette().color(QPalette.ColorRole.HighlightedText) |
527 QPalette.ColorRole.HighlightedText)) |
539 ) |
528 self.setSelectionToEol(Preferences.getEditor("ExtendSelectionToEol")) |
540 self.setSelectionToEol(Preferences.getEditor("ExtendSelectionToEol")) |
529 self.setCaretForegroundColor( |
541 self.setCaretForegroundColor(Preferences.getEditorColour("CaretForeground")) |
530 Preferences.getEditorColour("CaretForeground")) |
|
531 self.setCaretLineVisible(False) |
542 self.setCaretLineVisible(False) |
532 self.caretWidth = Preferences.getEditor("CaretWidth") |
543 self.caretWidth = Preferences.getEditor("CaretWidth") |
533 self.setCaretWidth(self.caretWidth) |
544 self.setCaretWidth(self.caretWidth) |
534 if Preferences.getShell("WrapEnabled"): |
545 if Preferences.getShell("WrapEnabled"): |
535 self.setWrapMode(QsciScintilla.WrapMode.WrapWord) |
546 self.setWrapMode(QsciScintilla.WrapMode.WrapWord) |
536 else: |
547 else: |
537 self.setWrapMode(QsciScintilla.WrapMode.WrapNone) |
548 self.setWrapMode(QsciScintilla.WrapMode.WrapNone) |
538 self.useMonospaced = Preferences.getShell("UseMonospacedFont") |
549 self.useMonospaced = Preferences.getShell("UseMonospacedFont") |
539 self.__setMonospaced(self.useMonospaced) |
550 self.__setMonospaced(self.useMonospaced) |
540 |
551 |
541 self.setCursorFlashTime(QApplication.cursorFlashTime()) |
552 self.setCursorFlashTime(QApplication.cursorFlashTime()) |
542 |
553 |
543 if Preferences.getEditor("OverrideEditAreaColours"): |
554 if Preferences.getEditor("OverrideEditAreaColours"): |
544 self.setColor(Preferences.getEditorColour("EditAreaForeground")) |
555 self.setColor(Preferences.getEditorColour("EditAreaForeground")) |
545 self.setPaper(Preferences.getEditorColour("EditAreaBackground")) |
556 self.setPaper(Preferences.getEditorColour("EditAreaBackground")) |
546 |
557 |
547 def __setMonospaced(self, on): |
558 def __setMonospaced(self, on): |
548 """ |
559 """ |
549 Private method to set/reset a monospaced font. |
560 Private method to set/reset a monospaced font. |
550 |
561 |
551 @param on flag to indicate usage of a monospace font (boolean) |
562 @param on flag to indicate usage of a monospace font (boolean) |
552 """ |
563 """ |
553 if on: |
564 if on: |
554 if not self.lexer_: |
565 if not self.lexer_: |
555 f = Preferences.getShell("MonospacedFont") |
566 f = Preferences.getShell("MonospacedFont") |
557 else: |
568 else: |
558 if not self.lexer_: |
569 if not self.lexer_: |
559 self.clearStyles() |
570 self.clearStyles() |
560 self.__setMargin0() |
571 self.__setMargin0() |
561 self.setFont(Preferences.getShell("MonospacedFont")) |
572 self.setFont(Preferences.getShell("MonospacedFont")) |
562 |
573 |
563 self.useMonospaced = on |
574 self.useMonospaced = on |
564 |
575 |
565 def __setAutoCompletion(self, language='Python'): |
576 def __setAutoCompletion(self, language="Python"): |
566 """ |
577 """ |
567 Private method to configure the autocompletion function. |
578 Private method to configure the autocompletion function. |
568 |
579 |
569 @param language of the autocompletion set to set (string) |
580 @param language of the autocompletion set to set (string) |
570 """ |
581 """ |
571 self.setAutoCompletionCaseSensitivity( |
582 self.setAutoCompletionCaseSensitivity( |
572 Preferences.getEditor("AutoCompletionCaseSensitivity")) |
583 Preferences.getEditor("AutoCompletionCaseSensitivity") |
|
584 ) |
573 self.setAutoCompletionThreshold(-1) |
585 self.setAutoCompletionThreshold(-1) |
574 |
586 |
575 self.racEnabled = Preferences.getShell("AutoCompletionEnabled") |
587 self.racEnabled = Preferences.getShell("AutoCompletionEnabled") |
576 |
588 |
577 self.setAutoCompletionWidgetSize( |
589 self.setAutoCompletionWidgetSize( |
578 Preferences.getEditor("AutoCompletionMaxChars"), |
590 Preferences.getEditor("AutoCompletionMaxChars"), |
579 Preferences.getEditor("AutoCompletionMaxLines") |
591 Preferences.getEditor("AutoCompletionMaxLines"), |
580 ) |
592 ) |
581 |
593 |
582 def __setCallTips(self, language='Python'): |
594 def __setCallTips(self, language="Python"): |
583 """ |
595 """ |
584 Private method to configure the calltips function. |
596 Private method to configure the calltips function. |
585 |
597 |
586 @param language of the calltips set to set (string) |
598 @param language of the calltips set to set (string) |
587 """ |
599 """ |
588 if Preferences.getShell("CallTipsEnabled"): |
600 if Preferences.getShell("CallTipsEnabled"): |
589 self.setCallTipsBackgroundColor( |
601 self.setCallTipsBackgroundColor( |
590 Preferences.getEditorColour("CallTipsBackground")) |
602 Preferences.getEditorColour("CallTipsBackground") |
|
603 ) |
591 self.setCallTipsForegroundColor( |
604 self.setCallTipsForegroundColor( |
592 Preferences.getEditorColour("CallTipsForeground")) |
605 Preferences.getEditorColour("CallTipsForeground") |
|
606 ) |
593 self.setCallTipsHighlightColor( |
607 self.setCallTipsHighlightColor( |
594 Preferences.getEditorColour("CallTipsHighlight")) |
608 Preferences.getEditorColour("CallTipsHighlight") |
|
609 ) |
595 self.setCallTipsVisible(Preferences.getEditor("CallTipsVisible")) |
610 self.setCallTipsVisible(Preferences.getEditor("CallTipsVisible")) |
596 calltipsStyle = Preferences.getEditor("CallTipsStyle") |
611 calltipsStyle = Preferences.getEditor("CallTipsStyle") |
597 if calltipsStyle == QsciScintilla.CallTipsStyle.CallTipsNoContext: |
612 if calltipsStyle == QsciScintilla.CallTipsStyle.CallTipsNoContext: |
598 self.setCallTipsStyle( |
613 self.setCallTipsStyle(QsciScintilla.CallTipsStyle.CallTipsNoContext) |
599 QsciScintilla.CallTipsStyle.CallTipsNoContext) |
|
600 elif ( |
614 elif ( |
601 calltipsStyle == |
615 calltipsStyle |
602 QsciScintilla.CallTipsStyle.CallTipsNoAutoCompletionContext |
616 == QsciScintilla.CallTipsStyle.CallTipsNoAutoCompletionContext |
603 ): |
617 ): |
604 self.setCallTipsStyle( |
618 self.setCallTipsStyle( |
605 QsciScintilla.CallTipsStyle |
619 QsciScintilla.CallTipsStyle.CallTipsNoAutoCompletionContext |
606 .CallTipsNoAutoCompletionContext) |
620 ) |
607 else: |
621 else: |
608 self.setCallTipsStyle( |
622 self.setCallTipsStyle(QsciScintilla.CallTipsStyle.CallTipsContext) |
609 QsciScintilla.CallTipsStyle.CallTipsContext) |
|
610 else: |
623 else: |
611 self.setCallTipsStyle(QsciScintilla.CallTipsStyle.CallTipsNone) |
624 self.setCallTipsStyle(QsciScintilla.CallTipsStyle.CallTipsNone) |
612 |
625 |
613 def setDebuggerUI(self, ui): |
626 def setDebuggerUI(self, ui): |
614 """ |
627 """ |
615 Public method to set the debugger UI. |
628 Public method to set the debugger UI. |
616 |
629 |
617 @param ui reference to the debugger UI object (DebugUI) |
630 @param ui reference to the debugger UI object (DebugUI) |
618 """ |
631 """ |
619 ui.exceptionInterrupt.connect(self.__writePrompt) |
632 ui.exceptionInterrupt.connect(self.__writePrompt) |
620 self.registerDebuggerIdMethod(ui.getSelectedDebuggerId) |
633 self.registerDebuggerIdMethod(ui.getSelectedDebuggerId) |
621 |
634 |
622 def registerDebuggerIdMethod(self, method): |
635 def registerDebuggerIdMethod(self, method): |
623 """ |
636 """ |
624 Public method to register a method to get the debugger ID to send data |
637 Public method to register a method to get the debugger ID to send data |
625 to. |
638 to. |
626 |
639 |
627 @param method reference to the method |
640 @param method reference to the method |
628 @type function |
641 @type function |
629 """ |
642 """ |
630 self.__getSelectedDebuggerId = method |
643 self.__getSelectedDebuggerId = method |
631 |
644 |
632 def __initialise(self): |
645 def __initialise(self): |
633 """ |
646 """ |
634 Private method to get ready for a new remote interpreter. |
647 Private method to get ready for a new remote interpreter. |
635 """ |
648 """ |
636 self.buff = "" |
649 self.buff = "" |
662 self.__setTextDisplay() |
675 self.__setTextDisplay() |
663 self.__setMargin0() |
676 self.__setMargin0() |
664 self.__setAutoCompletion(self.clientType) |
677 self.__setAutoCompletion(self.clientType) |
665 self.__setCallTips(self.clientType) |
678 self.__setCallTips(self.clientType) |
666 self.racEnabled = ( |
679 self.racEnabled = ( |
667 Preferences.getShell("AutoCompletionEnabled") and |
680 Preferences.getShell("AutoCompletionEnabled") |
668 (cap & HasCompleter) > 0 |
681 and (cap & HasCompleter) > 0 |
669 ) |
682 ) |
670 |
683 |
671 if self.clientType not in self.__historyLists: |
684 if self.clientType not in self.__historyLists: |
672 # load history list |
685 # load history list |
673 self.loadHistory(self.clientType) |
686 self.loadHistory(self.clientType) |
674 self.__history = self.__historyLists[self.clientType] |
687 self.__history = self.__historyLists[self.clientType] |
675 self.__setHistoryIndex() |
688 self.__setHistoryIndex() |
676 |
689 |
677 self.virtualEnvironmentChanged.emit(venvName) |
690 self.virtualEnvironmentChanged.emit(venvName) |
678 Preferences.setShell("LastVirtualEnvironment", venvName) |
691 Preferences.setShell("LastVirtualEnvironment", venvName) |
679 |
692 |
680 def __setHistoryIndex(self, index=None): |
693 def __setHistoryIndex(self, index=None): |
681 """ |
694 """ |
682 Private method to set the initial history index. |
695 Private method to set the initial history index. |
683 |
696 |
684 @param index index value to be set |
697 @param index index value to be set |
685 @type int or None |
698 @type int or None |
686 """ |
699 """ |
687 if index is None: |
700 if index is None: |
688 # determine based on history style |
701 # determine based on history style |
689 if ( |
702 if ( |
690 self.clientType and |
703 self.clientType |
691 self.__historyStyle == ShellHistoryStyle.WINDOWSSTYLE |
704 and self.__historyStyle == ShellHistoryStyle.WINDOWSSTYLE |
692 ): |
705 ): |
693 idx = int(Preferences.getSettings().value( |
706 idx = int( |
694 "Shell/HistoryIndexes/" + self.clientType, -1)) |
707 Preferences.getSettings().value( |
|
708 "Shell/HistoryIndexes/" + self.clientType, -1 |
|
709 ) |
|
710 ) |
695 if idx >= len(self.__history): |
711 if idx >= len(self.__history): |
696 idx = -1 |
712 idx = -1 |
697 self.__histidx = idx |
713 self.__histidx = idx |
698 else: |
714 else: |
699 self.__histidx = -1 |
715 self.__histidx = -1 |
700 else: |
716 else: |
701 self.__histidx = index |
717 self.__histidx = index |
702 if self.__histidx >= len(self.__history): |
718 if self.__histidx >= len(self.__history): |
703 self.__histidx = -1 |
719 self.__histidx = -1 |
704 if ( |
720 if ( |
705 self.clientType and |
721 self.clientType |
706 self.__historyStyle == ShellHistoryStyle.WINDOWSSTYLE |
722 and self.__historyStyle == ShellHistoryStyle.WINDOWSSTYLE |
707 ): |
723 ): |
708 Preferences.getSettings().setValue( |
724 Preferences.getSettings().setValue( |
709 "Shell/HistoryIndexes/" + self.clientType, self.__histidx) |
725 "Shell/HistoryIndexes/" + self.clientType, self.__histidx |
710 |
726 ) |
|
727 |
711 def __isHistoryIndexValid(self): |
728 def __isHistoryIndexValid(self): |
712 """ |
729 """ |
713 Private method to test, if the history index is valid. |
730 Private method to test, if the history index is valid. |
714 |
731 |
715 @return flag indicating validity |
732 @return flag indicating validity |
716 @rtype bool |
733 @rtype bool |
717 """ |
734 """ |
718 return (0 <= self.__histidx < len(self.__history)) |
735 return 0 <= self.__histidx < len(self.__history) |
719 |
736 |
720 def getHistoryIndex(self): |
737 def getHistoryIndex(self): |
721 """ |
738 """ |
722 Public method to get the current value of the history index. |
739 Public method to get the current value of the history index. |
723 |
740 |
724 @return history index |
741 @return history index |
725 @rtype int |
742 @rtype int |
726 """ |
743 """ |
727 return self.__histidx |
744 return self.__histidx |
728 |
745 |
729 def loadHistory(self, clientType): |
746 def loadHistory(self, clientType): |
730 """ |
747 """ |
731 Public method to load the history for the given client type. |
748 Public method to load the history for the given client type. |
732 |
749 |
733 @param clientType type of the debug client (string) |
750 @param clientType type of the debug client (string) |
734 """ |
751 """ |
735 hl = Preferences.getSettings().value("Shell/Histories/" + clientType) |
752 hl = Preferences.getSettings().value("Shell/Histories/" + clientType) |
736 if hl is not None: |
753 if hl is not None: |
737 self.__historyLists[clientType] = hl[-self.__maxHistoryEntries:] |
754 self.__historyLists[clientType] = hl[-self.__maxHistoryEntries :] |
738 else: |
755 else: |
739 self.__historyLists[clientType] = [] |
756 self.__historyLists[clientType] = [] |
740 |
757 |
741 def reloadHistory(self): |
758 def reloadHistory(self): |
742 """ |
759 """ |
743 Public method to reload the history of the currently selected client |
760 Public method to reload the history of the currently selected client |
744 type. |
761 type. |
745 """ |
762 """ |
746 self.loadHistory(self.clientType) |
763 self.loadHistory(self.clientType) |
747 self.__history = self.__historyLists[self.clientType] |
764 self.__history = self.__historyLists[self.clientType] |
748 self.__setHistoryIndex() |
765 self.__setHistoryIndex() |
749 |
766 |
750 def saveHistory(self, clientType): |
767 def saveHistory(self, clientType): |
751 """ |
768 """ |
752 Public method to save the history for the given client type. |
769 Public method to save the history for the given client type. |
753 |
770 |
754 @param clientType type of the debug client (string) |
771 @param clientType type of the debug client (string) |
755 """ |
772 """ |
756 if clientType in self.__historyLists: |
773 if clientType in self.__historyLists: |
757 Preferences.getSettings().setValue( |
774 Preferences.getSettings().setValue( |
758 "Shell/Histories/" + clientType, |
775 "Shell/Histories/" + clientType, self.__historyLists[clientType] |
759 self.__historyLists[clientType]) |
776 ) |
760 |
777 |
761 def getHistory(self, clientType): |
778 def getHistory(self, clientType): |
762 """ |
779 """ |
763 Public method to get the history for the given client type. |
780 Public method to get the history for the given client type. |
764 |
781 |
765 @param clientType type of the debug client (string). |
782 @param clientType type of the debug client (string). |
766 If it is None, the current history is returned. |
783 If it is None, the current history is returned. |
767 @return reference to the history list (list of strings) |
784 @return reference to the history list (list of strings) |
768 """ |
785 """ |
769 if clientType is None: |
786 if clientType is None: |
770 return self.__history |
787 return self.__history |
771 elif clientType in self.__historyLists: |
788 elif clientType in self.__historyLists: |
772 return self.__historyLists[clientType] |
789 return self.__historyLists[clientType] |
773 else: |
790 else: |
774 return [] |
791 return [] |
775 |
792 |
776 def clearHistory(self): |
793 def clearHistory(self): |
777 """ |
794 """ |
778 Public slot to clear the current history. |
795 Public slot to clear the current history. |
779 """ |
796 """ |
780 if self.clientType: |
797 if self.clientType: |
781 self.__historyLists[self.clientType] = [] |
798 self.__historyLists[self.clientType] = [] |
782 self.__history = self.__historyLists[self.clientType] |
799 self.__history = self.__historyLists[self.clientType] |
783 else: |
800 else: |
784 self.__history = [] |
801 self.__history = [] |
785 self.__setHistoryIndex(index=-1) |
802 self.__setHistoryIndex(index=-1) |
786 |
803 |
787 def selectHistory(self): |
804 def selectHistory(self): |
788 """ |
805 """ |
789 Public slot to select a history entry to execute. |
806 Public slot to select a history entry to execute. |
790 """ |
807 """ |
791 current = self.__histidx |
808 current = self.__histidx |
792 if current == -1: |
809 if current == -1: |
793 current = len(self.__history) - 1 |
810 current = len(self.__history) - 1 |
794 cmd, ok = QInputDialog.getItem( |
811 cmd, ok = QInputDialog.getItem( |
795 self, |
812 self, |
796 self.tr("Select History"), |
813 self.tr("Select History"), |
797 self.tr("Select the history entry to execute" |
814 self.tr("Select the history entry to execute" " (most recent shown last)."), |
798 " (most recent shown last)."), |
|
799 self.__history, |
815 self.__history, |
800 current, False) |
816 current, |
|
817 False, |
|
818 ) |
801 if ok: |
819 if ok: |
802 self.__insertHistory(cmd) |
820 self.__insertHistory(cmd) |
803 |
821 |
804 def showHistory(self): |
822 def showHistory(self): |
805 """ |
823 """ |
806 Public slot to show the shell history dialog. |
824 Public slot to show the shell history dialog. |
807 """ |
825 """ |
808 from .ShellHistoryDialog import ShellHistoryDialog |
826 from .ShellHistoryDialog import ShellHistoryDialog |
|
827 |
809 dlg = ShellHistoryDialog(self.__history, self.vm, self) |
828 dlg = ShellHistoryDialog(self.__history, self.vm, self) |
810 if dlg.exec() == QDialog.DialogCode.Accepted: |
829 if dlg.exec() == QDialog.DialogCode.Accepted: |
811 self.__historyLists[self.clientType], idx = dlg.getHistory() |
830 self.__historyLists[self.clientType], idx = dlg.getHistory() |
812 self.__history = self.__historyLists[self.clientType] |
831 self.__history = self.__historyLists[self.clientType] |
813 self.__setHistoryIndex(index=idx) |
832 self.__setHistoryIndex(index=idx) |
814 |
833 |
815 def clearAllHistories(self): |
834 def clearAllHistories(self): |
816 """ |
835 """ |
817 Public method to clear all available histories and sync them. |
836 Public method to clear all available histories and sync them. |
818 """ |
837 """ |
819 Preferences.getSettings().beginGroup("Shell/Histories") |
838 Preferences.getSettings().beginGroup("Shell/Histories") |
820 for clientType in Preferences.getSettings().childKeys(): |
839 for clientType in Preferences.getSettings().childKeys(): |
821 self.__historyLists[clientType] = [] |
840 self.__historyLists[clientType] = [] |
822 self.saveHistory(clientType) |
841 self.saveHistory(clientType) |
823 Preferences.getSettings().endGroup() |
842 Preferences.getSettings().endGroup() |
824 |
843 |
825 self.clearHistory() |
844 self.clearHistory() |
826 |
845 |
827 def getClientType(self): |
846 def getClientType(self): |
828 """ |
847 """ |
829 Public slot to get the clients type. |
848 Public slot to get the clients type. |
830 |
849 |
831 @return client type (string) |
850 @return client type (string) |
832 """ |
851 """ |
833 return self.clientType |
852 return self.clientType |
834 |
853 |
835 def __getBanner(self): |
854 def __getBanner(self): |
836 """ |
855 """ |
837 Private method to get the banner for the remote interpreter. |
856 Private method to get the banner for the remote interpreter. |
838 |
857 |
839 It requests the interpreter version and platform running on the |
858 It requests the interpreter version and platform running on the |
840 debug client side. |
859 debug client side. |
841 """ |
860 """ |
842 if self.passive: |
861 if self.passive: |
843 self.__writeBanner('', '', '', '') |
862 self.__writeBanner("", "", "", "") |
844 else: |
863 else: |
845 self.dbs.remoteBanner() |
864 self.dbs.remoteBanner() |
846 |
865 |
847 def __writeBanner(self, version, platform, venvName): |
866 def __writeBanner(self, version, platform, venvName): |
848 """ |
867 """ |
849 Private method to write a banner with info from the debug client. |
868 Private method to write a banner with info from the debug client. |
850 |
869 |
851 @param version interpreter version string |
870 @param version interpreter version string |
852 @type str |
871 @type str |
853 @param platform platform of the remote interpreter |
872 @param platform platform of the remote interpreter |
854 @type str |
873 @type str |
855 @param venvName name of the virtual environment |
874 @param venvName name of the virtual environment |
856 @type str |
875 @type str |
857 """ |
876 """ |
858 super().clear() |
877 super().clear() |
859 if self.passive and not self.dbs.isConnected(): |
878 if self.passive and not self.dbs.isConnected(): |
860 self.__write(self.tr('Passive Debug Mode')) |
879 self.__write(self.tr("Passive Debug Mode")) |
861 self.__write(self.tr('\nNot connected')) |
880 self.__write(self.tr("\nNot connected")) |
862 else: |
881 else: |
863 self.__currentVenv = venvName |
882 self.__currentVenv = venvName |
864 version = version.replace("#", self.tr("No.")) |
883 version = version.replace("#", self.tr("No.")) |
865 if platform != "": |
884 if platform != "": |
866 self.__write(self.tr('{0} on {1}').format(version, platform)) |
885 self.__write(self.tr("{0} on {1}").format(version, platform)) |
867 else: |
886 else: |
868 self.__write(version) |
887 self.__write(version) |
869 if venvName: |
888 if venvName: |
870 self.__write("\n[{0}]".format(venvName)) |
889 self.__write("\n[{0}]".format(venvName)) |
871 |
890 |
872 self.virtualEnvironmentChanged.emit(venvName) |
891 self.virtualEnvironmentChanged.emit(venvName) |
873 Preferences.setShell("LastVirtualEnvironment", venvName) |
892 Preferences.setShell("LastVirtualEnvironment", venvName) |
874 self.__write('\n') |
893 self.__write("\n") |
875 |
894 |
876 self.__write(sys.ps1) |
895 self.__write(sys.ps1) |
877 |
896 |
878 def __writePrompt(self): |
897 def __writePrompt(self): |
879 """ |
898 """ |
880 Private method to write the prompt using a write queue. |
899 Private method to write the prompt using a write queue. |
881 """ |
900 """ |
882 self.queueText.emit(self.inContinue and sys.ps2 or sys.ps1) |
901 self.queueText.emit(self.inContinue and sys.ps2 or sys.ps1) |
883 |
902 |
884 def __clientStatement(self, more): |
903 def __clientStatement(self, more): |
885 """ |
904 """ |
886 Private method to handle the response from the debugger client. |
905 Private method to handle the response from the debugger client. |
887 |
906 |
888 @param more flag indicating that more user input is required |
907 @param more flag indicating that more user input is required |
889 @type bool |
908 @type bool |
890 """ |
909 """ |
891 if not self.__inRawMode: |
910 if not self.__inRawMode: |
892 self.inContinue = more |
911 self.inContinue = more |
893 self.__writePrompt() |
912 self.__writePrompt() |
894 self.inCommandExecution = False |
913 self.inCommandExecution = False |
895 |
914 |
896 def __clientException(self, exceptionType, exceptionMessage, stackTrace): |
915 def __clientException(self, exceptionType, exceptionMessage, stackTrace): |
897 """ |
916 """ |
898 Private method to handle an exception of the client. |
917 Private method to handle an exception of the client. |
899 |
918 |
900 @param exceptionType type of exception raised (string) |
919 @param exceptionType type of exception raised (string) |
901 @param exceptionMessage message given by the exception (string) |
920 @param exceptionMessage message given by the exception (string) |
902 @param stackTrace list of stack entries (list of string) |
921 @param stackTrace list of stack entries (list of string) |
903 """ |
922 """ |
904 self .__clientError() |
923 self.__clientError() |
905 |
924 |
906 if ( |
925 if ( |
907 not self.__windowed and |
926 not self.__windowed |
908 Preferences.getDebugger("ShowExceptionInShell") and |
927 and Preferences.getDebugger("ShowExceptionInShell") |
909 exceptionType |
928 and exceptionType |
910 ): |
929 ): |
911 if stackTrace: |
930 if stackTrace: |
912 self.__write( |
931 self.__write( |
913 self.tr('Exception "{0}"\n{1}\nFile: {2}, Line: {3}\n') |
932 self.tr('Exception "{0}"\n{1}\nFile: {2}, Line: {3}\n').format( |
914 .format( |
|
915 exceptionType, |
933 exceptionType, |
916 exceptionMessage, |
934 exceptionMessage, |
917 stackTrace[0][0], |
935 stackTrace[0][0], |
918 stackTrace[0][1] |
936 stackTrace[0][1], |
919 ) |
937 ) |
920 ) |
938 ) |
921 else: |
939 else: |
922 self.__write( |
940 self.__write( |
923 self.tr('Exception "{0}"\n{1}\n') |
941 self.tr('Exception "{0}"\n{1}\n').format( |
924 .format( |
942 exceptionType, exceptionMessage |
925 exceptionType, |
943 ) |
926 exceptionMessage) |
|
927 ) |
944 ) |
928 |
945 |
929 def __clientSyntaxError(self, message, filename, lineNo, characterNo): |
946 def __clientSyntaxError(self, message, filename, lineNo, characterNo): |
930 """ |
947 """ |
931 Private method to handle a syntax error in the debugged program. |
948 Private method to handle a syntax error in the debugged program. |
932 |
949 |
933 @param message message of the syntax error (string) |
950 @param message message of the syntax error (string) |
934 @param filename translated filename of the syntax error position |
951 @param filename translated filename of the syntax error position |
935 (string) |
952 (string) |
936 @param lineNo line number of the syntax error position (integer) |
953 @param lineNo line number of the syntax error position (integer) |
937 @param characterNo character number of the syntax error position |
954 @param characterNo character number of the syntax error position |
938 (integer) |
955 (integer) |
939 """ |
956 """ |
940 self .__clientError() |
957 self.__clientError() |
941 |
958 |
942 if ( |
959 if not self.__windowed and Preferences.getDebugger("ShowExceptionInShell"): |
943 not self.__windowed and |
|
944 Preferences.getDebugger("ShowExceptionInShell") |
|
945 ): |
|
946 if message is None: |
960 if message is None: |
947 self.__write(self.tr("Unspecified syntax error.\n")) |
961 self.__write(self.tr("Unspecified syntax error.\n")) |
948 else: |
962 else: |
949 self.__write( |
963 self.__write( |
950 self.tr('Syntax error "{1}" in file {0} at line {2},' |
964 self.tr( |
951 ' character {3}.\n') |
965 'Syntax error "{1}" in file {0} at line {2},' |
952 .format(filename, message, lineNo, characterNo) |
966 " character {3}.\n" |
|
967 ).format(filename, message, lineNo, characterNo) |
953 ) |
968 ) |
954 |
969 |
955 def __clientSignal(self, message, filename, lineNo, funcName, funcArgs): |
970 def __clientSignal(self, message, filename, lineNo, funcName, funcArgs): |
956 """ |
971 """ |
957 Private method to handle a signal generated on the client side. |
972 Private method to handle a signal generated on the client side. |
958 |
973 |
959 @param message message of the syntax error |
974 @param message message of the syntax error |
960 @type str |
975 @type str |
961 @param filename translated filename of the syntax error position |
976 @param filename translated filename of the syntax error position |
962 @type str |
977 @type str |
963 @param lineNo line number of the syntax error position |
978 @param lineNo line number of the syntax error position |
966 @type str |
981 @type str |
967 @param funcArgs function arguments |
982 @param funcArgs function arguments |
968 @type str |
983 @type str |
969 """ |
984 """ |
970 self.__clientError() |
985 self.__clientError() |
971 |
986 |
972 self.__write( |
987 self.__write( |
973 self.tr("""Signal "{0}" generated in file {1} at line {2}.\n""" |
988 self.tr( |
974 """Function: {3}({4})""") |
989 """Signal "{0}" generated in file {1} at line {2}.\n""" |
975 .format(message, filename, lineNo, funcName, funcArgs) |
990 """Function: {3}({4})""" |
|
991 ).format(message, filename, lineNo, funcName, funcArgs) |
976 ) |
992 ) |
977 |
993 |
978 def __clientError(self): |
994 def __clientError(self): |
979 """ |
995 """ |
980 Private method to handle an error in the client. |
996 Private method to handle an error in the client. |
981 """ |
997 """ |
982 self.inCommandExecution = False |
998 self.inCommandExecution = False |
983 self.interruptCommandExecution = True |
999 self.interruptCommandExecution = True |
984 self.inContinue = False |
1000 self.inContinue = False |
985 |
1001 |
986 def __getEndPos(self): |
1002 def __getEndPos(self): |
987 """ |
1003 """ |
988 Private method to return the line and column of the last character. |
1004 Private method to return the line and column of the last character. |
989 |
1005 |
990 @return tuple of two values (int, int) giving the line and column |
1006 @return tuple of two values (int, int) giving the line and column |
991 """ |
1007 """ |
992 line = self.lines() - 1 |
1008 line = self.lines() - 1 |
993 return (line, len(self.text(line))) |
1009 return (line, len(self.text(line))) |
994 |
1010 |
995 def __writeQueued(self, s): |
1011 def __writeQueued(self, s): |
996 """ |
1012 """ |
997 Private method to display some text using a write queue. |
1013 Private method to display some text using a write queue. |
998 |
1014 |
999 @param s text to be displayed (string) |
1015 @param s text to be displayed (string) |
1000 """ |
1016 """ |
1001 self.queueText.emit(s) |
1017 self.queueText.emit(s) |
1002 |
1018 |
1003 def __concatenateText(self, text): |
1019 def __concatenateText(self, text): |
1004 """ |
1020 """ |
1005 Private slot to queue text and process it in one step. |
1021 Private slot to queue text and process it in one step. |
1006 |
1022 |
1007 @param text text to be appended |
1023 @param text text to be appended |
1008 @type str |
1024 @type str |
1009 """ |
1025 """ |
1010 self.__queuedText += text |
1026 self.__queuedText += text |
1011 if self.__blockTextProcessing: |
1027 if self.__blockTextProcessing: |
1012 return |
1028 return |
1013 |
1029 |
1014 self.__blockTextProcessing = True |
1030 self.__blockTextProcessing = True |
1015 # Get all text which is still waiting for output |
1031 # Get all text which is still waiting for output |
1016 QApplication.processEvents() |
1032 QApplication.processEvents() |
1017 |
1033 |
1018 # Finally process the accumulated text |
1034 # Finally process the accumulated text |
1019 self.__flushQueuedText() |
1035 self.__flushQueuedText() |
1020 |
1036 |
1021 def __flushQueuedText(self): |
1037 def __flushQueuedText(self): |
1022 """ |
1038 """ |
1023 Private slot to flush the accumulated text output. |
1039 Private slot to flush the accumulated text output. |
1024 """ |
1040 """ |
1025 self.__write(self.__queuedText) |
1041 self.__write(self.__queuedText) |
1026 |
1042 |
1027 self.__queuedText = '' |
1043 self.__queuedText = "" |
1028 self.__blockTextProcessing = False |
1044 self.__blockTextProcessing = False |
1029 |
1045 |
1030 # little trick to get the cursor position registered within QScintilla |
1046 # little trick to get the cursor position registered within QScintilla |
1031 self.SendScintilla(QsciScintilla.SCI_CHARLEFT) |
1047 self.SendScintilla(QsciScintilla.SCI_CHARLEFT) |
1032 self.SendScintilla(QsciScintilla.SCI_CHARRIGHT) |
1048 self.SendScintilla(QsciScintilla.SCI_CHARRIGHT) |
1033 |
1049 |
1034 def __write(self, s): |
1050 def __write(self, s): |
1035 """ |
1051 """ |
1036 Private method to display some text without queuing. |
1052 Private method to display some text without queuing. |
1037 |
1053 |
1038 @param s text to be displayed |
1054 @param s text to be displayed |
1039 @type str |
1055 @type str |
1040 """ |
1056 """ |
1041 line, col = self.__getEndPos() |
1057 line, col = self.__getEndPos() |
1042 self.setCursorPosition(line, col) |
1058 self.setCursorPosition(line, col) |
1043 self.insert(Utilities.filterAnsiSequences(s)) |
1059 self.insert(Utilities.filterAnsiSequences(s)) |
1044 self.prline, self.prcol = self.getCursorPosition() |
1060 self.prline, self.prcol = self.getCursorPosition() |
1045 self.ensureCursorVisible() |
1061 self.ensureCursorVisible() |
1046 self.ensureLineVisible(self.prline) |
1062 self.ensureLineVisible(self.prline) |
1047 |
1063 |
1048 def __writeStdOut(self, s): |
1064 def __writeStdOut(self, s): |
1049 """ |
1065 """ |
1050 Private method to display some text with StdOut label. |
1066 Private method to display some text with StdOut label. |
1051 |
1067 |
1052 @param s text to be displayed (string) |
1068 @param s text to be displayed (string) |
1053 """ |
1069 """ |
1054 self.__write(self.tr("StdOut: {0}").format(s)) |
1070 self.__write(self.tr("StdOut: {0}").format(s)) |
1055 |
1071 |
1056 def __writeStdErr(self, s): |
1072 def __writeStdErr(self, s): |
1057 """ |
1073 """ |
1058 Private method to display some text with StdErr label. |
1074 Private method to display some text with StdErr label. |
1059 |
1075 |
1060 @param s text to be displayed (string) |
1076 @param s text to be displayed (string) |
1061 """ |
1077 """ |
1062 self.__write(self.tr("StdErr: {0}").format(s)) |
1078 self.__write(self.tr("StdErr: {0}").format(s)) |
1063 |
1079 |
1064 def __raw_input(self, prompt, echo, debuggerId): |
1080 def __raw_input(self, prompt, echo, debuggerId): |
1065 """ |
1081 """ |
1066 Private method to handle raw input. |
1082 Private method to handle raw input. |
1067 |
1083 |
1068 @param prompt the input prompt |
1084 @param prompt the input prompt |
1069 @type str |
1085 @type str |
1070 @param echo flag indicating an echoing of the input |
1086 @param echo flag indicating an echoing of the input |
1071 @type bool |
1087 @type bool |
1072 @param debuggerId ID of the debugger backend |
1088 @param debuggerId ID of the debugger backend |
1212 col = len(sys.ps2) |
1228 col = len(sys.ps2) |
1213 else: |
1229 else: |
1214 col = 0 |
1230 col = 0 |
1215 self.setCursorPosition(line, col) |
1231 self.setCursorPosition(line, col) |
1216 self.deleteLineRight() |
1232 self.deleteLineRight() |
1217 |
1233 |
1218 def __insertText(self, s): |
1234 def __insertText(self, s): |
1219 """ |
1235 """ |
1220 Private method to insert some text at the current cursor position. |
1236 Private method to insert some text at the current cursor position. |
1221 |
1237 |
1222 @param s text to be inserted (string) |
1238 @param s text to be inserted (string) |
1223 """ |
1239 """ |
1224 line, col = self.getCursorPosition() |
1240 line, col = self.getCursorPosition() |
1225 self.insertAt(Utilities.filterAnsiSequences(s), line, col) |
1241 self.insertAt(Utilities.filterAnsiSequences(s), line, col) |
1226 self.setCursorPosition(line, col + len(s)) |
1242 self.setCursorPosition(line, col + len(s)) |
1227 |
1243 |
1228 def __insertTextAtEnd(self, s): |
1244 def __insertTextAtEnd(self, s): |
1229 """ |
1245 """ |
1230 Private method to insert some text at the end of the command line. |
1246 Private method to insert some text at the end of the command line. |
1231 |
1247 |
1232 @param s text to be inserted (string) |
1248 @param s text to be inserted (string) |
1233 """ |
1249 """ |
1234 line, col = self.__getEndPos() |
1250 line, col = self.__getEndPos() |
1235 self.setCursorPosition(line, col) |
1251 self.setCursorPosition(line, col) |
1236 self.insert(Utilities.filterAnsiSequences(s)) |
1252 self.insert(Utilities.filterAnsiSequences(s)) |
1237 self.prline, _ = self.getCursorPosition() |
1253 self.prline, _ = self.getCursorPosition() |
1238 |
1254 |
1239 def __insertTextNoEcho(self, s): |
1255 def __insertTextNoEcho(self, s): |
1240 """ |
1256 """ |
1241 Private method to insert some text at the end of the buffer without |
1257 Private method to insert some text at the end of the buffer without |
1242 echoing it. |
1258 echoing it. |
1243 |
1259 |
1244 @param s text to be inserted (string) |
1260 @param s text to be inserted (string) |
1245 """ |
1261 """ |
1246 self.buff += s |
1262 self.buff += s |
1247 self.prline, self.prcol = self.getCursorPosition() |
1263 self.prline, self.prcol = self.getCursorPosition() |
1248 |
1264 |
1249 def mousePressEvent(self, event): |
1265 def mousePressEvent(self, event): |
1250 """ |
1266 """ |
1251 Protected method to handle the mouse press event. |
1267 Protected method to handle the mouse press event. |
1252 |
1268 |
1253 @param event the mouse press event (QMouseEvent) |
1269 @param event the mouse press event (QMouseEvent) |
1254 """ |
1270 """ |
1255 self.setFocus() |
1271 self.setFocus() |
1256 if event.button() == Qt.MouseButton.MiddleButton: |
1272 if event.button() == Qt.MouseButton.MiddleButton: |
1257 lines = QApplication.clipboard().text(QClipboard.Mode.Selection) |
1273 lines = QApplication.clipboard().text(QClipboard.Mode.Selection) |
1258 self.paste(lines) |
1274 self.paste(lines) |
1259 else: |
1275 else: |
1260 super().mousePressEvent(event) |
1276 super().mousePressEvent(event) |
1261 |
1277 |
1262 def wheelEvent(self, evt): |
1278 def wheelEvent(self, evt): |
1263 """ |
1279 """ |
1264 Protected method to handle wheel events. |
1280 Protected method to handle wheel events. |
1265 |
1281 |
1266 @param evt reference to the wheel event (QWheelEvent) |
1282 @param evt reference to the wheel event (QWheelEvent) |
1267 """ |
1283 """ |
1268 if evt.modifiers() & Qt.KeyboardModifier.ControlModifier: |
1284 if evt.modifiers() & Qt.KeyboardModifier.ControlModifier: |
1269 delta = evt.angleDelta().y() |
1285 delta = evt.angleDelta().y() |
1270 if delta < 0: |
1286 if delta < 0: |
1271 self.zoomOut() |
1287 self.zoomOut() |
1272 elif delta > 0: |
1288 elif delta > 0: |
1273 self.zoomIn() |
1289 self.zoomIn() |
1274 evt.accept() |
1290 evt.accept() |
1275 return |
1291 return |
1276 |
1292 |
1277 super().wheelEvent(evt) |
1293 super().wheelEvent(evt) |
1278 |
1294 |
1279 def event(self, evt): |
1295 def event(self, evt): |
1280 """ |
1296 """ |
1281 Public method handling events. |
1297 Public method handling events. |
1282 |
1298 |
1283 @param evt reference to the event (QEvent) |
1299 @param evt reference to the event (QEvent) |
1284 @return flag indicating, if the event was handled (boolean) |
1300 @return flag indicating, if the event was handled (boolean) |
1285 """ |
1301 """ |
1286 if evt.type() == QEvent.Type.Gesture: |
1302 if evt.type() == QEvent.Type.Gesture: |
1287 self.gestureEvent(evt) |
1303 self.gestureEvent(evt) |
1288 return True |
1304 return True |
1289 |
1305 |
1290 return super().event(evt) |
1306 return super().event(evt) |
1291 |
1307 |
1292 def gestureEvent(self, evt): |
1308 def gestureEvent(self, evt): |
1293 """ |
1309 """ |
1294 Protected method handling gesture events. |
1310 Protected method handling gesture events. |
1295 |
1311 |
1296 @param evt reference to the gesture event (QGestureEvent |
1312 @param evt reference to the gesture event (QGestureEvent |
1297 """ |
1313 """ |
1298 pinch = evt.gesture(Qt.GestureType.PinchGesture) |
1314 pinch = evt.gesture(Qt.GestureType.PinchGesture) |
1299 if pinch: |
1315 if pinch: |
1300 if pinch.state() == Qt.GestureState.GestureStarted: |
1316 if pinch.state() == Qt.GestureState.GestureStarted: |
1836 if venvName == self.tr("Project"): |
1848 if venvName == self.tr("Project"): |
1837 if self.__project.isOpen(): |
1849 if self.__project.isOpen(): |
1838 self.dbs.startClient( |
1850 self.dbs.startClient( |
1839 False, |
1851 False, |
1840 forProject=True, |
1852 forProject=True, |
1841 workingDir=self.__project |
1853 workingDir=self.__project.getProjectPath(), |
1842 .getProjectPath() |
|
1843 ) |
1854 ) |
1844 self.__currentWorkingDirectory = ( |
1855 self.__currentWorkingDirectory = ( |
1845 self.__project.getProjectPath() |
1856 self.__project.getProjectPath() |
1846 ) |
1857 ) |
1847 else: |
1858 else: |
1848 self.dbs.startClient( |
1859 self.dbs.startClient( |
1849 False, |
1860 False, |
1850 venvName=self.__currentVenv, |
1861 venvName=self.__currentVenv, |
1851 workingDir=self |
1862 workingDir=self.__currentWorkingDirectory, |
1852 .__currentWorkingDirectory |
|
1853 ) |
1863 ) |
1854 # same as reset |
1864 # same as reset |
1855 else: |
1865 else: |
1856 self.dbs.startClient(False, venvName=venvName) |
1866 self.dbs.startClient(False, venvName=venvName) |
1857 self.__currentWorkingDirectory = "" |
1867 self.__currentWorkingDirectory = "" |
1858 self.__getBanner() |
1868 self.__getBanner() |
1859 return |
1869 return |
1860 elif cmd == '%clear': |
1870 elif cmd == "%clear": |
1861 # Display the banner. |
1871 # Display the banner. |
1862 self.__getBanner() |
1872 self.__getBanner() |
1863 if not self.passive: |
1873 if not self.passive: |
1864 return |
1874 return |
1865 else: |
1875 else: |
1866 cmd = '' |
1876 cmd = "" |
1867 elif cmd in ['%reset', '%restart']: |
1877 elif cmd in ["%reset", "%restart"]: |
1868 self.dbs.startClient( |
1878 self.dbs.startClient( |
1869 False, venvName=self.__currentVenv, |
1879 False, |
1870 workingDir=self.__currentWorkingDirectory) |
1880 venvName=self.__currentVenv, |
|
1881 workingDir=self.__currentWorkingDirectory, |
|
1882 ) |
1871 if self.passive: |
1883 if self.passive: |
1872 return |
1884 return |
1873 else: |
1885 else: |
1874 cmd = '' |
1886 cmd = "" |
1875 elif cmd in ['%envs', '%environments']: |
1887 elif cmd in ["%envs", "%environments"]: |
1876 venvs = ( |
1888 venvs = ( |
1877 ericApp().getObject("VirtualEnvManager") |
1889 ericApp().getObject("VirtualEnvManager").getVirtualenvNames() |
1878 .getVirtualenvNames() |
|
1879 ) |
1890 ) |
1880 s = ( |
1891 s = self.tr("Available Virtual Environments:\n{0}\n").format( |
1881 self.tr('Available Virtual Environments:\n{0}\n') |
1892 "\n".join("- {0}".format(venv) for venv in sorted(venvs)) |
1882 .format('\n'.join( |
|
1883 "- {0}".format(venv) |
|
1884 for venv in sorted(venvs) |
|
1885 )) |
|
1886 ) |
1893 ) |
1887 self.__write(s) |
1894 self.__write(s) |
1888 self.__clientStatement(False) |
1895 self.__clientStatement(False) |
1889 return |
1896 return |
1890 elif cmd == '%which': |
1897 elif cmd == "%which": |
1891 s = self.tr("Current Virtual Environment: '{0}'\n").format( |
1898 s = self.tr("Current Virtual Environment: '{0}'\n").format( |
1892 self.__currentVenv) |
1899 self.__currentVenv |
|
1900 ) |
1893 self.__write(s) |
1901 self.__write(s) |
1894 self.__clientStatement(False) |
1902 self.__clientStatement(False) |
1895 return |
1903 return |
1896 elif ( |
1904 elif ( |
1897 cmd in ["%quit", "%quit()", "%exit", "%exit()"] and |
1905 cmd in ["%quit", "%quit()", "%exit", "%exit()"] and self.__windowed |
1898 self.__windowed |
|
1899 ): |
1906 ): |
1900 # call main window quit() |
1907 # call main window quit() |
1901 self.vm.quit() |
1908 self.vm.quit() |
1902 return |
1909 return |
1903 else: |
1910 else: |
1904 self.dbs.remoteStatement( |
1911 self.dbs.remoteStatement(self.__getSelectedDebuggerId(), cmd) |
1905 self.__getSelectedDebuggerId(), cmd) |
|
1906 while self.inCommandExecution: |
1912 while self.inCommandExecution: |
1907 with contextlib.suppress(KeyboardInterrupt): |
1913 with contextlib.suppress(KeyboardInterrupt): |
1908 QApplication.processEvents() |
1914 QApplication.processEvents() |
1909 else: |
1915 else: |
1910 if not self.__echoInput: |
1916 if not self.__echoInput: |
1911 cmd = self.buff |
1917 cmd = self.buff |
1912 self.buff = "" |
1918 self.buff = "" |
1913 elif cmd: |
1919 elif cmd: |
1914 cmd = cmd[len(self.prompt):] |
1920 cmd = cmd[len(self.prompt) :] |
1915 self.__inRawMode = False |
1921 self.__inRawMode = False |
1916 self.__echoInput = True |
1922 self.__echoInput = True |
1917 |
1923 |
1918 self.dbs.remoteRawInput(self.__rawModeDebuggerId, cmd) |
1924 self.dbs.remoteRawInput(self.__rawModeDebuggerId, cmd) |
1919 |
1925 |
1920 if self.__rawModeQueue: |
1926 if self.__rawModeQueue: |
1921 debuggerId, prompt, echo = self.__rawModeQueue.pop(0) |
1927 debuggerId, prompt, echo = self.__rawModeQueue.pop(0) |
1922 self.__raw_input(prompt, echo, debuggerId) |
1928 self.__raw_input(prompt, echo, debuggerId) |
1923 |
1929 |
1924 def __showVenvName(self): |
1930 def __showVenvName(self): |
1925 """ |
1931 """ |
1926 Private method to show the name of the active virtual environment. |
1932 Private method to show the name of the active virtual environment. |
1927 """ |
1933 """ |
1928 s = "\n" + self.tr("Current Virtual Environment: '{0}'\n").format( |
1934 s = "\n" + self.tr("Current Virtual Environment: '{0}'\n").format( |
1929 self.__currentVenv) |
1935 self.__currentVenv |
|
1936 ) |
1930 self.__write(s) |
1937 self.__write(s) |
1931 self.__clientStatement(False) |
1938 self.__clientStatement(False) |
1932 |
1939 |
1933 def __useHistory(self): |
1940 def __useHistory(self): |
1934 """ |
1941 """ |
1935 Private method to display a command from the history. |
1942 Private method to display a command from the history. |
1936 """ |
1943 """ |
1937 if self.__isHistoryIndexValid(): |
1944 if self.__isHistoryIndexValid(): |
1938 cmd = self.__history[self.__histidx] |
1945 cmd = self.__history[self.__histidx] |
1939 else: |
1946 else: |
1940 cmd = "" |
1947 cmd = "" |
1941 self.__resetIncrementalHistorySearch() |
1948 self.__resetIncrementalHistorySearch() |
1942 |
1949 |
1943 self.__insertHistory(cmd) |
1950 self.__insertHistory(cmd) |
1944 |
1951 |
1945 def __insertHistory(self, cmd): |
1952 def __insertHistory(self, cmd): |
1946 """ |
1953 """ |
1947 Private method to insert a command selected from the history. |
1954 Private method to insert a command selected from the history. |
1948 |
1955 |
1949 @param cmd history entry to be inserted (string) |
1956 @param cmd history entry to be inserted (string) |
1950 """ |
1957 """ |
1951 self.setCursorPosition(self.prline, self.prcol) |
1958 self.setCursorPosition(self.prline, self.prcol) |
1952 self.setSelection(self.prline, self.prcol, |
1959 self.setSelection( |
1953 self.prline, self.lineLength(self.prline)) |
1960 self.prline, self.prcol, self.prline, self.lineLength(self.prline) |
|
1961 ) |
1954 self.removeSelectedText() |
1962 self.removeSelectedText() |
1955 self.__insertText(cmd) |
1963 self.__insertText(cmd) |
1956 |
1964 |
1957 def __resetIncrementalHistorySearch(self): |
1965 def __resetIncrementalHistorySearch(self): |
1958 """ |
1966 """ |
1959 Private method to reset the incremental history search. |
1967 Private method to reset the incremental history search. |
1960 """ |
1968 """ |
1961 self.incrementalSearchString = "" |
1969 self.incrementalSearchString = "" |
1962 self.incrementalSearchActive = False |
1970 self.incrementalSearchActive = False |
1963 |
1971 |
1964 def __searchHistory(self, txt, startIdx=-1): |
1972 def __searchHistory(self, txt, startIdx=-1): |
1965 """ |
1973 """ |
1966 Private method used to search the history. |
1974 Private method used to search the history. |
1967 |
1975 |
1968 @param txt text to match at the beginning |
1976 @param txt text to match at the beginning |
1969 @type str |
1977 @type str |
1970 @param startIdx index to start search from |
1978 @param startIdx index to start search from |
1971 @type int |
1979 @type int |
1972 @return tuple containing the index of found entry and a flag indicating |
1980 @return tuple containing the index of found entry and a flag indicating |
1973 that something was found |
1981 that something was found |
1974 @rtype tuple of (int, bool) |
1982 @rtype tuple of (int, bool) |
1975 """ |
1983 """ |
1976 idx = 0 if startIdx == -1 else startIdx + 1 |
1984 idx = 0 if startIdx == -1 else startIdx + 1 |
1977 while ( |
1985 while idx < len(self.__history) and not self.__history[idx].startswith(txt): |
1978 idx < len(self.__history) and |
|
1979 not self.__history[idx].startswith(txt) |
|
1980 ): |
|
1981 idx += 1 |
1986 idx += 1 |
1982 found = (idx < len(self.__history) and |
1987 found = idx < len(self.__history) and self.__history[idx].startswith(txt) |
1983 self.__history[idx].startswith(txt)) |
|
1984 return idx, found |
1988 return idx, found |
1985 |
1989 |
1986 def __rsearchHistory(self, txt, startIdx=-1): |
1990 def __rsearchHistory(self, txt, startIdx=-1): |
1987 """ |
1991 """ |
1988 Private method used to reverse search the history. |
1992 Private method used to reverse search the history. |
1989 |
1993 |
1990 @param txt text to match at the beginning |
1994 @param txt text to match at the beginning |
1991 @type str |
1995 @type str |
1992 @param startIdx index to start search from |
1996 @param startIdx index to start search from |
1993 @type int |
1997 @type int |
1994 @return tuple containing the index of found entry and a flag indicating |
1998 @return tuple containing the index of found entry and a flag indicating |
1995 that something was found |
1999 that something was found |
1996 @rtype tuple of (int, bool) |
2000 @rtype tuple of (int, bool) |
1997 """ |
2001 """ |
1998 idx = len(self.__history) - 1 if startIdx == -1 else startIdx - 1 |
2002 idx = len(self.__history) - 1 if startIdx == -1 else startIdx - 1 |
1999 while ( |
2003 while idx >= 0 and not self.__history[idx].startswith(txt): |
2000 idx >= 0 and |
|
2001 not self.__history[idx].startswith(txt) |
|
2002 ): |
|
2003 idx -= 1 |
2004 idx -= 1 |
2004 found = idx >= 0 and self.__history[idx].startswith(txt) |
2005 found = idx >= 0 and self.__history[idx].startswith(txt) |
2005 return idx, found |
2006 return idx, found |
2006 |
2007 |
2007 def focusNextPrevChild(self, nextChild): |
2008 def focusNextPrevChild(self, nextChild): |
2008 """ |
2009 """ |
2009 Public method to stop Tab moving to the next window. |
2010 Public method to stop Tab moving to the next window. |
2010 |
2011 |
2011 While the user is entering a multi-line command, the movement to |
2012 While the user is entering a multi-line command, the movement to |
2012 the next window by the Tab key being pressed is suppressed. |
2013 the next window by the Tab key being pressed is suppressed. |
2013 |
2014 |
2014 @param nextChild next window |
2015 @param nextChild next window |
2015 @return flag indicating the movement |
2016 @return flag indicating the movement |
2016 """ |
2017 """ |
2017 if nextChild and self.inContinue: |
2018 if nextChild and self.inContinue: |
2018 return False |
2019 return False |
2019 |
2020 |
2020 return QsciScintillaCompat.focusNextPrevChild(self, nextChild) |
2021 return QsciScintillaCompat.focusNextPrevChild(self, nextChild) |
2021 |
2022 |
2022 def contextMenuEvent(self, ev): |
2023 def contextMenuEvent(self, ev): |
2023 """ |
2024 """ |
2024 Protected method to show our own context menu. |
2025 Protected method to show our own context menu. |
2025 |
2026 |
2026 @param ev context menu event (QContextMenuEvent) |
2027 @param ev context menu event (QContextMenuEvent) |
2027 """ |
2028 """ |
2028 if not self.__windowed: |
2029 if not self.__windowed: |
2029 self.menu.popup(ev.globalPos()) |
2030 self.menu.popup(ev.globalPos()) |
2030 ev.accept() |
2031 ev.accept() |
2031 |
2032 |
2032 def clear(self): |
2033 def clear(self): |
2033 """ |
2034 """ |
2034 Public slot to clear the display. |
2035 Public slot to clear the display. |
2035 """ |
2036 """ |
2036 # Display the banner. |
2037 # Display the banner. |
2037 self.__getBanner() |
2038 self.__getBanner() |
2038 |
2039 |
2039 def doClearRestart(self): |
2040 def doClearRestart(self): |
2040 """ |
2041 """ |
2041 Public slot to handle the 'restart and clear' context menu entry. |
2042 Public slot to handle the 'restart and clear' context menu entry. |
2042 """ |
2043 """ |
2043 self.doRestart() |
2044 self.doRestart() |
2044 self.clear() |
2045 self.clear() |
2045 |
2046 |
2046 def doRestart(self): |
2047 def doRestart(self): |
2047 """ |
2048 """ |
2048 Public slot to handle the 'restart' context menu entry. |
2049 Public slot to handle the 'restart' context menu entry. |
2049 """ |
2050 """ |
2050 self.dbs.startClient(False, venvName=self.__currentVenv, |
2051 self.dbs.startClient( |
2051 workingDir=self.__currentWorkingDirectory) |
2052 False, |
2052 |
2053 venvName=self.__currentVenv, |
|
2054 workingDir=self.__currentWorkingDirectory, |
|
2055 ) |
|
2056 |
2053 def __startDebugClient(self, action): |
2057 def __startDebugClient(self, action): |
2054 """ |
2058 """ |
2055 Private slot to start a debug client according to the action |
2059 Private slot to start a debug client according to the action |
2056 triggered. |
2060 triggered. |
2057 |
2061 |
2058 @param action context menu action that was triggered (QAction) |
2062 @param action context menu action that was triggered (QAction) |
2059 """ |
2063 """ |
2060 venvName = action.text() |
2064 venvName = action.text() |
2061 if venvName == self.tr("Project"): |
2065 if venvName == self.tr("Project"): |
2062 if self.__project.isOpen(): |
2066 if self.__project.isOpen(): |
2063 self.__currentWorkingDirectory = ( |
2067 self.__currentWorkingDirectory = self.__project.getProjectPath() |
2064 self.__project.getProjectPath() |
2068 self.dbs.startClient( |
2065 ) |
2069 False, forProject=True, workingDir=self.__currentWorkingDirectory |
2066 self.dbs.startClient(False, forProject=True, |
2070 ) |
2067 workingDir=self.__currentWorkingDirectory) |
|
2068 else: |
2071 else: |
2069 self.dbs.startClient(False, venvName=venvName) |
2072 self.dbs.startClient(False, venvName=venvName) |
2070 self.__getBanner() |
2073 self.__getBanner() |
2071 |
2074 |
2072 def handlePreferencesChanged(self): |
2075 def handlePreferencesChanged(self): |
2073 """ |
2076 """ |
2074 Public slot to handle the preferencesChanged signal. |
2077 Public slot to handle the preferencesChanged signal. |
2075 """ |
2078 """ |
2076 # rebind the lexer |
2079 # rebind the lexer |
2077 self.__bindLexer(self.language) |
2080 self.__bindLexer(self.language) |
2078 self.recolor() |
2081 self.recolor() |
2079 |
2082 |
2080 # set margin 0 configuration |
2083 # set margin 0 configuration |
2081 self.__setTextDisplay() |
2084 self.__setTextDisplay() |
2082 self.__setMargin0() |
2085 self.__setMargin0() |
2083 |
2086 |
2084 # set the autocompletion and calltips function |
2087 # set the autocompletion and calltips function |
2085 self.__setAutoCompletion() |
2088 self.__setAutoCompletion() |
2086 self.__setCallTips() |
2089 self.__setCallTips() |
2087 |
2090 |
2088 # do the history related stuff |
2091 # do the history related stuff |
2089 self.__maxHistoryEntries = Preferences.getShell("MaxHistoryEntries") |
2092 self.__maxHistoryEntries = Preferences.getShell("MaxHistoryEntries") |
2090 for key in list(self.__historyLists.keys()): |
2093 for key in list(self.__historyLists.keys()): |
2091 self.__historyLists[key] = ( |
2094 self.__historyLists[key] = self.__historyLists[key][ |
2092 self.__historyLists[key][-self.__maxHistoryEntries:] |
2095 -self.__maxHistoryEntries : |
2093 ) |
2096 ] |
2094 self.__historyStyle = Preferences.getShell("HistoryStyle") |
2097 self.__historyStyle = Preferences.getShell("HistoryStyle") |
2095 self.__historyWrap = Preferences.getShell("HistoryWrap") |
2098 self.__historyWrap = Preferences.getShell("HistoryWrap") |
2096 self.__setHistoryIndex() |
2099 self.__setHistoryIndex() |
2097 if not self.__windowed: |
2100 if not self.__windowed: |
2098 self.hmenu.menuAction().setEnabled(self.isHistoryEnabled()) |
2101 self.hmenu.menuAction().setEnabled(self.isHistoryEnabled()) |
2099 self.__historyNavigateByCursor = Preferences.getShell( |
2102 self.__historyNavigateByCursor = Preferences.getShell("HistoryNavigateByCursor") |
2100 "HistoryNavigateByCursor") |
|
2101 self.historyStyleChanged.emit(self.__historyStyle) |
2103 self.historyStyleChanged.emit(self.__historyStyle) |
2102 |
2104 |
2103 # do stdout /stderr stuff |
2105 # do stdout /stderr stuff |
2104 showStdOutErr = Preferences.getShell("ShowStdOutErr") |
2106 showStdOutErr = Preferences.getShell("ShowStdOutErr") |
2105 if self.__showStdOutErr != showStdOutErr: |
2107 if self.__showStdOutErr != showStdOutErr: |
2106 if showStdOutErr: |
2108 if showStdOutErr: |
2107 self.dbs.clientProcessStdout.connect(self.__writeStdOut) |
2109 self.dbs.clientProcessStdout.connect(self.__writeStdOut) |
2108 self.dbs.clientProcessStderr.connect(self.__writeStdErr) |
2110 self.dbs.clientProcessStderr.connect(self.__writeStdErr) |
2109 else: |
2111 else: |
2110 self.dbs.clientProcessStdout.disconnect(self.__writeStdOut) |
2112 self.dbs.clientProcessStdout.disconnect(self.__writeStdOut) |
2111 self.dbs.clientProcessStderr.disconnect(self.__writeStdErr) |
2113 self.dbs.clientProcessStderr.disconnect(self.__writeStdErr) |
2112 self.__showStdOutErr = showStdOutErr |
2114 self.__showStdOutErr = showStdOutErr |
2113 |
2115 |
2114 @pyqtSlot(list, str) |
2116 @pyqtSlot(list, str) |
2115 def __showCompletions(self, completions, text): |
2117 def __showCompletions(self, completions, text): |
2116 """ |
2118 """ |
2117 Private method to display the possible completions. |
2119 Private method to display the possible completions. |
2118 |
2120 |
2119 @param completions list of possible completions (list of strings) |
2121 @param completions list of possible completions (list of strings) |
2120 @param text text that is about to be completed (string) |
2122 @param text text that is about to be completed (string) |
2121 """ |
2123 """ |
2122 if len(completions) == 0: |
2124 if len(completions) == 0: |
2123 return |
2125 return |
2124 |
2126 |
2125 if len(completions) > 1: |
2127 if len(completions) > 1: |
2126 completions.sort() |
2128 completions.sort() |
2127 self.showUserList(1, completions) |
2129 self.showUserList(1, completions) |
2128 self.completionText = text |
2130 self.completionText = text |
2129 else: |
2131 else: |
2130 txt = completions[0] |
2132 txt = completions[0] |
2131 if text != "": |
2133 if text != "": |
2132 txt = txt.replace(text, "") |
2134 txt = txt.replace(text, "") |
2133 self.__insertText(txt) |
2135 self.__insertText(txt) |
2134 self.completionText = "" |
2136 self.completionText = "" |
2135 |
2137 |
2136 def __completionListSelected(self, listId, txt): |
2138 def __completionListSelected(self, listId, txt): |
2137 """ |
2139 """ |
2138 Private slot to handle the selection from the completion list. |
2140 Private slot to handle the selection from the completion list. |
2139 |
2141 |
2140 @param listId the ID of the user list (should be 1) (integer) |
2142 @param listId the ID of the user list (should be 1) (integer) |
2141 @param txt the selected text (string) |
2143 @param txt the selected text (string) |
2142 """ |
2144 """ |
2143 if listId == 1: |
2145 if listId == 1: |
2144 if self.completionText != "": |
2146 if self.completionText != "": |
2145 txt = txt.replace(self.completionText, "") |
2147 txt = txt.replace(self.completionText, "") |
2146 self.__insertText(txt) |
2148 self.__insertText(txt) |
2147 self.completionText = "" |
2149 self.completionText = "" |
2148 |
2150 |
2149 ################################################################# |
2151 ################################################################# |
2150 ## Drag and Drop Support |
2152 ## Drag and Drop Support |
2151 ################################################################# |
2153 ################################################################# |
2152 |
2154 |
2153 def dragEnterEvent(self, event): |
2155 def dragEnterEvent(self, event): |
2154 """ |
2156 """ |
2155 Protected method to handle the drag enter event. |
2157 Protected method to handle the drag enter event. |
2156 |
2158 |
2157 @param event the drag enter event (QDragEnterEvent) |
2159 @param event the drag enter event (QDragEnterEvent) |
2158 """ |
2160 """ |
2159 self.inDragDrop = ( |
2161 self.inDragDrop = event.mimeData().hasUrls() or event.mimeData().hasText() |
2160 event.mimeData().hasUrls() or |
|
2161 event.mimeData().hasText() |
|
2162 ) |
|
2163 if self.inDragDrop: |
2162 if self.inDragDrop: |
2164 event.acceptProposedAction() |
2163 event.acceptProposedAction() |
2165 else: |
2164 else: |
2166 super().dragEnterEvent(event) |
2165 super().dragEnterEvent(event) |
2167 |
2166 |
2168 def dragMoveEvent(self, event): |
2167 def dragMoveEvent(self, event): |
2169 """ |
2168 """ |
2170 Protected method to handle the drag move event. |
2169 Protected method to handle the drag move event. |
2171 |
2170 |
2172 @param event the drag move event (QDragMoveEvent) |
2171 @param event the drag move event (QDragMoveEvent) |
2173 """ |
2172 """ |
2174 if self.inDragDrop: |
2173 if self.inDragDrop: |
2175 event.accept() |
2174 event.accept() |
2176 else: |
2175 else: |
2177 super().dragMoveEvent(event) |
2176 super().dragMoveEvent(event) |
2178 |
2177 |
2179 def dragLeaveEvent(self, event): |
2178 def dragLeaveEvent(self, event): |
2180 """ |
2179 """ |
2181 Protected method to handle the drag leave event. |
2180 Protected method to handle the drag leave event. |
2182 |
2181 |
2183 @param event the drag leave event (QDragLeaveEvent) |
2182 @param event the drag leave event (QDragLeaveEvent) |
2184 """ |
2183 """ |
2185 if self.inDragDrop: |
2184 if self.inDragDrop: |
2186 self.inDragDrop = False |
2185 self.inDragDrop = False |
2187 event.accept() |
2186 event.accept() |
2188 else: |
2187 else: |
2189 super().dragLeaveEvent(event) |
2188 super().dragLeaveEvent(event) |
2190 |
2189 |
2191 def dropEvent(self, event): |
2190 def dropEvent(self, event): |
2192 """ |
2191 """ |
2193 Protected method to handle the drop event. |
2192 Protected method to handle the drop event. |
2194 |
2193 |
2195 @param event the drop event (QDropEvent) |
2194 @param event the drop event (QDropEvent) |
2196 """ |
2195 """ |
2197 if event.mimeData().hasUrls() and not self.__windowed: |
2196 if event.mimeData().hasUrls() and not self.__windowed: |
2198 for url in event.mimeData().urls(): |
2197 for url in event.mimeData().urls(): |
2199 fname = url.toLocalFile() |
2198 fname = url.toLocalFile() |
2249 self.__searchShortcut.setEnabled(True) |
2256 self.__searchShortcut.setEnabled(True) |
2250 self.__searchNextShortcut.setEnabled(True) |
2257 self.__searchNextShortcut.setEnabled(True) |
2251 self.__searchPrevShortcut.setEnabled(True) |
2258 self.__searchPrevShortcut.setEnabled(True) |
2252 self.setCaretWidth(self.caretWidth) |
2259 self.setCaretWidth(self.caretWidth) |
2253 self.setCursorFlashTime(QApplication.cursorFlashTime()) |
2260 self.setCursorFlashTime(QApplication.cursorFlashTime()) |
2254 |
2261 |
2255 super().focusInEvent(event) |
2262 super().focusInEvent(event) |
2256 |
2263 |
2257 def focusOutEvent(self, event): |
2264 def focusOutEvent(self, event): |
2258 """ |
2265 """ |
2259 Protected method called when the shell loses focus. |
2266 Protected method called when the shell loses focus. |
2260 |
2267 |
2261 @param event the event object (QFocusEvent) |
2268 @param event the event object (QFocusEvent) |
2262 """ |
2269 """ |
2263 with contextlib.suppress(AttributeError): |
2270 with contextlib.suppress(AttributeError): |
2264 self.vm.editorActGrp.setEnabled(False) |
2271 self.vm.editorActGrp.setEnabled(False) |
2265 if not self.__windowed: |
2272 if not self.__windowed: |
2266 self.__searchShortcut.setEnabled(False) |
2273 self.__searchShortcut.setEnabled(False) |
2267 self.__searchNextShortcut.setEnabled(False) |
2274 self.__searchNextShortcut.setEnabled(False) |
2268 self.__searchPrevShortcut.setEnabled(False) |
2275 self.__searchPrevShortcut.setEnabled(False) |
2269 self.setCaretWidth(0) |
2276 self.setCaretWidth(0) |
2270 super().focusOutEvent(event) |
2277 super().focusOutEvent(event) |
2271 |
2278 |
2272 def insert(self, txt): |
2279 def insert(self, txt): |
2273 """ |
2280 """ |
2274 Public slot to insert text at the current cursor position. |
2281 Public slot to insert text at the current cursor position. |
2275 |
2282 |
2276 The cursor is advanced to the end of the inserted text. |
2283 The cursor is advanced to the end of the inserted text. |
2277 |
2284 |
2278 @param txt text to be inserted (string) |
2285 @param txt text to be inserted (string) |
2279 """ |
2286 """ |
2280 txt = Utilities.filterAnsiSequences(txt) |
2287 txt = Utilities.filterAnsiSequences(txt) |
2281 length = len(txt) |
2288 length = len(txt) |
2282 line, col = self.getCursorPosition() |
2289 line, col = self.getCursorPosition() |
2283 self.insertAt(txt, line, col) |
2290 self.insertAt(txt, line, col) |
2284 if re.search(self.linesepRegExp, txt) is not None: |
2291 if re.search(self.linesepRegExp, txt) is not None: |
2285 line += 1 |
2292 line += 1 |
2286 self.setCursorPosition(line, col + length) |
2293 self.setCursorPosition(line, col + length) |
2287 |
2294 |
2288 def __configure(self): |
2295 def __configure(self): |
2289 """ |
2296 """ |
2290 Private method to open the configuration dialog. |
2297 Private method to open the configuration dialog. |
2291 """ |
2298 """ |
2292 ericApp().getObject("UserInterface").showPreferences("shellPage") |
2299 ericApp().getObject("UserInterface").showPreferences("shellPage") |
2293 |
2300 |
2294 def __find(self): |
2301 def __find(self): |
2295 """ |
2302 """ |
2296 Private slot to show the find widget. |
2303 Private slot to show the find widget. |
2297 """ |
2304 """ |
2298 txt = self.selectedText() |
2305 txt = self.selectedText() |
2299 self.__mainWindow.showFind(txt) |
2306 self.__mainWindow.showFind(txt) |
2300 |
2307 |
2301 def __searchNext(self): |
2308 def __searchNext(self): |
2302 """ |
2309 """ |
2303 Private method to search for the next occurrence. |
2310 Private method to search for the next occurrence. |
2304 """ |
2311 """ |
2305 if self.__lastSearch: |
2312 if self.__lastSearch: |
2306 self.searchNext(*self.__lastSearch) |
2313 self.searchNext(*self.__lastSearch) |
2307 |
2314 |
2308 def searchNext(self, txt, caseSensitive, wholeWord, regexp): |
2315 def searchNext(self, txt, caseSensitive, wholeWord, regexp): |
2309 """ |
2316 """ |
2310 Public method to search the next occurrence of the given text. |
2317 Public method to search the next occurrence of the given text. |
2311 |
2318 |
2312 @param txt text to search for |
2319 @param txt text to search for |
2313 @type str |
2320 @type str |
2314 @param caseSensitive flag indicating to perform a case sensitive |
2321 @param caseSensitive flag indicating to perform a case sensitive |
2315 search |
2322 search |
2316 @type bool |
2323 @type bool |