예제 #1
0
def test_dynamic_folding_insert_section():
    # test insert section under empty data division
    # data division (which is not a fold trigger initially) block will become a fold trigger
    editor = CobolCodeEdit()
    editor.setPlainText(section_code, '', '')
    th = TextHelper(editor)
    block = editor.document().findBlockByNumber(2)
    assert TextBlockHelper.is_fold_trigger(block) is False
    cursor = th.goto_line(2, column=len('       DATA DIVISION.'))
    cursor.insertText('\n       WORKING-STORAGE SECTION.')
    assert TextBlockHelper.is_fold_trigger(block) is True
예제 #2
0
def test_dynamic_folding_insert_section():
    # test insert section under empty data division
    # data division (which is not a fold trigger initially) block will become a fold trigger
    editor = CobolCodeEdit()
    editor.setPlainText(section_code, '', '')
    th = TextHelper(editor)
    block = editor.document().findBlockByNumber(2)
    assert TextBlockHelper.is_fold_trigger(block) is False
    cursor = th.goto_line(2, column=len('       DATA DIVISION.'))
    cursor.insertText('\n       WORKING-STORAGE SECTION.')
    assert TextBlockHelper.is_fold_trigger(block) is True
예제 #3
0
 def collapse_all(self):
     """
     Collapses all triggers and makes all blocks with fold level > 0
     invisible.
     """
     self._clear_block_deco()
     block = self.editor.document().firstBlock()
     last = self.editor.document().lastBlock()
     while block.isValid():
         lvl = TextBlockHelper.get_fold_lvl(block)
         trigger = TextBlockHelper.is_fold_trigger(block)
         if trigger:
             if lvl == 0:
                 self._show_previous_blank_lines(block)
             TextBlockHelper.set_fold_trigger_state(block, True)
         block.setVisible(lvl == 0)
         if block == last and block.text().strip() == '':
             block.setVisible(True)
             self._show_previous_blank_lines(block)
         block = block.next()
     self._refresh_editor_and_scrollbars()
     tc = self.editor.textCursor()
     tc.movePosition(tc.Start)
     self.editor.setTextCursor(tc)
     self.collapse_all_triggered.emit()
예제 #4
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 [QtCore.Qt.Key_Backspace,
                                      QtCore.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)
예제 #5
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 [QtCore.Qt.Key_Backspace,
                                      QtCore.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)
예제 #6
0
    def find_parent_scope(block):
        """
        Find parent scope, if the block is not a fold trigger.

        """
        original = block
        if not TextBlockHelper.is_fold_trigger(block):
            # search level of next non blank line
            while block.text().strip() == '' and block.isValid():
                block = block.next()
            ref_lvl = TextBlockHelper.get_fold_lvl(block) - 1
            block = original
            while (block.blockNumber() and
                   (not TextBlockHelper.is_fold_trigger(block) or
                    TextBlockHelper.get_fold_lvl(block) > ref_lvl)):
                block = block.previous()
        return block
예제 #7
0
def test_expand_all(editor):
    panel = get_panel(editor)
    QTest.qWait(1000)
    panel.collapse_all()
    QTest.qWait(1000)
    panel.expand_all()
    block = editor.document().firstBlock()
    while block.blockNumber() < editor.document().blockCount() - 1:
        assert block.isVisible()
        if TextBlockHelper.is_fold_trigger(block):
            assert TextBlockHelper.is_collapsed(block) is False
        block = block.next()
예제 #8
0
def test_mouse_press(editor):
    panel = get_panel(editor)
    panel.highlight_caret_scope = False
    # fold child block
    toggle_fold_trigger(editor, 15, panel)
    block = editor.document().findBlockByNumber(14)
    assert TextBlockHelper.is_fold_trigger(block) is True
    assert TextBlockHelper.is_collapsed(block) is True
    block = block.next()
    while block.blockNumber() < 21:
        assert block.isVisible() is False
        block = block.next()
    # fold top level block
    toggle_fold_trigger(editor, 9, panel)
    block = editor.document().findBlockByNumber(8)
    assert TextBlockHelper.is_fold_trigger(block)
    block = block.next()
    while block.blockNumber() < 27:
        if block.blockNumber() == 14:
            assert TextBlockHelper.is_fold_trigger(block) is True
            assert TextBlockHelper.is_collapsed(block) is True
        assert block.isVisible() is False
        block = block.next()
    # unfold it top level block
    toggle_fold_trigger(editor, 9, panel)
    block = editor.document().findBlockByNumber(8)
    assert TextBlockHelper.is_fold_trigger(block)
    block = block.next()
    while block.blockNumber() < 27:
        if 14 < block.blockNumber() < 22:
            assert block.isVisible() is False
        else:
            assert block.isVisible() is True
        block = block.next()

    # cleanup
    QTest.mouseMove(panel, QtCore.QPoint(0, 0))
    panel.leaveEvent(None)
    editor.setFocus()
    panel.highlight_caret_scope = True
예제 #9
0
def test_collapse_all(editor):
    panel = get_panel(editor)
    QTest.qWait(1000)
    panel.collapse_all()
    QTest.qWait(1000)
    block = editor.document().firstBlock()
    while block.blockNumber() < editor.document().blockCount() - 1:
        blank_line = len(block.text().strip()) == 0
        if TextBlockHelper.get_fold_lvl(block) > 0:
            if not blank_line:
                assert block.isVisible() is False
        else:
            assert block.isVisible() is True
        if TextBlockHelper.is_fold_trigger(block):
            assert TextBlockHelper.is_collapsed(block) is True
        block = block.next()
