Esempio n. 1
0
 def show(self):
     super(EncodingPanel, self).show()
     self.editor.selectAll()
     self._deco = TextDecoration(self.editor.textCursor())
     self._deco.set_background(QtCore.Qt.red)
     self._deco.set_foreground(QtCore.Qt.black)
     self.editor.decorations.append(self._deco)
     cursor = self.editor.textCursor()
     cursor.clearSelection()
     cursor.setPosition(0)
     self.editor.setTextCursor(cursor)
     self.editor.setReadOnly(True)
Esempio n. 2
0
 def _create_decoration(self, selection_start, selection_end):
     """ Creates the text occurences decoration """
     deco = TextDecoration(self.editor.document(), selection_start,
                           selection_end)
     deco.set_background(QtGui.QBrush(self.background))
     deco.set_outline(self._outline)
     deco.set_foreground(QtCore.Qt.black)
     deco.draw_order = 1
     return deco
Esempio n. 3
0
 def refresh(self):
     """
     Updates the current line decoration
     """
     if self.enabled and self.line:
         self._clear_deco()
         brush = QtGui.QBrush(self._color)
         self._decoration = TextDecoration(self.editor.textCursor(),
                                           start_line=self.line)
         self._decoration.set_background(brush)
         self._decoration.set_full_width()
         self._decoration.draw_order = 255
         self.editor.decorations.append(self._decoration)
Esempio n. 4
0
 def _create_decoration(self, selection_start, selection_end):
     """ Creates the text occurences decoration """
     deco = TextDecoration(self.editor.document(), selection_start, selection_end)
     deco.set_background(QtGui.QBrush(self.background))
     deco.set_outline(self._outline)
     deco.set_foreground(QtCore.Qt.black)
     deco.draw_order = 1
     return deco
Esempio n. 5
0
 def refresh(self):
     """
     Updates the current line decoration
     """
     if self.enabled:
         self._clear_deco()
         if self._color:
             color = self._color
         else:
             color = drift_color(self.editor.background, 110)
         brush = QtGui.QBrush(color)
         self._decoration = TextDecoration(self.editor.textCursor())
         self._decoration.set_background(brush)
         self._decoration.set_full_width()
         self.editor.decorations.append(self._decoration)
Esempio n. 6
0
 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)
Esempio n. 7
0
 def show(self):
     super(EncodingPanel, self).show()
     self.editor.selectAll()
     self._deco = TextDecoration(self.editor.textCursor())
     self._deco.set_background(QtCore.Qt.red)
     self._deco.set_foreground(QtCore.Qt.black)
     self.editor.decorations.append(self._deco)
     cursor = self.editor.textCursor()
     cursor.clearSelection()
     cursor.setPosition(0)
     self.editor.setTextCursor(cursor)
     self.editor.setReadOnly(True)
 def refresh(self):
     """
     Updates the current line decoration
     """
     if self.enabled and self.line:
         self._clear_deco()
         brush = QtGui.QBrush(self._color)
         self._decoration = TextDecoration(
             self.editor.textCursor(), start_line=self.line)
         self._decoration.set_background(brush)
         self._decoration.set_full_width()
         self._decoration.draw_order = 255
         self.editor.decorations.append(self._decoration)
Esempio n. 9
0
 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)
Esempio n. 10
0
 def _add_batch(self):
     if self.editor is None:
         return
     for i in range(10):
         if not len(self._pending_msg):
             # all pending message added
             self._finished = True
             _logger(self.__class__).log(5, 'finished')
             self.editor.repaint()
             return False
         message = self._pending_msg.pop(0)
         if message.line >= 0:
             try:
                 usd = message.block.userData()
             except AttributeError:
                 message.block = self.editor.document().findBlockByNumber(
                     message.line)
                 usd = message.block.userData()
             if usd is None:
                 usd = TextBlockUserData()
                 message.block.setUserData(usd)
             # check if the same message already exists
             if message in usd.messages:
                 continue
             self._messages.append(message)
             usd.messages.append(message)
             tooltip = None
             if self._show_tooltip:
                 tooltip = message.description
             message.decoration = TextDecoration(self.editor.textCursor(),
                                                 start_line=message.line,
                                                 tooltip=tooltip,
                                                 draw_order=3)
             message.decoration.set_full_width()
             message.decoration.set_as_error(
                 color=QtGui.QColor(message.color))
             self.editor.decorations.append(message.decoration)
     QtCore.QTimer.singleShot(1, self._add_batch)
     self.editor.repaint()
     return True
