cadquery-freecad-module/Libs/pyqode/core/modes/wordclick.py

125 lines
4.7 KiB
Python

# -*- coding: utf-8 -*-
"""
This module contains the WordClickMode
"""
from pyqode.core.api.decoration import TextDecoration
from pyqode.core.api.mode import Mode
from pyqode.qt import QtCore, QtGui
from pyqode.core.api import TextHelper, DelayJobRunner
class WordClickMode(Mode, QtCore.QObject):
""" Adds support for word click events.
It will highlight the click-able word when the user press control and move
the mouse over a word.
Detecting whether a word is click-able is the responsability of the
subclasses. You must override ``_check_word_cursor`` and call
``_select_word_cursor`` if this is a click-able word (this
process might be asynchrone) otherwise _clear_selection.
:attr:`pyqode.core.modes.WordClickMode.word_clicked` is emitted
when the word is clicked by the user (while keeping control pressed).
"""
#: Signal emitted when a word is clicked. The parameter is a
#: QTextCursor with the clicked word set as the selected text.
word_clicked = QtCore.Signal(QtGui.QTextCursor)
def __init__(self):
QtCore.QObject.__init__(self)
Mode.__init__(self)
self._previous_cursor_start = -1
self._previous_cursor_end = -1
self._deco = None
self._cursor = None
self._timer = DelayJobRunner(delay=200)
def on_state_changed(self, state):
if state:
self.editor.mouse_moved.connect(self._on_mouse_moved)
self.editor.mouse_pressed.connect(self._on_mouse_pressed)
self.editor.key_released.connect(self._on_key_released)
self.editor.mouse_double_clicked.connect(
self._on_mouse_double_clicked)
else:
self.editor.mouse_moved.disconnect(self._on_mouse_moved)
self.editor.mouse_pressed.disconnect(self._on_mouse_pressed)
self.editor.mouse_double_clicked.disconnect(
self._on_mouse_double_clicked)
def _on_mouse_double_clicked(self):
self._timer.cancel_requests()
def _on_key_released(self, event):
if event.key() == QtCore.Qt.Key_Control:
self._clear_selection()
self._cursor = None
def _select_word_cursor(self):
""" Selects the word under the mouse cursor. """
cursor = TextHelper(self.editor).word_under_mouse_cursor()
if (self._previous_cursor_start != cursor.selectionStart() and
self._previous_cursor_end != cursor.selectionEnd()):
self._remove_decoration()
self._add_decoration(cursor)
self._previous_cursor_start = cursor.selectionStart()
self._previous_cursor_end = cursor.selectionEnd()
def _clear_selection(self):
try:
self._remove_decoration()
except ValueError:
pass
self.editor.set_mouse_cursor(QtCore.Qt.IBeamCursor)
self._previous_cursor_start = -1
self._previous_cursor_end = -1
def _on_mouse_moved(self, event):
""" mouse moved callback """
if event.modifiers() & QtCore.Qt.ControlModifier:
cursor = TextHelper(self.editor).word_under_mouse_cursor()
if (not self._cursor or
cursor.position() != self._cursor.position()):
self._check_word_cursor(cursor)
self._cursor = cursor
else:
self._cursor = None
self._clear_selection()
def _check_word_under_mouse_cursor(self, cursor):
raise NotImplementedError()
def _on_mouse_pressed(self, event):
""" mouse pressed callback """
if event.button() == 1 and self._deco:
cursor = TextHelper(self.editor).word_under_mouse_cursor()
if cursor and cursor.selectedText():
self._timer.request_job(
self.word_clicked.emit, cursor)
def _add_decoration(self, cursor):
"""
Adds a decoration for the word under ``cursor``.
"""
if self._deco is None:
if cursor.selectedText():
self._deco = TextDecoration(cursor)
if self.editor.background.lightness() < 128:
self._deco.set_foreground(QtGui.QColor('#0681e0'))
else:
self._deco.set_foreground(QtCore.Qt.blue)
self._deco.set_as_underlined()
self.editor.decorations.append(self._deco)
self.editor.set_mouse_cursor(QtCore.Qt.PointingHandCursor)
else:
self.editor.set_mouse_cursor(QtCore.Qt.IBeamCursor)
def _remove_decoration(self):
"""
Removes the word under cursor's decoration
"""
if self._deco is not None:
self.editor.decorations.remove(self._deco)
self._deco = None