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