aboutsummaryrefslogtreecommitdiffstats
path: root/Lib/defconQt/scriptingWindow.py
blob: c6403e8e2573e1598076d38fe685c52f0d06c9fc (plain)
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
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


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))