Skip to content

Commit

Permalink
Refactor drag and drop support to explicitly use drag and drop events.
Browse files Browse the repository at this point in the history
Removes event filter code which was previously used to ensure that text
outside of the current cell could not be removed via drag and drop.
  • Loading branch information
bfroehle committed Oct 25, 2012
1 parent 3d4dc71 commit f5cbf8b
Showing 1 changed file with 35 additions and 35 deletions.
70 changes: 35 additions & 35 deletions IPython/frontend/qt/console/console_widget.py
Expand Up @@ -268,7 +268,6 @@ def __init__(self, parent=None, **kw):
self._continuation_prompt = '> '
self._continuation_prompt_html = None
self._executing = False
self._filter_drag = False
self._filter_resize = False
self._html_exporter = HtmlExporter(self._control)
self._input_buffer_executing = ''
Expand Down Expand Up @@ -343,7 +342,37 @@ def __init__(self, parent=None, **kw):
triggered=self.reset_font)
self.addAction(self.reset_font_size)

# Accept drag and drop events here. Drops were already turned off
# in self._control when that widget was created.
self.setAcceptDrops(True)

#---------------------------------------------------------------------------
# Drag and drop support
#---------------------------------------------------------------------------

def dragEnterEvent(self, e):
if e.mimeData().hasText():
# By changing the action to copy we don't need to worry about
# the user accidentally moving text around in the widget.
e.setDropAction(QtCore.Qt.CopyAction)
e.accept()

def dragMoveEvent(self, e):
if e.mimeData().hasText():
cursor = self._control.cursorForPosition(e.pos())
if self._in_buffer(cursor.position()):
e.setDropAction(QtCore.Qt.CopyAction)
self._control.setTextCursor(cursor)
else:
e.setDropAction(QtCore.Qt.IgnoreAction)
e.accept()

def dropEvent(self, e):
if e.mimeData().hasText():
cursor = self._control.cursorForPosition(e.pos())
if self._in_buffer(cursor.position()):
text = e.mimeData().text()
self._insert_plain_text_into_buffer(cursor, text)

def eventFilter(self, obj, event):
""" Reimplemented to ensure a console-like behavior in the underlying
Expand Down Expand Up @@ -392,39 +421,6 @@ def eventFilter(self, obj, event):
event.key() in self._shortcuts:
event.accept()

# Ensure that drags are safe. The problem is that the drag starting
# logic, which determines whether the drag is a Copy or Move, is locked
# down in QTextControl. If the widget is editable, which it must be if
# we're not executing, the drag will be a Move. The following hack
# prevents QTextControl from deleting the text by clearing the selection
# when a drag leave event originating from this widget is dispatched.
# The fact that we have to clear the user's selection is unfortunate,
# but the alternative--trying to prevent Qt from using its hardwired
# drag logic and writing our own--is worse.
elif etype == QtCore.QEvent.DragEnter and \
obj == self._control.viewport() and \
event.source() == self._control.viewport():
self._filter_drag = True
elif etype == QtCore.QEvent.DragLeave and \
obj == self._control.viewport() and \
self._filter_drag:
cursor = self._control.textCursor()
cursor.clearSelection()
self._control.setTextCursor(cursor)
self._filter_drag = False

# Ensure that drops are safe.
elif etype == QtCore.QEvent.Drop and obj == self._control.viewport():
cursor = self._control.cursorForPosition(event.pos())
if self._in_buffer(cursor.position()):
text = event.mimeData().text()
self._insert_plain_text_into_buffer(cursor, text)

# Qt is expecting to get something here--drag and drop occurs in its
# own event loop. Send a DragLeave event to end it.
QtGui.qApp.sendEvent(obj, QtGui.QDragLeaveEvent())
return True

# Handle scrolling of the vsplit pager. This hack attempts to solve
# problems with tearing of the help text inside the pager window. This
# happens only on Mac OS X with both PySide and PyQt. This fix isn't
Expand Down Expand Up @@ -1035,8 +1031,12 @@ def _create_control(self):
control.setAcceptRichText(False)
control.setMouseTracking(True)

# Prevent the widget from handling drops, as we already provide
# the logic in this class.
control.setAcceptDrops(False)

# Install event filters. The filter on the viewport is needed for
# mouse events and drag events.
# mouse events.
control.installEventFilter(self)
control.viewport().installEventFilter(self)

Expand Down

0 comments on commit f5cbf8b

Please sign in to comment.