Esempio n. 11
0
class EncodingPanel(Panel):
    """ Displays a warning when an encoding error occured and let you reload.

    This panel display a warning in case encoding/decoding error and
    give the user the possibility to try out another encoding, to edit any way
    or to close the editor.

    The panel is automatically shown by
    :class:`pyqode.core.managers.FileManager` in case of error so that you
    don't have to worry about encoding issues. The only think you might do
    is to provide to your user a way to specify the default encoding, i.e. the
    one that is tried before showing this panel.

    The panel is a simple widget with a label describing the error, an encoding
    menu and 3 buttons: ``Retry``, ``Edit`` anyway and ``Cancel``. It is
    strongly inspired by the GEdit encoding panel.

    You can change the background color and the label foreground color by
    setting up the ``color`` and ``foreground`` properties.

    It's up to the client code to handle cancel requests. To do that simply
    connect ``cancel_requested`` signal to remove the editor from your
    application.

    """
    #: Signal emitted when the user pressed on cancel. It is up to the client
    #: code to handle this event.
    cancel_requested = QtCore.Signal(object)

    _description = ('<html><head/><body><p><span style=" font-weight:600;">%s'
                    '</span></p><p><span style=" font-size:9pt;">'
                    'The file you opened has some invalid characters. '
                    'If you continue editing this file you could corrupt this '
                    'document. You can also choose another character encoding '
                    'and try again.</span></p></body></html>')

    @property
    def color(self):
        """
        Returns the panel color.
        """
        return self._color

    @color.setter
    def color(self, value):
        self._color = value
        self._refresh_stylesheet()
        if self.editor:
            # propagate changes to every clone
            for clone in self.editor.clones:
                try:
                    clone.modes.get(self.__class__).color = value
                except KeyError:
                    # this should never happen since we're working with clones
                    pass

    @property
    def foreground(self):
        return self._foreground

    @foreground.setter
    def foreground(self, value):
        self._foreground = value
        self._refresh_stylesheet()
        # propagate changes to every clone
        if self.editor:
            for clone in self.editor.clones:
                try:
                    clone.modes.get(self.__class__).foreground = value
                except KeyError:
                    # this should never happen since we're working with clones
                    pass

    def _refresh_stylesheet(self):
        try:
            self._lbl_stylesheet = (
                'color: %s;background: %s' %
                (self._foreground.name(), self._color.name()))
            for lbl in self._labels:
                lbl.setStyleSheet(self._lbl_stylesheet)
        except AttributeError:
            pass

    def __init__(self, add_context_menu=True):
        super(EncodingPanel, self).__init__(dynamic=True)
        # leave it here otherwise you will have circular import errors
        from pyqode.core._forms.pnl_encoding_ui import Ui_Form
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.__add_ctx_mnu = add_context_menu
        self._labels = [self.ui.label, self.ui.lblDescription]
        self._color = None
        self.color = QtGui.QColor('#8AADD4')
        self._foreground = None
        self.foreground = QtGui.QColor('#FFFFFF')
        self._deco = None
        self.ui.pushButtonRetry.clicked.connect(self._reload)
        self.ui.pushButtonEdit.clicked.connect(self._edit_anyway)
        self.ui.pushButtonCancel.clicked.connect(self.cancel)
        self.hide()

    def enable_caret_line(self, value=True):
        try:
            from pyqode.core.modes import CaretLineHighlighterMode

            mode = self.editor.modes.get(CaretLineHighlighterMode)
        except KeyError:
            pass
        else:
            mode.enabled = value

    def on_open_failed(self, path, encoding):
        self.enable_caret_line(False)
        self.ui.comboBoxEncodings.current_encoding = encoding
        self.ui.lblDescription.setText(
            self._description %
            (_('There was a problem opening the file %r') % path))
        # load text as binary and mark it as red, user might make use the
        # binary to recognize the original encoding
        try:
            with open(path, 'rb') as file:
                content = str(file.read(16))
        except OSError:
            content = ''
        # set plain text
        self.editor.setPlainText(content, self.editor.file.get_mimetype(path),
                                 self.editor.file.encoding)
        self.editor.setDocumentTitle(self.editor.file.name)
        self.editor.setWindowTitle(self.editor.file.name)

        # Delay because the editor might not have been shown yet
        QtCore.QTimer.singleShot(1, self.show)

    def on_save_failed(self, path, encoding):
        pass

    def show(self):
        super(EncodingPanel, self).show()
        self.editor.selectAll()
        self._deco = TextDecoration(self.editor.textCursor())
        self._deco.set_background(QtCore.Qt.red)
        self._deco.set_foreground(QtCore.Qt.black)
        self.editor.decorations.append(self._deco)
        cursor = self.editor.textCursor()
        cursor.clearSelection()
        cursor.setPosition(0)
        self.editor.setTextCursor(cursor)
        self.editor.setReadOnly(True)

    def paintEvent(self, event):
        """ Fills the panel background. """
        super(EncodingPanel, self).paintEvent(event)
        if self.isVisible():
            # fill background
            painter = QtGui.QPainter(self)
            self._background_brush = QtGui.QBrush(self._color)
            painter.fillRect(event.rect(), self._background_brush)

    def on_install(self, editor):
        super(EncodingPanel, self).on_install(editor)
        if self.__add_ctx_mnu:
            # add context menu
            from pyqode.core.widgets import EncodingsContextMenu
            EncodingsContextMenu(parent=editor)

    def _reload(self):
        self.hide()
        self._rm_deco()
        self.editor.setReadOnly(False)
        self.enable_caret_line(True)
        self.editor.file.reload(self.ui.comboBoxEncodings.current_encoding)

    def _edit_anyway(self):
        self._rm_deco()
        self.editor.setReadOnly(False)
        self.enable_caret_line(True)
        self.hide()

    def _rm_deco(self):
        if self._deco:
            self.editor.decorations.remove(self._deco)
            self._deco = None

    def cancel(self):
        if self.sender():
            self.editor.clear()
        self.close_panel()

    def close_panel(self):
        self._rm_deco()
        self.enable_caret_line(True)
        self.cancel_requested.emit(self.editor)
        self.hide()

    def clone_settings(self, original):
        self.color = original.color
        self.foreground = original.foreground
