/IPython/frontend/qt/console/completion_widget.py
https://github.com/yarikoptic/ipython01x · Python · 134 lines · 93 code · 18 blank · 23 comment · 6 complexity · 378690ca7cea888d5d163a5728a7ecd9 MD5 · raw file
- # System library imports
- from IPython.external.qt import QtCore, QtGui
- class CompletionWidget(QtGui.QListWidget):
- """ A widget for GUI tab completion.
- """
- #--------------------------------------------------------------------------
- # 'QObject' interface
- #--------------------------------------------------------------------------
- def __init__(self, text_edit):
- """ Create a completion widget that is attached to the specified Qt
- text edit widget.
- """
- assert isinstance(text_edit, (QtGui.QTextEdit, QtGui.QPlainTextEdit))
- super(CompletionWidget, self).__init__()
- self._text_edit = text_edit
- self.setAttribute(QtCore.Qt.WA_StaticContents)
- self.setWindowFlags(QtCore.Qt.ToolTip | QtCore.Qt.WindowStaysOnTopHint)
- # Ensure that the text edit keeps focus when widget is displayed.
- self.setFocusProxy(self._text_edit)
- self.setFrameShadow(QtGui.QFrame.Plain)
- self.setFrameShape(QtGui.QFrame.StyledPanel)
- self.itemActivated.connect(self._complete_current)
- def eventFilter(self, obj, event):
- """ Reimplemented to handle keyboard input and to auto-hide when the
- text edit loses focus.
- """
- if obj == self._text_edit:
- etype = event.type()
- if etype == QtCore.QEvent.KeyPress:
- key, text = event.key(), event.text()
- if key in (QtCore.Qt.Key_Return, QtCore.Qt.Key_Enter,
- QtCore.Qt.Key_Tab):
- self._complete_current()
- return True
- elif key == QtCore.Qt.Key_Escape:
- self.hide()
- return True
- elif key in (QtCore.Qt.Key_Up, QtCore.Qt.Key_Down,
- QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown,
- QtCore.Qt.Key_Home, QtCore.Qt.Key_End):
- self.keyPressEvent(event)
- return True
- elif etype == QtCore.QEvent.FocusOut:
- self.hide()
- return super(CompletionWidget, self).eventFilter(obj, event)
- #--------------------------------------------------------------------------
- # 'QWidget' interface
- #--------------------------------------------------------------------------
- def hideEvent(self, event):
- """ Reimplemented to disconnect signal handlers and event filter.
- """
- super(CompletionWidget, self).hideEvent(event)
- self._text_edit.cursorPositionChanged.disconnect(self._update_current)
- self._text_edit.removeEventFilter(self)
- def showEvent(self, event):
- """ Reimplemented to connect signal handlers and event filter.
- """
- super(CompletionWidget, self).showEvent(event)
- self._text_edit.cursorPositionChanged.connect(self._update_current)
- self._text_edit.installEventFilter(self)
- #--------------------------------------------------------------------------
- # 'CompletionWidget' interface
- #--------------------------------------------------------------------------
- def show_items(self, cursor, items):
- """ Shows the completion widget with 'items' at the position specified
- by 'cursor'.
- """
- text_edit = self._text_edit
- point = text_edit.cursorRect(cursor).bottomRight()
- point = text_edit.mapToGlobal(point)
- height = self.sizeHint().height()
- screen_rect = QtGui.QApplication.desktop().availableGeometry(self)
- if screen_rect.size().height() - point.y() - height < 0:
- point = text_edit.mapToGlobal(text_edit.cursorRect().topRight())
- point.setY(point.y() - height)
- self.move(point)
- self._start_position = cursor.position()
- self.clear()
- self.addItems(items)
- self.setCurrentRow(0)
- self.show()
- #--------------------------------------------------------------------------
- # Protected interface
- #--------------------------------------------------------------------------
- def _complete_current(self):
- """ Perform the completion with the currently selected item.
- """
- self._current_text_cursor().insertText(self.currentItem().text())
- self.hide()
- def _current_text_cursor(self):
- """ Returns a cursor with text between the start position and the
- current position selected.
- """
- cursor = self._text_edit.textCursor()
- if cursor.position() >= self._start_position:
- cursor.setPosition(self._start_position,
- QtGui.QTextCursor.KeepAnchor)
- return cursor
- def _update_current(self):
- """ Updates the current item based on the current text.
- """
- prefix = self._current_text_cursor().selection().toPlainText()
- if prefix:
- items = self.findItems(prefix, (QtCore.Qt.MatchStartsWith |
- QtCore.Qt.MatchCaseSensitive))
- if items:
- self.setCurrentItem(items[0])
- else:
- self.hide()
- else:
- self.hide()