File: interactive.py

package info (click to toggle)
turing 0.11-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,340 kB
  • sloc: python: 106,582; xml: 101; makefile: 53; sh: 29
file content (138 lines) | stat: -rw-r--r-- 5,925 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
"""
This module contains the Interactive python console, for running python
programs.
"""
from pyqode.qt import QtCore, QtGui, QtWidgets
from pyqode.core.widgets import InteractiveConsole


class PyInteractiveConsole(InteractiveConsole):
    """
    Extends the InteractiveConcole to highlight python traceback. If the user
    press on a filename in a traceback, the signal open_file_requested is
    emitted with the file path to open and the line where the user want to go.

    .. deprecated: since version 2.10.0, you should use pyqode.core.widgets.OutputWindow

    """
    #: Signal emitted when the user pressed on a traceback file location.
    #: Client code should open the requested file in the editor.
    open_file_requested = QtCore.Signal(str, int)

    class UserData(QtGui.QTextBlockUserData):
        def __init__(self, filename, line, start, end):
            super(PyInteractiveConsole.UserData, self).__init__()
            self.filename = filename
            self.line = line
            self.start_pos_in_block = start
            self.end_pos_in_block = end

    def __init__(self, parent=None):
        super(PyInteractiveConsole, self).__init__(parent)
        self.set_writer(self._write)
        self.setMouseTracking(True)
        self.PROG = QtCore.QRegExp(
            r'\s*File ".*", line [0-9]*, in ')
        self.FILENAME_PROG = QtCore.QRegExp(r'".*"')
        self.LINE_PROG = QtCore.QRegExp(r'line [0-9]*')
        self.setLineWrapMode(self.NoWrap)
        self._module_color = QtGui.QColor('blue')

    def start_process(self, process, args=None, cwd=None, env=None):
        if env is None:
            env = {}
        if 'PYTHONUNBUFFERED' not in env:
            env['PYTHONUNBUFFERED'] = '1'
        if 'QT_LOGGING_TO_CONSOLE' not in env:
            env['QT_LOGGING_TO_CONSOLE'] = '1'
        super(PyInteractiveConsole, self).start_process(
            process, args, cwd, env)

    def _write(self, text_edit, text, color):
        def write(text_edit, text, color):
            text_edit.moveCursor(QtGui.QTextCursor.End)
            fmt = QtGui.QTextCharFormat()
            fmt.setUnderlineStyle(QtGui.QTextCharFormat.NoUnderline)
            fmt.setForeground(QtGui.QBrush(color))
            text_edit.setCurrentCharFormat(fmt)
            text_edit.insertPlainText(text)
            text_edit.moveCursor(QtGui.QTextCursor.End)

        def write_with_underline(text_edit, text, color, line, start, end):
            text_edit.moveCursor(QtGui.QTextCursor.End)
            text_edit.setTextColor(color)
            fmt = QtGui.QTextCharFormat()
            fmt.setUnderlineColor(color)
            fmt.setUnderlineStyle(QtGui.QTextCharFormat.SingleUnderline)
            fmt.setForeground(QtGui.QBrush(color))
            text_edit.setCurrentCharFormat(fmt)
            text_edit.insertPlainText(text)
            text_edit.moveCursor(QtGui.QTextCursor.End)
            block = self.document().lastBlock()
            data = self.UserData(text, line, start, end)
            block.setUserData(data)

        text = text.replace('\n', '{@}\n')
        text = text.replace('\r', '')
        for i, line in enumerate(text.split('{@}')):
            # check if File and highlight it in blue, also store it
            if self.PROG.indexIn(line) != -1:
                # get line number
                self.LINE_PROG.indexIn(line)
                start = self.LINE_PROG.pos(0)
                end = start + len(self.LINE_PROG.cap(0))
                l = int(line[start:end].replace('line ', '')) - 1

                self.FILENAME_PROG.indexIn(line)
                start = self.FILENAME_PROG.pos(0)
                end = start + len(self.FILENAME_PROG.cap(0))
                write(self, line[:start + 1], color)
                write_with_underline(self, line[start + 1:end - 1],
                                     self._module_color, l,
                                     start, end)
                write(self, line[end - 1:], color)
            else:
                write(text_edit, line, color)

    def mouseMoveEvent(self, e):
        """
        Extends mouseMoveEvent to display a pointing hand cursor when the
        mouse cursor is over a file location
        """
        super(PyInteractiveConsole, self).mouseMoveEvent(e)
        cursor = self.cursorForPosition(e.pos())
        assert isinstance(cursor, QtGui.QTextCursor)
        p = cursor.positionInBlock()
        usd = cursor.block().userData()
        if usd and usd.start_pos_in_block <= p <= usd.end_pos_in_block:
            if QtWidgets.QApplication.overrideCursor() is None:
                QtWidgets.QApplication.setOverrideCursor(
                    QtGui.QCursor(QtCore.Qt.PointingHandCursor))
        else:
            if QtWidgets.QApplication.overrideCursor() is not None:
                QtWidgets.QApplication.restoreOverrideCursor()

    def mousePressEvent(self, e):
        """
        Emits open_file_requested if the press event occured  over
        a file location string.
        """
        super(PyInteractiveConsole, self).mousePressEvent(e)
        cursor = self.cursorForPosition(e.pos())
        p = cursor.positionInBlock()
        usd = cursor.block().userData()
        if usd and usd.start_pos_in_block <= p <= usd.end_pos_in_block:
            if e.button() == QtCore.Qt.LeftButton:
                self.open_file_requested.emit(usd.filename, usd.line)

    def leaveEvent(self, e):
        super(PyInteractiveConsole, self).leaveEvent(e)
        if QtWidgets.QApplication.overrideCursor() is not None:
            QtWidgets.QApplication.restoreOverrideCursor()

    def apply_color_scheme(self, color_scheme):
        super(PyInteractiveConsole, self).apply_color_scheme(color_scheme)
        if color_scheme.background.lightness() < 128:
            self._module_color = QtGui.QColor('#0681e0')
        else:
            self._module_color = QtGui.QColor('blue')