easycoder 250118.1__py2.py3-none-any.whl → 251103.4__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 +4 -1
- easycoder/close.png +0 -0
- easycoder/ec_border.py +63 -0
- easycoder/ec_classes.py +10 -6
- easycoder/ec_compiler.py +48 -19
- easycoder/ec_condition.py +2 -1
- easycoder/ec_core.py +632 -281
- easycoder/ec_handler.py +4 -2
- easycoder/ec_keyboard.py +439 -0
- easycoder/ec_program.py +43 -38
- easycoder/ec_pyside.py +1545 -0
- easycoder/ec_timestamp.py +1 -1
- easycoder/tick.png +0 -0
- {easycoder-250118.1.dist-info → easycoder-251103.4.dist-info}/METADATA +30 -30
- easycoder-251103.4.dist-info/RECORD +19 -0
- {easycoder-250118.1.dist-info → easycoder-251103.4.dist-info}/WHEEL +1 -1
- easycoder/README.md +0 -6
- easycoder/ec_graphics.py +0 -314
- easycoder/ec_gutils.py +0 -84
- easycoder-250118.1.dist-info/RECORD +0 -17
- {easycoder-250118.1.dist-info → easycoder-251103.4.dist-info}/entry_points.txt +0 -0
- {easycoder-250118.1.dist-info → easycoder-251103.4.dist-info/licenses}/LICENSE +0 -0
easycoder/ec_pyside.py
ADDED
|
@@ -0,0 +1,1545 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from functools import partial
|
|
3
|
+
from .ec_handler import Handler
|
|
4
|
+
from .ec_classes import RuntimeError, Object
|
|
5
|
+
from .ec_border import Border
|
|
6
|
+
from PySide6.QtCore import Qt, QTimer, Signal, QRect
|
|
7
|
+
from PySide6.QtGui import QPixmap, QPainter
|
|
8
|
+
from PySide6.QtWidgets import (
|
|
9
|
+
QApplication,
|
|
10
|
+
QCheckBox,
|
|
11
|
+
QComboBox,
|
|
12
|
+
QDateEdit,
|
|
13
|
+
QDateTimeEdit,
|
|
14
|
+
QDial,
|
|
15
|
+
QDoubleSpinBox,
|
|
16
|
+
QFontComboBox,
|
|
17
|
+
QLabel,
|
|
18
|
+
QLCDNumber,
|
|
19
|
+
QLineEdit,
|
|
20
|
+
QPlainTextEdit,
|
|
21
|
+
QListWidget,
|
|
22
|
+
QMainWindow,
|
|
23
|
+
QProgressBar,
|
|
24
|
+
QPushButton,
|
|
25
|
+
QRadioButton,
|
|
26
|
+
QSlider,
|
|
27
|
+
QSpinBox,
|
|
28
|
+
QTimeEdit,
|
|
29
|
+
QLayout,
|
|
30
|
+
QVBoxLayout,
|
|
31
|
+
QHBoxLayout,
|
|
32
|
+
QGridLayout,
|
|
33
|
+
QStackedLayout,
|
|
34
|
+
QGroupBox,
|
|
35
|
+
QWidget,
|
|
36
|
+
QSpacerItem,
|
|
37
|
+
QSizePolicy,
|
|
38
|
+
QDialog,
|
|
39
|
+
QMessageBox,
|
|
40
|
+
QDialogButtonBox,
|
|
41
|
+
QGraphicsDropShadowEffect
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
class Graphics(Handler):
|
|
45
|
+
|
|
46
|
+
def __init__(self, compiler):
|
|
47
|
+
super().__init__(compiler)
|
|
48
|
+
self.blocked = False
|
|
49
|
+
self.runOnTick = 0
|
|
50
|
+
self.vkb = False
|
|
51
|
+
|
|
52
|
+
def getName(self):
|
|
53
|
+
return 'graphics'
|
|
54
|
+
|
|
55
|
+
def closeEvent(self):
|
|
56
|
+
print('window closed')
|
|
57
|
+
|
|
58
|
+
def isWidget(self, keyword):
|
|
59
|
+
return keyword in [
|
|
60
|
+
'layout',
|
|
61
|
+
'group',
|
|
62
|
+
'label',
|
|
63
|
+
'pushbutton',
|
|
64
|
+
'checkbox',
|
|
65
|
+
'lineinput',
|
|
66
|
+
'multiline',
|
|
67
|
+
'listbox',
|
|
68
|
+
'combobox',
|
|
69
|
+
'widget'
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
def setWidget(self, record, widget):
|
|
73
|
+
if record['index'] >= record['elements']:
|
|
74
|
+
RuntimeError(self.program, f'Index out of range for widget {record["name"]}')
|
|
75
|
+
if not 'widget' in record:
|
|
76
|
+
record['widget'] = [None] * record['elements']
|
|
77
|
+
while len(record['widget']) < record['elements']:
|
|
78
|
+
record['widget'].append(None)
|
|
79
|
+
record['widget'][record['index']] = widget
|
|
80
|
+
|
|
81
|
+
def getWidget(self, record):
|
|
82
|
+
if 'widget' in record and record['widget'] != None:
|
|
83
|
+
if record['keyword'] in ['layout', 'group']: return record['widget']
|
|
84
|
+
return record['widget'][record['index']]
|
|
85
|
+
else:
|
|
86
|
+
return None
|
|
87
|
+
|
|
88
|
+
def dialogTypes(self):
|
|
89
|
+
return ['confirm', 'lineedit', 'multiline', 'generic']
|
|
90
|
+
|
|
91
|
+
class ClickableLineEdit(QLineEdit):
|
|
92
|
+
clicked = Signal()
|
|
93
|
+
|
|
94
|
+
def __init__(self):
|
|
95
|
+
super().__init__()
|
|
96
|
+
self.multiline = False
|
|
97
|
+
self.container = None
|
|
98
|
+
|
|
99
|
+
def setContainer(self, container):
|
|
100
|
+
self.container = container
|
|
101
|
+
|
|
102
|
+
def mousePressEvent(self, event):
|
|
103
|
+
self.clicked.emit()
|
|
104
|
+
super().mousePressEvent(event)
|
|
105
|
+
if self.container != None: self.container.setClickSource(self)
|
|
106
|
+
|
|
107
|
+
class ClickablePlainTextEdit(QPlainTextEdit):
|
|
108
|
+
clicked = Signal()
|
|
109
|
+
|
|
110
|
+
def __init__(self):
|
|
111
|
+
super().__init__()
|
|
112
|
+
self.multiline = True
|
|
113
|
+
self.container = None
|
|
114
|
+
|
|
115
|
+
def setContainer(self, container):
|
|
116
|
+
self.container = container
|
|
117
|
+
|
|
118
|
+
def mousePressEvent(self, event):
|
|
119
|
+
self.clicked.emit()
|
|
120
|
+
super().mousePressEvent(event)
|
|
121
|
+
if self.container != None: self.container.setClickSource(self)
|
|
122
|
+
|
|
123
|
+
#############################################################################
|
|
124
|
+
# Keyword handlers
|
|
125
|
+
|
|
126
|
+
# (1) add {value} to {widget}
|
|
127
|
+
# (2) add {widget} to {layout}
|
|
128
|
+
# (3) add stretch {widget} to {layout}
|
|
129
|
+
# (4) add stretch to {layout}
|
|
130
|
+
# (5) add spacer [size] {size} to {layout}
|
|
131
|
+
# (6) add {widget} at {col} {row} in {grid layout}
|
|
132
|
+
def k_add(self, command):
|
|
133
|
+
def addToLayout():
|
|
134
|
+
if self.nextIsSymbol():
|
|
135
|
+
record = self.getSymbolRecord()
|
|
136
|
+
if record['keyword'] in ['layout', 'group', 'element']:
|
|
137
|
+
command['layout'] = record['name']
|
|
138
|
+
self.add(command)
|
|
139
|
+
return True
|
|
140
|
+
return False
|
|
141
|
+
|
|
142
|
+
token = self.peek()
|
|
143
|
+
if token == 'stretch':
|
|
144
|
+
self.nextToken()
|
|
145
|
+
# It's either (3) or (4)
|
|
146
|
+
if self.nextIs('to'):
|
|
147
|
+
# (4)
|
|
148
|
+
command['stretch'] = False
|
|
149
|
+
command['widget'] = 'stretch'
|
|
150
|
+
return addToLayout()
|
|
151
|
+
if self.isSymbol():
|
|
152
|
+
# (3)
|
|
153
|
+
record = self.getSymbolRecord()
|
|
154
|
+
command['widget'] = record['name']
|
|
155
|
+
command['stretch'] = True
|
|
156
|
+
if self.nextIs('to'):
|
|
157
|
+
return addToLayout()
|
|
158
|
+
return False
|
|
159
|
+
|
|
160
|
+
elif token == 'spacer':
|
|
161
|
+
self.nextToken()
|
|
162
|
+
self.skip('size')
|
|
163
|
+
command['widget'] = 'spacer'
|
|
164
|
+
command['size'] = self.nextValue()
|
|
165
|
+
self.skip('to')
|
|
166
|
+
return addToLayout()
|
|
167
|
+
|
|
168
|
+
# Here it's either (1) or (2)
|
|
169
|
+
elif self.nextIsSymbol():
|
|
170
|
+
record = self.getSymbolRecord()
|
|
171
|
+
if record['extra'] == 'gui':
|
|
172
|
+
if self.isWidget(record['keyword']):
|
|
173
|
+
command['widget'] = record['name']
|
|
174
|
+
if self.peek() == 'to':
|
|
175
|
+
# (2)
|
|
176
|
+
record = self.getSymbolRecord()
|
|
177
|
+
self.nextToken()
|
|
178
|
+
return addToLayout()
|
|
179
|
+
elif self.peek() == 'at':
|
|
180
|
+
# (6)
|
|
181
|
+
self.nextToken()
|
|
182
|
+
command['row'] = self.nextValue()
|
|
183
|
+
command['col'] = self.nextValue()
|
|
184
|
+
self.skip('in')
|
|
185
|
+
return addToLayout()
|
|
186
|
+
|
|
187
|
+
else: return False
|
|
188
|
+
# (1)
|
|
189
|
+
value = self.getValue()
|
|
190
|
+
if value == None: return False
|
|
191
|
+
command['value'] = value
|
|
192
|
+
self.skip('to')
|
|
193
|
+
if self.nextIsSymbol():
|
|
194
|
+
record = self.getSymbolRecord()
|
|
195
|
+
command['widget'] = record['name']
|
|
196
|
+
self.add(command)
|
|
197
|
+
return True
|
|
198
|
+
return False
|
|
199
|
+
|
|
200
|
+
def r_add(self, command):
|
|
201
|
+
if 'value' in command:
|
|
202
|
+
value = self.getRuntimeValue(command['value'])
|
|
203
|
+
record = self.getVariable(command['widget'])
|
|
204
|
+
if record['keyword'] == 'listbox':
|
|
205
|
+
self.getWidget(record).addItem(value)
|
|
206
|
+
elif record['keyword'] == 'combobox':
|
|
207
|
+
if isinstance(value, list): record['widget'].addItems(value)
|
|
208
|
+
else: self.getWidget(record).addItem(value)
|
|
209
|
+
elif 'row' in command and 'col' in command:
|
|
210
|
+
layout = self.getVariable(command['layout'])['widget']
|
|
211
|
+
record = self.getVariable(command['widget'])
|
|
212
|
+
widget = self.getWidget(record)
|
|
213
|
+
row = self.getRuntimeValue(command['row'])
|
|
214
|
+
col = self.getRuntimeValue(command['col'])
|
|
215
|
+
if record['keyword'] == 'layout':
|
|
216
|
+
layout.addLayout(widget, row, col)
|
|
217
|
+
else:
|
|
218
|
+
layout.addWidget(widget, row, col)
|
|
219
|
+
else:
|
|
220
|
+
layoutRecord = self.getVariable(command['layout'])
|
|
221
|
+
widget = command['widget']
|
|
222
|
+
if widget == 'stretch':
|
|
223
|
+
self.getWidget(layoutRecord).addStretch()
|
|
224
|
+
elif widget == 'spacer':
|
|
225
|
+
self.getWidget(layoutRecord).addSpacing(self.getRuntimeValue(command['size']))
|
|
226
|
+
else:
|
|
227
|
+
widgetRecord = self.getVariable(widget)
|
|
228
|
+
layoutRecord = self.getVariable(command['layout'])
|
|
229
|
+
widget = self.getWidget(widgetRecord)
|
|
230
|
+
layout = layoutRecord['widget']
|
|
231
|
+
stretch = 'stretch' in command
|
|
232
|
+
if widgetRecord['keyword'] == 'layout':
|
|
233
|
+
if layoutRecord['keyword'] == 'group':
|
|
234
|
+
if widgetRecord['keyword'] == 'layout':
|
|
235
|
+
layout.setLayout(widget)
|
|
236
|
+
else:
|
|
237
|
+
RuntimeError(self.program, 'Can only add a layout to a group')
|
|
238
|
+
else:
|
|
239
|
+
if stretch: layout.addLayout(widget, stretch=1)
|
|
240
|
+
else: layout.addLayout(widget)
|
|
241
|
+
else:
|
|
242
|
+
if stretch: layout.addWidget(widget, stretch=1)
|
|
243
|
+
else: layout.addWidget(widget)
|
|
244
|
+
return self.nextPC()
|
|
245
|
+
|
|
246
|
+
# Center one window on another
|
|
247
|
+
# center {window2} on {window1}
|
|
248
|
+
def k_center(self, command):
|
|
249
|
+
if self.nextIsSymbol():
|
|
250
|
+
record = self.getSymbolRecord()
|
|
251
|
+
if record['keyword'] == 'window':
|
|
252
|
+
command['window2'] = record['name']
|
|
253
|
+
self.skip('on')
|
|
254
|
+
if self.nextIsSymbol():
|
|
255
|
+
record = self.getSymbolRecord()
|
|
256
|
+
if record['keyword'] == 'window':
|
|
257
|
+
command['window1'] = record['name']
|
|
258
|
+
self.add(command)
|
|
259
|
+
return True
|
|
260
|
+
return False
|
|
261
|
+
|
|
262
|
+
def r_center(self, command):
|
|
263
|
+
window1 = self.getVariable(command['window1'])['window']
|
|
264
|
+
window2 = self.getVariable(command['window2'])['window']
|
|
265
|
+
geo1 = window1.geometry()
|
|
266
|
+
geo2 = window2.geometry()
|
|
267
|
+
geo2.moveCenter(geo1.center())
|
|
268
|
+
window2.setGeometry(geo2)
|
|
269
|
+
return self.nextPC()
|
|
270
|
+
|
|
271
|
+
# Declare a checkbox variable
|
|
272
|
+
def k_checkbox(self, command):
|
|
273
|
+
return self.compileVariable(command, 'gui')
|
|
274
|
+
|
|
275
|
+
def r_checkbox(self, command):
|
|
276
|
+
return self.nextPC()
|
|
277
|
+
|
|
278
|
+
# clear {widget}
|
|
279
|
+
def k_clear(self, command):
|
|
280
|
+
if self.nextIsSymbol():
|
|
281
|
+
record = self.getSymbolRecord()
|
|
282
|
+
if self.isWidget(record['keyword']):
|
|
283
|
+
command['name'] = record['name']
|
|
284
|
+
self.add(command)
|
|
285
|
+
return True
|
|
286
|
+
return False
|
|
287
|
+
|
|
288
|
+
def r_clear(self, command):
|
|
289
|
+
|
|
290
|
+
def clearLayout(layout: QLayout) -> None:
|
|
291
|
+
if layout is None:
|
|
292
|
+
return
|
|
293
|
+
while layout.count() > 0:
|
|
294
|
+
item = layout.takeAt(0)
|
|
295
|
+
if item is None:
|
|
296
|
+
continue
|
|
297
|
+
widget = item.widget()
|
|
298
|
+
if widget is not None:
|
|
299
|
+
# Delete the widget
|
|
300
|
+
widget.deleteLater()
|
|
301
|
+
elif item.layout() is not None:
|
|
302
|
+
# Recursively clear sub-layout
|
|
303
|
+
clearLayout(item.layout())
|
|
304
|
+
item.layout().deleteLater()
|
|
305
|
+
# The QLayoutItem will be automatically cleaned up by Qt
|
|
306
|
+
|
|
307
|
+
def clearWidget(widget: QWidget) -> None:
|
|
308
|
+
if widget is None:
|
|
309
|
+
return
|
|
310
|
+
# Clear the layout first
|
|
311
|
+
layout = widget.layout()
|
|
312
|
+
if layout is not None:
|
|
313
|
+
clearLayout(layout)
|
|
314
|
+
layout.deleteLater()
|
|
315
|
+
# Clear any remaining child widgets
|
|
316
|
+
child_widgets = widget.findChildren(QWidget, "", Qt.FindDirectChildrenOnly)
|
|
317
|
+
for child in child_widgets:
|
|
318
|
+
child.deleteLater()
|
|
319
|
+
|
|
320
|
+
widget = self.getWidget(self.getVariable(command['name']))
|
|
321
|
+
clearWidget(widget)
|
|
322
|
+
return self.nextPC()
|
|
323
|
+
|
|
324
|
+
return self.nextPC()
|
|
325
|
+
|
|
326
|
+
# close {window}
|
|
327
|
+
def k_close(self, command):
|
|
328
|
+
if self.nextIsSymbol():
|
|
329
|
+
record = self.getSymbolRecord()
|
|
330
|
+
if record['keyword'] == 'window':
|
|
331
|
+
command['name'] = record['name']
|
|
332
|
+
self.add(command)
|
|
333
|
+
return True
|
|
334
|
+
return False
|
|
335
|
+
|
|
336
|
+
def r_close(self, command):
|
|
337
|
+
self.getVariable(command['name'])['window'].close()
|
|
338
|
+
return self.nextPC()
|
|
339
|
+
|
|
340
|
+
# Declare a combobox variable
|
|
341
|
+
def k_combobox(self, command):
|
|
342
|
+
return self.compileVariable(command, 'gui')
|
|
343
|
+
|
|
344
|
+
def r_combobox(self, command):
|
|
345
|
+
return self.nextPC()
|
|
346
|
+
|
|
347
|
+
# Create a window
|
|
348
|
+
def k_createWindow(self, command):
|
|
349
|
+
title = None
|
|
350
|
+
x = None
|
|
351
|
+
y = None
|
|
352
|
+
w = self.compileConstant(640)
|
|
353
|
+
h = self.compileConstant(480)
|
|
354
|
+
while True:
|
|
355
|
+
token = self.peek()
|
|
356
|
+
if token in ['title', 'at', 'size', 'layout']:
|
|
357
|
+
self.nextToken()
|
|
358
|
+
if token == 'title': title = self.nextValue()
|
|
359
|
+
elif token == 'at':
|
|
360
|
+
x = self.nextValue()
|
|
361
|
+
y = self.nextValue()
|
|
362
|
+
elif token == 'size':
|
|
363
|
+
w = self.nextValue()
|
|
364
|
+
h = self.nextValue()
|
|
365
|
+
elif token == 'layout':
|
|
366
|
+
if self.nextIsSymbol():
|
|
367
|
+
record = self.getSymbolRecord()
|
|
368
|
+
if record['keyword'] == 'layout':
|
|
369
|
+
command['layout'] = record['name']
|
|
370
|
+
else: return False
|
|
371
|
+
else: break
|
|
372
|
+
command['title'] = title
|
|
373
|
+
command['x'] = x
|
|
374
|
+
command['y'] = y
|
|
375
|
+
command['w'] = w
|
|
376
|
+
command['h'] = h
|
|
377
|
+
self.add(command)
|
|
378
|
+
return True
|
|
379
|
+
|
|
380
|
+
# Create a widget
|
|
381
|
+
def k_createLayout(self, command):
|
|
382
|
+
self.skip('type')
|
|
383
|
+
command['type'] = self.nextToken()
|
|
384
|
+
self.add(command)
|
|
385
|
+
return True
|
|
386
|
+
|
|
387
|
+
def k_createGroupBox(self, command):
|
|
388
|
+
if self.peek() == 'title':
|
|
389
|
+
self.nextToken()
|
|
390
|
+
title = self.nextValue()
|
|
391
|
+
else: title = ''
|
|
392
|
+
command['title'] = title
|
|
393
|
+
self.add(command)
|
|
394
|
+
return True
|
|
395
|
+
|
|
396
|
+
def k_createLabel(self, command):
|
|
397
|
+
text = self.compileConstant('')
|
|
398
|
+
while True:
|
|
399
|
+
token = self.peek()
|
|
400
|
+
if token == 'text':
|
|
401
|
+
self.nextToken()
|
|
402
|
+
text = self.nextValue()
|
|
403
|
+
elif token == 'size':
|
|
404
|
+
self.nextToken()
|
|
405
|
+
command['size'] = self.nextValue()
|
|
406
|
+
elif token == 'expand':
|
|
407
|
+
self.nextToken()
|
|
408
|
+
command['expand'] = True
|
|
409
|
+
elif token == 'align':
|
|
410
|
+
self.nextToken()
|
|
411
|
+
token = self.nextToken()
|
|
412
|
+
if token in ['left', 'right', 'center', 'centre', 'justify']:
|
|
413
|
+
command['align'] = token
|
|
414
|
+
else: break
|
|
415
|
+
command['text'] = text
|
|
416
|
+
self.add(command)
|
|
417
|
+
return True
|
|
418
|
+
|
|
419
|
+
def k_createPushbutton(self, command):
|
|
420
|
+
while True:
|
|
421
|
+
token = self.peek()
|
|
422
|
+
if token == 'text':
|
|
423
|
+
self.nextToken()
|
|
424
|
+
command['text'] = self.nextValue()
|
|
425
|
+
elif token == 'icon':
|
|
426
|
+
self.nextToken()
|
|
427
|
+
command['icon'] = self.nextValue()
|
|
428
|
+
elif token == 'size':
|
|
429
|
+
self.nextToken()
|
|
430
|
+
command['size'] = self.nextValue()
|
|
431
|
+
else: break
|
|
432
|
+
self.add(command)
|
|
433
|
+
return True
|
|
434
|
+
|
|
435
|
+
def k_createCheckBox(self, command):
|
|
436
|
+
if self.peek() == 'text':
|
|
437
|
+
self.nextToken()
|
|
438
|
+
text = self.nextValue()
|
|
439
|
+
else: text = self.compileConstant('')
|
|
440
|
+
command['text'] = text
|
|
441
|
+
self.add(command)
|
|
442
|
+
return True
|
|
443
|
+
|
|
444
|
+
def k_createLineEdit(self, command):
|
|
445
|
+
text = self.compileConstant('')
|
|
446
|
+
size = self.compileConstant(40)
|
|
447
|
+
while True:
|
|
448
|
+
token = self.peek()
|
|
449
|
+
if token == 'text':
|
|
450
|
+
self.nextToken()
|
|
451
|
+
text = self.nextValue()
|
|
452
|
+
elif token == 'size':
|
|
453
|
+
self.nextToken()
|
|
454
|
+
size = self.nextValue()
|
|
455
|
+
else: break;
|
|
456
|
+
command['size'] = size
|
|
457
|
+
command['text'] = text
|
|
458
|
+
self.add(command)
|
|
459
|
+
return True
|
|
460
|
+
|
|
461
|
+
def k_createMultiLineEdit(self, command):
|
|
462
|
+
cols = self.compileConstant(30)
|
|
463
|
+
rows = self.compileConstant(5)
|
|
464
|
+
while True:
|
|
465
|
+
next = self.peek()
|
|
466
|
+
if next == 'cols':
|
|
467
|
+
self.nextToken()
|
|
468
|
+
cols = self.nextValue()
|
|
469
|
+
elif next == 'rows':
|
|
470
|
+
self.nextToken()
|
|
471
|
+
rows = self.nextValue()
|
|
472
|
+
else: break;
|
|
473
|
+
command['cols'] = cols
|
|
474
|
+
command['rows'] = rows
|
|
475
|
+
self.add(command)
|
|
476
|
+
return True
|
|
477
|
+
|
|
478
|
+
def k_createWidget(self, command):
|
|
479
|
+
self.add(command)
|
|
480
|
+
return True
|
|
481
|
+
|
|
482
|
+
def k_createDialog(self, command):
|
|
483
|
+
if self.peek() == 'on':
|
|
484
|
+
self.nextToken()
|
|
485
|
+
if self.nextIsSymbol():
|
|
486
|
+
command['window'] = self.getSymbolRecord()['name']
|
|
487
|
+
else: command['window'] = None
|
|
488
|
+
while True:
|
|
489
|
+
if self.peek() == 'type':
|
|
490
|
+
self.nextToken()
|
|
491
|
+
dialogType = self.nextToken()
|
|
492
|
+
if dialogType in self.dialogTypes(): command['type'] = dialogType
|
|
493
|
+
else: return False
|
|
494
|
+
elif self.peek() == 'title':
|
|
495
|
+
self.nextToken()
|
|
496
|
+
command['title'] = self.nextValue()
|
|
497
|
+
elif self.peek() == 'prompt':
|
|
498
|
+
self.nextToken()
|
|
499
|
+
command['prompt'] = self.nextValue()
|
|
500
|
+
elif self.peek() == 'value':
|
|
501
|
+
self.nextToken()
|
|
502
|
+
command['value'] = self.nextValue()
|
|
503
|
+
elif self.peek() == 'with':
|
|
504
|
+
self.nextToken()
|
|
505
|
+
command['layout'] = self.nextToken()
|
|
506
|
+
else: break
|
|
507
|
+
if not 'title' in command: command['title'] = self.compileConstant('')
|
|
508
|
+
if not 'value' in command: command['value'] = self.compileConstant('')
|
|
509
|
+
if not 'prompt' in command: command['prompt'] = self.compileConstant('')
|
|
510
|
+
self.add(command)
|
|
511
|
+
return True
|
|
512
|
+
|
|
513
|
+
def k_createMessageBox(self, command):
|
|
514
|
+
if self.peek() == 'on':
|
|
515
|
+
self.nextToken()
|
|
516
|
+
if self.nextIsSymbol():
|
|
517
|
+
command['window'] = self.getSymbolRecord()['name']
|
|
518
|
+
else: command['window'] = None
|
|
519
|
+
style = 'question'
|
|
520
|
+
title = ''
|
|
521
|
+
message = ''
|
|
522
|
+
while True:
|
|
523
|
+
if self.peek() == 'style':
|
|
524
|
+
self.nextToken()
|
|
525
|
+
style = self.nextToken()
|
|
526
|
+
elif self.peek() == 'title':
|
|
527
|
+
self.nextToken()
|
|
528
|
+
title = self.nextValue()
|
|
529
|
+
elif self.peek() == 'message':
|
|
530
|
+
self.nextToken()
|
|
531
|
+
message = self.nextValue()
|
|
532
|
+
else: break
|
|
533
|
+
command['style'] = style
|
|
534
|
+
command['title'] = title
|
|
535
|
+
command['message'] = message
|
|
536
|
+
self.add(command)
|
|
537
|
+
return True
|
|
538
|
+
|
|
539
|
+
def k_create(self, command):
|
|
540
|
+
if self.nextIsSymbol():
|
|
541
|
+
record = self.getSymbolRecord()
|
|
542
|
+
command['name'] = record['name']
|
|
543
|
+
keyword = record['keyword']
|
|
544
|
+
if keyword == 'window': return self.k_createWindow(command)
|
|
545
|
+
elif keyword in ['listbox', 'combobox', 'widget']: return self.k_createWidget(command)
|
|
546
|
+
elif keyword == 'layout': return self.k_createLayout(command)
|
|
547
|
+
elif keyword == 'group': return self.k_createGroupBox(command)
|
|
548
|
+
elif keyword == 'label': return self.k_createLabel(command)
|
|
549
|
+
elif keyword == 'pushbutton': return self.k_createPushbutton(command)
|
|
550
|
+
elif keyword == 'checkbox': return self.k_createCheckBox(command)
|
|
551
|
+
elif keyword == 'lineinput': return self.k_createLineEdit(command)
|
|
552
|
+
elif keyword == 'multiline': return self.k_createMultiLineEdit(command)
|
|
553
|
+
elif keyword == 'dialog': return self.k_createDialog(command)
|
|
554
|
+
elif keyword == 'messagebox': return self.k_createMessageBox(command)
|
|
555
|
+
return False
|
|
556
|
+
|
|
557
|
+
def r_createWindow(self, command, record):
|
|
558
|
+
window = QMainWindow()
|
|
559
|
+
title = self.getRuntimeValue(command['title'])
|
|
560
|
+
if title == None: title = 'EasyCoder Main Window'
|
|
561
|
+
window.setWindowTitle(title)
|
|
562
|
+
w = self.getRuntimeValue(command['w'])
|
|
563
|
+
h = self.getRuntimeValue(command['h'])
|
|
564
|
+
x = command['x']
|
|
565
|
+
y = command['y']
|
|
566
|
+
if hasattr(self.program, 'screenWidth'): screenWidth = self.program.screenWidth
|
|
567
|
+
else: screenWidth = self.program.parent.program.screenWidth
|
|
568
|
+
if hasattr(self.program, 'screenHeight'): screenHeight = self.program.screenHeight
|
|
569
|
+
else: screenHeight = self.program.parent.program.screenHeight
|
|
570
|
+
if x == None: x = (screenWidth - w) / 2
|
|
571
|
+
else: x = self.getRuntimeValue(x)
|
|
572
|
+
if y == None: y = (screenHeight - h) / 2
|
|
573
|
+
else: y = self.getRuntimeValue(x)
|
|
574
|
+
window.setGeometry(x, y, w, h)
|
|
575
|
+
record['window'] = window
|
|
576
|
+
return self.nextPC()
|
|
577
|
+
|
|
578
|
+
def r_createLayout(self, command, record):
|
|
579
|
+
layoutType = command['type']
|
|
580
|
+
if layoutType == 'QHBoxLayout': layout = QHBoxLayout()
|
|
581
|
+
elif layoutType == 'QGridLayout': layout = QGridLayout()
|
|
582
|
+
elif layoutType == 'QStackedLayout': layout = QStackedLayout()
|
|
583
|
+
else: layout = QVBoxLayout()
|
|
584
|
+
layout.setContentsMargins(5,0,5,0)
|
|
585
|
+
record['widget'] = layout
|
|
586
|
+
return self.nextPC()
|
|
587
|
+
|
|
588
|
+
def r_createGroupBox(self, command, record):
|
|
589
|
+
group = QGroupBox(self.getRuntimeValue(command['title']))
|
|
590
|
+
group.setAlignment(Qt.AlignLeft)
|
|
591
|
+
record['widget'] = group
|
|
592
|
+
return self.nextPC()
|
|
593
|
+
|
|
594
|
+
def r_createLabel(self, command, record):
|
|
595
|
+
label = QLabel(str(self.getRuntimeValue(command['text'])))
|
|
596
|
+
label.setStyleSheet("""
|
|
597
|
+
background-color: transparent;
|
|
598
|
+
border: none;
|
|
599
|
+
""")
|
|
600
|
+
if 'size' in command:
|
|
601
|
+
fm = label.fontMetrics()
|
|
602
|
+
c = label.contentsMargins()
|
|
603
|
+
w = fm.horizontalAdvance('m') * self.getRuntimeValue(command['size']) +c.left()+c.right()
|
|
604
|
+
label.setMaximumWidth(w)
|
|
605
|
+
if 'align' in command:
|
|
606
|
+
alignment = command['align']
|
|
607
|
+
if alignment == 'left': label.setAlignment(Qt.AlignLeft)
|
|
608
|
+
elif alignment == 'right': label.setAlignment(Qt.AlignRight)
|
|
609
|
+
elif alignment in ['center', 'centre']: label.setAlignment(Qt.AlignHCenter)
|
|
610
|
+
elif alignment == 'justify': label.setAlignment(Qt.AlignJustify)
|
|
611
|
+
if 'expand' in command:
|
|
612
|
+
label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
|
|
613
|
+
self.setWidget(record, label)
|
|
614
|
+
return self.nextPC()
|
|
615
|
+
|
|
616
|
+
def r_createPushbutton(self, command, record):
|
|
617
|
+
if 'size' in command:
|
|
618
|
+
size = self.getRuntimeValue(command['size'])
|
|
619
|
+
else: size = None
|
|
620
|
+
if 'icon' in command:
|
|
621
|
+
iconPath = self.getRuntimeValue(command['icon'])
|
|
622
|
+
pixmap = QPixmap(iconPath)
|
|
623
|
+
if pixmap.isNull():
|
|
624
|
+
RuntimeError(self.program, f'Icon not found: {iconPath}')
|
|
625
|
+
icon = pixmap.scaledToHeight(size if size != None else 24, Qt.SmoothTransformation)
|
|
626
|
+
pushbutton = QPushButton()
|
|
627
|
+
pushbutton.setIcon(icon)
|
|
628
|
+
pushbutton.setIconSize(icon.size())
|
|
629
|
+
elif 'text' in command:
|
|
630
|
+
text = self.getRuntimeValue(command['text'])
|
|
631
|
+
pushbutton = QPushButton(text)
|
|
632
|
+
pushbutton.setAccessibleName(text)
|
|
633
|
+
if size != None:
|
|
634
|
+
fm = pushbutton.fontMetrics()
|
|
635
|
+
c = pushbutton.contentsMargins()
|
|
636
|
+
w = fm.horizontalAdvance('m') * self.getRuntimeValue(command['size']) + c.left()+c.right()
|
|
637
|
+
pushbutton.setMaximumWidth(w)
|
|
638
|
+
self.putSymbolValue(record, pushbutton)
|
|
639
|
+
self.setWidget(record, pushbutton)
|
|
640
|
+
return self.nextPC()
|
|
641
|
+
|
|
642
|
+
def r_createCheckBox(self, command, record):
|
|
643
|
+
checkbox = QCheckBox(self.getRuntimeValue(command['text']))
|
|
644
|
+
checkbox.setStyleSheet("""
|
|
645
|
+
QCheckBox::indicator {
|
|
646
|
+
border: 1px solid black;
|
|
647
|
+
border-radius: 3px;
|
|
648
|
+
background: white;
|
|
649
|
+
width: 16px;
|
|
650
|
+
height: 16px;
|
|
651
|
+
}
|
|
652
|
+
QCheckBox::indicator:checked {
|
|
653
|
+
background: #0078d7;
|
|
654
|
+
}
|
|
655
|
+
QCheckBox {
|
|
656
|
+
border: none;
|
|
657
|
+
background: transparent;
|
|
658
|
+
}
|
|
659
|
+
""")
|
|
660
|
+
checkbox.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Preferred)
|
|
661
|
+
self.setWidget(record, checkbox)
|
|
662
|
+
return self.nextPC()
|
|
663
|
+
|
|
664
|
+
def r_createLineEdit(self, command, record):
|
|
665
|
+
lineinput = self.ClickableLineEdit()
|
|
666
|
+
lineinput.setText(self.getRuntimeValue(command['text']))
|
|
667
|
+
fm = lineinput.fontMetrics()
|
|
668
|
+
m = lineinput.textMargins()
|
|
669
|
+
c = lineinput.contentsMargins()
|
|
670
|
+
w = fm.horizontalAdvance('x') * self.getRuntimeValue(command['size']) +m.left()+m.right()+c.left()+c.right()
|
|
671
|
+
lineinput.setMaximumWidth(w)
|
|
672
|
+
self.setWidget(record, lineinput)
|
|
673
|
+
return self.nextPC()
|
|
674
|
+
|
|
675
|
+
def r_createMultiLineEdit(self, command, record):
|
|
676
|
+
textinput = self.ClickablePlainTextEdit()
|
|
677
|
+
fontMetrics = textinput.fontMetrics()
|
|
678
|
+
charWidth = fontMetrics.horizontalAdvance('x')
|
|
679
|
+
charHeight = fontMetrics.height()
|
|
680
|
+
textinput.setFixedWidth(charWidth * self.getRuntimeValue(command['cols']))
|
|
681
|
+
textinput.setFixedHeight(charHeight * self.getRuntimeValue(command['rows']))
|
|
682
|
+
self.setWidget(record, textinput)
|
|
683
|
+
return self.nextPC()
|
|
684
|
+
|
|
685
|
+
def r_createListWidget(self, command, record):
|
|
686
|
+
self.setWidget(record, QListWidget())
|
|
687
|
+
return self.nextPC()
|
|
688
|
+
|
|
689
|
+
def r_createComboBox(self, command, record):
|
|
690
|
+
self.setWidget(record, QComboBox())
|
|
691
|
+
return self.nextPC()
|
|
692
|
+
|
|
693
|
+
def r_createWidget(self, command, record):
|
|
694
|
+
self.setWidget(record, QWidget())
|
|
695
|
+
return self.nextPC()
|
|
696
|
+
|
|
697
|
+
def r_createDialog(self, command, record):
|
|
698
|
+
|
|
699
|
+
class ECDialog(QDialog):
|
|
700
|
+
def __init__(self, parent, record):
|
|
701
|
+
super().__init__(parent)
|
|
702
|
+
self.record = record
|
|
703
|
+
|
|
704
|
+
def showEvent(self, event):
|
|
705
|
+
super().showEvent(event)
|
|
706
|
+
QTimer.singleShot(100, self.afterShown)
|
|
707
|
+
|
|
708
|
+
def afterShown(self):
|
|
709
|
+
if 'action' in self.record: self.record['action']()
|
|
710
|
+
|
|
711
|
+
win = command['window']
|
|
712
|
+
if win != None:
|
|
713
|
+
win = self.getVariable(win)['window']
|
|
714
|
+
dialog = ECDialog(win, record)
|
|
715
|
+
dialogType = command['type'].lower()
|
|
716
|
+
dialog.dialogType = dialogType
|
|
717
|
+
mainLayout = QVBoxLayout(dialog)
|
|
718
|
+
if dialogType == 'generic':
|
|
719
|
+
dialog.setFixedWidth(500)
|
|
720
|
+
dialog.setFixedHeight(500)
|
|
721
|
+
dialog.setWindowFlags(Qt.FramelessWindowHint)
|
|
722
|
+
dialog.setModal(True)
|
|
723
|
+
dialog.setStyleSheet('background-color: white;border:1px solid black;')
|
|
724
|
+
|
|
725
|
+
border = Border()
|
|
726
|
+
border.tickClicked.connect(dialog.accept)
|
|
727
|
+
border.closeClicked.connect(dialog.reject)
|
|
728
|
+
mainLayout.addWidget(border)
|
|
729
|
+
if 'layout' in command:
|
|
730
|
+
layout = self.getVariable(command['layout'])['widget']
|
|
731
|
+
mainLayout.addLayout(layout)
|
|
732
|
+
dialog.setLayout(mainLayout)
|
|
733
|
+
else:
|
|
734
|
+
dialog.setWindowTitle(self.getRuntimeValue(command['title']))
|
|
735
|
+
prompt = self.getRuntimeValue(command['prompt'])
|
|
736
|
+
if dialogType == 'confirm':
|
|
737
|
+
mainLayout.addWidget(QLabel(prompt))
|
|
738
|
+
elif dialogType == 'lineedit':
|
|
739
|
+
mainLayout.addWidget(QLabel(prompt))
|
|
740
|
+
dialog.lineEdit = self.ClickableLineEdit(dialog)
|
|
741
|
+
dialog.value = self.getRuntimeValue(command['value'])
|
|
742
|
+
dialog.lineEdit.setText(dialog.value)
|
|
743
|
+
mainLayout.addWidget(dialog.lineEdit)
|
|
744
|
+
elif dialogType == 'multiline':
|
|
745
|
+
mainLayout.addWidget(QLabel(prompt))
|
|
746
|
+
dialog.textEdit = self.ClickablePlainTextEdit(self)
|
|
747
|
+
dialog.textEdit.setText(dialog.value)
|
|
748
|
+
mainLayout.addWidget(dialog.textEdit)
|
|
749
|
+
buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
|
|
750
|
+
buttonBox.accepted.connect(dialog.accept)
|
|
751
|
+
buttonBox.rejected.connect(dialog.reject)
|
|
752
|
+
mainLayout.addWidget(buttonBox, alignment=Qt.AlignHCenter)
|
|
753
|
+
record['dialog'] = dialog
|
|
754
|
+
return self.nextPC()
|
|
755
|
+
|
|
756
|
+
# Creates a message box but doesn't run it
|
|
757
|
+
def r_createMessageBox(self, command, record):
|
|
758
|
+
data = {}
|
|
759
|
+
data['window'] = command['window']
|
|
760
|
+
data['style'] = command['style']
|
|
761
|
+
data['title'] = self.getRuntimeValue(command['title'])
|
|
762
|
+
data['message'] = self.getRuntimeValue(command['message'])
|
|
763
|
+
record['data'] = data
|
|
764
|
+
return self.nextPC()
|
|
765
|
+
|
|
766
|
+
def r_create(self, command):
|
|
767
|
+
record = self.getVariable(command['name'])
|
|
768
|
+
keyword = record['keyword']
|
|
769
|
+
if keyword == 'window': return self.r_createWindow(command, record)
|
|
770
|
+
elif keyword == 'layout': return self.r_createLayout(command, record)
|
|
771
|
+
elif keyword == 'group': return self.r_createGroupBox(command, record)
|
|
772
|
+
elif keyword == 'label': return self.r_createLabel(command, record)
|
|
773
|
+
elif keyword == 'pushbutton': return self.r_createPushbutton(command, record)
|
|
774
|
+
elif keyword == 'checkbox': return self.r_createCheckBox(command, record)
|
|
775
|
+
elif keyword == 'lineinput': return self.r_createLineEdit(command, record)
|
|
776
|
+
elif keyword == 'multiline': return self.r_createMultiLineEdit(command, record)
|
|
777
|
+
elif keyword == 'listbox': return self.r_createListWidget(command, record)
|
|
778
|
+
elif keyword == 'combobox': return self.r_createComboBox(command, record)
|
|
779
|
+
elif keyword == 'widget': return self.r_createWidget(command, record)
|
|
780
|
+
elif keyword == 'dialog': return self.r_createDialog(command, record)
|
|
781
|
+
elif keyword == 'messagebox': return self.r_createMessageBox(command, record)
|
|
782
|
+
return None
|
|
783
|
+
|
|
784
|
+
# Declare a dialog variable
|
|
785
|
+
def k_dialog(self, command):
|
|
786
|
+
return self.compileVariable(command, 'gui')
|
|
787
|
+
|
|
788
|
+
def r_dialog(self, command):
|
|
789
|
+
return self.nextPC()
|
|
790
|
+
|
|
791
|
+
# Disable a widget
|
|
792
|
+
def k_disable(self, command):
|
|
793
|
+
if self.nextIsSymbol():
|
|
794
|
+
command['name'] = self.getSymbolRecord()['name']
|
|
795
|
+
self.add(command)
|
|
796
|
+
return True
|
|
797
|
+
return False
|
|
798
|
+
|
|
799
|
+
def r_disable(self, command):
|
|
800
|
+
self.getWidget(self.getVariable(command['name'])).setEnabled(False)
|
|
801
|
+
return self.nextPC()
|
|
802
|
+
|
|
803
|
+
# Enable a widget
|
|
804
|
+
def k_enable(self, command):
|
|
805
|
+
if self.nextIsSymbol():
|
|
806
|
+
command['name'] = self.getSymbolRecord()['name']
|
|
807
|
+
self.add(command)
|
|
808
|
+
return True
|
|
809
|
+
return False
|
|
810
|
+
|
|
811
|
+
def r_enable(self, command):
|
|
812
|
+
self.getWidget(self.getVariable(command['name'])).setEnabled(True)
|
|
813
|
+
return self.nextPC()
|
|
814
|
+
|
|
815
|
+
# Create a group box
|
|
816
|
+
def k_group(self, command):
|
|
817
|
+
return self.compileVariable(command, 'gui')
|
|
818
|
+
|
|
819
|
+
def r_group(self, command):
|
|
820
|
+
return self.nextPC()
|
|
821
|
+
|
|
822
|
+
# hide {widget}
|
|
823
|
+
def k_hide(self, command):
|
|
824
|
+
if self.nextIsSymbol():
|
|
825
|
+
record = self.getSymbolRecord()
|
|
826
|
+
if self.isWidget(record['keyword']):
|
|
827
|
+
command['widget'] = record['name']
|
|
828
|
+
self.add(command)
|
|
829
|
+
return True
|
|
830
|
+
return False
|
|
831
|
+
|
|
832
|
+
def r_hide(self, command):
|
|
833
|
+
record = self.getVariable(command['widget'])
|
|
834
|
+
if 'widget' in record: self.getWidget(record).hide()
|
|
835
|
+
return self.nextPC()
|
|
836
|
+
|
|
837
|
+
# Initialize the graphics environment
|
|
838
|
+
# Unused: def k_init(self, command):
|
|
839
|
+
|
|
840
|
+
def r_init(self, command):
|
|
841
|
+
self.app = QApplication(sys.argv)
|
|
842
|
+
screen = QApplication.screens()[0].size().toTuple()
|
|
843
|
+
self.program.screenWidth = screen[0]
|
|
844
|
+
self.program.screenHeight = screen[1]
|
|
845
|
+
print(f'Screen: {self.program.screenWidth}x{self.program.screenHeight}')
|
|
846
|
+
# return self.nextPC()
|
|
847
|
+
def on_last_window_closed():
|
|
848
|
+
self.program.kill()
|
|
849
|
+
def init():
|
|
850
|
+
self.program.flush(self.nextPC())
|
|
851
|
+
def flush():
|
|
852
|
+
if not self.blocked:
|
|
853
|
+
if self.runOnTick != 0:
|
|
854
|
+
self.program.run(self.runOnTick)
|
|
855
|
+
self.program.flushCB()
|
|
856
|
+
timer = QTimer()
|
|
857
|
+
timer.timeout.connect(flush)
|
|
858
|
+
timer.start(10)
|
|
859
|
+
QTimer.singleShot(500, init)
|
|
860
|
+
self.app.lastWindowClosed.connect(on_last_window_closed)
|
|
861
|
+
self.app.exec()
|
|
862
|
+
|
|
863
|
+
# Declare a label variable
|
|
864
|
+
def k_label(self, command):
|
|
865
|
+
return self.compileVariable(command, 'gui')
|
|
866
|
+
|
|
867
|
+
def r_label(self, command):
|
|
868
|
+
return self.nextPC()
|
|
869
|
+
|
|
870
|
+
# Declare a layout variable
|
|
871
|
+
def k_layout(self, command):
|
|
872
|
+
return self.compileVariable(command, 'gui')
|
|
873
|
+
|
|
874
|
+
def r_layout(self, command):
|
|
875
|
+
return self.nextPC()
|
|
876
|
+
|
|
877
|
+
# Declare a line input variable
|
|
878
|
+
def k_lineinput(self, command):
|
|
879
|
+
return self.compileVariable(command, 'gui')
|
|
880
|
+
|
|
881
|
+
def r_lineinput(self, command):
|
|
882
|
+
return self.nextPC()
|
|
883
|
+
|
|
884
|
+
# Declare a listbox input variable
|
|
885
|
+
def k_listbox(self, command):
|
|
886
|
+
return self.compileVariable(command, 'gui')
|
|
887
|
+
|
|
888
|
+
def r_listbox(self, command):
|
|
889
|
+
return self.nextPC()
|
|
890
|
+
|
|
891
|
+
# Declare a messagebox variable
|
|
892
|
+
def k_messagebox(self, command):
|
|
893
|
+
return self.compileVariable(command)
|
|
894
|
+
|
|
895
|
+
def r_messagebox(self, command):
|
|
896
|
+
return self.nextPC()
|
|
897
|
+
|
|
898
|
+
# Declare a multiline input variable
|
|
899
|
+
def k_multiline(self, command):
|
|
900
|
+
return self.compileVariable(command, 'gui')
|
|
901
|
+
|
|
902
|
+
def r_multiline(self, command):
|
|
903
|
+
return self.nextPC()
|
|
904
|
+
|
|
905
|
+
# on click {pushbutton}/{lineinput}/{multiline}
|
|
906
|
+
# on select {combobox}/{listbox}
|
|
907
|
+
# on tick
|
|
908
|
+
def k_on(self, command):
|
|
909
|
+
def setupOn():
|
|
910
|
+
command['goto'] = self.getPC() + 2
|
|
911
|
+
self.add(command)
|
|
912
|
+
self.nextToken()
|
|
913
|
+
# Step over the click handler
|
|
914
|
+
pcNext = self.getPC()
|
|
915
|
+
cmd = {}
|
|
916
|
+
cmd['domain'] = 'core'
|
|
917
|
+
cmd['lino'] = command['lino']
|
|
918
|
+
cmd['keyword'] = 'gotoPC'
|
|
919
|
+
cmd['goto'] = 0
|
|
920
|
+
cmd['debug'] = False
|
|
921
|
+
self.add(cmd)
|
|
922
|
+
# This is the click handler
|
|
923
|
+
self.compileOne()
|
|
924
|
+
cmd = {}
|
|
925
|
+
cmd['domain'] = 'core'
|
|
926
|
+
cmd['lino'] = command['lino']
|
|
927
|
+
cmd['keyword'] = 'stop'
|
|
928
|
+
cmd['debug'] = False
|
|
929
|
+
self.add(cmd)
|
|
930
|
+
# Fixup the goto
|
|
931
|
+
self.getCommandAt(pcNext)['goto'] = self.getPC()
|
|
932
|
+
|
|
933
|
+
token = self.nextToken()
|
|
934
|
+
command['type'] = token
|
|
935
|
+
if token == 'click':
|
|
936
|
+
if self.nextIsSymbol():
|
|
937
|
+
record = self.getSymbolRecord()
|
|
938
|
+
if record['keyword'] in ['pushbutton', 'lineinput', 'multiline']:
|
|
939
|
+
command['name'] = record['name']
|
|
940
|
+
setupOn()
|
|
941
|
+
return True
|
|
942
|
+
elif token == 'select':
|
|
943
|
+
if self.nextIsSymbol():
|
|
944
|
+
record = self.getSymbolRecord()
|
|
945
|
+
if record['keyword'] in ['combobox', 'listbox']:
|
|
946
|
+
command['name'] = record['name']
|
|
947
|
+
setupOn()
|
|
948
|
+
return True
|
|
949
|
+
elif token == 'tick':
|
|
950
|
+
command['tick'] = True
|
|
951
|
+
command['runOnTick'] = self.getPC() + 2
|
|
952
|
+
self.add(command)
|
|
953
|
+
self.nextToken()
|
|
954
|
+
# Step over the on tick action
|
|
955
|
+
pcNext = self.getPC()
|
|
956
|
+
cmd = {}
|
|
957
|
+
cmd['domain'] = 'core'
|
|
958
|
+
cmd['lino'] = command['lino']
|
|
959
|
+
cmd['keyword'] = 'gotoPC'
|
|
960
|
+
cmd['goto'] = 0
|
|
961
|
+
cmd['debug'] = False
|
|
962
|
+
self.add(cmd)
|
|
963
|
+
# This is the on tick handler
|
|
964
|
+
self.compileOne()
|
|
965
|
+
cmd = {}
|
|
966
|
+
cmd['domain'] = 'core'
|
|
967
|
+
cmd['lino'] = command['lino']
|
|
968
|
+
cmd['keyword'] = 'stop'
|
|
969
|
+
cmd['debug'] = False
|
|
970
|
+
self.add(cmd)
|
|
971
|
+
# Fixup the goto
|
|
972
|
+
self.getCommandAt(pcNext)['goto'] = self.getPC()
|
|
973
|
+
return True
|
|
974
|
+
return False
|
|
975
|
+
|
|
976
|
+
def r_on(self, command):
|
|
977
|
+
def run(widget, record):
|
|
978
|
+
for i, w in enumerate(record['widget']):
|
|
979
|
+
if w == widget:
|
|
980
|
+
record['index'] = i
|
|
981
|
+
self.run(command['goto'])
|
|
982
|
+
return
|
|
983
|
+
|
|
984
|
+
if command['type'] == 'tick':
|
|
985
|
+
self.runOnTick = command['runOnTick']
|
|
986
|
+
else:
|
|
987
|
+
record = self.getVariable(command['name'])
|
|
988
|
+
widget = self.getWidget(record)
|
|
989
|
+
keyword = record['keyword']
|
|
990
|
+
if keyword == 'pushbutton':
|
|
991
|
+
handler = partial(run, widget, record)
|
|
992
|
+
widget.clicked.connect(handler)
|
|
993
|
+
elif keyword == 'combobox':
|
|
994
|
+
widget.currentIndexChanged.connect(lambda: self.run(command['goto']))
|
|
995
|
+
elif keyword == 'listbox':
|
|
996
|
+
widget.itemClicked.connect(lambda: self.run(command['goto']))
|
|
997
|
+
return self.nextPC()
|
|
998
|
+
|
|
999
|
+
# Declare a pushbutton variable
|
|
1000
|
+
def k_pushbutton(self, command):
|
|
1001
|
+
return self.compileVariable(command, 'gui')
|
|
1002
|
+
|
|
1003
|
+
def r_pushbutton(self, command):
|
|
1004
|
+
return self.nextPC()
|
|
1005
|
+
|
|
1006
|
+
# remove [the] [current/selected] [item] [from/in] {combobox}/{listbox}
|
|
1007
|
+
def k_remove(self, command):
|
|
1008
|
+
command['variant'] = None
|
|
1009
|
+
self.skip('the')
|
|
1010
|
+
self.skip(['current', 'selected'])
|
|
1011
|
+
self.skip('item')
|
|
1012
|
+
self.skip(['from', 'in'])
|
|
1013
|
+
if self.nextIsSymbol():
|
|
1014
|
+
record = self.getSymbolRecord()
|
|
1015
|
+
if record['keyword'] == 'combobox':
|
|
1016
|
+
command['variant'] = 'current'
|
|
1017
|
+
command['name'] = record['name']
|
|
1018
|
+
self.add(command)
|
|
1019
|
+
return True
|
|
1020
|
+
elif record['keyword'] == 'listbox':
|
|
1021
|
+
command['variant'] = 'current'
|
|
1022
|
+
command['name'] = record['name']
|
|
1023
|
+
self.add(command)
|
|
1024
|
+
return True
|
|
1025
|
+
return False
|
|
1026
|
+
|
|
1027
|
+
def r_remove(self, command):
|
|
1028
|
+
variant = command['variant']
|
|
1029
|
+
record = self.getVariable(command['name'])
|
|
1030
|
+
if variant == 'current':
|
|
1031
|
+
if record['keyword'] == 'combobox':
|
|
1032
|
+
widget = self.getWidget(record)
|
|
1033
|
+
widget.removeItem(widget.currentIndex())
|
|
1034
|
+
if record['keyword'] == 'listbox':
|
|
1035
|
+
widget = self.getWidget(record)
|
|
1036
|
+
selectedItem = widget.currentItem()
|
|
1037
|
+
if selectedItem:
|
|
1038
|
+
row = widget.row(selectedItem)
|
|
1039
|
+
widget.takeItem(row)
|
|
1040
|
+
return self.nextPC()
|
|
1041
|
+
|
|
1042
|
+
# select index {n} [of] {combobox]}
|
|
1043
|
+
# select {name} [in] {combobox}
|
|
1044
|
+
def k_select(self, command):
|
|
1045
|
+
if self.nextIs('index'):
|
|
1046
|
+
command['index'] = self.nextValue()
|
|
1047
|
+
self.skip('of')
|
|
1048
|
+
else:
|
|
1049
|
+
command['name'] = self.getValue()
|
|
1050
|
+
self.skip('in')
|
|
1051
|
+
if self.nextIsSymbol():
|
|
1052
|
+
record = self.getSymbolRecord()
|
|
1053
|
+
if record['keyword'] == 'combobox':
|
|
1054
|
+
command['widget'] = record['name']
|
|
1055
|
+
self.add(command)
|
|
1056
|
+
return True
|
|
1057
|
+
return False
|
|
1058
|
+
|
|
1059
|
+
def r_select(self, command):
|
|
1060
|
+
widget = self.getWidget(self.getVariable(command['widget']))
|
|
1061
|
+
if 'index' in command:
|
|
1062
|
+
index = self.getRuntimeValue(command['index'])
|
|
1063
|
+
else:
|
|
1064
|
+
name = self.getRuntimeValue(command['name'])
|
|
1065
|
+
index = widget.findText(name, Qt.MatchFixedString)
|
|
1066
|
+
if index >= 0:
|
|
1067
|
+
widget.setCurrentIndex(index)
|
|
1068
|
+
return self.nextPC()
|
|
1069
|
+
|
|
1070
|
+
# set [the] width/height [of] {widget} [to] {value}
|
|
1071
|
+
# set [the] layout of {window}/{widget} to {layout}
|
|
1072
|
+
# set [the] spacing of {layout} to {value}
|
|
1073
|
+
# set [the] text [of] {label}/{button}/{lineinput}/{multiline} [to] {text}
|
|
1074
|
+
# set [the] color [of] {label}/{button}/{lineinput}/{multiline} [to] {color}
|
|
1075
|
+
# set [the] state [of] {checkbox} [to] {state}
|
|
1076
|
+
# set [the] style of {widget} to {style}
|
|
1077
|
+
# set {listbox} to {list}
|
|
1078
|
+
# set blocked true/false
|
|
1079
|
+
def k_set(self, command):
|
|
1080
|
+
self.skip('the')
|
|
1081
|
+
token = self.nextToken()
|
|
1082
|
+
command['what'] = token
|
|
1083
|
+
if token in ['width', 'height']:
|
|
1084
|
+
self.skip('of')
|
|
1085
|
+
if self.nextIsSymbol():
|
|
1086
|
+
record = self.getSymbolRecord()
|
|
1087
|
+
if record['extra'] == 'gui':
|
|
1088
|
+
command['name'] = record['name']
|
|
1089
|
+
self.skip('to')
|
|
1090
|
+
command['value'] = self.nextValue()
|
|
1091
|
+
self.add(command)
|
|
1092
|
+
return True
|
|
1093
|
+
elif token == 'layout':
|
|
1094
|
+
self.skip('of')
|
|
1095
|
+
if self.nextIsSymbol():
|
|
1096
|
+
record = self.getSymbolRecord()
|
|
1097
|
+
keyword = record['keyword']
|
|
1098
|
+
if keyword in ['window', 'widget']:
|
|
1099
|
+
command['name'] = record['name']
|
|
1100
|
+
self.skip('to')
|
|
1101
|
+
if self.nextIsSymbol():
|
|
1102
|
+
record = self.getSymbolRecord()
|
|
1103
|
+
if record['keyword'] == 'layout':
|
|
1104
|
+
command['layout'] = record['name']
|
|
1105
|
+
self.add(command)
|
|
1106
|
+
return True
|
|
1107
|
+
elif token == 'spacing':
|
|
1108
|
+
self.skip('of')
|
|
1109
|
+
if self.nextIsSymbol():
|
|
1110
|
+
record = self.getSymbolRecord()
|
|
1111
|
+
if record['keyword'] == 'layout':
|
|
1112
|
+
command['name'] = record['name']
|
|
1113
|
+
self.skip('to')
|
|
1114
|
+
command['value'] = self.nextValue()
|
|
1115
|
+
self.add(command)
|
|
1116
|
+
return True
|
|
1117
|
+
elif token == 'text':
|
|
1118
|
+
self.skip('of')
|
|
1119
|
+
if self.nextIsSymbol():
|
|
1120
|
+
record = self.getSymbolRecord()
|
|
1121
|
+
if record['keyword'] in ['label', 'pushbutton', 'lineinput', 'multiline', 'element']:
|
|
1122
|
+
command['name'] = record['name']
|
|
1123
|
+
self.skip('to')
|
|
1124
|
+
command['value'] = self.nextValue()
|
|
1125
|
+
self.add(command)
|
|
1126
|
+
return True
|
|
1127
|
+
elif token == 'state':
|
|
1128
|
+
self.skip('of')
|
|
1129
|
+
if self.nextIsSymbol():
|
|
1130
|
+
record = self.getSymbolRecord()
|
|
1131
|
+
if record['keyword'] == 'checkbox':
|
|
1132
|
+
command['name'] = record['name']
|
|
1133
|
+
self.skip('to')
|
|
1134
|
+
if self.peek() == 'checked':
|
|
1135
|
+
command['value'] = self.compileConstant(True)
|
|
1136
|
+
self.nextToken()
|
|
1137
|
+
elif self.peek() == 'unchecked':
|
|
1138
|
+
command['value'] = self.compileConstant(False)
|
|
1139
|
+
self.nextToken()
|
|
1140
|
+
else: command['value'] = self.nextValue()
|
|
1141
|
+
self.add(command)
|
|
1142
|
+
return True
|
|
1143
|
+
elif token == 'style':
|
|
1144
|
+
self.skip('of')
|
|
1145
|
+
if self.nextIsSymbol():
|
|
1146
|
+
record = self.getSymbolRecord()
|
|
1147
|
+
if record['extra'] == 'gui':
|
|
1148
|
+
command['name'] = record['name']
|
|
1149
|
+
self.skip('to')
|
|
1150
|
+
command['value'] = self.nextValue()
|
|
1151
|
+
self.add(command)
|
|
1152
|
+
return True
|
|
1153
|
+
elif token == 'alignment':
|
|
1154
|
+
self.skip('of')
|
|
1155
|
+
if self.nextIsSymbol():
|
|
1156
|
+
record = self.getSymbolRecord()
|
|
1157
|
+
if record['extra'] == 'gui':
|
|
1158
|
+
command['name'] = record['name']
|
|
1159
|
+
self.skip('to')
|
|
1160
|
+
flags = []
|
|
1161
|
+
while self.peek() in ['left', 'hcenter', 'right', 'top', 'vcenter', 'bottom', 'center']:
|
|
1162
|
+
flags.append(self.nextToken())
|
|
1163
|
+
command['value'] = flags
|
|
1164
|
+
self.add(command)
|
|
1165
|
+
return True
|
|
1166
|
+
elif token == 'style':
|
|
1167
|
+
self.skip('of')
|
|
1168
|
+
if self.nextIsSymbol():
|
|
1169
|
+
record = self.getSymbolRecord()
|
|
1170
|
+
if record['keyword'] == 'label':
|
|
1171
|
+
command['name'] = record['name']
|
|
1172
|
+
self.skip('to')
|
|
1173
|
+
command['value'] = self.nextValue()
|
|
1174
|
+
self.add(command)
|
|
1175
|
+
return True
|
|
1176
|
+
elif token == 'color':
|
|
1177
|
+
self.skip('of')
|
|
1178
|
+
if self.nextIsSymbol():
|
|
1179
|
+
record = self.getSymbolRecord()
|
|
1180
|
+
if record['keyword'] == 'label':
|
|
1181
|
+
command['name'] = record['name']
|
|
1182
|
+
self.skip('to')
|
|
1183
|
+
command['value'] = self.nextValue()
|
|
1184
|
+
self.add(command)
|
|
1185
|
+
return True
|
|
1186
|
+
elif token == 'background':
|
|
1187
|
+
self.skip('color')
|
|
1188
|
+
self.skip('of')
|
|
1189
|
+
if self.nextIsSymbol():
|
|
1190
|
+
record = self.getSymbolRecord()
|
|
1191
|
+
if record['keyword'] in ['label', 'pushbutton', 'lineinput', 'multiline']:
|
|
1192
|
+
command['name'] = record['name']
|
|
1193
|
+
self.skip('to')
|
|
1194
|
+
command['value'] = self.nextValue()
|
|
1195
|
+
self.add(command)
|
|
1196
|
+
return True
|
|
1197
|
+
elif token == 'blocked':
|
|
1198
|
+
self.blocked = True if self.nextToken() == 'true' else False
|
|
1199
|
+
return True
|
|
1200
|
+
elif self.isSymbol():
|
|
1201
|
+
record = self.getSymbolRecord()
|
|
1202
|
+
if record['keyword'] == 'listbox':
|
|
1203
|
+
command['what'] = 'listbox'
|
|
1204
|
+
command['name'] = record['name']
|
|
1205
|
+
self.skip('to')
|
|
1206
|
+
command['value'] = self.nextValue()
|
|
1207
|
+
self.add(command)
|
|
1208
|
+
return True
|
|
1209
|
+
return False
|
|
1210
|
+
|
|
1211
|
+
def r_set(self, command):
|
|
1212
|
+
what = command['what']
|
|
1213
|
+
if what == 'height':
|
|
1214
|
+
widget = self.getWidget(self.getVariable(command['name']))
|
|
1215
|
+
widget.setFixedHeight(self.getRuntimeValue(command['value']))
|
|
1216
|
+
elif what == 'width':
|
|
1217
|
+
widget = self.getWidget(self.getVariable(command['name']))
|
|
1218
|
+
widget.setFixedWidth(self.getRuntimeValue(command['value']))
|
|
1219
|
+
elif what == 'layout':
|
|
1220
|
+
record = self.getVariable(command['layout'])
|
|
1221
|
+
layout = record['widget']
|
|
1222
|
+
record = self.getVariable(command['name'])
|
|
1223
|
+
keyword = record['keyword']
|
|
1224
|
+
if keyword == 'window':
|
|
1225
|
+
window = record['window']
|
|
1226
|
+
container = QWidget()
|
|
1227
|
+
container.setLayout(layout)
|
|
1228
|
+
window.setCentralWidget(container)
|
|
1229
|
+
elif keyword == 'widget':
|
|
1230
|
+
widget = self.getWidget(record)
|
|
1231
|
+
widget.setLayout(layout)
|
|
1232
|
+
elif what == 'spacing':
|
|
1233
|
+
layout = self.getWidget(self.getVariable(command['name']))
|
|
1234
|
+
layout.setSpacing(self.getRuntimeValue(command['value']))
|
|
1235
|
+
elif what == 'text':
|
|
1236
|
+
record = self.getVariable(command['name'])
|
|
1237
|
+
widget = self.getWidget(record)
|
|
1238
|
+
text = self.getRuntimeValue(command['value'])
|
|
1239
|
+
keyword = record['keyword']
|
|
1240
|
+
setText = getattr(widget, "setText", None)
|
|
1241
|
+
if callable(setText):
|
|
1242
|
+
widget.setText(text)
|
|
1243
|
+
elif keyword == 'multiline':
|
|
1244
|
+
widget.setPlainText(text)
|
|
1245
|
+
if record['keyword'] == 'pushbutton':
|
|
1246
|
+
widget.setAccessibleName(text)
|
|
1247
|
+
elif what == 'state':
|
|
1248
|
+
record = self.getVariable(command['name'])
|
|
1249
|
+
if record['keyword'] == 'checkbox':
|
|
1250
|
+
state = self.getRuntimeValue(command['value'])
|
|
1251
|
+
self.getWidget(record).setChecked(state)
|
|
1252
|
+
elif what == 'alignment':
|
|
1253
|
+
widget = self.getVariable(command['name'])['widget']
|
|
1254
|
+
flags = command['value']
|
|
1255
|
+
alignment = 0
|
|
1256
|
+
for flag in flags:
|
|
1257
|
+
if flag == 'left': alignment |= Qt.AlignLeft
|
|
1258
|
+
elif flag == 'hcenter': alignment |= Qt.AlignHCenter
|
|
1259
|
+
elif flag == 'right': alignment |= Qt.AlignRight
|
|
1260
|
+
elif flag == 'top': alignment |= Qt.AlignTop
|
|
1261
|
+
elif flag == 'vcenter': alignment |= Qt.AlignVCenter
|
|
1262
|
+
elif flag == 'bottom': alignment |= Qt.AlignBottom
|
|
1263
|
+
elif flag == 'center': alignment |= Qt.AlignCenter
|
|
1264
|
+
widget.setAlignment(alignment)
|
|
1265
|
+
elif what == 'style':
|
|
1266
|
+
record = self.getVariable(command['name'])
|
|
1267
|
+
widget = self.getWidget(record)
|
|
1268
|
+
styles = self.getRuntimeValue(command['value'])
|
|
1269
|
+
widget.setStyleSheet(styles)
|
|
1270
|
+
elif what == 'color':
|
|
1271
|
+
record = self.getVariable(command['name'])
|
|
1272
|
+
widget = self.getWidget(record)
|
|
1273
|
+
color = self.getRuntimeValue(command['value'])
|
|
1274
|
+
widget.setStyleSheet(f"color: {color};")
|
|
1275
|
+
elif what == 'background-color':
|
|
1276
|
+
record = self.getVariable(command['name'])
|
|
1277
|
+
widget = self.getWidget(record)
|
|
1278
|
+
bg_color = self.getRuntimeValue(command['value'])
|
|
1279
|
+
widget.setStyleSheet(f"background-color: {bg_color};")
|
|
1280
|
+
elif what == 'listbox':
|
|
1281
|
+
record = self.getVariable(command['name'])
|
|
1282
|
+
widget = self.getWidget(record)
|
|
1283
|
+
value = self.getRuntimeValue(command['value'])
|
|
1284
|
+
widget.clear()
|
|
1285
|
+
widget.addItems(value)
|
|
1286
|
+
return self.nextPC()
|
|
1287
|
+
|
|
1288
|
+
# show {window}
|
|
1289
|
+
# show {dialog}
|
|
1290
|
+
# show {widget}
|
|
1291
|
+
# show {messagebox} giving {result}}
|
|
1292
|
+
def k_show(self, command):
|
|
1293
|
+
if self.nextIsSymbol():
|
|
1294
|
+
record = self.getSymbolRecord()
|
|
1295
|
+
keyword = record['keyword']
|
|
1296
|
+
if keyword == 'window':
|
|
1297
|
+
command['window'] = record['name']
|
|
1298
|
+
self.add(command)
|
|
1299
|
+
return True
|
|
1300
|
+
elif keyword == 'dialog':
|
|
1301
|
+
command['dialog'] = record['name']
|
|
1302
|
+
self.add(command)
|
|
1303
|
+
return True
|
|
1304
|
+
elif self.isWidget(keyword):
|
|
1305
|
+
command['name'] = record['name']
|
|
1306
|
+
self.add(command)
|
|
1307
|
+
return True
|
|
1308
|
+
elif keyword == 'messagebox':
|
|
1309
|
+
command['messagebox'] = record['name']
|
|
1310
|
+
self.skip('giving')
|
|
1311
|
+
if self.nextIsSymbol():
|
|
1312
|
+
command['result'] = self.getSymbolRecord()['name']
|
|
1313
|
+
self.add(command)
|
|
1314
|
+
return True
|
|
1315
|
+
return False
|
|
1316
|
+
|
|
1317
|
+
def r_show(self, command):
|
|
1318
|
+
if 'messagebox' in command:
|
|
1319
|
+
data = self.getVariable(command['messagebox'])['data']
|
|
1320
|
+
symbolRecord = self.getVariable(command['result'])
|
|
1321
|
+
window = self.getVariable(data['window'])['window']
|
|
1322
|
+
style = data['style']
|
|
1323
|
+
title = data['title']
|
|
1324
|
+
message = data['message']
|
|
1325
|
+
if style == 'question':
|
|
1326
|
+
choice = QMessageBox.question(window, title, message)
|
|
1327
|
+
result = 'Yes' if choice == QMessageBox.Yes else 'No'
|
|
1328
|
+
elif style == 'yesnocancel':
|
|
1329
|
+
choice = QMessageBox.question(
|
|
1330
|
+
window,
|
|
1331
|
+
title,
|
|
1332
|
+
message,
|
|
1333
|
+
QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel
|
|
1334
|
+
)
|
|
1335
|
+
if choice == QMessageBox.Yes:
|
|
1336
|
+
result = 'Yes'
|
|
1337
|
+
elif choice == QMessageBox.No:
|
|
1338
|
+
result = 'No'
|
|
1339
|
+
else:
|
|
1340
|
+
result = 'Cancel'
|
|
1341
|
+
elif style == 'warning':
|
|
1342
|
+
choice = QMessageBox.warning(window, title, message)
|
|
1343
|
+
if choice == QMessageBox.Ok: result = 'OK'
|
|
1344
|
+
else: result = ''
|
|
1345
|
+
else: result = 'Cancel'
|
|
1346
|
+
v = {}
|
|
1347
|
+
v['type'] = 'text'
|
|
1348
|
+
v['content'] = result
|
|
1349
|
+
self.putSymbolValue(symbolRecord, v)
|
|
1350
|
+
elif 'window' in command:
|
|
1351
|
+
window = self.getVariable(command['window'])['window']
|
|
1352
|
+
window.show()
|
|
1353
|
+
elif 'dialog' in command:
|
|
1354
|
+
record = self.getVariable(command['dialog'])
|
|
1355
|
+
dialog = record['dialog']
|
|
1356
|
+
if dialog.dialogType == 'generic':
|
|
1357
|
+
record['result'] = dialog.exec()
|
|
1358
|
+
elif dialog.dialogType == 'confirm':
|
|
1359
|
+
record['result'] = True if dialog.exec() == QDialog.Accepted else False
|
|
1360
|
+
elif dialog.dialogType == 'lineedit':
|
|
1361
|
+
if dialog.exec() == QDialog.Accepted:
|
|
1362
|
+
record['result'] = dialog.lineEdit.text()
|
|
1363
|
+
else: record['result'] = dialog.value
|
|
1364
|
+
elif dialog.dialogType == 'multiline':
|
|
1365
|
+
if dialog.exec() == QDialog.Accepted:
|
|
1366
|
+
record['result'] = dialog.textEdit.toPlainText()
|
|
1367
|
+
else: record['result'] = dialog.value
|
|
1368
|
+
elif 'name' in command:
|
|
1369
|
+
record = self.getVariable(command['name'])
|
|
1370
|
+
if 'widget' in record: self.getWidget(record).show()
|
|
1371
|
+
return self.nextPC()
|
|
1372
|
+
|
|
1373
|
+
# Start the graphics
|
|
1374
|
+
def k_start(self, command):
|
|
1375
|
+
if self.nextIs('graphics'):
|
|
1376
|
+
self.add(command)
|
|
1377
|
+
return True
|
|
1378
|
+
return False
|
|
1379
|
+
|
|
1380
|
+
def r_start(self, command):
|
|
1381
|
+
return self.nextPC()
|
|
1382
|
+
# def on_last_window_closed():
|
|
1383
|
+
# self.program.kill()
|
|
1384
|
+
# def init():
|
|
1385
|
+
# self.program.flush(self.nextPC())
|
|
1386
|
+
# def flush():
|
|
1387
|
+
# if not self.blocked:
|
|
1388
|
+
# if self.runOnTick != 0:
|
|
1389
|
+
# self.program.run(self.runOnTick)
|
|
1390
|
+
# self.program.flushCB()
|
|
1391
|
+
# timer = QTimer()
|
|
1392
|
+
# timer.timeout.connect(flush)
|
|
1393
|
+
# timer.start(10)
|
|
1394
|
+
# QTimer.singleShot(500, init)
|
|
1395
|
+
# self.app.lastWindowClosed.connect(on_last_window_closed)
|
|
1396
|
+
# self.app.exec()
|
|
1397
|
+
|
|
1398
|
+
# Declare a widget variable
|
|
1399
|
+
def k_widget(self, command):
|
|
1400
|
+
return self.compileVariable(command, 'gui')
|
|
1401
|
+
|
|
1402
|
+
def r_widget(self, command):
|
|
1403
|
+
return self.nextPC()
|
|
1404
|
+
|
|
1405
|
+
# Declare a window variable
|
|
1406
|
+
def k_window(self, command):
|
|
1407
|
+
return self.compileVariable(command)
|
|
1408
|
+
|
|
1409
|
+
def r_window(self, command):
|
|
1410
|
+
return self.nextPC()
|
|
1411
|
+
|
|
1412
|
+
#############################################################################
|
|
1413
|
+
# Compile a value in this domain
|
|
1414
|
+
def compileValue(self):
|
|
1415
|
+
value = {}
|
|
1416
|
+
value['domain'] = self.getName()
|
|
1417
|
+
token = self.getToken()
|
|
1418
|
+
if self.isSymbol():
|
|
1419
|
+
record = self.getSymbolRecord()
|
|
1420
|
+
if record['extra'] == 'gui':
|
|
1421
|
+
if self.isWidget(record['keyword']):
|
|
1422
|
+
value['name'] = token
|
|
1423
|
+
value['type'] = 'symbol'
|
|
1424
|
+
return value
|
|
1425
|
+
|
|
1426
|
+
else:
|
|
1427
|
+
if self.tokenIs('the'): token = self.nextToken()
|
|
1428
|
+
if token == 'count':
|
|
1429
|
+
self.skip('of')
|
|
1430
|
+
if self.nextIsSymbol():
|
|
1431
|
+
value['type'] = 'symbol'
|
|
1432
|
+
record = self.getSymbolRecord()
|
|
1433
|
+
keyword = record['keyword']
|
|
1434
|
+
if keyword in ['combobox', 'listbox']:
|
|
1435
|
+
value['type'] = 'count'
|
|
1436
|
+
value['name'] = record['name']
|
|
1437
|
+
return value
|
|
1438
|
+
|
|
1439
|
+
elif token == 'current':
|
|
1440
|
+
self.skip('item')
|
|
1441
|
+
self.skip('in')
|
|
1442
|
+
if self.nextIsSymbol():
|
|
1443
|
+
value['type'] = 'symbol'
|
|
1444
|
+
record = self.getSymbolRecord()
|
|
1445
|
+
keyword = record['keyword']
|
|
1446
|
+
if keyword == 'listbox':
|
|
1447
|
+
value['type'] = 'current'
|
|
1448
|
+
value['name'] = record['name']
|
|
1449
|
+
return value
|
|
1450
|
+
|
|
1451
|
+
return None
|
|
1452
|
+
|
|
1453
|
+
#############################################################################
|
|
1454
|
+
# Modify a value or leave it unchanged.
|
|
1455
|
+
def modifyValue(self, value):
|
|
1456
|
+
return value
|
|
1457
|
+
|
|
1458
|
+
#############################################################################
|
|
1459
|
+
# Value handlers
|
|
1460
|
+
|
|
1461
|
+
# This is used by the expression evaluator to get the value of a symbol
|
|
1462
|
+
def v_symbol(self, symbolRecord):
|
|
1463
|
+
symbolRecord = self.getVariable(symbolRecord['name'])
|
|
1464
|
+
keyword = symbolRecord['keyword']
|
|
1465
|
+
if keyword == 'pushbutton':
|
|
1466
|
+
pushbutton = self.getWidget(symbolRecord)
|
|
1467
|
+
v = {}
|
|
1468
|
+
v['type'] = 'text'
|
|
1469
|
+
v['content'] = pushbutton.accessibleName()
|
|
1470
|
+
return v
|
|
1471
|
+
elif keyword == 'lineinput':
|
|
1472
|
+
lineinput = self.getWidget(symbolRecord)
|
|
1473
|
+
v = {}
|
|
1474
|
+
v['type'] = 'text'
|
|
1475
|
+
v['content'] = lineinput.displayText()
|
|
1476
|
+
return v
|
|
1477
|
+
elif keyword == 'multiline':
|
|
1478
|
+
multiline = self.getWidget(symbolRecord)
|
|
1479
|
+
v = {}
|
|
1480
|
+
v['type'] = 'text'
|
|
1481
|
+
v['content'] = multiline.toPlainText()
|
|
1482
|
+
return v
|
|
1483
|
+
elif keyword == 'combobox':
|
|
1484
|
+
combobox = self.getWidget(symbolRecord)
|
|
1485
|
+
v = {}
|
|
1486
|
+
v['type'] = 'text'
|
|
1487
|
+
v['content'] = combobox.currentText()
|
|
1488
|
+
return v
|
|
1489
|
+
elif keyword == 'listbox':
|
|
1490
|
+
listbox = self.getWidget(symbolRecord)
|
|
1491
|
+
content = listbox.currentItem().text()
|
|
1492
|
+
v = {}
|
|
1493
|
+
v['type'] = 'text'
|
|
1494
|
+
v['content'] = content
|
|
1495
|
+
return v
|
|
1496
|
+
elif keyword == 'checkbox':
|
|
1497
|
+
checkbox =self.getWidget(symbolRecord)
|
|
1498
|
+
content = checkbox.isChecked()
|
|
1499
|
+
v = {}
|
|
1500
|
+
v['type'] = 'boolean'
|
|
1501
|
+
v['content'] = content
|
|
1502
|
+
return v
|
|
1503
|
+
elif keyword == 'dialog':
|
|
1504
|
+
content = symbolRecord['result']
|
|
1505
|
+
v = {}
|
|
1506
|
+
v['type'] = 'text'
|
|
1507
|
+
v['content'] = content
|
|
1508
|
+
return v
|
|
1509
|
+
return None
|
|
1510
|
+
|
|
1511
|
+
def v_count(self, v):
|
|
1512
|
+
record = self.getVariable(v['name'])
|
|
1513
|
+
keyword = record['keyword']
|
|
1514
|
+
widget = self.getWidget(record)
|
|
1515
|
+
if keyword in ['combobox', 'listbox']: content = widget.count()
|
|
1516
|
+
value = {}
|
|
1517
|
+
value['type'] = 'int'
|
|
1518
|
+
value['content'] = content
|
|
1519
|
+
return value
|
|
1520
|
+
|
|
1521
|
+
def v_current(self, v):
|
|
1522
|
+
record = self.getVariable(v['name'])
|
|
1523
|
+
keyword = record['keyword']
|
|
1524
|
+
widget = self.getWidget(record)
|
|
1525
|
+
if keyword == 'listbox': content = widget.currentItem().text()
|
|
1526
|
+
value = {}
|
|
1527
|
+
value['type'] = 'text'
|
|
1528
|
+
value['content'] = content
|
|
1529
|
+
return value
|
|
1530
|
+
|
|
1531
|
+
#############################################################################
|
|
1532
|
+
# Compile a condition
|
|
1533
|
+
def compileCondition(self):
|
|
1534
|
+
condition = Object()
|
|
1535
|
+
condition.negate = False
|
|
1536
|
+
return None
|
|
1537
|
+
|
|
1538
|
+
#############################################################################
|
|
1539
|
+
# Condition handlers
|
|
1540
|
+
|
|
1541
|
+
#############################################################################
|
|
1542
|
+
# Force the application to exit
|
|
1543
|
+
def force_exit(self):
|
|
1544
|
+
QApplication.quit() # Gracefully close the application
|
|
1545
|
+
sys.exit(0) # Force a complete system exit
|