Mercurial > lcfOS
annotate python/codeeditor.py @ 222:c3f1ce8b638f
Fixup of parser
author | Windel Bouwman |
---|---|
date | Tue, 09 Jul 2013 17:36:31 +0200 |
parents | d8c735dc31f9 |
children |
rev | line source |
---|---|
1 | 1 from PyQt4.QtCore import * |
2 from PyQt4.QtGui import * | |
100 | 3 #import compiler.lexer |
9
92ace1ca50a8
64 bits kernel without interrupts but with printf in C
windel
parents:
8
diff
changeset
|
4 import os.path |
1 | 5 |
6 class MySyntaxHighlighter(QSyntaxHighlighter): | |
7 def __init__(self, parent=None): | |
8 super(MySyntaxHighlighter, self).__init__(parent) | |
9
92ace1ca50a8
64 bits kernel without interrupts but with printf in C
windel
parents:
8
diff
changeset
|
9 # Syntax highlighting: |
1 | 10 self.rules = [] |
11 fmt = QTextCharFormat() | |
12 fmt.setForeground(Qt.darkBlue) | |
13 fmt.setFontWeight(QFont.Bold) | |
100 | 14 #for kw in compiler.lexer.keywords: |
15 # pattern = '\\b'+kw+'\\b' | |
16 # self.rules.append( (pattern, fmt) ) | |
1 | 17 |
18 # Comments: | |
19 fmt = QTextCharFormat() | |
20 fmt.setForeground(Qt.gray) | |
21 fmt.setFontItalic(True) | |
22 pattern = '\{.*\}' | |
23 self.rules.append( (pattern, fmt) ) | |
24 | |
25 # Procedure: | |
26 fmt = QTextCharFormat() | |
27 fmt.setForeground(Qt.blue) | |
28 fmt.setFontItalic(True) | |
29 #pattern = '(?<=procedure )[A-Za-z]' | |
30 # TODO lookbehind does not work, think something else | |
31 #self.rules.append( (pattern, fmt) ) | |
32 | |
33 def highlightBlock(self, text): | |
34 for pattern, fmt in self.rules: | |
35 expression = QRegExp(pattern) | |
36 index = expression.indexIn(text) | |
37 while index >= 0: | |
38 length = expression.matchedLength() | |
39 self.setFormat(index, length, fmt) | |
40 index = expression.indexIn(text, index + length) | |
41 | |
42 class LineNumberArea(QWidget): | |
43 def __init__(self, codeedit): | |
44 super(LineNumberArea, self).__init__(codeedit) | |
45 self.codeedit = codeedit | |
46 # TODO: display error in this: self.setToolTip('hello world') | |
47 def sizeHint(self): | |
48 return QSize(self.codeedit.lineNumberAreaWidth(), 0) | |
49 def paintEvent(self, ev): | |
50 self.codeedit.lineNumberAreaPaintEvent(ev) | |
51 | |
52 class CodeEdit(QPlainTextEdit): | |
53 def __init__(self, parent=None): | |
54 super(CodeEdit, self).__init__(parent) | |
9
92ace1ca50a8
64 bits kernel without interrupts but with printf in C
windel
parents:
8
diff
changeset
|
55 # members: |
92ace1ca50a8
64 bits kernel without interrupts but with printf in C
windel
parents:
8
diff
changeset
|
56 self.isUntitled = True |
1 | 57 self.filename = None |
58 self.setFont(QFont('Courier')) | |
59 self.lineNumberArea = LineNumberArea(self) | |
154 | 60 h = QFontMetrics(self.font()).height() |
61 print(h) | |
62 self.errorPixmap = QPixmap('error.png').scaled(h, h) | |
63 self.errorList = [] | |
1 | 64 |
65 self.blockCountChanged.connect(self.updateLineNumberAreaWidth) | |
66 self.updateRequest.connect(self.updateLineNumberArea) | |
67 | |
68 # Syntax highlighter: | |
69 self.highlighter = MySyntaxHighlighter(self.document()) | |
70 | |
15 | 71 def setFileName(self, filename): |
1 | 72 self.filename = filename |
9
92ace1ca50a8
64 bits kernel without interrupts but with printf in C
windel
parents:
8
diff
changeset
|
73 self.isUntitled = False |
15 | 74 self.setWindowTitle(filename) |
101 | 75 |
15 | 76 def setSource(self, source): |
1 | 77 self.setPlainText(source) |
101 | 78 def getSource(self): |
79 return self.toPlainText() | |
162 | 80 Source = property(getSource, setSource) |
15 | 81 |
9
92ace1ca50a8
64 bits kernel without interrupts but with printf in C
windel
parents:
8
diff
changeset
|
82 def save(self): |
101 | 83 self.saveFile() |
9
92ace1ca50a8
64 bits kernel without interrupts but with printf in C
windel
parents:
8
diff
changeset
|
84 def saveAs(self): |
101 | 85 print('save as') |
8 | 86 |
1 | 87 def saveFile(self): |
9
92ace1ca50a8
64 bits kernel without interrupts but with printf in C
windel
parents:
8
diff
changeset
|
88 if self.isUntitled: |
92ace1ca50a8
64 bits kernel without interrupts but with printf in C
windel
parents:
8
diff
changeset
|
89 self.saveAs() |
92ace1ca50a8
64 bits kernel without interrupts but with printf in C
windel
parents:
8
diff
changeset
|
90 else: |
1 | 91 source = str(self.toPlainText()) |
101 | 92 with open(self.filename, 'w') as f: |
93 f.write(source) | |
1 | 94 |
95 def highlightErrorLocation(self, row, col): | |
96 tc = QTextCursor(self.document()) | |
97 tc.clearSelection() | |
98 tc.movePosition(tc.Down, tc.MoveAnchor, row - 1) | |
99 tc.movePosition(tc.Right, tc.MoveAnchor, col - 1) | |
100 tc.movePosition(tc.NextCharacter, tc.KeepAnchor) # Select 1 character | |
101 selection = QTextEdit.ExtraSelection() | |
102 lineColor = QColor(Qt.red).lighter(160) | |
103 selection.format.setBackground(lineColor) | |
104 #selection.format.setProperty(QTextFormat.FullWidthSelection, True) | |
105 selection.cursor = tc | |
106 self.setExtraSelections( [ selection ] ) | |
107 def clearErrors(self): | |
108 self.setExtraSelections( [ ] ) | |
154 | 109 def setErrors(self, el): |
110 self.errorList = el | |
111 self.lineNumberArea.update() | |
1 | 112 |
113 def lineNumberAreaWidth(self): | |
114 digits = 1 | |
115 mx = max(1, self.blockCount()) | |
116 while mx >= 10: | |
117 mx = mx / 10 | |
118 digits += 1 | |
154 | 119 space = 3 + self.fontMetrics().width('8') * digits + self.errorPixmap.width() + 2 |
1 | 120 return space |
121 def lineNumberAreaPaintEvent(self, ev): | |
122 painter = QPainter(self.lineNumberArea) | |
123 painter.fillRect(ev.rect(), Qt.lightGray) | |
124 block = self.firstVisibleBlock() | |
125 blockNumber = block.blockNumber() | |
126 top = self.blockBoundingGeometry(block).translated(self.contentOffset()).top() | |
127 bottom = top + self.blockBoundingRect(block).height() | |
128 while block.isValid() and top <= ev.rect().bottom(): | |
129 if block.isVisible() and bottom >= ev.rect().top(): | |
130 num = str(blockNumber + 1) | |
131 painter.setPen(Qt.black) | |
132 painter.drawText(0, top, self.lineNumberArea.width(), self.fontMetrics().height(), Qt.AlignRight, num) | |
154 | 133 for e in self.errorList: |
134 if e.loc.row == blockNumber + 1: | |
135 painter.drawPixmap(0, top, self.errorPixmap) | |
136 | |
1 | 137 block = block.next() |
138 top = bottom | |
139 bottom = top + self.blockBoundingRect(block).height() | |
140 blockNumber += 1 | |
141 def resizeEvent(self, ev): | |
142 super(CodeEdit, self).resizeEvent(ev) | |
143 cr = self.contentsRect() | |
144 self.lineNumberArea.setGeometry(QRect(cr.left(), cr.top(), self.lineNumberAreaWidth(), cr.height() )) | |
145 def updateLineNumberAreaWidth(self, newBlockCount): | |
146 self.setViewportMargins(self.lineNumberAreaWidth(), 0, 0, 0) | |
147 def updateLineNumberArea(self, rect, dy): | |
148 if dy > 0: | |
149 self.lineNumberArea.scroll(0, dy) | |
150 else: | |
151 self.lineNumberArea.update(0, rect.y(), self.lineNumberArea.width(), rect.height()) | |
152 if rect.contains(self.viewport().rect()): | |
153 self.updateLineNumberAreaWidth(0) | |
154 |