Show More
@@ -81,9 +81,6 b' class ConsoleWidget(QtGui.QWidget):' | |||||
81 | self._reading_callback = None |
|
81 | self._reading_callback = None | |
82 | self._tab_width = 8 |
|
82 | self._tab_width = 8 | |
83 |
|
83 | |||
84 | # Define a custom context menu. |
|
|||
85 | self._context_menu = self._create_context_menu() |
|
|||
86 |
|
||||
87 | # Set a monospaced font. |
|
84 | # Set a monospaced font. | |
88 | self.reset_font() |
|
85 | self.reset_font() | |
89 |
|
86 | |||
@@ -94,14 +91,8 b' class ConsoleWidget(QtGui.QWidget):' | |||||
94 | if obj == self._control: |
|
91 | if obj == self._control: | |
95 | etype = event.type() |
|
92 | etype = event.type() | |
96 |
|
93 | |||
97 | # Override the default context menu with one that does not have |
|
|||
98 | # destructive actions. |
|
|||
99 | if etype == QtCore.QEvent.ContextMenu: |
|
|||
100 | self._context_menu.exec_(event.globalPos()) |
|
|||
101 | return True |
|
|||
102 |
|
||||
103 | # Disable moving text by drag and drop. |
|
94 | # Disable moving text by drag and drop. | |
104 |
|
|
95 | if etype == QtCore.QEvent.DragMove: | |
105 | return True |
|
96 | return True | |
106 |
|
97 | |||
107 | elif etype == QtCore.QEvent.KeyPress: |
|
98 | elif etype == QtCore.QEvent.KeyPress: | |
@@ -441,30 +432,6 b' class ConsoleWidget(QtGui.QWidget):' | |||||
441 |
|
432 | |||
442 | return down |
|
433 | return down | |
443 |
|
434 | |||
444 | def _create_context_menu(self): |
|
|||
445 | """ Creates a context menu for the underlying text widget. |
|
|||
446 | """ |
|
|||
447 | menu = QtGui.QMenu(self) |
|
|||
448 | clipboard = QtGui.QApplication.clipboard() |
|
|||
449 |
|
||||
450 | copy_action = QtGui.QAction('Copy', self) |
|
|||
451 | copy_action.triggered.connect(self.copy) |
|
|||
452 | self.copy_available.connect(copy_action.setEnabled) |
|
|||
453 | menu.addAction(copy_action) |
|
|||
454 |
|
||||
455 | paste_action = QtGui.QAction('Paste', self) |
|
|||
456 | paste_action.triggered.connect(self.paste) |
|
|||
457 | clipboard.dataChanged.connect( |
|
|||
458 | lambda: paste_action.setEnabled(not clipboard.text().isEmpty())) |
|
|||
459 | menu.addAction(paste_action) |
|
|||
460 | menu.addSeparator() |
|
|||
461 |
|
||||
462 | select_all_action = QtGui.QAction('Select All', self) |
|
|||
463 | select_all_action.triggered.connect(self.select_all) |
|
|||
464 | menu.addAction(select_all_action) |
|
|||
465 |
|
||||
466 | return menu |
|
|||
467 |
|
||||
468 | def _create_control(self, kind): |
|
435 | def _create_control(self, kind): | |
469 | """ Creates and sets the underlying text widget. |
|
436 | """ Creates and sets the underlying text widget. | |
470 | """ |
|
437 | """ | |
@@ -479,6 +446,8 b' class ConsoleWidget(QtGui.QWidget):' | |||||
479 | layout.addWidget(control) |
|
446 | layout.addWidget(control) | |
480 |
|
447 | |||
481 | control.installEventFilter(self) |
|
448 | control.installEventFilter(self) | |
|
449 | control.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) | |||
|
450 | control.customContextMenuRequested.connect(self._show_context_menu) | |||
482 | control.copyAvailable.connect(self.copy_available) |
|
451 | control.copyAvailable.connect(self.copy_available) | |
483 | control.redoAvailable.connect(self.redo_available) |
|
452 | control.redoAvailable.connect(self.redo_available) | |
484 | control.undoAvailable.connect(self.undo_available) |
|
453 | control.undoAvailable.connect(self.undo_available) | |
@@ -489,29 +458,37 b' class ConsoleWidget(QtGui.QWidget):' | |||||
489 | """ Filter key events for the underlying text widget to create a |
|
458 | """ Filter key events for the underlying text widget to create a | |
490 | console-like interface. |
|
459 | console-like interface. | |
491 | """ |
|
460 | """ | |
|
461 | key = event.key() | |||
|
462 | ctrl_down = self._control_key_down(event.modifiers()) | |||
|
463 | ||||
|
464 | # If the key is remapped, return immediately. | |||
|
465 | if ctrl_down and key in self._ctrl_down_remap: | |||
|
466 | new_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, | |||
|
467 | self._ctrl_down_remap[key], | |||
|
468 | QtCore.Qt.NoModifier) | |||
|
469 | QtGui.qApp.sendEvent(self._control, new_event) | |||
|
470 | return True | |||
|
471 | ||||
|
472 | # If the completion widget accepts the key press, return immediately. | |||
|
473 | if self._completion_widget.isVisible(): | |||
|
474 | self._completion_widget.keyPressEvent(event) | |||
|
475 | if event.isAccepted(): | |||
|
476 | return True | |||
|
477 | ||||
|
478 | # Otherwise, proceed normally and do not return early. | |||
492 | intercepted = False |
|
479 | intercepted = False | |
493 | replaced_event = None |
|
|||
494 | cursor = self._control.textCursor() |
|
480 | cursor = self._control.textCursor() | |
495 | position = cursor.position() |
|
481 | position = cursor.position() | |
496 | key = event.key() |
|
|||
497 | ctrl_down = self._control_key_down(event.modifiers()) |
|
|||
498 | alt_down = event.modifiers() & QtCore.Qt.AltModifier |
|
482 | alt_down = event.modifiers() & QtCore.Qt.AltModifier | |
499 | shift_down = event.modifiers() & QtCore.Qt.ShiftModifier |
|
483 | shift_down = event.modifiers() & QtCore.Qt.ShiftModifier | |
500 |
|
484 | |||
501 | # Even though we have reimplemented 'paste', the C++ level slot is still |
|
|||
502 | # called by Qt. So we intercept the key press here. |
|
|||
503 | if event.matches(QtGui.QKeySequence.Paste): |
|
485 | if event.matches(QtGui.QKeySequence.Paste): | |
|
486 | # Call our paste instead of the underlying text widget's. | |||
504 | self.paste() |
|
487 | self.paste() | |
505 | intercepted = True |
|
488 | intercepted = True | |
506 |
|
489 | |||
507 | elif ctrl_down: |
|
490 | elif ctrl_down: | |
508 |
if key |
|
491 | if key == QtCore.Qt.Key_K: | |
509 | ctrl_down = False |
|
|||
510 | key = self._ctrl_down_remap[key] |
|
|||
511 | replaced_event = QtGui.QKeyEvent(QtCore.QEvent.KeyPress, key, |
|
|||
512 | QtCore.Qt.NoModifier) |
|
|||
513 |
|
||||
514 | elif key == QtCore.Qt.Key_K: |
|
|||
515 | if self._in_buffer(position): |
|
492 | if self._in_buffer(position): | |
516 | cursor.movePosition(QtGui.QTextCursor.EndOfLine, |
|
493 | cursor.movePosition(QtGui.QTextCursor.EndOfLine, | |
517 | QtGui.QTextCursor.KeepAnchor) |
|
494 | QtGui.QTextCursor.KeepAnchor) | |
@@ -546,10 +523,6 b' class ConsoleWidget(QtGui.QWidget):' | |||||
546 | cursor.removeSelectedText() |
|
523 | cursor.removeSelectedText() | |
547 | intercepted = True |
|
524 | intercepted = True | |
548 |
|
525 | |||
549 | if self._completion_widget.isVisible(): |
|
|||
550 | self._completion_widget.keyPressEvent(event) |
|
|||
551 | intercepted = event.isAccepted() |
|
|||
552 |
|
||||
553 | else: |
|
526 | else: | |
554 | if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter): |
|
527 | if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter): | |
555 | if self._reading: |
|
528 | if self._reading: | |
@@ -621,13 +594,11 b' class ConsoleWidget(QtGui.QWidget):' | |||||
621 | anchor = cursor.anchor() |
|
594 | anchor = cursor.anchor() | |
622 | intercepted = not self._in_buffer(min(anchor, position)) |
|
595 | intercepted = not self._in_buffer(min(anchor, position)) | |
623 |
|
596 | |||
624 | # Don't move cursor if control is down to allow copy-paste using |
|
597 | # Don't move the cursor if control is down to allow copy-paste using | |
625 | # the keyboard in any part of the buffer. |
|
598 | # the keyboard in any part of the buffer. | |
626 | if not ctrl_down: |
|
599 | if not ctrl_down: | |
627 | self._keep_cursor_in_buffer() |
|
600 | self._keep_cursor_in_buffer() | |
628 |
|
601 | |||
629 | if not intercepted and replaced_event: |
|
|||
630 | QtGui.qApp.sendEvent(self._control, replaced_event) |
|
|||
631 | return intercepted |
|
602 | return intercepted | |
632 |
|
603 | |||
633 | def _format_as_columns(self, items, separator=' '): |
|
604 | def _format_as_columns(self, items, separator=' '): | |
@@ -909,6 +880,30 b' class ConsoleWidget(QtGui.QWidget):' | |||||
909 | """ |
|
880 | """ | |
910 | self._control.setTextCursor(self._get_selection_cursor(start, end)) |
|
881 | self._control.setTextCursor(self._get_selection_cursor(start, end)) | |
911 |
|
882 | |||
|
883 | def _show_context_menu(self, pos): | |||
|
884 | """ Shows a context menu at the given QPoint (in widget coordinates). | |||
|
885 | """ | |||
|
886 | menu = QtGui.QMenu() | |||
|
887 | ||||
|
888 | copy_action = QtGui.QAction('Copy', menu) | |||
|
889 | copy_action.triggered.connect(self.copy) | |||
|
890 | copy_action.setEnabled(self._get_cursor().hasSelection()) | |||
|
891 | copy_action.setShortcut(QtGui.QKeySequence.Copy) | |||
|
892 | menu.addAction(copy_action) | |||
|
893 | ||||
|
894 | paste_action = QtGui.QAction('Paste', menu) | |||
|
895 | paste_action.triggered.connect(self.paste) | |||
|
896 | paste_action.setEnabled(self._control.canPaste()) | |||
|
897 | paste_action.setShortcut(QtGui.QKeySequence.Paste) | |||
|
898 | menu.addAction(paste_action) | |||
|
899 | menu.addSeparator() | |||
|
900 | ||||
|
901 | select_all_action = QtGui.QAction('Select All', menu) | |||
|
902 | select_all_action.triggered.connect(self.select_all) | |||
|
903 | menu.addAction(select_all_action) | |||
|
904 | ||||
|
905 | menu.exec_(self._control.mapToGlobal(pos)) | |||
|
906 | ||||
912 | def _show_prompt(self, prompt=None, html=False, newline=True): |
|
907 | def _show_prompt(self, prompt=None, html=False, newline=True): | |
913 | """ Writes a new prompt at the end of the buffer. |
|
908 | """ Writes a new prompt at the end of the buffer. | |
914 |
|
909 |
General Comments 0
You need to be logged in to leave comments.
Login now