easycoder 251105.1__py2.py3-none-any.whl → 260111.1__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- easycoder/__init__.py +6 -3
- easycoder/debugger/__init__.py +5 -0
- easycoder/debugger/ec_dbg_value_display copy.py +195 -0
- easycoder/debugger/ec_dbg_value_display.py +24 -0
- easycoder/debugger/ec_dbg_watch_list copy.py +219 -0
- easycoder/debugger/ec_dbg_watchlist.py +293 -0
- easycoder/debugger/ec_debug.py +1025 -0
- easycoder/ec_classes.py +487 -11
- easycoder/ec_compiler.py +81 -44
- easycoder/ec_condition.py +1 -1
- easycoder/ec_core.py +1042 -1081
- easycoder/ec_gclasses.py +236 -0
- easycoder/ec_graphics.py +1683 -0
- easycoder/ec_handler.py +18 -14
- easycoder/ec_mqtt.py +248 -0
- easycoder/ec_program.py +297 -168
- easycoder/ec_psutil.py +48 -0
- easycoder/ec_value.py +65 -47
- easycoder/pre/README.md +3 -0
- easycoder/pre/__init__.py +17 -0
- easycoder/pre/debugger/__init__.py +5 -0
- easycoder/pre/debugger/ec_dbg_value_display copy.py +195 -0
- easycoder/pre/debugger/ec_dbg_value_display.py +24 -0
- easycoder/pre/debugger/ec_dbg_watch_list copy.py +219 -0
- easycoder/pre/debugger/ec_dbg_watchlist.py +293 -0
- easycoder/{ec_debug.py → pre/debugger/ec_debug.py} +418 -185
- easycoder/pre/ec_border.py +67 -0
- easycoder/pre/ec_classes.py +470 -0
- easycoder/pre/ec_compiler.py +291 -0
- easycoder/pre/ec_condition.py +27 -0
- easycoder/pre/ec_core.py +2772 -0
- easycoder/pre/ec_gclasses.py +230 -0
- easycoder/{ec_pyside.py → pre/ec_graphics.py} +583 -433
- easycoder/pre/ec_handler.py +79 -0
- easycoder/pre/ec_keyboard.py +439 -0
- easycoder/pre/ec_program.py +557 -0
- easycoder/pre/ec_psutil.py +48 -0
- easycoder/pre/ec_timestamp.py +11 -0
- easycoder/pre/ec_value.py +124 -0
- easycoder/pre/icons/close.png +0 -0
- easycoder/pre/icons/exit.png +0 -0
- easycoder/pre/icons/run.png +0 -0
- easycoder/pre/icons/step.png +0 -0
- easycoder/pre/icons/stop.png +0 -0
- easycoder/pre/icons/tick.png +0 -0
- {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/METADATA +11 -1
- easycoder-260111.1.dist-info/RECORD +59 -0
- easycoder-251105.1.dist-info/RECORD +0 -24
- {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/WHEEL +0 -0
- {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/entry_points.txt +0 -0
- {easycoder-251105.1.dist-info → easycoder-260111.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,9 +1,30 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
from functools import partial
|
|
3
3
|
from .ec_handler import Handler
|
|
4
|
-
from .ec_classes import
|
|
4
|
+
from .ec_classes import (
|
|
5
|
+
FatalError,
|
|
6
|
+
RuntimeError,
|
|
7
|
+
ECValue
|
|
8
|
+
)
|
|
9
|
+
from .ec_gclasses import (
|
|
10
|
+
ECWidget,
|
|
11
|
+
ECCoreWidget,
|
|
12
|
+
ECLayout,
|
|
13
|
+
ECGroup,
|
|
14
|
+
ECPanel,
|
|
15
|
+
ECLabel,
|
|
16
|
+
ECPushButton,
|
|
17
|
+
ECCheckBox,
|
|
18
|
+
ECLineInput,
|
|
19
|
+
ECMultiline,
|
|
20
|
+
ECListBox,
|
|
21
|
+
ECComboBox,
|
|
22
|
+
ECWindow,
|
|
23
|
+
ECDialog,
|
|
24
|
+
ECMessageBox,
|
|
25
|
+
)
|
|
5
26
|
from .ec_border import Border
|
|
6
|
-
from .ec_debug import Debugger
|
|
27
|
+
from .debugger.ec_debug import Debugger
|
|
7
28
|
from PySide6.QtCore import Qt, QTimer, Signal, QRect
|
|
8
29
|
from PySide6.QtGui import QPixmap, QPainter
|
|
9
30
|
from PySide6.QtWidgets import (
|
|
@@ -42,6 +63,120 @@ from PySide6.QtWidgets import (
|
|
|
42
63
|
QGraphicsDropShadowEffect
|
|
43
64
|
)
|
|
44
65
|
|
|
66
|
+
#############################################################################
|
|
67
|
+
# EC Label widget class
|
|
68
|
+
class ECLabelWidget(QLabel):
|
|
69
|
+
def __init__(self, text=None):
|
|
70
|
+
super().__init__(text)
|
|
71
|
+
self.setStyleSheet("""
|
|
72
|
+
background-color: transparent;
|
|
73
|
+
border: none;
|
|
74
|
+
""")
|
|
75
|
+
|
|
76
|
+
#############################################################################
|
|
77
|
+
# EC Pushbutton widget class
|
|
78
|
+
class ECPushButtonWidget(QPushButton):
|
|
79
|
+
def __init__(self, text=None):
|
|
80
|
+
super().__init__(text)
|
|
81
|
+
|
|
82
|
+
def getContent(self):
|
|
83
|
+
return self.text()
|
|
84
|
+
|
|
85
|
+
#############################################################################
|
|
86
|
+
# EC Checkbox widget class
|
|
87
|
+
class ECCheckBoxWidget(QCheckBox):
|
|
88
|
+
def __init__(self, text=None):
|
|
89
|
+
super().__init__(text)
|
|
90
|
+
self.setStyleSheet("""
|
|
91
|
+
QCheckBox::indicator {
|
|
92
|
+
border: 1px solid black;
|
|
93
|
+
border-radius: 3px;
|
|
94
|
+
background: white;
|
|
95
|
+
width: 16px;
|
|
96
|
+
height: 16px;
|
|
97
|
+
}
|
|
98
|
+
QCheckBox::indicator:checked {
|
|
99
|
+
background: #0078d7;
|
|
100
|
+
}
|
|
101
|
+
QCheckBox {
|
|
102
|
+
border: none;
|
|
103
|
+
background: transparent;
|
|
104
|
+
}
|
|
105
|
+
""")
|
|
106
|
+
|
|
107
|
+
#############################################################################
|
|
108
|
+
# EC line edit widget class
|
|
109
|
+
class ECLineEditWidget(QLineEdit):
|
|
110
|
+
clicked = Signal()
|
|
111
|
+
|
|
112
|
+
def __init__(self):
|
|
113
|
+
super().__init__()
|
|
114
|
+
self.multiline = False
|
|
115
|
+
self.container = None
|
|
116
|
+
|
|
117
|
+
def setContainer(self, container):
|
|
118
|
+
self.container = container
|
|
119
|
+
|
|
120
|
+
def mousePressEvent(self, event):
|
|
121
|
+
self.clicked.emit()
|
|
122
|
+
super().mousePressEvent(event)
|
|
123
|
+
if self.container != None: self.container.setClickSource(self)
|
|
124
|
+
|
|
125
|
+
#############################################################################
|
|
126
|
+
# EC plain text edit widget class
|
|
127
|
+
class ECPlainTextEditWidget(QPlainTextEdit):
|
|
128
|
+
clicked = Signal()
|
|
129
|
+
|
|
130
|
+
def __init__(self):
|
|
131
|
+
super().__init__()
|
|
132
|
+
self.multiline = True
|
|
133
|
+
self.container = None
|
|
134
|
+
|
|
135
|
+
def setContainer(self, container):
|
|
136
|
+
self.container = container
|
|
137
|
+
|
|
138
|
+
def mousePressEvent(self, event):
|
|
139
|
+
self.clicked.emit()
|
|
140
|
+
super().mousePressEvent(event)
|
|
141
|
+
if self.container != None: self.container.setClickSource(self)
|
|
142
|
+
|
|
143
|
+
#############################################################################
|
|
144
|
+
# EC Listbox widget class
|
|
145
|
+
class ECListBoxWidget(QListWidget):
|
|
146
|
+
def __init__(self, text=None):
|
|
147
|
+
super().__init__(text)
|
|
148
|
+
|
|
149
|
+
def text(self):
|
|
150
|
+
return self.currentItem().text()
|
|
151
|
+
|
|
152
|
+
#############################################################################
|
|
153
|
+
# EC ComboBox widget class
|
|
154
|
+
class ECComboBoxWidget(QComboBox):
|
|
155
|
+
def __init__(self, text=None):
|
|
156
|
+
super().__init__(text)
|
|
157
|
+
|
|
158
|
+
def text(self):
|
|
159
|
+
return self.currentText()
|
|
160
|
+
|
|
161
|
+
#############################################################################
|
|
162
|
+
# EC dialog class
|
|
163
|
+
class ECDialogWindow(QDialog):
|
|
164
|
+
clicked = Signal()
|
|
165
|
+
|
|
166
|
+
def __init__(self, window):
|
|
167
|
+
super().__init__(window)
|
|
168
|
+
self.multiline = True
|
|
169
|
+
self.container = None
|
|
170
|
+
|
|
171
|
+
def setContainer(self, container):
|
|
172
|
+
self.container = container
|
|
173
|
+
|
|
174
|
+
def mousePressEvent(self, event):
|
|
175
|
+
self.clicked.emit()
|
|
176
|
+
super().mousePressEvent(event)
|
|
177
|
+
if self.container != None: self.container.setClickSource(self)
|
|
178
|
+
|
|
179
|
+
###############################################################################
|
|
45
180
|
class Graphics(Handler):
|
|
46
181
|
|
|
47
182
|
def __init__(self, compiler):
|
|
@@ -56,71 +191,19 @@ class Graphics(Handler):
|
|
|
56
191
|
def closeEvent(self):
|
|
57
192
|
print('window closed')
|
|
58
193
|
|
|
59
|
-
def
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
'group',
|
|
63
|
-
'label',
|
|
64
|
-
'pushbutton',
|
|
65
|
-
'checkbox',
|
|
66
|
-
'lineinput',
|
|
67
|
-
'multiline',
|
|
68
|
-
'listbox',
|
|
69
|
-
'combobox',
|
|
70
|
-
'widget'
|
|
71
|
-
]
|
|
72
|
-
|
|
73
|
-
def setWidget(self, record, widget):
|
|
74
|
-
if record['index'] >= record['elements']:
|
|
75
|
-
RuntimeError(self.program, f'Index out of range for widget {record["name"]}')
|
|
76
|
-
if not 'widget' in record:
|
|
77
|
-
record['widget'] = [None] * record['elements']
|
|
78
|
-
while len(record['widget']) < record['elements']:
|
|
79
|
-
record['widget'].append(None)
|
|
80
|
-
record['widget'][record['index']] = widget
|
|
194
|
+
def isCoreWidget(self, object):
|
|
195
|
+
if isinstance(object, dict): object = object['object']
|
|
196
|
+
return isinstance(object, ECCoreWidget)
|
|
81
197
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return None
|
|
198
|
+
# Set a graphic element as the value of a record
|
|
199
|
+
def setGraphicElement(self, record, element):
|
|
200
|
+
object = self.getObject(record)
|
|
201
|
+
# object.setValue(ECValue(domain=self.getName(), type='object', content=element))
|
|
202
|
+
object.setValue(element)
|
|
88
203
|
|
|
89
204
|
def dialogTypes(self):
|
|
90
205
|
return ['confirm', 'lineedit', 'multiline', 'generic']
|
|
91
|
-
|
|
92
|
-
class ClickableLineEdit(QLineEdit):
|
|
93
|
-
clicked = Signal()
|
|
94
|
-
|
|
95
|
-
def __init__(self):
|
|
96
|
-
super().__init__()
|
|
97
|
-
self.multiline = False
|
|
98
|
-
self.container = None
|
|
99
|
-
|
|
100
|
-
def setContainer(self, container):
|
|
101
|
-
self.container = container
|
|
102
|
-
|
|
103
|
-
def mousePressEvent(self, event):
|
|
104
|
-
self.clicked.emit()
|
|
105
|
-
super().mousePressEvent(event)
|
|
106
|
-
if self.container != None: self.container.setClickSource(self)
|
|
107
|
-
|
|
108
|
-
class ClickablePlainTextEdit(QPlainTextEdit):
|
|
109
|
-
clicked = Signal()
|
|
110
|
-
|
|
111
|
-
def __init__(self):
|
|
112
|
-
super().__init__()
|
|
113
|
-
self.multiline = True
|
|
114
|
-
self.container = None
|
|
115
|
-
|
|
116
|
-
def setContainer(self, container):
|
|
117
|
-
self.container = container
|
|
118
|
-
|
|
119
|
-
def mousePressEvent(self, event):
|
|
120
|
-
self.clicked.emit()
|
|
121
|
-
super().mousePressEvent(event)
|
|
122
|
-
if self.container != None: self.container.setClickSource(self)
|
|
123
|
-
|
|
206
|
+
|
|
124
207
|
#############################################################################
|
|
125
208
|
# Keyword handlers
|
|
126
209
|
|
|
@@ -131,13 +214,16 @@ class Graphics(Handler):
|
|
|
131
214
|
# (5) add spacer [size] {size} to {layout}
|
|
132
215
|
# (6) add {widget} at {col} {row} in {grid layout}
|
|
133
216
|
def k_add(self, command):
|
|
217
|
+
|
|
218
|
+
# Add to a layout, group, list or combo box
|
|
134
219
|
def addToLayout():
|
|
135
220
|
if self.nextIsSymbol():
|
|
136
221
|
record = self.getSymbolRecord()
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
222
|
+
object = self.getObject(record)
|
|
223
|
+
self.checkObjectType(record, (ECLayout, ECGroup, ECListBox, ECComboBox))
|
|
224
|
+
command['target'] = record['name']
|
|
225
|
+
self.add(command)
|
|
226
|
+
return True
|
|
141
227
|
return False
|
|
142
228
|
|
|
143
229
|
token = self.peek()
|
|
@@ -166,82 +252,90 @@ class Graphics(Handler):
|
|
|
166
252
|
self.skip('to')
|
|
167
253
|
return addToLayout()
|
|
168
254
|
|
|
169
|
-
# Here it's either (1) or (
|
|
255
|
+
# Here it's either (1), (2) or (6)
|
|
170
256
|
elif self.nextIsSymbol():
|
|
171
257
|
record = self.getSymbolRecord()
|
|
172
|
-
if record
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
258
|
+
if self.isObjectType(record, ECWidget):
|
|
259
|
+
# It's either (2), (6) or (1)
|
|
260
|
+
command['widget'] = record['name']
|
|
261
|
+
if self.peek() == 'to':
|
|
262
|
+
# (2)
|
|
263
|
+
record = self.getSymbolRecord()
|
|
264
|
+
domainName = record['domain']
|
|
265
|
+
if domainName != self.getName():
|
|
266
|
+
domain = self.program.domainIndex[domainName]
|
|
267
|
+
handler = domain.keywordHandler('add')
|
|
268
|
+
return handler(command)
|
|
269
|
+
self.nextToken()
|
|
270
|
+
return addToLayout()
|
|
271
|
+
elif self.peek() == 'at':
|
|
272
|
+
# (6)
|
|
273
|
+
self.nextToken()
|
|
274
|
+
command['row'] = self.nextValue()
|
|
275
|
+
command['col'] = self.nextValue()
|
|
276
|
+
self.skip('in')
|
|
277
|
+
return addToLayout()
|
|
278
|
+
else:
|
|
279
|
+
# It's (1) with a non-widget variable
|
|
280
|
+
command['value'] = self.getValue()
|
|
281
|
+
self.skip('to')
|
|
282
|
+
return addToLayout()
|
|
187
283
|
|
|
188
|
-
|
|
189
|
-
# (1)
|
|
284
|
+
# (1) with a value
|
|
190
285
|
value = self.getValue()
|
|
191
286
|
if value == None: return False
|
|
192
287
|
command['value'] = value
|
|
193
288
|
self.skip('to')
|
|
194
|
-
|
|
195
|
-
record = self.getSymbolRecord()
|
|
196
|
-
command['widget'] = record['name']
|
|
197
|
-
self.add(command)
|
|
198
|
-
return True
|
|
199
|
-
return False
|
|
289
|
+
return addToLayout()
|
|
200
290
|
|
|
201
291
|
def r_add(self, command):
|
|
202
292
|
if 'value' in command:
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
293
|
+
record = self.getVariable(command['target'])
|
|
294
|
+
object = self.getObject(record)
|
|
295
|
+
value = self.textify(command['value'])
|
|
296
|
+
if isinstance(object, ECListBox):
|
|
297
|
+
self.getInnerObject(record).addItem(value) # type: ignore
|
|
298
|
+
elif isinstance(object, ECComboBox):
|
|
208
299
|
if isinstance(value, list): record['widget'].addItems(value)
|
|
209
|
-
else: self.
|
|
300
|
+
else: self.getInnerObject(record).addItem(value) # type: ignore
|
|
210
301
|
elif 'row' in command and 'col' in command:
|
|
211
302
|
layout = self.getVariable(command['layout'])['widget']
|
|
212
303
|
record = self.getVariable(command['widget'])
|
|
213
|
-
widget = self.
|
|
214
|
-
row = self.
|
|
215
|
-
col = self.
|
|
216
|
-
if record
|
|
304
|
+
widget = self.getInnerObject(record)
|
|
305
|
+
row = self.textify(command['row'])
|
|
306
|
+
col = self.textify(command['col'])
|
|
307
|
+
if self.isObjectType(record, ECLayout):
|
|
217
308
|
layout.addLayout(widget, row, col)
|
|
218
309
|
else:
|
|
219
310
|
layout.addWidget(widget, row, col)
|
|
220
311
|
else:
|
|
221
|
-
layoutRecord = self.getVariable(command['
|
|
312
|
+
layoutRecord = self.getVariable(command['target'])
|
|
222
313
|
widget = command['widget']
|
|
223
314
|
if widget == 'stretch':
|
|
224
|
-
self.
|
|
315
|
+
self.getInnerObject(layoutRecord).addStretch() # type: ignore
|
|
225
316
|
elif widget == 'spacer':
|
|
226
|
-
self.
|
|
317
|
+
self.getInnerObject(layoutRecord).addSpacing(self.textify(command['size'])) # type: ignore
|
|
227
318
|
else:
|
|
228
319
|
widgetRecord = self.getVariable(widget)
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
320
|
+
self.checkObjectType(widgetRecord, ECCoreWidget)
|
|
321
|
+
self.checkObjectType(layoutRecord, ECLayout)
|
|
322
|
+
widget = self.getInnerObject(widgetRecord)
|
|
323
|
+
layout = self.getInnerObject(layoutRecord)
|
|
232
324
|
stretch = 'stretch' in command
|
|
233
|
-
if widgetRecord
|
|
234
|
-
if layoutRecord
|
|
235
|
-
if widgetRecord
|
|
236
|
-
layout.setLayout(widget)
|
|
325
|
+
if self.isObjectType(widgetRecord, ECLayout):
|
|
326
|
+
if self.isObjectType(layoutRecord, ECGroup):
|
|
327
|
+
if self.isObjectType(widgetRecord, ECLayout):
|
|
328
|
+
layout.setLayout(widget) # type: ignore
|
|
237
329
|
else:
|
|
238
330
|
RuntimeError(self.program, 'Can only add a layout to a group')
|
|
239
331
|
else:
|
|
240
|
-
if stretch: layout.addLayout(widget, stretch=1)
|
|
241
|
-
else:
|
|
332
|
+
if stretch: layout.addLayout(widget, stretch=1) # type: ignore
|
|
333
|
+
else:
|
|
334
|
+
layout.addLayout(widget) # type: ignore
|
|
242
335
|
else:
|
|
243
|
-
if stretch: layout.addWidget(widget, stretch=1)
|
|
244
|
-
else:
|
|
336
|
+
if stretch: layout.addWidget(widget, stretch=1) # type: ignore
|
|
337
|
+
else:
|
|
338
|
+
layout.addWidget(widget) # type: ignore
|
|
245
339
|
return self.nextPC()
|
|
246
340
|
|
|
247
341
|
# Center one window on another
|
|
@@ -249,46 +343,58 @@ class Graphics(Handler):
|
|
|
249
343
|
def k_center(self, command):
|
|
250
344
|
if self.nextIsSymbol():
|
|
251
345
|
record = self.getSymbolRecord()
|
|
252
|
-
if record
|
|
346
|
+
if self.isObjectType(record, ECWindow):
|
|
253
347
|
command['window2'] = record['name']
|
|
254
348
|
self.skip('on')
|
|
255
349
|
if self.nextIsSymbol():
|
|
256
350
|
record = self.getSymbolRecord()
|
|
257
|
-
if record
|
|
351
|
+
if self.isObjectType(record, ECWindow):
|
|
258
352
|
command['window1'] = record['name']
|
|
259
353
|
self.add(command)
|
|
260
354
|
return True
|
|
261
355
|
return False
|
|
262
356
|
|
|
357
|
+
def k_centre(self,command):
|
|
358
|
+
return self.k_center(command)
|
|
359
|
+
|
|
263
360
|
def r_center(self, command):
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
361
|
+
object = self.getVariable(command['window1'])['object']
|
|
362
|
+
self.checkObjectType(object, ECWindow)
|
|
363
|
+
window1 = self.getInnerObject(object)
|
|
364
|
+
object = self.getVariable(command['window2'])['object']
|
|
365
|
+
self.checkObjectType(object, ECWindow)
|
|
366
|
+
window2 = self.getInnerObject(object)
|
|
367
|
+
geo1 = window1.geometry() # type: ignore
|
|
368
|
+
geo2 = window2.geometry() # type: ignore
|
|
268
369
|
geo2.moveCenter(geo1.center())
|
|
269
|
-
window2.setGeometry(geo2)
|
|
370
|
+
window2.setGeometry(geo2) # type: ignore
|
|
270
371
|
return self.nextPC()
|
|
271
372
|
|
|
272
373
|
# Declare a checkbox variable
|
|
273
374
|
def k_checkbox(self, command):
|
|
274
|
-
|
|
375
|
+
self.compiler.addValueType()
|
|
376
|
+
return self.compileVariable(command, 'ECCheckBox')
|
|
275
377
|
|
|
276
378
|
def r_checkbox(self, command):
|
|
277
379
|
return self.nextPC()
|
|
278
380
|
|
|
279
|
-
# clear {widget}
|
|
381
|
+
# clear {window/widget}
|
|
280
382
|
def k_clear(self, command):
|
|
281
383
|
if self.nextIsSymbol():
|
|
282
384
|
record = self.getSymbolRecord()
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
385
|
+
object = self.getObject(record)
|
|
386
|
+
if object.isCoreClass():
|
|
387
|
+
if object.isClearable():
|
|
388
|
+
command['name'] = record['name']
|
|
389
|
+
self.add(command)
|
|
390
|
+
return True
|
|
391
|
+
raise FatalError(self.compiler, f'The object {record["name"]} is not clearable')
|
|
287
392
|
return False
|
|
288
393
|
|
|
289
394
|
def r_clear(self, command):
|
|
290
395
|
|
|
291
396
|
def clearLayout(layout: QLayout) -> None:
|
|
397
|
+
"""Recursively clear all items from a layout."""
|
|
292
398
|
if layout is None:
|
|
293
399
|
return
|
|
294
400
|
while layout.count() > 0:
|
|
@@ -297,50 +403,59 @@ class Graphics(Handler):
|
|
|
297
403
|
continue
|
|
298
404
|
widget = item.widget()
|
|
299
405
|
if widget is not None:
|
|
300
|
-
# Delete the widget
|
|
301
406
|
widget.deleteLater()
|
|
302
407
|
elif item.layout() is not None:
|
|
303
|
-
# Recursively clear sub-layout
|
|
304
408
|
clearLayout(item.layout())
|
|
305
409
|
item.layout().deleteLater()
|
|
306
|
-
# The QLayoutItem will be automatically cleaned up by Qt
|
|
307
410
|
|
|
308
411
|
def clearWidget(widget: QWidget) -> None:
|
|
412
|
+
"""Clear all contents from a widget."""
|
|
309
413
|
if widget is None:
|
|
310
414
|
return
|
|
311
|
-
|
|
415
|
+
if isinstance(widget, (QListWidget, QComboBox)):
|
|
416
|
+
if isinstance(widget, QListWidget):
|
|
417
|
+
for i in range(widget.count()):
|
|
418
|
+
item_widget = widget.itemWidget(widget.item(i))
|
|
419
|
+
if item_widget:
|
|
420
|
+
item_widget.deleteLater()
|
|
421
|
+
widget.clear()
|
|
422
|
+
return
|
|
312
423
|
layout = widget.layout()
|
|
313
424
|
if layout is not None:
|
|
314
425
|
clearLayout(layout)
|
|
315
426
|
layout.deleteLater()
|
|
316
|
-
# Clear any remaining child widgets
|
|
317
427
|
child_widgets = widget.findChildren(QWidget, "", Qt.FindChildOption.FindDirectChildrenOnly)
|
|
318
428
|
for child in child_widgets:
|
|
319
429
|
child.deleteLater()
|
|
320
430
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
431
|
+
element = self.getInnerObject(self.getVariable(command['name']))
|
|
432
|
+
if isinstance(element, QLayout):
|
|
433
|
+
clearLayout(element) # type: ignore
|
|
434
|
+
else:
|
|
435
|
+
clearWidget(element) # type: ignore
|
|
325
436
|
return self.nextPC()
|
|
326
437
|
|
|
327
438
|
# close {window}
|
|
328
439
|
def k_close(self, command):
|
|
329
440
|
if self.nextIsSymbol():
|
|
330
441
|
record = self.getSymbolRecord()
|
|
331
|
-
if record
|
|
442
|
+
if self.isObjectType(record, ECWindow):
|
|
332
443
|
command['name'] = record['name']
|
|
333
444
|
self.add(command)
|
|
334
445
|
return True
|
|
335
446
|
return False
|
|
336
447
|
|
|
337
448
|
def r_close(self, command):
|
|
338
|
-
self.getVariable(command['name'])
|
|
449
|
+
record = self.getVariable(command['name'])
|
|
450
|
+
window = self.getInnerObject(record)
|
|
451
|
+
self.checkObjectType(window, QMainWindow)
|
|
452
|
+
window.close() # type: ignore
|
|
339
453
|
return self.nextPC()
|
|
340
454
|
|
|
341
455
|
# Declare a combobox variable
|
|
342
456
|
def k_combobox(self, command):
|
|
343
|
-
|
|
457
|
+
self.compiler.addValueType()
|
|
458
|
+
return self.compileVariable(command, 'ECComboBox')
|
|
344
459
|
|
|
345
460
|
def r_combobox(self, command):
|
|
346
461
|
return self.nextPC()
|
|
@@ -366,7 +481,7 @@ class Graphics(Handler):
|
|
|
366
481
|
elif token == 'layout':
|
|
367
482
|
if self.nextIsSymbol():
|
|
368
483
|
record = self.getSymbolRecord()
|
|
369
|
-
if record
|
|
484
|
+
if self.isObjectType(record, ECLayout):
|
|
370
485
|
command['layout'] = record['name']
|
|
371
486
|
else: return False
|
|
372
487
|
else: break
|
|
@@ -476,7 +591,15 @@ class Graphics(Handler):
|
|
|
476
591
|
self.add(command)
|
|
477
592
|
return True
|
|
478
593
|
|
|
479
|
-
def
|
|
594
|
+
def k_createListBox(self, command):
|
|
595
|
+
self.add(command)
|
|
596
|
+
return True
|
|
597
|
+
|
|
598
|
+
def k_createComboBox(self, command):
|
|
599
|
+
self.add(command)
|
|
600
|
+
return True
|
|
601
|
+
|
|
602
|
+
def k_createPanel(self, command):
|
|
480
603
|
self.add(command)
|
|
481
604
|
return True
|
|
482
605
|
|
|
@@ -543,7 +666,6 @@ class Graphics(Handler):
|
|
|
543
666
|
command['name'] = record['name']
|
|
544
667
|
keyword = record['keyword']
|
|
545
668
|
if keyword == 'window': return self.k_createWindow(command)
|
|
546
|
-
elif keyword in ['listbox', 'combobox', 'widget']: return self.k_createWidget(command)
|
|
547
669
|
elif keyword == 'layout': return self.k_createLayout(command)
|
|
548
670
|
elif keyword == 'group': return self.k_createGroupBox(command)
|
|
549
671
|
elif keyword == 'label': return self.k_createLabel(command)
|
|
@@ -551,17 +673,20 @@ class Graphics(Handler):
|
|
|
551
673
|
elif keyword == 'checkbox': return self.k_createCheckBox(command)
|
|
552
674
|
elif keyword == 'lineinput': return self.k_createLineEdit(command)
|
|
553
675
|
elif keyword == 'multiline': return self.k_createMultiLineEdit(command)
|
|
676
|
+
elif keyword == 'listbox': return self.k_createListBox(command)
|
|
677
|
+
elif keyword == 'combobox': return self.k_createComboBox(command)
|
|
678
|
+
elif keyword == 'panel': return self.k_createPanel(command)
|
|
554
679
|
elif keyword == 'dialog': return self.k_createDialog(command)
|
|
555
680
|
elif keyword == 'messagebox': return self.k_createMessageBox(command)
|
|
556
681
|
return False
|
|
557
682
|
|
|
558
683
|
def r_createWindow(self, command, record):
|
|
559
684
|
window = QMainWindow()
|
|
560
|
-
title = self.
|
|
685
|
+
title = self.textify(command['title'])
|
|
561
686
|
if title == None: title = 'EasyCoder Main Window'
|
|
562
687
|
window.setWindowTitle(title)
|
|
563
|
-
w = self.
|
|
564
|
-
h = self.
|
|
688
|
+
w = self.textify(command['w'])
|
|
689
|
+
h = self.textify(command['h'])
|
|
565
690
|
x = command['x']
|
|
566
691
|
y = command['y']
|
|
567
692
|
if hasattr(self.program, 'screenWidth'): screenWidth = self.program.screenWidth
|
|
@@ -569,11 +694,11 @@ class Graphics(Handler):
|
|
|
569
694
|
if hasattr(self.program, 'screenHeight'): screenHeight = self.program.screenHeight
|
|
570
695
|
else: screenHeight = self.program.parent.program.screenHeight
|
|
571
696
|
if x == None: x = (screenWidth - w) / 2
|
|
572
|
-
else: x = self.
|
|
697
|
+
else: x = self.textify(x)
|
|
573
698
|
if y == None: y = (screenHeight - h) / 2
|
|
574
|
-
else: y = self.
|
|
699
|
+
else: y = self.textify(x)
|
|
575
700
|
window.setGeometry(x, y, w, h)
|
|
576
|
-
record
|
|
701
|
+
self.setGraphicElement(record, window)
|
|
577
702
|
return self.nextPC()
|
|
578
703
|
|
|
579
704
|
def r_createLayout(self, command, record):
|
|
@@ -583,25 +708,21 @@ class Graphics(Handler):
|
|
|
583
708
|
elif layoutType == 'QStackedLayout': layout = QStackedLayout()
|
|
584
709
|
else: layout = QVBoxLayout()
|
|
585
710
|
layout.setContentsMargins(5,0,5,0)
|
|
586
|
-
record
|
|
711
|
+
self.setGraphicElement(record, layout)
|
|
587
712
|
return self.nextPC()
|
|
588
713
|
|
|
589
714
|
def r_createGroupBox(self, command, record):
|
|
590
|
-
group = QGroupBox(self.
|
|
715
|
+
group = QGroupBox(self.textify(command['title']))
|
|
591
716
|
group.setAlignment(Qt.AlignmentFlag.AlignLeft)
|
|
592
|
-
record
|
|
717
|
+
self.setGraphicElement(record, group)
|
|
593
718
|
return self.nextPC()
|
|
594
719
|
|
|
595
720
|
def r_createLabel(self, command, record):
|
|
596
|
-
label =
|
|
597
|
-
label.setStyleSheet("""
|
|
598
|
-
background-color: transparent;
|
|
599
|
-
border: none;
|
|
600
|
-
""")
|
|
721
|
+
label = ECLabelWidget(str(self.textify(command['text'])))
|
|
601
722
|
if 'size' in command:
|
|
602
723
|
fm = label.fontMetrics()
|
|
603
724
|
c = label.contentsMargins()
|
|
604
|
-
w = fm.horizontalAdvance('m') * self.
|
|
725
|
+
w = fm.horizontalAdvance('m') * self.textify(command['size']) +c.left()+c.right()
|
|
605
726
|
label.setMaximumWidth(w)
|
|
606
727
|
if 'align' in command:
|
|
607
728
|
alignment = command['align']
|
|
@@ -611,15 +732,15 @@ class Graphics(Handler):
|
|
|
611
732
|
elif alignment == 'justify': label.setAlignment(Qt.AlignmentFlag.AlignJustify)
|
|
612
733
|
if 'expand' in command:
|
|
613
734
|
label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
|
|
614
|
-
self.
|
|
735
|
+
self.setGraphicElement(record, label)
|
|
615
736
|
return self.nextPC()
|
|
616
737
|
|
|
617
738
|
def r_createPushbutton(self, command, record):
|
|
618
739
|
if 'size' in command:
|
|
619
|
-
size = self.
|
|
740
|
+
size = self.textify(command['size'])
|
|
620
741
|
else: size = None
|
|
621
742
|
if 'icon' in command:
|
|
622
|
-
iconPath = self.
|
|
743
|
+
iconPath = self.textify(command['icon'])
|
|
623
744
|
pixmap = QPixmap(iconPath)
|
|
624
745
|
if pixmap.isNull():
|
|
625
746
|
RuntimeError(self.program, f'Icon not found: {iconPath}')
|
|
@@ -628,76 +749,63 @@ class Graphics(Handler):
|
|
|
628
749
|
pushbutton.setIcon(icon)
|
|
629
750
|
pushbutton.setIconSize(icon.size())
|
|
630
751
|
elif 'text' in command:
|
|
631
|
-
text = self.
|
|
632
|
-
pushbutton =
|
|
752
|
+
text = self.textify(command['text'])
|
|
753
|
+
pushbutton = ECPushButtonWidget(text)
|
|
633
754
|
pushbutton.setAccessibleName(text)
|
|
634
755
|
if size != None:
|
|
635
756
|
fm = pushbutton.fontMetrics()
|
|
636
757
|
c = pushbutton.contentsMargins()
|
|
637
|
-
w = fm.horizontalAdvance('m') * self.
|
|
758
|
+
w = fm.horizontalAdvance('m') * self.textify(command['size']) + c.left()+c.right()
|
|
638
759
|
pushbutton.setMaximumWidth(w)
|
|
639
760
|
self.putSymbolValue(record, pushbutton)
|
|
640
|
-
self.
|
|
761
|
+
self.setGraphicElement(record, pushbutton)
|
|
641
762
|
return self.nextPC()
|
|
642
763
|
|
|
643
764
|
def r_createCheckBox(self, command, record):
|
|
644
|
-
checkbox =
|
|
645
|
-
checkbox.setStyleSheet("""
|
|
646
|
-
QCheckBox::indicator {
|
|
647
|
-
border: 1px solid black;
|
|
648
|
-
border-radius: 3px;
|
|
649
|
-
background: white;
|
|
650
|
-
width: 16px;
|
|
651
|
-
height: 16px;
|
|
652
|
-
}
|
|
653
|
-
QCheckBox::indicator:checked {
|
|
654
|
-
background: #0078d7;
|
|
655
|
-
}
|
|
656
|
-
QCheckBox {
|
|
657
|
-
border: none;
|
|
658
|
-
background: transparent;
|
|
659
|
-
}
|
|
660
|
-
""")
|
|
765
|
+
checkbox = ECCheckBoxWidget(self.textify(command['text']))
|
|
661
766
|
checkbox.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
|
|
662
|
-
self.
|
|
767
|
+
self.setGraphicElement(record, checkbox)
|
|
663
768
|
return self.nextPC()
|
|
664
769
|
|
|
665
770
|
def r_createLineEdit(self, command, record):
|
|
666
|
-
lineinput =
|
|
667
|
-
lineinput.setText(self.
|
|
771
|
+
lineinput = ECLineEditWidget()
|
|
772
|
+
lineinput.setText(self.textify(command['text']))
|
|
668
773
|
fm = lineinput.fontMetrics()
|
|
669
774
|
m = lineinput.textMargins()
|
|
670
775
|
c = lineinput.contentsMargins()
|
|
671
|
-
w = fm.horizontalAdvance('x') * self.
|
|
776
|
+
w = fm.horizontalAdvance('x') * self.textify(command['size']) +m.left()+m.right()+c.left()+c.right()
|
|
672
777
|
lineinput.setMaximumWidth(w)
|
|
673
|
-
self.
|
|
778
|
+
self.setGraphicElement(record, lineinput)
|
|
674
779
|
return self.nextPC()
|
|
675
780
|
|
|
676
781
|
def r_createMultiLineEdit(self, command, record):
|
|
677
|
-
textinput =
|
|
782
|
+
textinput = ECPlainTextEditWidget()
|
|
678
783
|
fontMetrics = textinput.fontMetrics()
|
|
679
784
|
charWidth = fontMetrics.horizontalAdvance('x')
|
|
680
785
|
charHeight = fontMetrics.height()
|
|
681
|
-
textinput.setFixedWidth(charWidth * self.
|
|
682
|
-
textinput.setFixedHeight(charHeight * self.
|
|
683
|
-
self.
|
|
786
|
+
textinput.setFixedWidth(charWidth * self.textify(command['cols']))
|
|
787
|
+
textinput.setFixedHeight(charHeight * self.textify(command['rows']))
|
|
788
|
+
self.setGraphicElement(record, textinput)
|
|
684
789
|
return self.nextPC()
|
|
685
790
|
|
|
686
791
|
def r_createListWidget(self, command, record):
|
|
687
|
-
|
|
792
|
+
listwidget = ECListBoxWidget()
|
|
793
|
+
self.setGraphicElement(record, listwidget)
|
|
688
794
|
return self.nextPC()
|
|
689
795
|
|
|
690
796
|
def r_createComboBox(self, command, record):
|
|
691
|
-
|
|
797
|
+
combobox = ECComboBoxWidget()
|
|
798
|
+
self.setGraphicElement(record, combobox)
|
|
692
799
|
return self.nextPC()
|
|
693
800
|
|
|
694
|
-
def
|
|
695
|
-
self.
|
|
801
|
+
def r_createPanel(self, command, record):
|
|
802
|
+
self.setGraphicElement(record, QWidget())
|
|
696
803
|
return self.nextPC()
|
|
697
804
|
|
|
698
805
|
def r_createDialog(self, command, record):
|
|
699
806
|
|
|
700
|
-
|
|
807
|
+
# This is probably not needed anymore
|
|
808
|
+
class ECDialogX(QDialog):
|
|
701
809
|
def __init__(self, parent, record):
|
|
702
810
|
super().__init__(parent)
|
|
703
811
|
self.record = record
|
|
@@ -711,8 +819,8 @@ class Graphics(Handler):
|
|
|
711
819
|
|
|
712
820
|
win = command['window']
|
|
713
821
|
if win != None:
|
|
714
|
-
win = self.getVariable(win)
|
|
715
|
-
dialog =
|
|
822
|
+
win = self.getInnerObject(self.getVariable(win))
|
|
823
|
+
dialog = ECDialogWindow(win)
|
|
716
824
|
dialogType = command['type'].lower()
|
|
717
825
|
dialog.dialogType = dialogType # type: ignore
|
|
718
826
|
mainLayout = QVBoxLayout(dialog)
|
|
@@ -732,36 +840,35 @@ class Graphics(Handler):
|
|
|
732
840
|
mainLayout.addLayout(layout)
|
|
733
841
|
dialog.setLayout(mainLayout)
|
|
734
842
|
else:
|
|
735
|
-
dialog.setWindowTitle(self.
|
|
736
|
-
prompt = self.
|
|
843
|
+
dialog.setWindowTitle(self.textify(command['title']))
|
|
844
|
+
prompt = self.textify(command['prompt'])
|
|
737
845
|
if dialogType == 'confirm':
|
|
738
|
-
mainLayout.addWidget(
|
|
846
|
+
mainLayout.addWidget(ECLabelWidget(prompt))
|
|
739
847
|
elif dialogType == 'lineedit':
|
|
740
|
-
mainLayout.addWidget(
|
|
741
|
-
dialog.lineEdit = self.
|
|
742
|
-
dialog.value = self.
|
|
848
|
+
mainLayout.addWidget(ECLabelWidget(prompt))
|
|
849
|
+
dialog.lineEdit = self.ECLineEdit(dialog) # type: ignore
|
|
850
|
+
dialog.value = self.textify(command['value']) # type: ignore
|
|
743
851
|
dialog.lineEdit.setText(dialog.value) # type: ignore
|
|
744
852
|
mainLayout.addWidget(dialog.lineEdit) # type: ignore
|
|
745
853
|
elif dialogType == 'multiline':
|
|
746
|
-
mainLayout.addWidget(
|
|
747
|
-
dialog.textEdit = self.
|
|
854
|
+
mainLayout.addWidget(ECLabelWidget(prompt))
|
|
855
|
+
dialog.textEdit = self.ECPlainTextEdit(dialog) # type: ignore
|
|
748
856
|
dialog.textEdit.setText(dialog.value) # type: ignore
|
|
749
857
|
mainLayout.addWidget(dialog.textEdit) # type: ignore
|
|
750
858
|
buttonBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
|
|
751
859
|
buttonBox.accepted.connect(dialog.accept)
|
|
752
860
|
buttonBox.rejected.connect(dialog.reject)
|
|
753
861
|
mainLayout.addWidget(buttonBox, alignment=Qt.AlignmentFlag.AlignHCenter)
|
|
754
|
-
|
|
862
|
+
|
|
863
|
+
self.setGraphicElement(record, dialog)
|
|
755
864
|
return self.nextPC()
|
|
756
865
|
|
|
757
866
|
# Creates a message box but doesn't run it
|
|
758
867
|
def r_createMessageBox(self, command, record):
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
data['message'] = self.getRuntimeValue(command['message'])
|
|
764
|
-
record['data'] = data
|
|
868
|
+
record['window'] = command['window']
|
|
869
|
+
record['style'] = command['style']
|
|
870
|
+
record['title'] = self.textify(command['title'])
|
|
871
|
+
record['message'] = self.textify(command['message'])
|
|
765
872
|
return self.nextPC()
|
|
766
873
|
|
|
767
874
|
def r_create(self, command):
|
|
@@ -777,14 +884,15 @@ class Graphics(Handler):
|
|
|
777
884
|
elif keyword == 'multiline': return self.r_createMultiLineEdit(command, record)
|
|
778
885
|
elif keyword == 'listbox': return self.r_createListWidget(command, record)
|
|
779
886
|
elif keyword == 'combobox': return self.r_createComboBox(command, record)
|
|
780
|
-
elif keyword == '
|
|
887
|
+
elif keyword == 'panel': return self.r_createPanel(command, record)
|
|
781
888
|
elif keyword == 'dialog': return self.r_createDialog(command, record)
|
|
782
889
|
elif keyword == 'messagebox': return self.r_createMessageBox(command, record)
|
|
783
890
|
return None
|
|
784
891
|
|
|
785
892
|
# Declare a dialog variable
|
|
786
893
|
def k_dialog(self, command):
|
|
787
|
-
|
|
894
|
+
self.compiler.addValueType()
|
|
895
|
+
return self.compileVariable(command, 'ECDialog')
|
|
788
896
|
|
|
789
897
|
def r_dialog(self, command):
|
|
790
898
|
return self.nextPC()
|
|
@@ -798,7 +906,7 @@ class Graphics(Handler):
|
|
|
798
906
|
return False
|
|
799
907
|
|
|
800
908
|
def r_disable(self, command):
|
|
801
|
-
self.
|
|
909
|
+
self.getInnerObject(self.getVariable(command['name'])).setEnabled(False) # type: ignore
|
|
802
910
|
return self.nextPC()
|
|
803
911
|
|
|
804
912
|
# Enable a widget
|
|
@@ -810,12 +918,13 @@ class Graphics(Handler):
|
|
|
810
918
|
return False
|
|
811
919
|
|
|
812
920
|
def r_enable(self, command):
|
|
813
|
-
self.
|
|
921
|
+
self.getInnerObject(self.getVariable(command['name'])).setEnabled(True) # type: ignore
|
|
814
922
|
return self.nextPC()
|
|
815
923
|
|
|
816
924
|
# Create a group box
|
|
817
925
|
def k_group(self, command):
|
|
818
|
-
|
|
926
|
+
self.compiler.addValueType()
|
|
927
|
+
return self.compileVariable(command, 'ECGroup')
|
|
819
928
|
|
|
820
929
|
def r_group(self, command):
|
|
821
930
|
return self.nextPC()
|
|
@@ -824,7 +933,8 @@ class Graphics(Handler):
|
|
|
824
933
|
def k_hide(self, command):
|
|
825
934
|
if self.nextIsSymbol():
|
|
826
935
|
record = self.getSymbolRecord()
|
|
827
|
-
if self.
|
|
936
|
+
if self.isObjectType(record, ECCoreWidget):
|
|
937
|
+
command['domain'] = record['domain']
|
|
828
938
|
command['widget'] = record['name']
|
|
829
939
|
self.add(command)
|
|
830
940
|
return True
|
|
@@ -832,13 +942,14 @@ class Graphics(Handler):
|
|
|
832
942
|
|
|
833
943
|
def r_hide(self, command):
|
|
834
944
|
record = self.getVariable(command['widget'])
|
|
835
|
-
|
|
945
|
+
self.getInnerObject(record).hide() # type: ignore
|
|
836
946
|
return self.nextPC()
|
|
837
947
|
|
|
838
948
|
# Initialize the graphics environment
|
|
839
949
|
# Unused: def k_init(self, command):
|
|
840
950
|
|
|
841
951
|
def r_init(self, command):
|
|
952
|
+
print('Initializing graphics...')
|
|
842
953
|
self.app = QApplication(sys.argv)
|
|
843
954
|
screen = QApplication.screens()[0].size().toTuple()
|
|
844
955
|
self.program.screenWidth = screen[0] # type: ignore
|
|
@@ -858,53 +969,61 @@ class Graphics(Handler):
|
|
|
858
969
|
timer.timeout.connect(flush)
|
|
859
970
|
timer.start(10)
|
|
860
971
|
QTimer.singleShot(500, init)
|
|
861
|
-
|
|
972
|
+
self.program.startGraphics()
|
|
973
|
+
if self.program.debugging:
|
|
974
|
+
print('Starting debugger...')
|
|
975
|
+
self.program.debugger = Debugger(self.program)
|
|
976
|
+
self.program.debugger.enableBreakpoints()
|
|
862
977
|
self.app.lastWindowClosed.connect(on_last_window_closed)
|
|
863
978
|
self.app.exec()
|
|
864
979
|
|
|
865
980
|
# Declare a label variable
|
|
866
981
|
def k_label(self, command):
|
|
867
|
-
|
|
868
|
-
|
|
982
|
+
self.compiler.addValueType()
|
|
983
|
+
return self.compileVariable(command, 'ECLabel')
|
|
869
984
|
def r_label(self, command):
|
|
870
985
|
return self.nextPC()
|
|
871
986
|
|
|
872
987
|
# Declare a layout variable
|
|
873
988
|
def k_layout(self, command):
|
|
874
|
-
|
|
989
|
+
self.compiler.addValueType()
|
|
990
|
+
return self.compileVariable(command, 'ECLayout')
|
|
875
991
|
|
|
876
992
|
def r_layout(self, command):
|
|
877
993
|
return self.nextPC()
|
|
878
994
|
|
|
879
995
|
# Declare a line input variable
|
|
880
996
|
def k_lineinput(self, command):
|
|
881
|
-
|
|
997
|
+
self.compiler.addValueType()
|
|
998
|
+
return self.compileVariable(command, 'ECLineInput')
|
|
882
999
|
|
|
883
1000
|
def r_lineinput(self, command):
|
|
884
1001
|
return self.nextPC()
|
|
885
1002
|
|
|
886
1003
|
# Declare a listbox input variable
|
|
887
1004
|
def k_listbox(self, command):
|
|
888
|
-
|
|
1005
|
+
self.compiler.addValueType()
|
|
1006
|
+
return self.compileVariable(command, 'ECListBox')
|
|
889
1007
|
|
|
890
1008
|
def r_listbox(self, command):
|
|
891
1009
|
return self.nextPC()
|
|
892
1010
|
|
|
893
1011
|
# Declare a messagebox variable
|
|
894
1012
|
def k_messagebox(self, command):
|
|
895
|
-
|
|
1013
|
+
self.compiler.addValueType()
|
|
1014
|
+
return self.compileVariable(command, 'ECMessageBox')
|
|
896
1015
|
|
|
897
1016
|
def r_messagebox(self, command):
|
|
898
1017
|
return self.nextPC()
|
|
899
1018
|
|
|
900
1019
|
# Declare a multiline input variable
|
|
901
1020
|
def k_multiline(self, command):
|
|
902
|
-
|
|
903
|
-
|
|
1021
|
+
self.compiler.addValueType()
|
|
1022
|
+
return self.compileVariable(command, 'ECMultiline')
|
|
904
1023
|
def r_multiline(self, command):
|
|
905
1024
|
return self.nextPC()
|
|
906
1025
|
|
|
907
|
-
# on click {pushbutton}/{lineinput}/{multiline}
|
|
1026
|
+
# on click/tap {pushbutton}/{lineinput}/{multiline}
|
|
908
1027
|
# on select {combobox}/{listbox}
|
|
909
1028
|
# on tick
|
|
910
1029
|
def k_on(self, command):
|
|
@@ -934,17 +1053,18 @@ class Graphics(Handler):
|
|
|
934
1053
|
|
|
935
1054
|
token = self.nextToken()
|
|
936
1055
|
command['type'] = token
|
|
937
|
-
if token
|
|
1056
|
+
if token in ['click', 'tap']:
|
|
938
1057
|
if self.nextIsSymbol():
|
|
939
1058
|
record = self.getSymbolRecord()
|
|
940
|
-
if record
|
|
1059
|
+
if isinstance(self.getObject(record), ECWidget):
|
|
1060
|
+
command['domain'] = record['domain']
|
|
941
1061
|
command['name'] = record['name']
|
|
942
1062
|
setupOn()
|
|
943
1063
|
return True
|
|
944
1064
|
elif token == 'select':
|
|
945
1065
|
if self.nextIsSymbol():
|
|
946
1066
|
record = self.getSymbolRecord()
|
|
947
|
-
if record
|
|
1067
|
+
if isinstance(self.getObject(record), ECCoreWidget):
|
|
948
1068
|
command['name'] = record['name']
|
|
949
1069
|
setupOn()
|
|
950
1070
|
return True
|
|
@@ -976,50 +1096,53 @@ class Graphics(Handler):
|
|
|
976
1096
|
return False
|
|
977
1097
|
|
|
978
1098
|
def r_on(self, command):
|
|
979
|
-
def run(widget, record):
|
|
980
|
-
for i, w in enumerate(record['widget']):
|
|
981
|
-
if w == widget:
|
|
982
|
-
record['index'] = i
|
|
983
|
-
self.run(command['goto'])
|
|
984
|
-
return
|
|
985
|
-
|
|
986
1099
|
if command['type'] == 'tick':
|
|
987
1100
|
self.runOnTick = command['runOnTick']
|
|
988
1101
|
else:
|
|
989
1102
|
record = self.getVariable(command['name'])
|
|
990
|
-
widget = self.
|
|
991
|
-
|
|
992
|
-
if
|
|
993
|
-
handler = partial(
|
|
994
|
-
widget.clicked.connect(handler)
|
|
995
|
-
elif
|
|
996
|
-
widget.currentIndexChanged.connect(lambda: self.run(
|
|
997
|
-
elif
|
|
998
|
-
widget.itemClicked.connect(lambda: self.run(
|
|
1103
|
+
widget = self.getInnerObject(self.getObject(record))
|
|
1104
|
+
goto = command['goto']
|
|
1105
|
+
if self.isObjectType(record, ECPushButton):
|
|
1106
|
+
handler = partial(self.callback, widget, record, goto)
|
|
1107
|
+
widget.clicked.connect(handler)
|
|
1108
|
+
elif self.isObjectType(record, ECComboBox):
|
|
1109
|
+
widget.currentIndexChanged.connect(lambda: self.run(goto))
|
|
1110
|
+
elif self.isObjectType(record, ECListBox):
|
|
1111
|
+
widget.itemClicked.connect(lambda: self.run(goto))
|
|
1112
|
+
return self.nextPC()
|
|
1113
|
+
|
|
1114
|
+
# Declare a simple panel variable
|
|
1115
|
+
def k_panel(self, command):
|
|
1116
|
+
self.compiler.addValueType()
|
|
1117
|
+
return self.compileVariable(command, 'ECPanel')
|
|
1118
|
+
|
|
1119
|
+
def r_panel(self, command):
|
|
999
1120
|
return self.nextPC()
|
|
1000
1121
|
|
|
1001
1122
|
# Declare a pushbutton variable
|
|
1002
1123
|
def k_pushbutton(self, command):
|
|
1003
|
-
|
|
1124
|
+
self.compiler.addValueType()
|
|
1125
|
+
return self.compileVariable(command, 'ECPushButton')
|
|
1004
1126
|
|
|
1005
1127
|
def r_pushbutton(self, command):
|
|
1006
1128
|
return self.nextPC()
|
|
1007
1129
|
|
|
1008
1130
|
# remove [the] [current/selected] [item] [from/in] {combobox}/{listbox}
|
|
1131
|
+
# Graphics-reserved syntax: optional article pattern is plugin-safe (core-only command)
|
|
1009
1132
|
def k_remove(self, command):
|
|
1010
1133
|
command['variant'] = None
|
|
1011
|
-
self.
|
|
1134
|
+
self.skipArticles() # Optional 'the', 'a', 'an' — syntactic sugar
|
|
1012
1135
|
self.skip(['current', 'selected'])
|
|
1013
1136
|
self.skip('item')
|
|
1014
1137
|
self.skip(['from', 'in'])
|
|
1015
1138
|
if self.nextIsSymbol():
|
|
1016
1139
|
record = self.getSymbolRecord()
|
|
1017
|
-
if record
|
|
1140
|
+
if self.isObjectType(record, ECComboBox):
|
|
1018
1141
|
command['variant'] = 'current'
|
|
1019
1142
|
command['name'] = record['name']
|
|
1020
1143
|
self.add(command)
|
|
1021
1144
|
return True
|
|
1022
|
-
elif record
|
|
1145
|
+
elif self.isObjectType(record, ECListBox):
|
|
1023
1146
|
command['variant'] = 'current'
|
|
1024
1147
|
command['name'] = record['name']
|
|
1025
1148
|
self.add(command)
|
|
@@ -1030,11 +1153,11 @@ class Graphics(Handler):
|
|
|
1030
1153
|
variant = command['variant']
|
|
1031
1154
|
record = self.getVariable(command['name'])
|
|
1032
1155
|
if variant == 'current':
|
|
1033
|
-
if record
|
|
1034
|
-
widget = self.
|
|
1156
|
+
if self.isObjectType(record, ECComboBox):
|
|
1157
|
+
widget = self.getInnerObject(record)
|
|
1035
1158
|
widget.removeItem(widget.currentIndex()) # type: ignore
|
|
1036
|
-
if record
|
|
1037
|
-
widget = self.
|
|
1159
|
+
if self.isObjectType(record, ECListBox):
|
|
1160
|
+
widget = self.getInnerObject(record)
|
|
1038
1161
|
selectedItem = widget.currentItem() # type: ignore
|
|
1039
1162
|
if selectedItem:
|
|
1040
1163
|
row = widget.row(selectedItem) # type: ignore
|
|
@@ -1052,18 +1175,18 @@ class Graphics(Handler):
|
|
|
1052
1175
|
self.skip('in')
|
|
1053
1176
|
if self.nextIsSymbol():
|
|
1054
1177
|
record = self.getSymbolRecord()
|
|
1055
|
-
if record
|
|
1178
|
+
if self.isObjectType(record, ECComboBox):
|
|
1056
1179
|
command['widget'] = record['name']
|
|
1057
1180
|
self.add(command)
|
|
1058
1181
|
return True
|
|
1059
1182
|
return False
|
|
1060
1183
|
|
|
1061
1184
|
def r_select(self, command):
|
|
1062
|
-
widget = self.
|
|
1185
|
+
widget = self.getInnerObject(self.getVariable(command['widget']))
|
|
1063
1186
|
if 'index' in command:
|
|
1064
|
-
index = self.
|
|
1187
|
+
index = self.textify(command['index'])
|
|
1065
1188
|
else:
|
|
1066
|
-
name = self.
|
|
1189
|
+
name = self.textify(command['name'])
|
|
1067
1190
|
index = widget.findText(name, Qt.MatchFlag.MatchFixedString) # type: ignore
|
|
1068
1191
|
if index >= 0:
|
|
1069
1192
|
widget.setCurrentIndex(index) # type: ignore
|
|
@@ -1079,14 +1202,18 @@ class Graphics(Handler):
|
|
|
1079
1202
|
# set {listbox} to {list}
|
|
1080
1203
|
# set blocked true/false
|
|
1081
1204
|
def k_set(self, command):
|
|
1082
|
-
|
|
1205
|
+
# Graphics-reserved syntax: optional article pattern with 'of'/'to' prepositions
|
|
1206
|
+
# Forms like 'set the layout of Window to MainPanel' and 'set layout of Window to MainPanel' are equivalent
|
|
1207
|
+
# Plugin-safe: graphics is a core-only module
|
|
1208
|
+
self.skipArticles() # Optional 'the', 'a', 'an' — syntactic sugar for readability
|
|
1083
1209
|
token = self.nextToken()
|
|
1084
1210
|
command['what'] = token
|
|
1085
1211
|
if token in ['width', 'height']:
|
|
1086
1212
|
self.skip('of')
|
|
1087
1213
|
if self.nextIsSymbol():
|
|
1088
1214
|
record = self.getSymbolRecord()
|
|
1089
|
-
if record
|
|
1215
|
+
if self.isObjectType(record, ECCoreWidget):
|
|
1216
|
+
command['domain'] = record['domain']
|
|
1090
1217
|
command['name'] = record['name']
|
|
1091
1218
|
self.skip('to')
|
|
1092
1219
|
command['value'] = self.nextValue()
|
|
@@ -1096,13 +1223,12 @@ class Graphics(Handler):
|
|
|
1096
1223
|
self.skip('of')
|
|
1097
1224
|
if self.nextIsSymbol():
|
|
1098
1225
|
record = self.getSymbolRecord()
|
|
1099
|
-
|
|
1100
|
-
if keyword in ['window', 'widget']:
|
|
1226
|
+
if self.isObjectType(record, (ECWindow, ECGroup, ECPanel)):
|
|
1101
1227
|
command['name'] = record['name']
|
|
1102
1228
|
self.skip('to')
|
|
1103
1229
|
if self.nextIsSymbol():
|
|
1104
1230
|
record = self.getSymbolRecord()
|
|
1105
|
-
if record
|
|
1231
|
+
if self.isObjectType(record, ECLayout):
|
|
1106
1232
|
command['layout'] = record['name']
|
|
1107
1233
|
self.add(command)
|
|
1108
1234
|
return True
|
|
@@ -1110,7 +1236,7 @@ class Graphics(Handler):
|
|
|
1110
1236
|
self.skip('of')
|
|
1111
1237
|
if self.nextIsSymbol():
|
|
1112
1238
|
record = self.getSymbolRecord()
|
|
1113
|
-
if record
|
|
1239
|
+
if self.isObjectType(record, ECLayout):
|
|
1114
1240
|
command['name'] = record['name']
|
|
1115
1241
|
self.skip('to')
|
|
1116
1242
|
command['value'] = self.nextValue()
|
|
@@ -1120,7 +1246,7 @@ class Graphics(Handler):
|
|
|
1120
1246
|
self.skip('of')
|
|
1121
1247
|
if self.nextIsSymbol():
|
|
1122
1248
|
record = self.getSymbolRecord()
|
|
1123
|
-
if record
|
|
1249
|
+
if self.isObjectType(record, (ECLabel, ECPushButton, ECLineInput, ECMultiline)):
|
|
1124
1250
|
command['name'] = record['name']
|
|
1125
1251
|
self.skip('to')
|
|
1126
1252
|
command['value'] = self.nextValue()
|
|
@@ -1130,7 +1256,7 @@ class Graphics(Handler):
|
|
|
1130
1256
|
self.skip('of')
|
|
1131
1257
|
if self.nextIsSymbol():
|
|
1132
1258
|
record = self.getSymbolRecord()
|
|
1133
|
-
if record
|
|
1259
|
+
if self.isObjectType(record, ECCheckBox):
|
|
1134
1260
|
command['name'] = record['name']
|
|
1135
1261
|
self.skip('to')
|
|
1136
1262
|
if self.peek() == 'checked':
|
|
@@ -1146,7 +1272,7 @@ class Graphics(Handler):
|
|
|
1146
1272
|
self.skip('of')
|
|
1147
1273
|
if self.nextIsSymbol():
|
|
1148
1274
|
record = self.getSymbolRecord()
|
|
1149
|
-
if record
|
|
1275
|
+
if self.isObjectType(record, ECWidget):
|
|
1150
1276
|
command['name'] = record['name']
|
|
1151
1277
|
self.skip('to')
|
|
1152
1278
|
command['value'] = self.nextValue()
|
|
@@ -1156,7 +1282,7 @@ class Graphics(Handler):
|
|
|
1156
1282
|
self.skip('of')
|
|
1157
1283
|
if self.nextIsSymbol():
|
|
1158
1284
|
record = self.getSymbolRecord()
|
|
1159
|
-
if record
|
|
1285
|
+
if self.isObjectType(record, ECWidget):
|
|
1160
1286
|
command['name'] = record['name']
|
|
1161
1287
|
self.skip('to')
|
|
1162
1288
|
flags = []
|
|
@@ -1169,7 +1295,7 @@ class Graphics(Handler):
|
|
|
1169
1295
|
self.skip('of')
|
|
1170
1296
|
if self.nextIsSymbol():
|
|
1171
1297
|
record = self.getSymbolRecord()
|
|
1172
|
-
if record
|
|
1298
|
+
if self.isObjectType(record, ECLabel):
|
|
1173
1299
|
command['name'] = record['name']
|
|
1174
1300
|
self.skip('to')
|
|
1175
1301
|
command['value'] = self.nextValue()
|
|
@@ -1179,7 +1305,7 @@ class Graphics(Handler):
|
|
|
1179
1305
|
self.skip('of')
|
|
1180
1306
|
if self.nextIsSymbol():
|
|
1181
1307
|
record = self.getSymbolRecord()
|
|
1182
|
-
if record
|
|
1308
|
+
if self.isObjectType(record, ECLabel):
|
|
1183
1309
|
command['name'] = record['name']
|
|
1184
1310
|
self.skip('to')
|
|
1185
1311
|
command['value'] = self.nextValue()
|
|
@@ -1190,7 +1316,7 @@ class Graphics(Handler):
|
|
|
1190
1316
|
self.skip('of')
|
|
1191
1317
|
if self.nextIsSymbol():
|
|
1192
1318
|
record = self.getSymbolRecord()
|
|
1193
|
-
if record
|
|
1319
|
+
if self.isObjectType(record, (ECLabel, ECPushButton, ECLineInput, ECMultiline)):
|
|
1194
1320
|
command['name'] = record['name']
|
|
1195
1321
|
self.skip('to')
|
|
1196
1322
|
command['value'] = self.nextValue()
|
|
@@ -1201,7 +1327,7 @@ class Graphics(Handler):
|
|
|
1201
1327
|
return True
|
|
1202
1328
|
elif self.isSymbol():
|
|
1203
1329
|
record = self.getSymbolRecord()
|
|
1204
|
-
if record
|
|
1330
|
+
if self.isObjectType(record, ECListBox):
|
|
1205
1331
|
command['what'] = 'listbox'
|
|
1206
1332
|
command['name'] = record['name']
|
|
1207
1333
|
self.skip('to')
|
|
@@ -1213,44 +1339,44 @@ class Graphics(Handler):
|
|
|
1213
1339
|
def r_set(self, command):
|
|
1214
1340
|
what = command['what']
|
|
1215
1341
|
if what == 'height':
|
|
1216
|
-
widget = self.
|
|
1217
|
-
widget.setFixedHeight(self.
|
|
1342
|
+
widget = self.getInnerObject(self.getVariable(command['name']))
|
|
1343
|
+
widget.setFixedHeight(self.textify(command['value'])) # type: ignore
|
|
1218
1344
|
elif what == 'width':
|
|
1219
|
-
widget = self.
|
|
1220
|
-
widget.setFixedWidth(self.
|
|
1345
|
+
widget = self.getInnerObject(self.getVariable(command['name']))
|
|
1346
|
+
widget.setFixedWidth(self.textify(command['value'])) # type: ignore
|
|
1221
1347
|
elif what == 'layout':
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1348
|
+
target = self.getVariable(command['name'])
|
|
1349
|
+
object = target['object']
|
|
1350
|
+
layoutObject = self.getVariable(command['layout'])['object']
|
|
1351
|
+
self.checkObjectType(layoutObject, ECLayout)
|
|
1352
|
+
layout = self.getInnerObject(layoutObject)
|
|
1353
|
+
if isinstance(object, ECWindow):
|
|
1354
|
+
window = self.getInnerObject(object)
|
|
1228
1355
|
container = QWidget()
|
|
1229
|
-
container.setLayout(layout)
|
|
1230
|
-
|
|
1231
|
-
elif
|
|
1232
|
-
|
|
1233
|
-
widget.setLayout(layout) # type: ignore
|
|
1356
|
+
container.setLayout(layout) # type: ignore
|
|
1357
|
+
self.getInnerObject(object).setCentralWidget(container) # type: ignore
|
|
1358
|
+
elif isinstance(object, (ECLayout, ECGroup, ECPanel)):
|
|
1359
|
+
self.getInnerObject(object).setLayout(layout) # type: ignore
|
|
1234
1360
|
elif what == 'spacing':
|
|
1235
|
-
layout = self.
|
|
1236
|
-
layout.setSpacing(self.
|
|
1361
|
+
layout = self.getInnerObject(self.getVariable(command['name']))
|
|
1362
|
+
layout.setSpacing(self.textify(command['value'])) # type: ignore
|
|
1237
1363
|
elif what == 'text':
|
|
1238
1364
|
record = self.getVariable(command['name'])
|
|
1239
|
-
widget = self.
|
|
1240
|
-
text = self.
|
|
1365
|
+
widget = self.getInnerObject(record)
|
|
1366
|
+
text = self.textify(command['value'])
|
|
1241
1367
|
keyword = record['keyword']
|
|
1242
1368
|
setText = getattr(widget, "setText", None)
|
|
1243
1369
|
if callable(setText):
|
|
1244
1370
|
widget.setText(text) # type: ignore
|
|
1245
|
-
elif
|
|
1371
|
+
elif self.isObjectType(record, ECMultiline):
|
|
1246
1372
|
widget.setPlainText(text) # type: ignore
|
|
1247
|
-
if record
|
|
1373
|
+
if self.isObjectType(record, ECPushButton):
|
|
1248
1374
|
widget.setAccessibleName(text) # type: ignore
|
|
1249
1375
|
elif what == 'state':
|
|
1250
1376
|
record = self.getVariable(command['name'])
|
|
1251
|
-
if record
|
|
1252
|
-
state = self.
|
|
1253
|
-
self.
|
|
1377
|
+
if self.isObjectType(record, ECCheckBox):
|
|
1378
|
+
state = self.textify(command['value'])
|
|
1379
|
+
self.getInnerObject(record).setChecked(state) # type: ignore
|
|
1254
1380
|
elif what == 'alignment':
|
|
1255
1381
|
widget = self.getVariable(command['name'])['widget']
|
|
1256
1382
|
flags = command['value']
|
|
@@ -1266,23 +1392,23 @@ class Graphics(Handler):
|
|
|
1266
1392
|
widget.setAlignment(alignment)
|
|
1267
1393
|
elif what == 'style':
|
|
1268
1394
|
record = self.getVariable(command['name'])
|
|
1269
|
-
widget = self.
|
|
1270
|
-
styles = self.
|
|
1395
|
+
widget = self.getInnerObject(record)
|
|
1396
|
+
styles = self.textify(command['value'])
|
|
1271
1397
|
widget.setStyleSheet(styles) # type: ignore
|
|
1272
1398
|
elif what == 'color':
|
|
1273
1399
|
record = self.getVariable(command['name'])
|
|
1274
|
-
widget = self.
|
|
1275
|
-
color = self.
|
|
1400
|
+
widget = self.getInnerObject(record)
|
|
1401
|
+
color = self.textify(command['value'])
|
|
1276
1402
|
widget.setStyleSheet(f"color: {color};") # type: ignore
|
|
1277
1403
|
elif what == 'background-color':
|
|
1278
1404
|
record = self.getVariable(command['name'])
|
|
1279
|
-
widget = self.
|
|
1280
|
-
bg_color = self.
|
|
1405
|
+
widget = self.getInnerObject(record)
|
|
1406
|
+
bg_color = self.textify(command['value'])
|
|
1281
1407
|
widget.setStyleSheet(f"background-color: {bg_color};") # type: ignore
|
|
1282
1408
|
elif what == 'listbox':
|
|
1283
1409
|
record = self.getVariable(command['name'])
|
|
1284
|
-
widget = self.
|
|
1285
|
-
value = self.
|
|
1410
|
+
widget = self.getInnerObject(record)
|
|
1411
|
+
value = self.textify(command['value'])
|
|
1286
1412
|
widget.clear() # type: ignore
|
|
1287
1413
|
widget.addItems(value) # type: ignore
|
|
1288
1414
|
return self.nextPC()
|
|
@@ -1294,20 +1420,20 @@ class Graphics(Handler):
|
|
|
1294
1420
|
def k_show(self, command):
|
|
1295
1421
|
if self.nextIsSymbol():
|
|
1296
1422
|
record = self.getSymbolRecord()
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
command['
|
|
1423
|
+
if self.isObjectType(record, ECCoreWidget):
|
|
1424
|
+
command['domain'] = record['domain']
|
|
1425
|
+
command['name'] = record['name']
|
|
1300
1426
|
self.add(command)
|
|
1301
1427
|
return True
|
|
1302
|
-
elif
|
|
1303
|
-
command['
|
|
1428
|
+
elif self.isObjectType(record, ECWindow):
|
|
1429
|
+
command['window'] = record['name']
|
|
1304
1430
|
self.add(command)
|
|
1305
1431
|
return True
|
|
1306
|
-
elif self.
|
|
1307
|
-
command['
|
|
1432
|
+
elif self.isObjectType(record, ECDialog):
|
|
1433
|
+
command['dialog'] = record['name']
|
|
1308
1434
|
self.add(command)
|
|
1309
1435
|
return True
|
|
1310
|
-
elif
|
|
1436
|
+
elif self.isObjectType(record, ECMessageBox):
|
|
1311
1437
|
command['messagebox'] = record['name']
|
|
1312
1438
|
self.skip('giving')
|
|
1313
1439
|
if self.nextIsSymbol():
|
|
@@ -1318,12 +1444,13 @@ class Graphics(Handler):
|
|
|
1318
1444
|
|
|
1319
1445
|
def r_show(self, command):
|
|
1320
1446
|
if 'messagebox' in command:
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
window = self.
|
|
1324
|
-
style =
|
|
1325
|
-
title =
|
|
1326
|
-
message =
|
|
1447
|
+
record = self.getVariable(command['messagebox'])
|
|
1448
|
+
windowRecord = self.getVariable(record['window'])
|
|
1449
|
+
window = self.getInnerObject(windowRecord)
|
|
1450
|
+
style = record['style']
|
|
1451
|
+
title = record['title']
|
|
1452
|
+
message = record['message']
|
|
1453
|
+
target = self.getVariable(command['result'])
|
|
1327
1454
|
if style == 'question':
|
|
1328
1455
|
choice = QMessageBox.question(window, title, message)
|
|
1329
1456
|
result = 'Yes' if choice == QMessageBox.StandardButton.Yes else 'No'
|
|
@@ -1345,53 +1472,37 @@ class Graphics(Handler):
|
|
|
1345
1472
|
if choice == QMessageBox.StandardButton.Ok: result = 'OK'
|
|
1346
1473
|
else: result = ''
|
|
1347
1474
|
else: result = 'Cancel'
|
|
1348
|
-
v =
|
|
1349
|
-
v
|
|
1350
|
-
v['content'] = result
|
|
1351
|
-
self.putSymbolValue(symbolRecord, v)
|
|
1475
|
+
v = ECValue(domain='graphics', type=str, content=result)
|
|
1476
|
+
self.putSymbolValue(target, v)
|
|
1352
1477
|
elif 'window' in command:
|
|
1353
|
-
window = self.getVariable(command['window'])['
|
|
1354
|
-
window.show()
|
|
1478
|
+
window = self.getInnerObject(self.getVariable(command['window'])['object'])
|
|
1479
|
+
window.show() # type: ignore
|
|
1355
1480
|
elif 'dialog' in command:
|
|
1356
1481
|
record = self.getVariable(command['dialog'])
|
|
1357
|
-
|
|
1482
|
+
object = self.getObject(record)
|
|
1483
|
+
dialog = self.getInnerObject(record)
|
|
1358
1484
|
if dialog.dialogType == 'generic':
|
|
1359
|
-
|
|
1485
|
+
object.result = dialog.exec()
|
|
1360
1486
|
elif dialog.dialogType == 'confirm':
|
|
1361
|
-
|
|
1487
|
+
object.result = True if dialog.exec() == QDialog.DialogCode.Accepted else False
|
|
1488
|
+
pass
|
|
1362
1489
|
elif dialog.dialogType == 'lineedit':
|
|
1363
1490
|
if dialog.exec() == QDialog.DialogCode.Accepted:
|
|
1364
|
-
|
|
1365
|
-
else:
|
|
1491
|
+
object.result = dialog.lineEdit.text() # type: ignore
|
|
1492
|
+
else: object.result = dialog.value # type: ignore
|
|
1366
1493
|
elif dialog.dialogType == 'multiline':
|
|
1367
1494
|
if dialog.exec() == QDialog.DialogCode.Accepted:
|
|
1368
|
-
|
|
1369
|
-
else:
|
|
1495
|
+
object.result = dialog.textEdit.toPlainText() # type: ignore
|
|
1496
|
+
else: object.result = dialog.value # type: ignore
|
|
1370
1497
|
elif 'name' in command:
|
|
1371
1498
|
record = self.getVariable(command['name'])
|
|
1372
|
-
|
|
1373
|
-
return self.nextPC()
|
|
1374
|
-
|
|
1375
|
-
# Start the graphics
|
|
1376
|
-
def k_start(self, command):
|
|
1377
|
-
if self.nextIs('graphics'):
|
|
1378
|
-
self.add(command)
|
|
1379
|
-
return True
|
|
1380
|
-
return False
|
|
1381
|
-
|
|
1382
|
-
def r_start(self, command):
|
|
1383
|
-
return self.nextPC()
|
|
1384
|
-
|
|
1385
|
-
# Declare a widget variable
|
|
1386
|
-
def k_widget(self, command):
|
|
1387
|
-
return self.compileVariable(command, 'gui')
|
|
1388
|
-
|
|
1389
|
-
def r_widget(self, command):
|
|
1499
|
+
self.getInnerObject(record).show() # type: ignore
|
|
1390
1500
|
return self.nextPC()
|
|
1391
1501
|
|
|
1392
1502
|
# Declare a window variable
|
|
1393
1503
|
def k_window(self, command):
|
|
1394
|
-
|
|
1504
|
+
self.compiler.addValueType()
|
|
1505
|
+
return self.compileVariable(command, 'ECWindow')
|
|
1395
1506
|
|
|
1396
1507
|
def r_window(self, command):
|
|
1397
1508
|
return self.nextPC()
|
|
@@ -1399,42 +1510,57 @@ class Graphics(Handler):
|
|
|
1399
1510
|
#############################################################################
|
|
1400
1511
|
# Compile a value in this domain
|
|
1401
1512
|
def compileValue(self):
|
|
1402
|
-
value =
|
|
1403
|
-
value['domain'] = self.getName()
|
|
1513
|
+
value = ECValue(domain=self.getName())
|
|
1404
1514
|
token = self.getToken()
|
|
1405
1515
|
if self.isSymbol():
|
|
1516
|
+
value.setContent(token)
|
|
1406
1517
|
record = self.getSymbolRecord()
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1518
|
+
object = self.getObject(record)
|
|
1519
|
+
if isinstance(object, ECCoreWidget) and object.hasRuntimeValue():
|
|
1520
|
+
value.setType('object')
|
|
1521
|
+
return value
|
|
1522
|
+
else: return None
|
|
1413
1523
|
else:
|
|
1414
1524
|
if self.tokenIs('the'): token = self.nextToken()
|
|
1415
|
-
|
|
1525
|
+
value.setType(token)
|
|
1526
|
+
if token in ['count', 'current', 'selected']:
|
|
1527
|
+
value.setType(token)
|
|
1528
|
+
if token == 'count':
|
|
1529
|
+
self.skip('of')
|
|
1530
|
+
elif token in ['current', 'selected']:
|
|
1531
|
+
token = self.nextToken()
|
|
1532
|
+
value.option = token
|
|
1533
|
+
if token == 'item': self.skip('in')
|
|
1534
|
+
elif token == 'index': self.skip('of')
|
|
1535
|
+
if self.nextIsSymbol():
|
|
1536
|
+
record = self.getSymbolRecord()
|
|
1537
|
+
if self.isObjectType(record, ECListBox) or self.isObjectType(record, ECComboBox): # type: ignore
|
|
1538
|
+
value.setContent(ECValue(domain=self.getName(), type='object', content=record['name']))
|
|
1539
|
+
return value
|
|
1540
|
+
elif token == 'count':
|
|
1416
1541
|
self.skip('of')
|
|
1417
1542
|
if self.nextIsSymbol():
|
|
1418
|
-
value['type'] = 'symbol'
|
|
1419
1543
|
record = self.getSymbolRecord()
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
value['type'] = 'count'
|
|
1423
|
-
value['name'] = record['name']
|
|
1544
|
+
if self.isObjectType(record, ECListBox) or self.isObjectType(record, ECComboBox): # type: ignore
|
|
1545
|
+
value.setContent(ECValue(domain=self.getName(), type='object', content=record['name']))
|
|
1424
1546
|
return value
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
self.skip('item')
|
|
1428
|
-
self.skip('in')
|
|
1547
|
+
elif token == 'text':
|
|
1548
|
+
self.skip('of')
|
|
1429
1549
|
if self.nextIsSymbol():
|
|
1430
|
-
value['type'] = 'symbol'
|
|
1431
1550
|
record = self.getSymbolRecord()
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
value
|
|
1551
|
+
if (
|
|
1552
|
+
self.isObjectType(record, (ECLabel, ECPushButton, ECMultiline, ECLineInput))
|
|
1553
|
+
): # type: ignore
|
|
1554
|
+
value.setContent(ECValue(domain=self.getName(), type='object', content=record['name']))
|
|
1555
|
+
return value
|
|
1556
|
+
elif token == 'index':
|
|
1557
|
+
self.skip('of')
|
|
1558
|
+
value.element = self.getValue()
|
|
1559
|
+
if self.nextIsSymbol():
|
|
1560
|
+
record = self.getSymbolRecord()
|
|
1561
|
+
if self.isObjectType(record, (ECListBox, ECComboBox)): # type: ignore
|
|
1562
|
+
value.setContent(ECValue(domain=self.getName(), type='object', content=record['name']))
|
|
1436
1563
|
return value
|
|
1437
|
-
|
|
1438
1564
|
return None
|
|
1439
1565
|
|
|
1440
1566
|
#############################################################################
|
|
@@ -1446,80 +1572,104 @@ class Graphics(Handler):
|
|
|
1446
1572
|
# Value handlers
|
|
1447
1573
|
|
|
1448
1574
|
# This is used by the expression evaluator to get the value of a symbol
|
|
1449
|
-
def v_symbol(self,
|
|
1450
|
-
|
|
1451
|
-
keyword =
|
|
1452
|
-
if
|
|
1453
|
-
pushbutton = self.
|
|
1454
|
-
v =
|
|
1455
|
-
v['type'] = 'text'
|
|
1456
|
-
v['content'] = pushbutton.accessibleName() # type: ignore
|
|
1575
|
+
def v_symbol(self, record):
|
|
1576
|
+
record = self.getVariable(record['name'])
|
|
1577
|
+
keyword = record['keyword']
|
|
1578
|
+
if self.isObjectType(record, ECPushButton):
|
|
1579
|
+
pushbutton = self.getInnerObject(record)
|
|
1580
|
+
v = ECValue(domain=self.getName(), type=str, content=pushbutton.accessibleName())
|
|
1457
1581
|
return v
|
|
1458
|
-
elif
|
|
1459
|
-
lineinput = self.
|
|
1460
|
-
v =
|
|
1461
|
-
v['type'] = 'text'
|
|
1462
|
-
v['content'] = lineinput.displayText() # type: ignore
|
|
1582
|
+
elif self.isObjectType(record, ECLineInput):
|
|
1583
|
+
lineinput = self.getInnerObject(record)
|
|
1584
|
+
v = ECValue(domain=self.getName(), type=str, content=lineinput.displayText())
|
|
1463
1585
|
return v
|
|
1464
|
-
elif
|
|
1465
|
-
multiline = self.
|
|
1466
|
-
v =
|
|
1467
|
-
v['type'] = 'text'
|
|
1468
|
-
v['content'] = multiline.toPlainText() # type: ignore
|
|
1586
|
+
elif self.isObjectType(record, ECMultiline):
|
|
1587
|
+
multiline = self.getInnerObject(record)
|
|
1588
|
+
v = ECValue(domain=self.getName(), type=str, content=multiline.toPlainText())
|
|
1469
1589
|
return v
|
|
1470
|
-
elif
|
|
1471
|
-
combobox = self.
|
|
1472
|
-
v =
|
|
1473
|
-
v['type'] = 'text'
|
|
1474
|
-
v['content'] = combobox.currentText() # type: ignore
|
|
1590
|
+
elif self.isObjectType(record, ECComboBox):
|
|
1591
|
+
combobox = self.getInnerObject(record)
|
|
1592
|
+
v = ECValue(domain=self.getName(), type=str, content=combobox.currentText())
|
|
1475
1593
|
return v
|
|
1476
|
-
elif
|
|
1477
|
-
listbox = self.
|
|
1594
|
+
elif self.isObjectType(record, ECListBox):
|
|
1595
|
+
listbox = self.getInnerObject(record)
|
|
1478
1596
|
content = listbox.currentItem().text() # type: ignore
|
|
1479
|
-
v =
|
|
1480
|
-
v['type'] = 'text'
|
|
1481
|
-
v['content'] = content
|
|
1597
|
+
v = ECValue(domain=self.getName(), type=str, content=content)
|
|
1482
1598
|
return v
|
|
1483
|
-
elif
|
|
1484
|
-
checkbox =self.
|
|
1599
|
+
elif self.isObjectType(record, ECCheckBox):
|
|
1600
|
+
checkbox =self.getInnerObject(record)
|
|
1485
1601
|
content = checkbox.isChecked() # type: ignore
|
|
1486
|
-
v =
|
|
1487
|
-
v['type'] = 'boolean'
|
|
1488
|
-
v['content'] = content
|
|
1602
|
+
v = ECValue(domain=self.getName(), type=bool, content=content)
|
|
1489
1603
|
return v
|
|
1490
|
-
elif
|
|
1491
|
-
content =
|
|
1492
|
-
v =
|
|
1493
|
-
v['type'] = 'text'
|
|
1494
|
-
v['content'] = content
|
|
1604
|
+
elif self.isObjectType(record, ECDialog):
|
|
1605
|
+
content = record['result']
|
|
1606
|
+
v = ECValue(domain=self.getName(), type=str, content=content)
|
|
1495
1607
|
return v
|
|
1496
1608
|
return None
|
|
1497
1609
|
|
|
1498
1610
|
def v_count(self, v):
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1611
|
+
content = v.getContent()
|
|
1612
|
+
if isinstance(content, ECValue) and content.getType() == 'object':
|
|
1613
|
+
record = self.getVariable(content.getContent())
|
|
1614
|
+
object = self.getObject(record)
|
|
1615
|
+
if isinstance(object, (ECListBox, ECComboBox)):
|
|
1616
|
+
widget = self.getInnerObject(object)
|
|
1617
|
+
value = widget.count() # type: ignore
|
|
1618
|
+
return ECValue(domain=self.getName(), type=int, content=value) # type: ignore
|
|
1619
|
+
else: raise RuntimeError(self.program, f"Object is not a listbox or combobox")
|
|
1507
1620
|
|
|
1508
1621
|
def v_current(self, v):
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1622
|
+
content = v.getContent()
|
|
1623
|
+
if isinstance(content, ECValue) and content.getType() == 'object':
|
|
1624
|
+
record = self.getVariable(content.getContent())
|
|
1625
|
+
object = self.getObject(record)
|
|
1626
|
+
option = v.option
|
|
1627
|
+
if isinstance(object, (ECListBox)):
|
|
1628
|
+
if option == 'item':
|
|
1629
|
+
content = object.getText() # type: ignore
|
|
1630
|
+
elif option == 'index':
|
|
1631
|
+
content = object.getIndex() # type: ignore
|
|
1632
|
+
return ECValue(domain=self.getName(), type=int, content=content)
|
|
1633
|
+
elif isinstance(object, (ECComboBox)):
|
|
1634
|
+
content = str(object.currentText()) # type: ignore
|
|
1635
|
+
return ECValue(domain=self.getName(), type=int, content=content)
|
|
1636
|
+
else: raise RuntimeError(self.program, f"Object is not a listbox or combobox")
|
|
1637
|
+
|
|
1638
|
+
def v_element(self, v):
|
|
1639
|
+
return v.getContent()
|
|
1640
|
+
|
|
1641
|
+
def v_empty(self, v):
|
|
1642
|
+
if v.type == 'object':
|
|
1643
|
+
record = self.getVariable(v.getContent())
|
|
1644
|
+
object = self.getObject(record)
|
|
1645
|
+
value = object.isEmpty()
|
|
1646
|
+
return ECValue(domain=self.getName(), type=bool, content=value) # type: ignore
|
|
1647
|
+
return None
|
|
1648
|
+
|
|
1649
|
+
def v_selected(self, v): return self.v_current(v)
|
|
1650
|
+
|
|
1651
|
+
def v_text(self, v):
|
|
1652
|
+
content = v.getContent()
|
|
1653
|
+
if isinstance(content, ECValue) and content.getType() == 'object':
|
|
1654
|
+
record = self.getVariable(content.getContent())
|
|
1655
|
+
object = self.getObject(record)
|
|
1656
|
+
value = object.getText()
|
|
1657
|
+
return ECValue(domain=self.getName(), type=int, content=value) # type: ignore
|
|
1658
|
+
|
|
1659
|
+
#############################################################################
|
|
1660
|
+
# Get the value of an unknown item (domain-specific)
|
|
1661
|
+
def getUnknownValue(self, value):
|
|
1662
|
+
if self.isObjectType(value, (ECLabelWidget, ECPushButtonWidget, ECLineEditWidget, ECListBoxWidget, ECComboBoxWidget)):
|
|
1663
|
+
return value.text() # type: ignore
|
|
1664
|
+
if self.isObjectType(value, (ECDialogWindow,)):
|
|
1665
|
+
return value.result() # type: ignore
|
|
1666
|
+
return None # Unable to get value
|
|
1517
1667
|
|
|
1518
1668
|
#############################################################################
|
|
1519
1669
|
# Compile a condition
|
|
1520
1670
|
def compileCondition(self):
|
|
1521
|
-
condition =
|
|
1522
|
-
condition.negate = False
|
|
1671
|
+
condition = ECValue()
|
|
1672
|
+
condition.negate = False # type: ignore
|
|
1523
1673
|
return None
|
|
1524
1674
|
|
|
1525
1675
|
#############################################################################
|