93 @signal searchStringFound(found) emitted to indicate the search |
93 @signal searchStringFound(found) emitted to indicate the search |
94 result (boolean) |
94 result (boolean) |
95 """ |
95 """ |
96 searchStringFound = pyqtSignal(bool) |
96 searchStringFound = pyqtSignal(bool) |
97 |
97 |
98 def __init__(self, dbs, vm, parent=None): |
98 def __init__(self, dbs, vm, windowedVariant, parent=None): |
99 """ |
99 """ |
100 Constructor |
100 Constructor |
101 |
101 |
102 @param dbs reference to the debug server object |
102 @param dbs reference to the debug server object |
103 @param vm reference to the viewmanager object |
103 @param vm reference to the viewmanager object |
|
104 @param windowedVariant flag indicating the shell window variant |
|
105 (boolean) |
104 @param parent parent widget (QWidget) |
106 @param parent parent widget (QWidget) |
105 """ |
107 """ |
106 super(Shell, self).__init__(parent) |
108 super(Shell, self).__init__(parent) |
107 self.setUtf8(True) |
109 self.setUtf8(True) |
108 |
110 |
109 self.vm = vm |
111 self.vm = vm |
110 self.__mainWindow = parent |
112 self.__mainWindow = parent |
111 self.__lastSearch = () |
113 self.__lastSearch = () |
|
114 self.__windowed = windowedVariant |
112 |
115 |
113 self.linesepRegExp = r"\r\n|\n|\r" |
116 self.linesepRegExp = r"\r\n|\n|\r" |
114 |
117 |
115 self.passive = Preferences.getDebugger("PassiveDbgEnabled") |
118 self.passive = ((not self.__windowed) and |
|
119 Preferences.getDebugger("PassiveDbgEnabled")) |
116 if self.passive: |
120 if self.passive: |
117 self.setWindowTitle(self.tr('Shell - Passive')) |
121 self.setWindowTitle(self.tr('Shell - Passive')) |
118 else: |
122 else: |
119 self.setWindowTitle(self.tr('Shell')) |
123 self.setWindowTitle(self.tr('Shell')) |
120 |
124 |
121 self.setWhatsThis(self.tr( |
125 if self.__windowed: |
122 """<b>The Shell Window</b>""" |
126 self.setWhatsThis(self.tr( |
123 """<p>This is simply an interpreter running in a window. The""" |
127 """<b>The Shell Window</b>""" |
124 """ interpreter is the one that is used to run the program""" |
128 """<p>You can use the cursor keys while entering commands.""" |
125 """ being debugged. This means that you can execute any command""" |
129 """ There is also a history of commands that can be recalled""" |
126 """ while the program being debugged is running.</p>""" |
130 """ using the up and down cursor keys. Pressing the up or""" |
127 """<p>You can use the cursor keys while entering commands. There""" |
131 """ down key after some text has been entered will start an""" |
128 """ is also a history of commands that can be recalled using the""" |
132 """ incremental search.</p>""" |
129 """ up and down cursor keys. Pressing the up or down key after""" |
133 """<p>The shell has some special commands. 'reset' kills the""" |
130 """ some text has been entered will start an incremental search.""" |
134 """ shell and starts a new one. 'clear' clears the display""" |
131 """</p>""" |
135 """ of the shell window. 'start' is used to switch the shell""" |
132 """<p>The shell has some special commands. 'reset' kills the""" |
136 """ language and must be followed by a supported language.""" |
133 """ shell and starts a new one. 'clear' clears the display of""" |
137 """ Supported languages are listed by the 'languages'""" |
134 """ the shell window. 'start' is used to switch the shell""" |
138 """ command. 'quit' is used to exit the application.These""" |
135 """ language and must be followed by a supported language.""" |
139 """ commands (except 'languages') are available through the""" |
136 """ Supported languages are listed by the 'languages' command.""" |
140 """ window menus as well.</p>""" |
137 """ These commands (except 'languages') are available through""" |
141 """<p>Pressing the Tab key after some text has been entered""" |
138 """ the context menu as well.</p>""" |
142 """ will show a list of possible completions. The relevant""" |
139 """<p>Pressing the Tab key after some text has been entered will""" |
143 """ entry may be selected from this list. If only one entry""" |
140 """ show a list of possible commandline completions. The""" |
144 """ is available, this will be inserted automatically.</p>""" |
141 """ relevant entry may be selected from this list. If only one""" |
145 )) |
142 """ entry is available, this will inserted automatically.</p>""" |
146 else: |
143 """<p>In passive debugging mode the shell is only available""" |
147 self.setWhatsThis(self.tr( |
144 """ after the program to be debugged has connected to the IDE""" |
148 """<b>The Shell Window</b>""" |
145 """ until it has finished. This is indicated by a different""" |
149 """<p>This is simply an interpreter running in a window. The""" |
146 """ prompt and by an indication in the window caption.</p>""" |
150 """ interpreter is the one that is used to run the program""" |
147 )) |
151 """ being debugged. This means that you can execute any""" |
|
152 """ command while the program being debugged is running.</p>""" |
|
153 """<p>You can use the cursor keys while entering commands.""" |
|
154 """ There is also a history of commands that can be recalled""" |
|
155 """ using the up and down cursor keys. Pressing the up or""" |
|
156 """ down key after some text has been entered will start an""" |
|
157 """ incremental search.</p>""" |
|
158 """<p>The shell has some special commands. 'reset' kills the""" |
|
159 """ shell and starts a new one. 'clear' clears the display""" |
|
160 """ of the shell window. 'start' is used to switch the shell""" |
|
161 """ language and must be followed by a supported language.""" |
|
162 """ Supported languages are listed by the 'languages'""" |
|
163 """ command. These commands (except 'languages') are""" |
|
164 """ available through the context menu as well.</p>""" |
|
165 """<p>Pressing the Tab key after some text has been entered""" |
|
166 """ will show a list of possible completions. The relevant""" |
|
167 """ entry may be selected from this list. If only one entry""" |
|
168 """ is available, this will be inserted automatically.</p>""" |
|
169 """<p>In passive debugging mode the shell is only available""" |
|
170 """ after the program to be debugged has connected to the""" |
|
171 """ IDE until it has finished. This is indicated by a""" |
|
172 """ different prompt and by an indication in the window""" |
|
173 """ caption.</p>""" |
|
174 )) |
148 |
175 |
149 self.userListActivated.connect(self.__completionListSelected) |
176 self.userListActivated.connect(self.__completionListSelected) |
150 self.linesChanged.connect(self.__resizeLinenoMargin) |
177 self.linesChanged.connect(self.__resizeLinenoMargin) |
151 |
178 |
152 self.__showStdOutErr = Preferences.getShell("ShowStdOutErr") |
179 if self.__windowed: |
|
180 self.__showStdOutErr = True |
|
181 else: |
|
182 self.__showStdOutErr = Preferences.getShell("ShowStdOutErr") |
153 if self.__showStdOutErr: |
183 if self.__showStdOutErr: |
154 dbs.clientProcessStdout.connect(self.__writeStdOut) |
184 dbs.clientProcessStdout.connect(self.__writeStdOut) |
155 dbs.clientProcessStderr.connect(self.__writeStdErr) |
185 dbs.clientProcessStderr.connect(self.__writeStdErr) |
156 dbs.clientOutput.connect(self.__write) |
186 dbs.clientOutput.connect(self.__write) |
157 dbs.clientStatement.connect(self.__clientStatement) |
187 dbs.clientStatement.connect(self.__clientStatement) |
204 sys.ps2 = "... " |
234 sys.ps2 = "... " |
205 |
235 |
206 if self.passive: |
236 if self.passive: |
207 self.__getBanner() |
237 self.__getBanner() |
208 |
238 |
209 # Create a little language context menu |
239 if not self.__windowed: |
210 self.lmenu = QMenu(self.tr('Start')) |
240 # Create a little language context menu |
211 self.lmenu.aboutToShow.connect(self.__showLanguageMenu) |
241 self.lmenu = QMenu(self.tr('Start')) |
212 self.lmenu.triggered.connect(self.__startDebugClient) |
242 self.lmenu.aboutToShow.connect(self.__showLanguageMenu) |
213 |
243 self.lmenu.triggered.connect(self.__startDebugClient) |
214 # Create the history context menu |
244 |
215 self.hmenu = QMenu(self.tr('History')) |
245 # Create the history context menu |
216 self.hmenu.addAction(self.tr('Select entry'), self.__selectHistory) |
246 self.hmenu = QMenu(self.tr('History')) |
217 self.hmenu.addAction(self.tr('Show'), self.__showHistory) |
247 self.hmenu.addAction(self.tr('Select entry'), self.selectHistory) |
218 self.hmenu.addAction(self.tr('Clear'), self.__clearHistory) |
248 self.hmenu.addAction(self.tr('Show'), self.showHistory) |
219 |
249 self.hmenu.addAction(self.tr('Clear'), self.clearHistory) |
220 # Create a little context menu |
250 |
221 self.menu = QMenu(self) |
251 # Create a little context menu |
222 self.menu.addAction(self.tr('Cut'), self.cut) |
252 self.menu = QMenu(self) |
223 self.menu.addAction(self.tr('Copy'), self.copy) |
253 self.menu.addAction(self.tr('Cut'), self.cut) |
224 self.menu.addAction(self.tr('Paste'), self.paste) |
254 self.menu.addAction(self.tr('Copy'), self.copy) |
225 self.menu.addMenu(self.hmenu) |
255 self.menu.addAction(self.tr('Paste'), self.paste) |
226 self.menu.addSeparator() |
256 self.menu.addMenu(self.hmenu) |
227 self.menu.addAction(self.tr('Find'), self.__find) |
257 self.menu.addSeparator() |
228 self.menu.addSeparator() |
258 self.menu.addAction(self.tr('Find'), self.__find) |
229 self.menu.addAction(self.tr('Clear'), self.clear) |
259 self.menu.addSeparator() |
230 self.menu.addAction(self.tr('Reset'), self.__reset) |
260 self.menu.addAction(self.tr('Clear'), self.clear) |
231 self.menu.addAction( |
261 self.menu.addAction(self.tr('Reset'), self.__reset) |
232 self.tr('Reset and Clear'), self.__resetAndClear) |
262 self.menu.addAction( |
233 self.menu.addSeparator() |
263 self.tr('Reset and Clear'), self.__resetAndClear) |
234 self.menu.addMenu(self.lmenu) |
264 self.menu.addSeparator() |
235 self.menu.addSeparator() |
265 self.menu.addMenu(self.lmenu) |
236 self.menu.addAction(self.tr("Configure..."), self.__configure) |
266 self.menu.addSeparator() |
|
267 self.menu.addAction(self.tr("Configure..."), self.__configure) |
237 |
268 |
238 self.__bindLexer() |
269 self.__bindLexer() |
239 self.__setTextDisplay() |
270 self.__setTextDisplay() |
240 self.__setMargin0() |
271 self.__setMargin0() |
241 |
272 |
264 QsciScintilla.SCI_CHARRIGHT: self.__QScintillaCharRight, |
295 QsciScintilla.SCI_CHARRIGHT: self.__QScintillaCharRight, |
265 QsciScintilla.SCI_WORDLEFT: self.__QScintillaWordLeft, |
296 QsciScintilla.SCI_WORDLEFT: self.__QScintillaWordLeft, |
266 QsciScintilla.SCI_WORDRIGHT: self.__QScintillaWordRight, |
297 QsciScintilla.SCI_WORDRIGHT: self.__QScintillaWordRight, |
267 QsciScintilla.SCI_VCHOME: self.__QScintillaVCHome, |
298 QsciScintilla.SCI_VCHOME: self.__QScintillaVCHome, |
268 QsciScintilla.SCI_LINEEND: self.__QScintillaLineEnd, |
299 QsciScintilla.SCI_LINEEND: self.__QScintillaLineEnd, |
269 QsciScintilla.SCI_LINEUP: self.__QScintillaLineUp, |
300 QsciScintilla.SCI_LINEUP: self.__QScintillaCommand, |
270 QsciScintilla.SCI_LINEDOWN: self.__QScintillaLineDown, |
301 QsciScintilla.SCI_LINEDOWN: self.__QScintillaCommand, |
|
302 QsciScintilla.SCI_LINESCROLLUP: self.__QScintillaHistoryUp, |
|
303 QsciScintilla.SCI_LINESCROLLDOWN: self.__QScintillaHistoryDown, |
271 |
304 |
272 QsciScintilla.SCI_PAGEUP: self.__QScintillaAutoCompletionCommand, |
305 QsciScintilla.SCI_PAGEUP: self.__QScintillaAutoCompletionCommand, |
273 QsciScintilla.SCI_PAGEDOWN: self.__QScintillaAutoCompletionCommand, |
306 QsciScintilla.SCI_PAGEDOWN: self.__QScintillaAutoCompletionCommand, |
274 QsciScintilla.SCI_CANCEL: self.__QScintillaAutoCompletionCommand, |
307 QsciScintilla.SCI_CANCEL: self.__QScintillaAutoCompletionCommand, |
275 |
308 |
1175 buf = buf.replace(sys.ps1, "") |
1221 buf = buf.replace(sys.ps1, "") |
1176 if buf.startswith(sys.ps2): |
1222 if buf.startswith(sys.ps2): |
1177 buf = buf.replace(sys.ps2, "") |
1223 buf = buf.replace(sys.ps2, "") |
1178 self.insert('\n') |
1224 self.insert('\n') |
1179 self.__executeCommand(buf) |
1225 self.__executeCommand(buf) |
|
1226 else: |
|
1227 txt = "" |
|
1228 line, col = self.getCursorPosition() |
|
1229 if self.hasSelectedText(): |
|
1230 lineFrom, indexFrom, lineTo, indexTo = self.getSelection() |
|
1231 if line == lineFrom: |
|
1232 txt = self.text(line)[indexFrom:].rstrip() |
|
1233 elif line == lineTo: |
|
1234 txt = self.text(line)[:indexTo] |
|
1235 else: |
|
1236 txt = self.text(line)[col:].rstrip() |
|
1237 |
|
1238 if txt: |
|
1239 line, col = self.__getEndPos() |
|
1240 self.setCursorPosition(line, col) |
|
1241 self.insert(txt) |
1180 |
1242 |
1181 def __QScintillaLeftCommand(self, method, allLinesAllowed=False): |
1243 def __QScintillaLeftCommand(self, method, allLinesAllowed=False): |
1182 """ |
1244 """ |
1183 Private method to handle a QScintilla command working to the left. |
1245 Private method to handle a QScintilla command working to the left. |
1184 |
1246 |
1269 if self.isListActive(): |
1335 if self.isListActive(): |
1270 self.SendScintilla(cmd) |
1336 self.SendScintilla(cmd) |
1271 elif self.__isCursorOnLastLine(): |
1337 elif self.__isCursorOnLastLine(): |
1272 self.moveCursorToEOL() |
1338 self.moveCursorToEOL() |
1273 |
1339 |
1274 def __QScintillaLineUp(self, cmd): |
1340 def __QScintillaHistoryUp(self, cmd): |
1275 """ |
1341 """ |
1276 Private method to handle the Up key. |
1342 Private method to handle the Ctrl+Up key. |
1277 |
1343 |
1278 @param cmd QScintilla command |
1344 @param cmd QScintilla command |
1279 """ |
1345 """ |
1280 if self.isListActive(): |
1346 line, col = self.__getEndPos() |
1281 self.SendScintilla(cmd) |
1347 buf = self.text(line) |
1282 else: |
1348 if buf.startswith(sys.ps1): |
1283 line, col = self.__getEndPos() |
1349 buf = buf.replace(sys.ps1, "") |
1284 buf = self.text(line) |
1350 if buf.startswith(sys.ps2): |
1285 if buf.startswith(sys.ps1): |
1351 buf = buf.replace(sys.ps2, "") |
1286 buf = buf.replace(sys.ps1, "") |
1352 if buf and self.incrementalSearchActive: |
1287 if buf.startswith(sys.ps2): |
1353 if self.incrementalSearchString: |
1288 buf = buf.replace(sys.ps2, "") |
1354 idx = self.__rsearchHistory(self.incrementalSearchString, |
1289 if buf and self.incrementalSearchActive: |
1355 self.histidx) |
1290 if self.incrementalSearchString: |
1356 if idx >= 0: |
1291 idx = self.__rsearchHistory(self.incrementalSearchString, |
1357 self.histidx = idx |
1292 self.histidx) |
1358 self.__useHistory() |
1293 if idx >= 0: |
|
1294 self.histidx = idx |
|
1295 self.__useHistory() |
|
1296 else: |
|
1297 idx = self.__rsearchHistory(buf) |
|
1298 if idx >= 0: |
|
1299 self.histidx = idx |
|
1300 self.incrementalSearchString = buf |
|
1301 self.__useHistory() |
|
1302 else: |
1359 else: |
1303 if self.histidx < 0: |
1360 idx = self.__rsearchHistory(buf) |
1304 self.histidx = len(self.history) |
1361 if idx >= 0: |
1305 if self.histidx > 0: |
1362 self.histidx = idx |
1306 self.histidx = self.histidx - 1 |
1363 self.incrementalSearchString = buf |
1307 self.__useHistory() |
1364 self.__useHistory() |
1308 |
1365 else: |
1309 def __QScintillaLineDown(self, cmd): |
1366 if self.histidx < 0: |
1310 """ |
1367 self.histidx = len(self.history) |
1311 Private method to handle the Down key. |
1368 if self.histidx > 0: |
|
1369 self.histidx = self.histidx - 1 |
|
1370 self.__useHistory() |
|
1371 |
|
1372 def __QScintillaHistoryDown(self, cmd): |
|
1373 """ |
|
1374 Private method to handle the Ctrl+Down key. |
1312 |
1375 |
1313 @param cmd QScintilla command |
1376 @param cmd QScintilla command |
1314 """ |
1377 """ |
1315 if self.isListActive(): |
1378 line, col = self.__getEndPos() |
1316 self.SendScintilla(cmd) |
1379 buf = self.text(line) |
1317 else: |
1380 if buf.startswith(sys.ps1): |
1318 line, col = self.__getEndPos() |
1381 buf = buf.replace(sys.ps1, "") |
1319 buf = self.text(line) |
1382 if buf.startswith(sys.ps2): |
1320 if buf.startswith(sys.ps1): |
1383 buf = buf.replace(sys.ps2, "") |
1321 buf = buf.replace(sys.ps1, "") |
1384 if buf and self.incrementalSearchActive: |
1322 if buf.startswith(sys.ps2): |
1385 if self.incrementalSearchString: |
1323 buf = buf.replace(sys.ps2, "") |
1386 idx = self.__searchHistory( |
1324 if buf and self.incrementalSearchActive: |
1387 self.incrementalSearchString, self.histidx) |
1325 if self.incrementalSearchString: |
1388 if idx >= 0: |
1326 idx = self.__searchHistory( |
1389 self.histidx = idx |
1327 self.incrementalSearchString, self.histidx) |
1390 self.__useHistory() |
1328 if idx >= 0: |
|
1329 self.histidx = idx |
|
1330 self.__useHistory() |
|
1331 else: |
|
1332 idx = self.__searchHistory(buf) |
|
1333 if idx >= 0: |
|
1334 self.histidx = idx |
|
1335 self.incrementalSearchString = buf |
|
1336 self.__useHistory() |
|
1337 else: |
1391 else: |
1338 if self.histidx >= 0 and self.histidx < len(self.history): |
1392 idx = self.__searchHistory(buf) |
1339 self.histidx += 1 |
1393 if idx >= 0: |
|
1394 self.histidx = idx |
|
1395 self.incrementalSearchString = buf |
1340 self.__useHistory() |
1396 self.__useHistory() |
|
1397 else: |
|
1398 if self.histidx >= 0 and self.histidx < len(self.history): |
|
1399 self.histidx += 1 |
|
1400 self.__useHistory() |
1341 |
1401 |
1342 def __QScintillaCharLeftExtend(self): |
1402 def __QScintillaCharLeftExtend(self): |
1343 """ |
1403 """ |
1344 Private method to handle the Extend Selection Left command. |
1404 Private method to handle the Extend Selection Left command. |
1345 """ |
1405 """ |