Пример #1
0
 def _on_key_pressed(self, event):
     """
     Override key press to select the current scope if the user wants
     to deleted a folded scope (without selecting it).
     """
     delete_request = event.key() in [Qt.Key_Backspace, Qt.Key_Delete]
     if event.text() or delete_request:
         cursor = self.editor.textCursor()
         if cursor.hasSelection():
             # change selection to encompass the whole scope.
             positions_to_check = cursor.selectionStart(
             ), cursor.selectionEnd()
         else:
             positions_to_check = (cursor.position(), )
         for pos in positions_to_check:
             block = self.editor.document().findBlock(pos)
             th = TextBlockHelper()
             if th.is_fold_trigger(block) and th.is_collapsed(block):
                 self.toggle_fold_trigger(block)
                 if delete_request and cursor.hasSelection():
                     scope = FoldScope(self.find_parent_scope(block))
                     tc = TextHelper(
                         self.editor).select_lines(*scope.get_range())
                     if tc.selectionStart() > cursor.selectionStart():
                         start = cursor.selectionStart()
                     else:
                         start = tc.selectionStart()
                     if tc.selectionEnd() < cursor.selectionEnd():
                         end = cursor.selectionEnd()
                     else:
                         end = tc.selectionEnd()
                     tc.setPosition(start)
                     tc.setPosition(end, tc.KeepAnchor)
                     self.editor.setTextCursor(tc)
Пример #2
0
 def _on_key_pressed(self, event):
     """
     Override key press to select the current scope if the user wants
     to deleted a folded scope (without selecting it).
     """
     delete_request = event.key() in [Qt.Key_Backspace,
                                      Qt.Key_Delete]
     if event.text() or delete_request:
         cursor = self.editor.textCursor()
         if cursor.hasSelection():
             # change selection to encompass the whole scope.
             positions_to_check = cursor.selectionStart(), cursor.selectionEnd()
         else:
             positions_to_check = (cursor.position(), )
         for pos in positions_to_check:
             block = self.editor.document().findBlock(pos)
             th = TextBlockHelper()
             if th.is_fold_trigger(block) and th.is_collapsed(block):
                 self.toggle_fold_trigger(block)
                 if delete_request and cursor.hasSelection():
                     scope = FoldScope(self.find_parent_scope(block))
                     tc = TextHelper(self.editor).select_lines(*scope.get_range())
                     if tc.selectionStart() > cursor.selectionStart():
                         start = cursor.selectionStart()
                     else:
                         start = tc.selectionStart()
                     if tc.selectionEnd() < cursor.selectionEnd():
                         end = cursor.selectionEnd()
                     else:
                         end = tc.selectionEnd()
                     tc.setPosition(start)
                     tc.setPosition(end, tc.KeepAnchor)
                     self.editor.setTextCursor(tc)
Пример #3
0
def test_close_quotes(qtbot, editor_close_quotes, text, expected_text,
                      cursor_column):
    """Test insertion of extra quotes."""
    editor = editor_close_quotes

    qtbot.keyClicks(editor, text)
    assert editor.toPlainText() == expected_text

    assert cursor_column == TextHelper(editor).current_column_nbr()
Пример #4
0
    def find(self,
             changed=True,
             forward=True,
             rehighlight=True,
             start_highlight_timer=False,
             multiline_replace_check=True):
        """Call the find function"""
        # When several lines are selected in the editor and replace box is activated,
        # dynamic search is deactivated to prevent changing the selection. Otherwise
        # we show matching items.
        if multiline_replace_check and self.replace_widgets[0].isVisible() and \
           len(to_text_string(self.editor.get_selected_text()).splitlines())>1:
            return None
        text = self.search_text.currentText()
        if len(text) == 0:
            self.search_text.lineEdit().setStyleSheet("")
            if not self.is_code_editor:
                # Clears the selection for WebEngine
                self.editor.find_text('')
            self.change_number_matches()
            return None
        else:
            case = self.case_button.isChecked()
            words = self.words_button.isChecked()
            regexp = self.re_button.isChecked()
            found = self.editor.find_text(text,
                                          changed,
                                          forward,
                                          case=case,
                                          words=words,
                                          regexp=regexp)
            self.search_text.lineEdit().setStyleSheet(self.STYLE[found])
            if self.is_code_editor and found:
                block = self.editor.textCursor().block()
                TextHelper(self.editor).unfold_if_colapsed(block)

                if rehighlight or not self.editor.found_results:
                    self.highlight_timer.stop()
                    if start_highlight_timer:
                        self.highlight_timer.start()
                    else:
                        self.highlight_matches()
            else:
                self.clear_matches()

            number_matches = self.editor.get_number_matches(text, case=case)
            if hasattr(self.editor, 'get_match_number'):
                match_number = self.editor.get_match_number(text, case=case)
            else:
                match_number = 0
            self.change_number_matches(current_match=match_number,
                                       total_matches=number_matches)
            return found
