##// END OF EJS Templates
* Added "smart copy" support to FrontendWidget and ConsoleWidget. Tabs are expanded and prompts are stripped....
epatters -
Show More
@@ -15,27 +15,6 b' from ansi_code_processor import QtAnsiCodeProcessor'
15 15 from completion_widget import CompletionWidget
16 16
17 17
18 class ConsolePlainTextEdit(QtGui.QPlainTextEdit):
19 """ A QPlainTextEdit suitable for use with ConsoleWidget.
20 """
21 # Prevents text from being moved by drag and drop. Note that is not, for
22 # some reason, sufficient to catch drag events in the ConsoleWidget's
23 # event filter.
24 def dragEnterEvent(self, event): pass
25 def dragLeaveEvent(self, event): pass
26 def dragMoveEvent(self, event): pass
27 def dropEvent(self, event): pass
28
29 class ConsoleTextEdit(QtGui.QTextEdit):
30 """ A QTextEdit suitable for use with ConsoleWidget.
31 """
32 # See above.
33 def dragEnterEvent(self, event): pass
34 def dragLeaveEvent(self, event): pass
35 def dragMoveEvent(self, event): pass
36 def dropEvent(self, event): pass
37
38
39 18 class ConsoleWidget(Configurable, QtGui.QWidget):
40 19 """ An abstract base class for console-type widgets. This class has
41 20 functionality for:
@@ -205,6 +184,11 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
205 184 event.accept()
206 185 return False
207 186
187 # Prevent text from being moved by drag and drop.
188 elif etype in (QtCore.QEvent.DragEnter, QtCore.QEvent.DragLeave,
189 QtCore.QEvent.DragMove, QtCore.QEvent.Drop):
190 return True
191
208 192 return super(ConsoleWidget, self).eventFilter(obj, event)
209 193
210 194 #---------------------------------------------------------------------------
@@ -267,7 +251,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
267 251 self.input_buffer = input_buffer
268 252
269 253 def copy(self):
270 """ Copy the current selected text to the clipboard.
254 """ Copy the currently selected text to the clipboard.
271 255 """
272 256 self._control.copy()
273 257
@@ -667,13 +651,13 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
667 651 """
668 652 # Create the underlying control.
669 653 if self.kind == 'plain':
670 control = ConsolePlainTextEdit()
654 control = QtGui.QPlainTextEdit()
671 655 elif self.kind == 'rich':
672 control = ConsoleTextEdit()
656 control = QtGui.QTextEdit()
673 657 control.setAcceptRichText(False)
674 658
675 659 # Install event filters. The filter on the viewport is needed for
676 # mouse events.
660 # mouse events and drag events.
677 661 control.installEventFilter(self)
678 662 control.viewport().installEventFilter(self)
679 663
@@ -694,7 +678,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
694 678 def _create_page_control(self):
695 679 """ Creates and connects the underlying paging widget.
696 680 """
697 control = ConsolePlainTextEdit()
681 control = QtGui.QPlainTextEdit()
698 682 control.installEventFilter(self)
699 683 control.setReadOnly(True)
700 684 control.setUndoRedoEnabled(False)
@@ -713,8 +697,11 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
713 697 alt_down = event.modifiers() & QtCore.Qt.AltModifier
714 698 shift_down = event.modifiers() & QtCore.Qt.ShiftModifier
715 699
716 if event.matches(QtGui.QKeySequence.Paste):
717 # Call our paste instead of the underlying text widget's.
700 if event.matches(QtGui.QKeySequence.Copy):
701 self.copy()
702 intercepted = True
703
704 elif event.matches(QtGui.QKeySequence.Paste):
718 705 self.paste()
719 706 intercepted = True
720 707
@@ -8,7 +8,7 b' from pygments.lexers import PythonLexer'
8 8 from PyQt4 import QtCore, QtGui
9 9
10 10 # Local imports
11 from IPython.core.inputsplitter import InputSplitter
11 from IPython.core.inputsplitter import InputSplitter, transform_classic_prompt
12 12 from IPython.frontend.qt.base_frontend_mixin import BaseFrontendMixin
13 13 from IPython.utils.io import raw_print
14 14 from IPython.utils.traitlets import Bool
@@ -127,6 +127,21 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
127 127 document.contentsChange.connect(self._document_contents_change)
128 128
129 129 #---------------------------------------------------------------------------
130 # 'ConsoleWidget' public interface
131 #---------------------------------------------------------------------------
132
133 def copy(self):
134 """ Copy the currently selected text to the clipboard, removing prompts.
135 """
136 text = str(self._control.textCursor().selection().toPlainText())
137 if text:
138 # Remove prompts.
139 lines = map(transform_classic_prompt, text.splitlines())
140 text = '\n'.join(lines)
141 # Expand tabs so that we respect PEP-8.
142 QtGui.QApplication.clipboard().setText(text.expandtabs(4))
143
144 #---------------------------------------------------------------------------
130 145 # 'ConsoleWidget' abstract interface
131 146 #---------------------------------------------------------------------------
132 147
@@ -306,7 +321,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
306 321 self._highlighter.highlighting_on = False
307 322
308 323 #---------------------------------------------------------------------------
309 # 'FrontendWidget' interface
324 # 'FrontendWidget' public interface
310 325 #---------------------------------------------------------------------------
311 326
312 327 def execute_file(self, path, hidden=False):
@@ -19,7 +19,8 b' from subprocess import Popen'
19 19 from PyQt4 import QtCore, QtGui
20 20
21 21 # Local imports
22 from IPython.core.inputsplitter import IPythonInputSplitter
22 from IPython.core.inputsplitter import IPythonInputSplitter, \
23 transform_ipy_prompt
23 24 from IPython.core.usage import default_banner
24 25 from IPython.utils.traitlets import Bool, Str
25 26 from frontend_widget import FrontendWidget
@@ -198,7 +199,23 b' class IPythonWidget(FrontendWidget):'
198 199 #self.kernel_manager.xreq_channel.history(raw=True, output=False)
199 200
200 201 #---------------------------------------------------------------------------
201 # 'FrontendWidget' interface
202 # 'ConsoleWidget' public interface
203 #---------------------------------------------------------------------------
204
205 def copy(self):
206 """ Copy the currently selected text to the clipboard, removing prompts
207 if possible.
208 """
209 text = str(self._control.textCursor().selection().toPlainText())
210 if text:
211 # Remove prompts.
212 lines = map(transform_ipy_prompt, text.splitlines())
213 text = '\n'.join(lines)
214 # Expand tabs so that we respect PEP-8.
215 QtGui.QApplication.clipboard().setText(text.expandtabs(4))
216
217 #---------------------------------------------------------------------------
218 # 'FrontendWidget' public interface
202 219 #---------------------------------------------------------------------------
203 220
204 221 def execute_file(self, path, hidden=False):
General Comments 0
You need to be logged in to leave comments. Login now