Mercurial > lcfOS
comparison python/codeedit.py @ 162:d8c735dc31f9
Used new editor in ide
author | Windel Bouwman |
---|---|
date | Sun, 10 Mar 2013 11:36:55 +0100 |
parents | 956f8e5ee48a |
children | 8104fc8b5e90 |
comparison
equal
deleted
inserted
replaced
161:956f8e5ee48a | 162:d8c735dc31f9 |
---|---|
11 if v < mn: return mn | 11 if v < mn: return mn |
12 if v > mx: return mx | 12 if v > mx: return mx |
13 return v | 13 return v |
14 | 14 |
15 class InnerCode(QWidget): | 15 class InnerCode(QWidget): |
16 textChanged = pyqtSignal() | |
16 def __init__(self, scrollArea): | 17 def __init__(self, scrollArea): |
17 super().__init__(scrollArea) | 18 super().__init__(scrollArea) |
18 self.scrollArea = scrollArea | 19 self.scrollArea = scrollArea |
19 self.setFont(QFont('Courier', 16)) | 20 self.setFont(QFont('Courier', 16)) |
20 self.setFocusPolicy(Qt.StrongFocus) | 21 self.setFocusPolicy(Qt.StrongFocus) |
22 h = QFontMetrics(self.font()).height() | |
23 self.errorPixmap = QPixmap('error.png').scaled(h, h) | |
21 self.blinkcursor = False | 24 self.blinkcursor = False |
25 self.errorlist = [] | |
22 # Initial values: | 26 # Initial values: |
23 self.setSource('') | 27 self.setSource('') |
24 self.CursorPosition = 0 | 28 self.CursorPosition = 0 |
25 t = QTimer(self) | 29 t = QTimer(self) |
26 t.timeout.connect(self.updateCursor) | 30 t.timeout.connect(self.updateCursor) |
30 self.blinkcursor = not self.blinkcursor | 34 self.blinkcursor = not self.blinkcursor |
31 self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight) | 35 self.update(self.cursorX, self.cursorY, self.charWidth, self.charHeight) |
32 def setSource(self, src): | 36 def setSource(self, src): |
33 self.src = src | 37 self.src = src |
34 self.adjust() | 38 self.adjust() |
39 def getSource(self): | |
40 return self.src | |
41 def setErrors(self, el): | |
42 self.errorlist = el | |
43 self.update() | |
35 def setCursorPosition(self, c): | 44 def setCursorPosition(self, c): |
36 self.cursorPosition = clipVal(c, 0, len(self.src)) | 45 self.cursorPosition = clipVal(c, 0, len(self.src)) |
37 self.cursorX = self.CursorCol * self.charWidth + self.xposTXT - self.charWidth | 46 self.cursorX = self.CursorCol * self.charWidth + self.xposTXT - self.charWidth |
38 self.cursorY = self.CursorRow * self.charHeight - self.charHeight | 47 self.cursorY = self.CursorRow * self.charHeight - self.charHeight |
39 self.update() | 48 self.update() |
56 def CurrentLine(self): | 65 def CurrentLine(self): |
57 return self.getRow(self.CursorRow) | 66 return self.getRow(self.CursorRow) |
58 def setRowCol(self, r, c): | 67 def setRowCol(self, r, c): |
59 prevRows = self.Rows[:r] | 68 prevRows = self.Rows[:r] |
60 txt = '\n'.join(prevRows) | 69 txt = '\n'.join(prevRows) |
61 self.CursorPosition = len(txt) + c | 70 c = clipVal(c, 1, len(self.getRow(r+1))) |
71 self.CursorPosition = len(txt) + c + 1 | |
62 def getRow(self, r): | 72 def getRow(self, r): |
63 rows = self.Rows | 73 rows = self.Rows |
64 r = r - 1 | 74 r = r - 1 |
65 if r < 0 or r > len(rows) - 1: | 75 if r < 0 or r > len(rows) - 1: |
66 return '' | 76 return '' |
67 else: | 77 else: |
68 return rows[r] | 78 return rows[r] |
79 # Annotations: | |
80 def addAnnotation(self, row, col, ln, msg): | |
81 pass | |
82 # Text modification: | |
69 def getChar(self, pos): | 83 def getChar(self, pos): |
70 pass | 84 pass |
71 def insertText(self, txt): | 85 def insertText(self, txt): |
72 self.setSource(self.src[0:self.CursorPosition] + txt + self.src[self.CursorPosition:]) | 86 self.setSource(self.src[0:self.CursorPosition] + txt + self.src[self.CursorPosition:]) |
73 self.CursorPosition += len(txt) | 87 self.CursorPosition += len(txt) |
88 self.textChanged.emit() | |
74 def deleteChar(self): | 89 def deleteChar(self): |
75 self.setSource(self.src[0:self.CursorPosition] + self.src[self.CursorPosition+1:]) | 90 self.setSource(self.src[0:self.CursorPosition] + self.src[self.CursorPosition+1:]) |
91 self.textChanged.emit() | |
76 def GotoNextChar(self): | 92 def GotoNextChar(self): |
77 if self.src[self.CursorPosition] != '\n': | 93 if self.src[self.CursorPosition] != '\n': |
78 self.CursorPosition += 1 | 94 self.CursorPosition += 1 |
79 def GotoPrevChar(self): | 95 def GotoPrevChar(self): |
80 if self.src[self.CursorPosition - 1] != '\n': | 96 if self.src[self.CursorPosition - 1] != '\n': |
81 self.CursorPosition -= 1 | 97 self.CursorPosition -= 1 |
82 def GotoNextLine(self): | 98 def GotoNextLine(self): |
83 curLine = self.CurrentLine | 99 curLine = self.CurrentLine |
84 c = self.CursorCol | 100 c = self.CursorCol - 1 # go to zero based |
85 self.CursorPosition += len(curLine) - c + 1 # line break char! | 101 self.CursorPosition += len(curLine) - c + 1 # line break char! |
86 curLine = self.CurrentLine | 102 curLine = self.CurrentLine |
87 if len(curLine) < c: | 103 if len(curLine) < c: |
88 self.CursorPosition += len(curLine) | 104 self.CursorPosition += len(curLine) |
89 else: | 105 else: |
90 self.CursorPosition += c | 106 self.CursorPosition += c |
91 def GotoPrevLine(self): | 107 def GotoPrevLine(self): |
92 c = self.CursorCol | 108 c = self.CursorCol - 1 # go to zero based |
93 self.CursorPosition -= c + 1 # line break char! | 109 self.CursorPosition -= c + 1 # line break char! |
94 curLine = self.CurrentLine | 110 curLine = self.CurrentLine |
95 if len(curLine) > c: | 111 if len(curLine) > c: |
96 self.CursorPosition -= len(curLine) - c | 112 self.CursorPosition -= len(curLine) - c |
97 def paintEvent(self, event): | 113 def paintEvent(self, event): |
99 er = event.rect() | 115 er = event.rect() |
100 chw, chh = self.charWidth, self.charHeight | 116 chw, chh = self.charWidth, self.charHeight |
101 painter = QPainter(self) | 117 painter = QPainter(self) |
102 # Background: | 118 # Background: |
103 painter.fillRect(er, self.palette().color(QPalette.Base)) | 119 painter.fillRect(er, self.palette().color(QPalette.Base)) |
104 painter.fillRect(QRect(self.xposLNA, er.top(), 8 * chw, er.bottom() + 1), Qt.gray) | 120 painter.fillRect(QRect(self.xposLNA, er.top(), 4 * chw, er.bottom() + 1), Qt.gray) |
105 painter.fillRect(er.left(), (self.CursorRow - 1) * chh, er.width(), chh, Qt.yellow) | 121 painter.fillRect(er.left(), (self.CursorRow - 1) * chh, er.width(), chh, Qt.yellow) |
106 painter.setPen(Qt.gray) | 122 errorPen = QPen(Qt.red, 3) |
107 # first and last row: | 123 # first and last row: |
108 row1 = max(int(er.top() / chh) - 1, 1) | 124 row1 = max(int(er.top() / chh) - 1, 1) |
109 row2 = max(int(er.bottom() / chh) + 1, 1) | 125 row2 = max(int(er.bottom() / chh) + 1, 1) |
110 # Draw contents: | 126 # Draw contents: |
111 for row in range(row1, row2 + 1): | 127 for row in range(row1, row2 + 1): |
112 ypos = row * chh - self.charDescent | 128 ypos = row * chh - self.charDescent |
113 painter.setPen(Qt.black) | 129 painter.setPen(Qt.black) |
114 painter.drawText(self.xposLNA, ypos, 'R ={0}'.format(row)) | 130 painter.drawText(self.xposLNA, ypos, '{0}'.format(row)) |
115 xpos = self.xposTXT | 131 xpos = self.xposTXT |
116 painter.drawText(xpos, ypos, self.getRow(row)) | 132 painter.drawText(xpos, ypos, self.getRow(row)) |
133 for e in self.errorlist: | |
134 if e.loc.row == row: | |
135 painter.drawPixmap(self.xposERR, ypos - chh + self.charDescent, self.errorPixmap) | |
136 painter.setPen(errorPen) | |
137 x = self.xposTXT + (e.loc.col - 1) * chw | |
138 painter.drawLine(x, ypos+1, x + 100, ypos+1) | |
117 # cursor | 139 # cursor |
118 if self.blinkcursor: | 140 if self.blinkcursor: |
119 painter.fillRect(self.cursorX, self.cursorY, 2, chh, Qt.black) | 141 painter.fillRect(self.cursorX, self.cursorY, 2, chh, Qt.black) |
120 def keyPressEvent(self, event): | 142 def keyPressEvent(self, event): |
121 if event.matches(QKeySequence.MoveToNextChar): | 143 if event.matches(QKeySequence.MoveToNextChar): |
157 def adjust(self): | 179 def adjust(self): |
158 metrics = self.fontMetrics() | 180 metrics = self.fontMetrics() |
159 self.charHeight = metrics.height() | 181 self.charHeight = metrics.height() |
160 self.charWidth = metrics.width('x') | 182 self.charWidth = metrics.width('x') |
161 self.charDescent = metrics.descent() | 183 self.charDescent = metrics.descent() |
162 self.xposLNA = GAP | 184 self.xposERR = GAP |
163 self.xposTXT = self.xposLNA + 8 * self.charWidth + GAP | 185 self.xposLNA = self.xposERR + GAP + self.errorPixmap.width() |
186 self.xposTXT = self.xposLNA + 4 * self.charWidth + GAP | |
164 self.xposEnd = self.xposTXT + self.charWidth * 80 | 187 self.xposEnd = self.xposTXT + self.charWidth * 80 |
165 self.setMinimumWidth(self.xposEnd) | 188 self.setMinimumWidth(self.xposEnd) |
166 txt = self.src.split('\n') | 189 txt = self.src.split('\n') |
167 self.setMinimumHeight(self.charHeight * len(txt)) | 190 self.setMinimumHeight(self.charHeight * len(txt)) |
168 self.update() | 191 self.update() |
169 | 192 |
170 class CodeEdit(QScrollArea): | 193 class CodeEdit(QScrollArea): |
171 def __init__(self): | 194 def __init__(self): |
172 super().__init__() | 195 super().__init__() |
173 self.ic = InnerCode(self) | 196 self.ic = InnerCode(self) |
197 self.textChanged = self.ic.textChanged | |
174 self.setWidget(self.ic) | 198 self.setWidget(self.ic) |
175 self.setWidgetResizable(True) | 199 self.setWidgetResizable(True) |
176 self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) | 200 self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) |
177 self.setFocusPolicy(Qt.NoFocus) | 201 self.setFocusPolicy(Qt.NoFocus) |
178 Source = property(lambda s: s.ic.getSource(), lambda s, v: s.ic.setSource(v)) | 202 Source = property(lambda s: s.ic.getSource(), lambda s, v: s.ic.setSource(v)) |
203 def setErrors(self, el): | |
204 self.ic.setErrors(el) | |
179 | 205 |
180 if __name__ == '__main__': | 206 if __name__ == '__main__': |
181 app = QApplication(sys.argv) | 207 app = QApplication(sys.argv) |
182 ce = CodeEdit() | 208 ce = CodeEdit() |
183 ce.show() | 209 ce.show() |
184 src = ''.join(inspect.getsourcelines(InnerCode)[0]) | 210 src = ''.join(inspect.getsourcelines(InnerCode)[0]) |
185 ce.Source = src | 211 ce.Source = src |
212 print(ce.Source) | |
186 ce.resize(600, 800) | 213 ce.resize(600, 800) |
187 app.exec() | 214 app.exec() |
188 | 215 |