Пример #5
0
    def _draw_fold_region_background(self, block, painter):
        """
        Draw the fold region when the mouse is over and non collapsed
        indicator.

        :param top: Top position
        :param block: Current block.
        :param painter: QPainter
        """
        r = FoldScope(block)
        th = TextHelper(self.editor)
        start, end = r.get_range(ignore_blank_lines=True)
        if start > 0:
            top = th.line_pos_from_number(start)
        else:
            top = 0
        bottom = th.line_pos_from_number(end + 1)
        h = bottom - top
        if h == 0:
            h = self.sizeHint().height()
        w = self.sizeHint().width()
        self._draw_rect(QRectF(0, top, w, h), painter)
Пример #6
0
    def _draw_fold_region_background(self, block, painter):
        """
        Draw the fold region when the mouse is over and non collapsed
        indicator.

        :param top: Top position
        :param block: Current block.
        :param painter: QPainter
        """
        r = FoldScope(block)
        th = TextHelper(self.editor)
        start, end = r.get_range(ignore_blank_lines=True)
        if start > 0:
            top = th.line_pos_from_number(start)
        else:
            top = 0
        bottom = th.line_pos_from_number(end + 1)
        h = bottom - top
        if h == 0:
            h = self.sizeHint().height()
        w = self.sizeHint().width()
        self._draw_rect(QRectF(0, top, w, h), painter)
Пример #7
0
    def mouseMoveEvent(self, event):
        """
        Detect mouser over indicator and highlight the current scope in the
        editor (up and down decoration arround the foldable text when the mouse
        is over an indicator).

        :param event: event
        """
        super(FoldingPanel, self).mouseMoveEvent(event)
        th = TextHelper(self.editor)
        line = th.line_nbr_from_position(event.pos().y())
        if line >= 0:
            block = FoldScope.find_parent_scope(
                self.editor.document().findBlockByNumber(line-1))
            if TextBlockHelper.is_fold_trigger(block):
                if self._mouse_over_line is None:
                    # mouse enter fold scope
                    QApplication.setOverrideCursor(
                        QCursor(Qt.PointingHandCursor))
                if self._mouse_over_line != block.blockNumber() and \
                        self._mouse_over_line is not None:
                    # fold scope changed, a previous block was highlighter so
                    # we quickly update our highlighting
                    self._mouse_over_line = block.blockNumber()
                    self._highlight_block(block)
                else:
                    # same fold scope, request highlight
                    self._mouse_over_line = block.blockNumber()
                    self._highlight_runner.request_job(
                        self._highlight_block, block)
                self._highight_block = block
            else:
                # no fold scope to highlight, cancel any pending requests
                self._highlight_runner.cancel_requests()
                self._mouse_over_line = None
                QApplication.restoreOverrideCursor()
            self.repaint()