Esempio n. 12
0
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.key_released.disconnect(self._on_key_released)
            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_cursor(self, cursor):
        pass

    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
Esempio n. 13
0
 def _create_decoration(self, pos, match=True):
     cursor = self.editor.textCursor()
     cursor.setPosition(pos)
     cursor.movePosition(cursor.NextCharacter, cursor.KeepAnchor)
     deco = TextDecoration(cursor, draw_order=10)
     deco.line = cursor.blockNumber()
     deco.column = cursor.columnNumber()
     deco.character = cursor.selectedText()
     deco.match = match
     if match:
         deco.set_foreground(self._match_foreground)
         deco.set_background(self._match_background)
     else:
         deco.set_foreground(self._unmatch_foreground)
         deco.set_background(self._unmatch_background)
     self._decorations.append(deco)
     self.editor.decorations.append(deco)
     return cursor
Esempio n. 14
0
class EncodingPanel(Panel):
    """ Displays a warning when an encoding error occured and let you reload.

    This panel display a warning in case encoding/decoding error and
    give the user the possibility to try out another encoding, to edit any way
    or to close the editor.

    The panel is automatically shown by
    :class:`pyqode.core.managers.FileManager` in case of error so that you
    don't have to worry about encoding issues. The only think you might do
    is to provide to your user a way to specify the default encoding, i.e. the
    one that is tried before showing this panel.

    The panel is a simple widget with a label describing the error, an encoding
    menu and 3 buttons: ``Retry``, ``Edit`` anyway and ``Cancel``. It is
    strongly inspired by the GEdit encoding panel.

    You can change the background color and the label foreground color by
    setting up the ``color`` and ``foreground`` properties.

    It's up to the client code to handle cancel requests. To do that simply
    connect ``cancel_requested`` signal to remove the editor from your
    application.

    """
    #: Signal emitted when the user pressed on cancel. It is up to the client
    #: code to handle this event.
    cancel_requested = QtCore.Signal(object)

    _description = ('<html><head/><body><p><span style=" font-weight:600;">%s'
                    '</span></p><p><span style=" font-size:9pt;">'
                    'The file you opened has some invalid characters. '
                    'If you continue editing this file you could corrupt this '
                    'document. You can also choose another character encoding '
                    'and try again.</span></p></body></html>')

    @property
    def color(self):
        """
        Returns the panel color.
        """
        return self._color

    @color.setter
    def color(self, value):
        self._color = value
        self._refresh_stylesheet()
        if self.editor:
            # propagate changes to every clone
            for clone in self.editor.clones:
                try:
                    clone.modes.get(self.__class__).color = value
                except KeyError:
                    # this should never happen since we're working with clones
                    pass

    @property
    def foreground(self):
        return self._foreground

    @foreground.setter
    def foreground(self, value):
        self._foreground = value
        self._refresh_stylesheet()
        # propagate changes to every clone
        if self.editor:
            for clone in self.editor.clones:
                try:
                    clone.modes.get(self.__class__).foreground = value
                except KeyError:
                    # this should never happen since we're working with clones
                    pass

    def _refresh_stylesheet(self):
        try:
            self._lbl_stylesheet = ('color: %s;background: %s' %
                                    (self._foreground.name(),
                                     self._color.name()))
            for lbl in self._labels:
                lbl.setStyleSheet(self._lbl_stylesheet)
        except AttributeError:
            pass

    def __init__(self, add_context_menu=True):
        super(EncodingPanel, self).__init__(dynamic=True)
        # leave it here otherwise you will have circular import errors
        from pyqode.core._forms.pnl_encoding_ui import Ui_Form
        self.ui = Ui_Form()
        self.ui.setupUi(self)
        self.__add_ctx_mnu = add_context_menu
        self._labels = [self.ui.label, self.ui.lblDescription]
        self._color = None
        self.color = QtGui.QColor('#8AADD4')
        self._foreground = None
        self.foreground = QtGui.QColor('#FFFFFF')
        self._deco = None
        self.ui.pushButtonRetry.clicked.connect(self._reload)
        self.ui.pushButtonEdit.clicked.connect(self._edit_anyway)
        self.ui.pushButtonCancel.clicked.connect(self.cancel)
        self.hide()

    def enable_caret_line(self, value=True):
        try:
            from pyqode.core.modes import CaretLineHighlighterMode

            mode = self.editor.modes.get(CaretLineHighlighterMode)
        except KeyError:
            pass
        else:
            mode.enabled = value

    def on_open_failed(self, path, encoding):
        self.enable_caret_line(False)
        self.ui.comboBoxEncodings.current_encoding = encoding
        self.ui.lblDescription.setText(
            self._description % (_('There was a problem opening the file %r') %
                                 path))
        # load text as binary and mark it as red, user might make use the
        # binary to recognize the original encoding
        with open(path, 'rb') as file:
            content = str(file.read(16))
        # set plain text
        self.editor.setPlainText(
            content, self.editor.file.get_mimetype(path),
            self.editor.file.encoding)
        self.editor.setDocumentTitle(self.editor.file.name)
        self.editor.setWindowTitle(self.editor.file.name)

        # Delay because the editor might not have been shown yet
        QtCore.QTimer.singleShot(1, self.show)

    def show(self):
        super(EncodingPanel, self).show()
        self.editor.selectAll()
        self._deco = TextDecoration(self.editor.textCursor())
        self._deco.set_background(QtCore.Qt.red)
        self._deco.set_foreground(QtCore.Qt.black)
        self.editor.decorations.append(self._deco)
        cursor = self.editor.textCursor()
        cursor.clearSelection()
        cursor.setPosition(0)
        self.editor.setTextCursor(cursor)
        self.editor.setReadOnly(True)

    def paintEvent(self, event):
        """ Fills the panel background. """
        super(EncodingPanel, self).paintEvent(event)
        if self.isVisible():
            # fill background
            painter = QtGui.QPainter(self)
            self._background_brush = QtGui.QBrush(self._color)
            painter.fillRect(event.rect(), self._background_brush)

    def on_install(self, editor):
        super(EncodingPanel, self).on_install(editor)
        if self.__add_ctx_mnu:
            # add context menu
            from pyqode.core.widgets import EncodingsContextMenu
            EncodingsContextMenu(parent=editor)

    def _reload(self):
        self.hide()
        self._rm_deco()
        self.editor.setReadOnly(False)
        self.enable_caret_line(True)
        self.editor.file.reload(self.ui.comboBoxEncodings.current_encoding)

    def _edit_anyway(self):
        self._rm_deco()
        self.editor.setReadOnly(False)
        self.enable_caret_line(True)
        self.hide()

    def _rm_deco(self):
        if self._deco:
            self.editor.decorations.remove(self._deco)
            self._deco = None

    def cancel(self):
        if self.sender():
            self.editor.clear()
        self._rm_deco()
        self.enable_caret_line(True)
        self.cancel_requested.emit(self.editor)
        self.hide()

    def clone_settings(self, original):
        self.color = original.color
        self.foreground = original.foreground
