##// 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 from completion_widget import CompletionWidget
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 class ConsoleWidget(Configurable, QtGui.QWidget):
18 class ConsoleWidget(Configurable, QtGui.QWidget):
40 """ An abstract base class for console-type widgets. This class has
19 """ An abstract base class for console-type widgets. This class has
41 functionality for:
20 functionality for:
@@ -205,6 +184,11 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
205 event.accept()
184 event.accept()
206 return False
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 return super(ConsoleWidget, self).eventFilter(obj, event)
192 return super(ConsoleWidget, self).eventFilter(obj, event)
209
193
210 #---------------------------------------------------------------------------
194 #---------------------------------------------------------------------------
@@ -267,7 +251,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
267 self.input_buffer = input_buffer
251 self.input_buffer = input_buffer
268
252
269 def copy(self):
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 self._control.copy()
256 self._control.copy()
273
257
@@ -667,13 +651,13 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
667 """
651 """
668 # Create the underlying control.
652 # Create the underlying control.
669 if self.kind == 'plain':
653 if self.kind == 'plain':
670 control = ConsolePlainTextEdit()
654 control = QtGui.QPlainTextEdit()
671 elif self.kind == 'rich':
655 elif self.kind == 'rich':
672 control = ConsoleTextEdit()
656 control = QtGui.QTextEdit()
673 control.setAcceptRichText(False)
657 control.setAcceptRichText(False)
674
658
675 # Install event filters. The filter on the viewport is needed for
659 # Install event filters. The filter on the viewport is needed for
676 # mouse events.
660 # mouse events and drag events.
677 control.installEventFilter(self)
661 control.installEventFilter(self)
678 control.viewport().installEventFilter(self)
662 control.viewport().installEventFilter(self)
679
663
@@ -694,7 +678,7 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
694 def _create_page_control(self):
678 def _create_page_control(self):
695 """ Creates and connects the underlying paging widget.
679 """ Creates and connects the underlying paging widget.
696 """
680 """
697 control = ConsolePlainTextEdit()
681 control = QtGui.QPlainTextEdit()
698 control.installEventFilter(self)
682 control.installEventFilter(self)
699 control.setReadOnly(True)
683 control.setReadOnly(True)
700 control.setUndoRedoEnabled(False)
684 control.setUndoRedoEnabled(False)
@@ -713,8 +697,11 b' class ConsoleWidget(Configurable, QtGui.QWidget):'
713 alt_down = event.modifiers() & QtCore.Qt.AltModifier
697 alt_down = event.modifiers() & QtCore.Qt.AltModifier
714 shift_down = event.modifiers() & QtCore.Qt.ShiftModifier
698 shift_down = event.modifiers() & QtCore.Qt.ShiftModifier
715
699
716 if event.matches(QtGui.QKeySequence.Paste):
700 if event.matches(QtGui.QKeySequence.Copy):
717 # Call our paste instead of the underlying text widget's.
701 self.copy()
702 intercepted = True
703
704 elif event.matches(QtGui.QKeySequence.Paste):
718 self.paste()
705 self.paste()
719 intercepted = True
706 intercepted = True
720
707
@@ -8,7 +8,7 b' from pygments.lexers import PythonLexer'
8 from PyQt4 import QtCore, QtGui
8 from PyQt4 import QtCore, QtGui
9
9
10 # Local imports
10 # Local imports
11 from IPython.core.inputsplitter import InputSplitter
11 from IPython.core.inputsplitter import InputSplitter, transform_classic_prompt
12 from IPython.frontend.qt.base_frontend_mixin import BaseFrontendMixin
12 from IPython.frontend.qt.base_frontend_mixin import BaseFrontendMixin
13 from IPython.utils.io import raw_print
13 from IPython.utils.io import raw_print
14 from IPython.utils.traitlets import Bool
14 from IPython.utils.traitlets import Bool
@@ -127,6 +127,21 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
127 document.contentsChange.connect(self._document_contents_change)
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 # 'ConsoleWidget' abstract interface
145 # 'ConsoleWidget' abstract interface
131 #---------------------------------------------------------------------------
146 #---------------------------------------------------------------------------
132
147
@@ -306,7 +321,7 b' class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin):'
306 self._highlighter.highlighting_on = False
321 self._highlighter.highlighting_on = False
307
322
308 #---------------------------------------------------------------------------
323 #---------------------------------------------------------------------------
309 # 'FrontendWidget' interface
324 # 'FrontendWidget' public interface
310 #---------------------------------------------------------------------------
325 #---------------------------------------------------------------------------
311
326
312 def execute_file(self, path, hidden=False):
327 def execute_file(self, path, hidden=False):
@@ -19,7 +19,8 b' from subprocess import Popen'
19 from PyQt4 import QtCore, QtGui
19 from PyQt4 import QtCore, QtGui
20
20
21 # Local imports
21 # Local imports
22 from IPython.core.inputsplitter import IPythonInputSplitter
22 from IPython.core.inputsplitter import IPythonInputSplitter, \
23 transform_ipy_prompt
23 from IPython.core.usage import default_banner
24 from IPython.core.usage import default_banner
24 from IPython.utils.traitlets import Bool, Str
25 from IPython.utils.traitlets import Bool, Str
25 from frontend_widget import FrontendWidget
26 from frontend_widget import FrontendWidget
@@ -198,7 +199,23 b' class IPythonWidget(FrontendWidget):'
198 #self.kernel_manager.xreq_channel.history(raw=True, output=False)
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 def execute_file(self, path, hidden=False):
221 def execute_file(self, path, hidden=False):
General Comments 0
You need to be logged in to leave comments. Login now