예제 #10
0
    def toggle_fold_trigger(self, block):
        """
        Toggle a fold trigger block (expand or collapse it).

        :param block: The QTextBlock to expand/collapse
        """
        if not TextBlockHelper.is_fold_trigger(block):
            return
        region = FoldScope(block)
        if region.collapsed:
            region.unfold()
            if self._mouse_over_line is not None:
                self._add_scope_decorations(
                    region._trigger, *region.get_range())
        else:
            region.fold()
            self._clear_scope_decos()
        self._refresh_editor_and_scrollbars()
        self.trigger_state_changed.emit(region._trigger, region.collapsed)
예제 #11
0
 def paintEvent(self, event):
     # Paints the fold indicators and the possible fold region background
     # on the folding panel.
     super(FoldingPanel, self).paintEvent(event)
     painter = QtGui.QPainter(self)
     # Draw background over the selected non collapsed fold region
     if self._mouse_over_line is not None:
         block = self.editor.document().findBlockByNumber(
             self._mouse_over_line)
         try:
             self._draw_fold_region_background(block, painter)
         except ValueError:
             pass
     # Draw fold triggers
     for top_position, line_number, block in self.editor.visible_blocks:
         if TextBlockHelper.is_fold_trigger(block):
             collapsed = TextBlockHelper.get_fold_trigger_state(block)
             mouse_over = self._mouse_over_line == line_number
             self._draw_fold_indicator(
                 top_position, mouse_over, collapsed, painter)
             if collapsed:
                 # check if the block already has a decoration, it might
                 # have been folded by the parent editor/document in the
                 # case of cloned editor
                 for deco in self._block_decos:
                     if deco.block == block:
                         # no need to add a deco, just go to the next block
                         break
                 else:
                     self._add_fold_decoration(block, FoldScope(block))
             else:
                 for deco in self._block_decos:
                     # check if the block decoration has been removed, it
                     # might have been unfolded by the parent
                     # editor/document in the case of cloned editor
                     if deco.block == block:
                         # remove it and
                         self._block_decos.remove(deco)
                         self.editor.decorations.remove(deco)
                         del deco
                         break
예제 #12
0
    def _highlight_caret_scope(self):
        """
        Highlight the scope surrounding the current caret position.

        This get called only if :attr:`
        pyqode.core.panels.FoldingPanel.highlight_care_scope` is True.
        """
        cursor = self.editor.textCursor()
        block_nbr = cursor.blockNumber()
        if self._block_nbr != block_nbr:
            block = FoldScope.find_parent_scope(
                self.editor.textCursor().block())
            try:
                s = FoldScope(block)
            except ValueError:
                self._clear_scope_decos()
            else:
                self._mouse_over_line = block.blockNumber()
                if TextBlockHelper.is_fold_trigger(block):
                    self._highlight_surrounding_scopes(block)
        self._block_nbr = block_nbr
예제 #13
0
    def open(self, path, encoding=None, use_cached_encoding=True):
        encoding = self.detect_encoding(path)
        super(PyFileManager, self).open(
            path, encoding=encoding, use_cached_encoding=use_cached_encoding)
        try:
            folding_panel = self.editor.panels.get('FoldingPanel')
        except KeyError:
            pass
        else:
            # fold imports and/or docstrings
            blocks_to_fold = []
            sh = self.editor.syntax_highlighter

            if self.fold_imports and sh.import_statements:
                blocks_to_fold += sh.import_statements
            if self.fold_docstrings and sh.docstrings:
                blocks_to_fold += sh.docstrings

            for block in blocks_to_fold:
                if TextBlockHelper.is_fold_trigger(block):
                    folding_panel.toggle_fold_trigger(block)
예제 #14
0
    def _add_scope_decorations(self, block, start, end):
        """
        Show a scope decoration on the editor widget

        :param start: Start line
        :param end: End line
        """
        try:
            parent = FoldScope(block).parent()
        except ValueError:
            parent = None
        if TextBlockHelper.is_fold_trigger(block):
            base_color = self._get_scope_highlight_color()
            factor_step = 5
            if base_color.lightness() < 128:
                factor_step = 10
                factor = 70
            else:
                factor = 100
            while parent:
                # highlight parent scope
                parent_start, parent_end = parent.get_range()
                self._add_scope_deco(
                    start, end + 1, parent_start, parent_end,
                    base_color, factor)
                # next parent scope
                start = parent_start
                end = parent_end
                parent = parent.parent()
                factor += factor_step
            # global scope
            parent_start = 0
            parent_end = self.editor.document().blockCount()
            self._add_scope_deco(
                start, end + 1, parent_start, parent_end, base_color,
                factor + factor_step)
        else:
            self._clear_scope_decos()
예제 #15
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))
            if TextBlockHelper.is_fold_trigger(block):
                if self._mouse_over_line is None:
                    # mouse enter fold scope
                    QtWidgets.QApplication.setOverrideCursor(
                        QtGui.QCursor(QtCore.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
                QtWidgets.QApplication.restoreOverrideCursor()
            self.repaint()