Пример #8
0
    def mouseMoveEvent(self, event):
        """
        Detect mouser over indicator and highlight the current scope in the
        editor (up and down decoration arround the foldable text when the mouse
        is over an indicator).

        :param event: event
        """
        super(FoldingPanel, self).mouseMoveEvent(event)
        th = TextHelper(self.editor)
        line = th.line_nbr_from_position(event.pos().y())
        if line >= 0:
            block = FoldScope.find_parent_scope(
                self.editor.document().findBlockByNumber(line - 1))
            if TextBlockHelper.is_fold_trigger(block):
                if self._mouse_over_line is None:
                    # mouse enter fold scope
                    QApplication.setOverrideCursor(
                        QCursor(Qt.PointingHandCursor))
                if self._mouse_over_line != block.blockNumber() and \
                        self._mouse_over_line is not None:
                    # fold scope changed, a previous block was highlighter so
                    # we quickly update our highlighting
                    self._mouse_over_line = block.blockNumber()
                    self._highlight_surrounding_scopes(block)
                else:
                    # same fold scope, request highlight
                    self._mouse_over_line = block.blockNumber()
                    self._highlight_runner.request_job(
                        self._highlight_surrounding_scopes, block)
                self._highight_block = block
            else:
                # no fold scope to highlight, cancel any pending requests
                self._highlight_runner.cancel_requests()
                self._mouse_over_line = None
                QApplication.restoreOverrideCursor()
            self.repaint()
Пример #9
0
    def _refresh_editor_and_scrollbars(self):
        """
        Refrehes editor content and scollbars.

        We generate a fake resize event to refresh scroll bar.

        We have the same problem as described here:
        http://www.qtcentre.org/threads/44803 and we apply the same solution
        (don't worry, there is no visual effect, the editor does not grow up
        at all, even with a value = 500)
        """
        TextHelper(self.editor).mark_whole_doc_dirty()
        self.editor.repaint()
        s = self.editor.size()
        s.setWidth(s.width() + 1)
        self.editor.resizeEvent(QResizeEvent(self.editor.size(), s))
Пример #10
0
    def find(self, changed=True, forward=True,
             rehighlight=True, start_highlight_timer=False, multiline_replace_check=True):
        """Call the find function"""
        # When several lines are selected in the editor and replace box is activated, 
        # dynamic search is deactivated to prevent changing the selection. Otherwise
        # we show matching items.
        def regexp_error_msg(pattern):
            """Returns None if the pattern is a valid regular expression or
            a string describing why the pattern is invalid.
            """
            try:
                re.compile(pattern)
            except re.error as e:
                return str(e)
            return None

        if multiline_replace_check and self.replace_widgets[0].isVisible() and \
           len(to_text_string(self.editor.get_selected_text()).splitlines())>1:
            return None
        text = self.search_text.currentText()
        if len(text) == 0:
            self.search_text.lineEdit().setStyleSheet("")
            if not self.is_code_editor:
                # Clears the selection for WebEngine
                self.editor.find_text('')
            self.change_number_matches()
            return None
        else:
            case = self.case_button.isChecked()
            words = self.words_button.isChecked()
            regexp = self.re_button.isChecked()
            found = self.editor.find_text(text, changed, forward, case=case,
                                          words=words, regexp=regexp)

            stylesheet = self.STYLE[found]
            tooltip = self.TOOLTIP[found]
            if not found and regexp:
                error_msg = regexp_error_msg(text)
                if error_msg:  # special styling for regexp errors
                    stylesheet = self.STYLE['regexp_error']
                    tooltip = self.TOOLTIP['regexp_error'] + ': ' + error_msg
            self.search_text.lineEdit().setStyleSheet(stylesheet)
            self.search_text.setToolTip(tooltip)

            if self.is_code_editor and found:
                block = self.editor.textCursor().block()
                TextHelper(self.editor).unfold_if_colapsed(block)

                if rehighlight or not self.editor.found_results:
                    self.highlight_timer.stop()
                    if start_highlight_timer:
                        self.highlight_timer.start()
                    else:
                        self.highlight_matches()
            else:
                self.clear_matches()

            number_matches = self.editor.get_number_matches(text, case=case)
            if hasattr(self.editor, 'get_match_number'):
                match_number = self.editor.get_match_number(text, case=case)
            else:
                match_number = 0
            self.change_number_matches(current_match=match_number,
                                       total_matches=number_matches)
            return found