Esempio n. 15
0
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_released.connect(self._on_mouse_released)
            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_released.disconnect(self._on_mouse_released)
            self.editor.key_released.disconnect(self._on_key_released)
            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_cursor(self, cursor):
        pass

    def _on_mouse_released(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
Esempio n. 16
0
class LineHighlighterMode(Mode):
    """ Highlights a line in the editor."""
    @property
    def background(self):
        """
        Background color of the highlighted line.
        """
        return self._color

    @background.setter
    def background(self, value):
        self._color = value
        self.refresh()
        # propagate changes to every clone
        if self.editor:
            for clone in self.editor.clones:
                try:
                    clone.modes.get(self.__class__).background = value
                except KeyError:
                    # this should never happen since we're working with clones
                    pass

    @property
    def line(self):
        if self._block:
            return self._block.blockNumber()
        else:
            return self._block

    @line.setter
    def line(self, value):
        if value is None:
            self._block = value
            self._clear_deco()
        else:
            self._block = self.editor.document().findBlockByNumber(value)
            self.refresh()

    def __init__(self):
        super(LineHighlighterMode, self).__init__()
        self._decoration = None
        self._block = None
        self._color = QtGui.QColor('#DD8080')

    def on_state_changed(self, state):
        if state:
            self.editor.new_text_set.connect(self.refresh)
            self.refresh()
        else:
            self.editor.new_text_set.disconnect(self.refresh)
            self._clear_deco()

    def on_install(self, editor):
        super(LineHighlighterMode, self).on_install(editor)
        self.refresh()

    def _clear_deco(self):
        """ Clear line decoration """
        if self._decoration:
            self.editor.decorations.remove(self._decoration)
            self._decoration = None

    def refresh(self):
        """
        Updates the current line decoration
        """
        if self.enabled and self.line:
            self._clear_deco()
            brush = QtGui.QBrush(self._color)
            self._decoration = TextDecoration(self.editor.textCursor(),
                                              start_line=self.line)
            self._decoration.set_background(brush)
            self._decoration.set_full_width()
            self._decoration.draw_order = 255
            self.editor.decorations.append(self._decoration)

    def clone_settings(self, original):
        self.background = original.background
Esempio n. 17
0
 def _create_decoration(self, pos, match=True):
     cursor = self.editor.textCursor()
     cursor.setPosition(pos)
     cursor.movePosition(cursor.NextCharacter, cursor.KeepAnchor)
     deco = TextDecoration(cursor, draw_order=10)
     deco.line = cursor.blockNumber()
     deco.column = cursor.columnNumber()
     deco.character = cursor.selectedText()
     deco.match = match
     if match:
         deco.set_foreground(self._match_foreground)
         deco.set_background(self._match_background)
     else:
         deco.set_foreground(self._unmatch_foreground)
         deco.set_background(self._unmatch_background)
     self._decorations.append(deco)
     self.editor.decorations.append(deco)
     return cursor
Esempio n. 18
0
class CaretLineHighlighterMode(Mode):
    """ Highlights the caret line """
    @property
    def background(self):
        """
        Background color of the caret line. Default is to use a color slightly
        darker/lighter than the background color. You can override the
        automatic color by setting up this property
        """
        if self._color or not self.editor:
            return self._color
        else:
            return drift_color(self.editor.background, 110)

    @background.setter
    def background(self, value):
        self._color = value
        self.refresh()
        # propagate changes to every clone
        if self.editor:
            for clone in self.editor.clones:
                try:
                    clone.modes.get(self.__class__).background = value
                except KeyError:
                    # this should never happen since we're working with clones
                    pass

    def __init__(self):
        super(CaretLineHighlighterMode, self).__init__()
        self._decoration = None
        self._pos = -1
        self._color = None

    def on_state_changed(self, state):
        if state:
            self.editor.cursorPositionChanged.connect(self.refresh)
            self.editor.new_text_set.connect(self.refresh)
            self.refresh()
        else:
            self.editor.cursorPositionChanged.disconnect(
                self.refresh)
            self.editor.new_text_set.disconnect(self.refresh)
            self._clear_deco()

    def on_install(self, editor):
        super(CaretLineHighlighterMode, self).on_install(editor)
        self.refresh()

    def _clear_deco(self):
        """ Clear line decoration """
        if self._decoration:
            self.editor.decorations.remove(self._decoration)
            self._decoration = None

    def refresh(self):
        """
        Updates the current line decoration
        """
        if self.enabled:
            self._clear_deco()
            if self._color:
                color = self._color
            else:
                color = drift_color(self.editor.background, 110)
            brush = QtGui.QBrush(color)
            self._decoration = TextDecoration(self.editor.textCursor())
            self._decoration.set_background(brush)
            self._decoration.set_full_width()
            self.editor.decorations.append(self._decoration)

    def clone_settings(self, original):
        self.background = original.background
class LineHighlighterMode(Mode):
    """ Highlights a line in the editor."""

    @property
    def background(self):
        """
        Background color of the highlighted line.
        """
        return self._color

    @background.setter
    def background(self, value):
        self._color = value
        self.refresh()
        # propagate changes to every clone
        if self.editor:
            for clone in self.editor.clones:
                try:
                    clone.modes.get(self.__class__).background = value
                except KeyError:
                    # this should never happen since we're working with clones
                    pass

    @property
    def line(self):
        if self._block:
            return self._block.blockNumber()
        else:
            return self._block

    @line.setter
    def line(self, value):
        if value is None:
            self._block = value
            self._clear_deco()
        else:
            self._block = self.editor.document().findBlockByNumber(value)
            self.refresh()

    def __init__(self):
        super(LineHighlighterMode, self).__init__()
        self._decoration = None
        self._block = None
        self._color = QtGui.QColor('#DD8080')

    def on_state_changed(self, state):
        if state:
            self.editor.new_text_set.connect(self.refresh)
            self.refresh()
        else:
            self.editor.new_text_set.disconnect(self.refresh)
            self._clear_deco()

    def on_install(self, editor):
        super(LineHighlighterMode, self).on_install(editor)
        self.refresh()

    def _clear_deco(self):
        """ Clear line decoration """
        if self._decoration:
            self.editor.decorations.remove(self._decoration)
            self._decoration = None

    def refresh(self):
        """
        Updates the current line decoration
        """
        if self.enabled and self.line:
            self._clear_deco()
            brush = QtGui.QBrush(self._color)
            self._decoration = TextDecoration(
                self.editor.textCursor(), start_line=self.line)
            self._decoration.set_background(brush)
            self._decoration.set_full_width()
            self._decoration.draw_order = 255
            self.editor.decorations.append(self._decoration)

    def clone_settings(self, original):
        self.background = original.background