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
|
from defconQt.baseCodeEditor import CodeEditor, CodeHighlighter
from keyword import kwlist
import traceback
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor, QFont, QKeySequence, QTextCharFormat, QTextCursor
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QPlainTextEdit
class MainScriptingWindow(QMainWindow):
def __init__(self):
super(MainScriptingWindow, self).__init__()
self.editor = PythonEditor(parent=self)
self.resize(600, 500)
fileMenu = QMenu("&File", self)
fileMenu.addAction("&Run…", self.runScript, "Ctrl+R")
fileMenu.addSeparator()
fileMenu.addAction("E&xit", self.close, QKeySequence.Quit)
self.menuBar().addMenu(fileMenu)
self.setCentralWidget(self.editor)
self.setWindowTitle("[*]Untitled.py")
# arm `undoAvailable` to `setWindowModified`
self.editor.undoAvailable.connect(self.setWindowModified)
def runScript(self):
app = QApplication.instance()
script = self.editor.toPlainText()
global_vars = {
"__builtins__": __builtins__,
"AllFonts": app.allFonts,
"CurrentFont": app.currentFont,
"CurrentGlyph": app.currentGlyph,
"rootHandle": self,
}
try:
code = compile(script, "<string>", "exec")
exec(code, global_vars)
except:
print(traceback.format_exc())
class PythonEditor(CodeEditor):
autocomplete = {
Qt.Key_ParenLeft: "()",
Qt.Key_BracketLeft: "[]",
Qt.Key_BraceLeft: "{}",
Qt.Key_Apostrophe: "''",
Qt.Key_QuoteDbl: '""',
}
def __init__(self, text=None, parent=None):
super(PythonEditor, self).__init__(text, parent)
self.openBlockDelimiter = ":"
self.highlighter = PythonHighlighter(self.document())
def keyPressEvent(self, event):
key = event.key()
if key in self.autocomplete.keys():
super(PythonEditor, self).keyPressEvent(event)
cursor = self.textCursor()
ok = cursor.movePosition(QTextCursor.NextCharacter)
if not ok:
cursor.insertText(self.autocomplete[key][-1])
cursor.movePosition(QTextCursor.PreviousCharacter)
self.setTextCursor(cursor)
event.accept()
return
elif key == Qt.Key_Backspace:
cursor = self.textCursor()
ok = cursor.movePosition(QTextCursor.PreviousCharacter)
if ok:
ok = cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor, 2)
if ok and cursor.selectedText() in self.autocomplete.values():
cursor.removeSelectedText()
event.accept()
return
super(PythonEditor, self).keyPressEvent(event)
class PythonHighlighter(CodeHighlighter):
def __init__(self, parent=None):
super(PythonHighlighter, self).__init__(parent)
keywordFormat = QTextCharFormat()
keywordFormat.setForeground(QColor(34, 34, 34))
keywordFormat.setFontWeight(QFont.Bold)
self.highlightingRules.append(("\\b(%s)\\b" % ("|".join(kwlist)), keywordFormat))
singleLineCommentFormat = QTextCharFormat()
singleLineCommentFormat.setForeground(Qt.darkGray)
self.highlightingRules.append(("#[^\n]*", singleLineCommentFormat))
classOrFnNameFormat = QTextCharFormat()
classOrFnNameFormat.setForeground(QColor(96, 106, 161))
self.highlightingRules.append(("(?<=\\bclass\\s|def\\s\\b)\\s*(\\w+)", classOrFnNameFormat))
quotationFormat = QTextCharFormat()
quotationFormat.setForeground(QColor(223, 17, 68))
self.highlightingRules.append(("'.*'|[\"]{1,3}.*[\"]{1,3}", quotationFormat))
|