easycoder 251104.1__py2.py3-none-any.whl → 251215.2__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.
@@ -1,8 +1,30 @@
1
1
  import sys
2
2
  from functools import partial
3
3
  from .ec_handler import Handler
4
- from .ec_classes import RuntimeError, Object
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
27
+ from .debugger.ec_debug import Debugger
6
28
  from PySide6.QtCore import Qt, QTimer, Signal, QRect
7
29
  from PySide6.QtGui import QPixmap, QPainter
8
30
  from PySide6.QtWidgets import (
@@ -41,6 +63,120 @@ from PySide6.QtWidgets import (
41
63
  QGraphicsDropShadowEffect
42
64
  )
43
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
+ ###############################################################################
44
180
  class Graphics(Handler):
45
181
 
46
182
  def __init__(self, compiler):
@@ -55,71 +191,19 @@ class Graphics(Handler):
55
191
  def closeEvent(self):
56
192
  print('window closed')
57
193
 
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
- ]
194
+ def isCoreWidget(self, object):
195
+ if isinstance(object, dict): object = object['object']
196
+ return isinstance(object, ECCoreWidget)
71
197
 
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
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)
87
203
 
88
204
  def dialogTypes(self):
89
205
  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
-
206
+
123
207
  #############################################################################
124
208
  # Keyword handlers
125
209
 
@@ -130,13 +214,16 @@ class Graphics(Handler):
130
214
  # (5) add spacer [size] {size} to {layout}
131
215
  # (6) add {widget} at {col} {row} in {grid layout}
132
216
  def k_add(self, command):
217
+
218
+ # Add to a layout, group, list or combo box
133
219
  def addToLayout():
134
220
  if self.nextIsSymbol():
135
221
  record = self.getSymbolRecord()
136
- if record['keyword'] in ['layout', 'group', 'element']:
137
- command['layout'] = record['name']
138
- self.add(command)
139
- return True
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
140
227
  return False
141
228
 
142
229
  token = self.peek()
@@ -165,82 +252,90 @@ class Graphics(Handler):
165
252
  self.skip('to')
166
253
  return addToLayout()
167
254
 
168
- # Here it's either (1) or (2)
255
+ # Here it's either (1), (2) or (6)
169
256
  elif self.nextIsSymbol():
170
257
  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()
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()
186
283
 
187
- else: return False
188
- # (1)
284
+ # (1) with a value
189
285
  value = self.getValue()
190
286
  if value == None: return False
191
287
  command['value'] = value
192
288
  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
289
+ return addToLayout()
199
290
 
200
291
  def r_add(self, command):
201
292
  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':
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):
207
299
  if isinstance(value, list): record['widget'].addItems(value)
208
- else: self.getWidget(record).addItem(value)
300
+ else: self.getInnerObject(record).addItem(value) # type: ignore
209
301
  elif 'row' in command and 'col' in command:
210
302
  layout = self.getVariable(command['layout'])['widget']
211
303
  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':
304
+ widget = self.getInnerObject(record)
305
+ row = self.textify(command['row'])
306
+ col = self.textify(command['col'])
307
+ if self.isObjectType(record, ECLayout):
216
308
  layout.addLayout(widget, row, col)
217
309
  else:
218
310
  layout.addWidget(widget, row, col)
219
311
  else:
220
- layoutRecord = self.getVariable(command['layout'])
312
+ layoutRecord = self.getVariable(command['target'])
221
313
  widget = command['widget']
222
314
  if widget == 'stretch':
223
- self.getWidget(layoutRecord).addStretch()
315
+ self.getInnerObject(layoutRecord).addStretch() # type: ignore
224
316
  elif widget == 'spacer':
225
- self.getWidget(layoutRecord).addSpacing(self.getRuntimeValue(command['size']))
317
+ self.getInnerObject(layoutRecord).addSpacing(self.textify(command['size'])) # type: ignore
226
318
  else:
227
319
  widgetRecord = self.getVariable(widget)
228
- layoutRecord = self.getVariable(command['layout'])
229
- widget = self.getWidget(widgetRecord)
230
- layout = layoutRecord['widget']
320
+ self.checkObjectType(widgetRecord, ECCoreWidget)
321
+ self.checkObjectType(layoutRecord, ECLayout)
322
+ widget = self.getInnerObject(widgetRecord)
323
+ layout = self.getInnerObject(layoutRecord)
231
324
  stretch = 'stretch' in command
232
- if widgetRecord['keyword'] == 'layout':
233
- if layoutRecord['keyword'] == 'group':
234
- if widgetRecord['keyword'] == 'layout':
235
- 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
236
329
  else:
237
330
  RuntimeError(self.program, 'Can only add a layout to a group')
238
331
  else:
239
- if stretch: layout.addLayout(widget, stretch=1)
240
- else: layout.addLayout(widget)
332
+ if stretch: layout.addLayout(widget, stretch=1) # type: ignore
333
+ else:
334
+ layout.addLayout(widget) # type: ignore
241
335
  else:
242
- if stretch: layout.addWidget(widget, stretch=1)
243
- else: layout.addWidget(widget)
336
+ if stretch: layout.addWidget(widget, stretch=1) # type: ignore
337
+ else:
338
+ layout.addWidget(widget) # type: ignore
244
339
  return self.nextPC()
245
340
 
246
341
  # Center one window on another
@@ -248,46 +343,58 @@ class Graphics(Handler):
248
343
  def k_center(self, command):
249
344
  if self.nextIsSymbol():
250
345
  record = self.getSymbolRecord()
251
- if record['keyword'] == 'window':
346
+ if self.isObjectType(record, ECWindow):
252
347
  command['window2'] = record['name']
253
348
  self.skip('on')
254
349
  if self.nextIsSymbol():
255
350
  record = self.getSymbolRecord()
256
- if record['keyword'] == 'window':
351
+ if self.isObjectType(record, ECWindow):
257
352
  command['window1'] = record['name']
258
353
  self.add(command)
259
354
  return True
260
355
  return False
261
356
 
357
+ def k_centre(self,command):
358
+ return self.k_center(command)
359
+
262
360
  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()
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
267
369
  geo2.moveCenter(geo1.center())
268
- window2.setGeometry(geo2)
370
+ window2.setGeometry(geo2) # type: ignore
269
371
  return self.nextPC()
270
372
 
271
373
  # Declare a checkbox variable
272
374
  def k_checkbox(self, command):
273
- return self.compileVariable(command, 'gui')
375
+ self.compiler.addValueType()
376
+ return self.compileVariable(command, 'ECCheckBox')
274
377
 
275
378
  def r_checkbox(self, command):
276
379
  return self.nextPC()
277
380
 
278
- # clear {widget}
381
+ # clear {window/widget}
279
382
  def k_clear(self, command):
280
383
  if self.nextIsSymbol():
281
384
  record = self.getSymbolRecord()
282
- if self.isWidget(record['keyword']):
283
- command['name'] = record['name']
284
- self.add(command)
285
- return True
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')
286
392
  return False
287
393
 
288
394
  def r_clear(self, command):
289
395
 
290
396
  def clearLayout(layout: QLayout) -> None:
397
+ """Recursively clear all items from a layout."""
291
398
  if layout is None:
292
399
  return
293
400
  while layout.count() > 0:
@@ -296,50 +403,59 @@ class Graphics(Handler):
296
403
  continue
297
404
  widget = item.widget()
298
405
  if widget is not None:
299
- # Delete the widget
300
406
  widget.deleteLater()
301
407
  elif item.layout() is not None:
302
- # Recursively clear sub-layout
303
408
  clearLayout(item.layout())
304
409
  item.layout().deleteLater()
305
- # The QLayoutItem will be automatically cleaned up by Qt
306
410
 
307
411
  def clearWidget(widget: QWidget) -> None:
412
+ """Clear all contents from a widget."""
308
413
  if widget is None:
309
414
  return
310
- # Clear the layout first
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
311
423
  layout = widget.layout()
312
424
  if layout is not None:
313
425
  clearLayout(layout)
314
426
  layout.deleteLater()
315
- # Clear any remaining child widgets
316
- child_widgets = widget.findChildren(QWidget, "", Qt.FindDirectChildrenOnly)
427
+ child_widgets = widget.findChildren(QWidget, "", Qt.FindChildOption.FindDirectChildrenOnly)
317
428
  for child in child_widgets:
318
429
  child.deleteLater()
319
430
 
320
- widget = self.getWidget(self.getVariable(command['name']))
321
- clearWidget(widget)
322
- return self.nextPC()
323
-
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
324
436
  return self.nextPC()
325
437
 
326
438
  # close {window}
327
439
  def k_close(self, command):
328
440
  if self.nextIsSymbol():
329
441
  record = self.getSymbolRecord()
330
- if record['keyword'] == 'window':
442
+ if self.isObjectType(record, ECWindow):
331
443
  command['name'] = record['name']
332
444
  self.add(command)
333
445
  return True
334
446
  return False
335
447
 
336
448
  def r_close(self, command):
337
- self.getVariable(command['name'])['window'].close()
449
+ record = self.getVariable(command['name'])
450
+ window = self.getInnerObject(record)
451
+ self.checkObjectType(window, QMainWindow)
452
+ window.close() # type: ignore
338
453
  return self.nextPC()
339
454
 
340
455
  # Declare a combobox variable
341
456
  def k_combobox(self, command):
342
- return self.compileVariable(command, 'gui')
457
+ self.compiler.addValueType()
458
+ return self.compileVariable(command, 'ECComboBox')
343
459
 
344
460
  def r_combobox(self, command):
345
461
  return self.nextPC()
@@ -365,7 +481,7 @@ class Graphics(Handler):
365
481
  elif token == 'layout':
366
482
  if self.nextIsSymbol():
367
483
  record = self.getSymbolRecord()
368
- if record['keyword'] == 'layout':
484
+ if self.isObjectType(record, ECLayout):
369
485
  command['layout'] = record['name']
370
486
  else: return False
371
487
  else: break
@@ -475,7 +591,15 @@ class Graphics(Handler):
475
591
  self.add(command)
476
592
  return True
477
593
 
478
- def k_createWidget(self, command):
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):
479
603
  self.add(command)
480
604
  return True
481
605
 
@@ -542,7 +666,6 @@ class Graphics(Handler):
542
666
  command['name'] = record['name']
543
667
  keyword = record['keyword']
544
668
  if keyword == 'window': return self.k_createWindow(command)
545
- elif keyword in ['listbox', 'combobox', 'widget']: return self.k_createWidget(command)
546
669
  elif keyword == 'layout': return self.k_createLayout(command)
547
670
  elif keyword == 'group': return self.k_createGroupBox(command)
548
671
  elif keyword == 'label': return self.k_createLabel(command)
@@ -550,17 +673,20 @@ class Graphics(Handler):
550
673
  elif keyword == 'checkbox': return self.k_createCheckBox(command)
551
674
  elif keyword == 'lineinput': return self.k_createLineEdit(command)
552
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)
553
679
  elif keyword == 'dialog': return self.k_createDialog(command)
554
680
  elif keyword == 'messagebox': return self.k_createMessageBox(command)
555
681
  return False
556
682
 
557
683
  def r_createWindow(self, command, record):
558
684
  window = QMainWindow()
559
- title = self.getRuntimeValue(command['title'])
685
+ title = self.textify(command['title'])
560
686
  if title == None: title = 'EasyCoder Main Window'
561
687
  window.setWindowTitle(title)
562
- w = self.getRuntimeValue(command['w'])
563
- h = self.getRuntimeValue(command['h'])
688
+ w = self.textify(command['w'])
689
+ h = self.textify(command['h'])
564
690
  x = command['x']
565
691
  y = command['y']
566
692
  if hasattr(self.program, 'screenWidth'): screenWidth = self.program.screenWidth
@@ -568,11 +694,11 @@ class Graphics(Handler):
568
694
  if hasattr(self.program, 'screenHeight'): screenHeight = self.program.screenHeight
569
695
  else: screenHeight = self.program.parent.program.screenHeight
570
696
  if x == None: x = (screenWidth - w) / 2
571
- else: x = self.getRuntimeValue(x)
697
+ else: x = self.textify(x)
572
698
  if y == None: y = (screenHeight - h) / 2
573
- else: y = self.getRuntimeValue(x)
699
+ else: y = self.textify(x)
574
700
  window.setGeometry(x, y, w, h)
575
- record['window'] = window
701
+ self.setGraphicElement(record, window)
576
702
  return self.nextPC()
577
703
 
578
704
  def r_createLayout(self, command, record):
@@ -582,121 +708,104 @@ class Graphics(Handler):
582
708
  elif layoutType == 'QStackedLayout': layout = QStackedLayout()
583
709
  else: layout = QVBoxLayout()
584
710
  layout.setContentsMargins(5,0,5,0)
585
- record['widget'] = layout
711
+ self.setGraphicElement(record, layout)
586
712
  return self.nextPC()
587
713
 
588
714
  def r_createGroupBox(self, command, record):
589
- group = QGroupBox(self.getRuntimeValue(command['title']))
590
- group.setAlignment(Qt.AlignLeft)
591
- record['widget'] = group
715
+ group = QGroupBox(self.textify(command['title']))
716
+ group.setAlignment(Qt.AlignmentFlag.AlignLeft)
717
+ self.setGraphicElement(record, group)
592
718
  return self.nextPC()
593
719
 
594
720
  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
- """)
721
+ label = ECLabelWidget(str(self.textify(command['text'])))
600
722
  if 'size' in command:
601
723
  fm = label.fontMetrics()
602
724
  c = label.contentsMargins()
603
- w = fm.horizontalAdvance('m') * self.getRuntimeValue(command['size']) +c.left()+c.right()
725
+ w = fm.horizontalAdvance('m') * self.textify(command['size']) +c.left()+c.right()
604
726
  label.setMaximumWidth(w)
605
727
  if 'align' in command:
606
728
  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)
729
+ if alignment == 'left': label.setAlignment(Qt.AlignmentFlag.AlignLeft)
730
+ elif alignment == 'right': label.setAlignment(Qt.AlignmentFlag.AlignRight)
731
+ elif alignment in ['center', 'centre']: label.setAlignment(Qt.AlignmentFlag.AlignHCenter)
732
+ elif alignment == 'justify': label.setAlignment(Qt.AlignmentFlag.AlignJustify)
611
733
  if 'expand' in command:
612
- label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
613
- self.setWidget(record, label)
734
+ label.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Preferred)
735
+ self.setGraphicElement(record, label)
614
736
  return self.nextPC()
615
737
 
616
738
  def r_createPushbutton(self, command, record):
617
739
  if 'size' in command:
618
- size = self.getRuntimeValue(command['size'])
740
+ size = self.textify(command['size'])
619
741
  else: size = None
620
742
  if 'icon' in command:
621
- iconPath = self.getRuntimeValue(command['icon'])
743
+ iconPath = self.textify(command['icon'])
622
744
  pixmap = QPixmap(iconPath)
623
745
  if pixmap.isNull():
624
746
  RuntimeError(self.program, f'Icon not found: {iconPath}')
625
- icon = pixmap.scaledToHeight(size if size != None else 24, Qt.SmoothTransformation)
747
+ icon = pixmap.scaledToHeight(size if size != None else 24, Qt.TransformationMode.SmoothTransformation)
626
748
  pushbutton = QPushButton()
627
749
  pushbutton.setIcon(icon)
628
750
  pushbutton.setIconSize(icon.size())
629
751
  elif 'text' in command:
630
- text = self.getRuntimeValue(command['text'])
631
- pushbutton = QPushButton(text)
752
+ text = self.textify(command['text'])
753
+ pushbutton = ECPushButtonWidget(text)
632
754
  pushbutton.setAccessibleName(text)
633
755
  if size != None:
634
756
  fm = pushbutton.fontMetrics()
635
757
  c = pushbutton.contentsMargins()
636
- w = fm.horizontalAdvance('m') * self.getRuntimeValue(command['size']) + c.left()+c.right()
758
+ w = fm.horizontalAdvance('m') * self.textify(command['size']) + c.left()+c.right()
637
759
  pushbutton.setMaximumWidth(w)
638
760
  self.putSymbolValue(record, pushbutton)
639
- self.setWidget(record, pushbutton)
761
+ self.setGraphicElement(record, pushbutton)
640
762
  return self.nextPC()
641
763
 
642
764
  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)
765
+ checkbox = ECCheckBoxWidget(self.textify(command['text']))
766
+ checkbox.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Preferred)
767
+ self.setGraphicElement(record, checkbox)
662
768
  return self.nextPC()
663
769
 
664
770
  def r_createLineEdit(self, command, record):
665
- lineinput = self.ClickableLineEdit()
666
- lineinput.setText(self.getRuntimeValue(command['text']))
771
+ lineinput = ECLineEditWidget()
772
+ lineinput.setText(self.textify(command['text']))
667
773
  fm = lineinput.fontMetrics()
668
774
  m = lineinput.textMargins()
669
775
  c = lineinput.contentsMargins()
670
- w = fm.horizontalAdvance('x') * self.getRuntimeValue(command['size']) +m.left()+m.right()+c.left()+c.right()
776
+ w = fm.horizontalAdvance('x') * self.textify(command['size']) +m.left()+m.right()+c.left()+c.right()
671
777
  lineinput.setMaximumWidth(w)
672
- self.setWidget(record, lineinput)
778
+ self.setGraphicElement(record, lineinput)
673
779
  return self.nextPC()
674
780
 
675
781
  def r_createMultiLineEdit(self, command, record):
676
- textinput = self.ClickablePlainTextEdit()
782
+ textinput = ECPlainTextEditWidget()
677
783
  fontMetrics = textinput.fontMetrics()
678
784
  charWidth = fontMetrics.horizontalAdvance('x')
679
785
  charHeight = fontMetrics.height()
680
- textinput.setFixedWidth(charWidth * self.getRuntimeValue(command['cols']))
681
- textinput.setFixedHeight(charHeight * self.getRuntimeValue(command['rows']))
682
- self.setWidget(record, textinput)
786
+ textinput.setFixedWidth(charWidth * self.textify(command['cols']))
787
+ textinput.setFixedHeight(charHeight * self.textify(command['rows']))
788
+ self.setGraphicElement(record, textinput)
683
789
  return self.nextPC()
684
790
 
685
791
  def r_createListWidget(self, command, record):
686
- self.setWidget(record, QListWidget())
792
+ listwidget = ECListBoxWidget()
793
+ self.setGraphicElement(record, listwidget)
687
794
  return self.nextPC()
688
795
 
689
796
  def r_createComboBox(self, command, record):
690
- self.setWidget(record, QComboBox())
797
+ combobox = ECComboBoxWidget()
798
+ self.setGraphicElement(record, combobox)
691
799
  return self.nextPC()
692
800
 
693
- def r_createWidget(self, command, record):
694
- self.setWidget(record, QWidget())
801
+ def r_createPanel(self, command, record):
802
+ self.setGraphicElement(record, QWidget())
695
803
  return self.nextPC()
696
804
 
697
805
  def r_createDialog(self, command, record):
698
806
 
699
- class ECDialog(QDialog):
807
+ # This is probably not needed anymore
808
+ class ECDialogX(QDialog):
700
809
  def __init__(self, parent, record):
701
810
  super().__init__(parent)
702
811
  self.record = record
@@ -710,15 +819,15 @@ class Graphics(Handler):
710
819
 
711
820
  win = command['window']
712
821
  if win != None:
713
- win = self.getVariable(win)['window']
714
- dialog = ECDialog(win, record)
822
+ win = self.getInnerObject(self.getVariable(win))
823
+ dialog = ECDialogWindow(win)
715
824
  dialogType = command['type'].lower()
716
- dialog.dialogType = dialogType
825
+ dialog.dialogType = dialogType # type: ignore
717
826
  mainLayout = QVBoxLayout(dialog)
718
827
  if dialogType == 'generic':
719
828
  dialog.setFixedWidth(500)
720
829
  dialog.setFixedHeight(500)
721
- dialog.setWindowFlags(Qt.FramelessWindowHint)
830
+ dialog.setWindowFlags(Qt.WindowType.FramelessWindowHint)
722
831
  dialog.setModal(True)
723
832
  dialog.setStyleSheet('background-color: white;border:1px solid black;')
724
833
 
@@ -731,36 +840,35 @@ class Graphics(Handler):
731
840
  mainLayout.addLayout(layout)
732
841
  dialog.setLayout(mainLayout)
733
842
  else:
734
- dialog.setWindowTitle(self.getRuntimeValue(command['title']))
735
- prompt = self.getRuntimeValue(command['prompt'])
843
+ dialog.setWindowTitle(self.textify(command['title']))
844
+ prompt = self.textify(command['prompt'])
736
845
  if dialogType == 'confirm':
737
- mainLayout.addWidget(QLabel(prompt))
846
+ mainLayout.addWidget(ECLabelWidget(prompt))
738
847
  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)
848
+ mainLayout.addWidget(ECLabelWidget(prompt))
849
+ dialog.lineEdit = self.ECLineEdit(dialog) # type: ignore
850
+ dialog.value = self.textify(command['value']) # type: ignore
851
+ dialog.lineEdit.setText(dialog.value) # type: ignore
852
+ mainLayout.addWidget(dialog.lineEdit) # type: ignore
744
853
  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)
854
+ mainLayout.addWidget(ECLabelWidget(prompt))
855
+ dialog.textEdit = self.ECPlainTextEdit(dialog) # type: ignore
856
+ dialog.textEdit.setText(dialog.value) # type: ignore
857
+ mainLayout.addWidget(dialog.textEdit) # type: ignore
858
+ buttonBox = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel)
750
859
  buttonBox.accepted.connect(dialog.accept)
751
860
  buttonBox.rejected.connect(dialog.reject)
752
- mainLayout.addWidget(buttonBox, alignment=Qt.AlignHCenter)
753
- record['dialog'] = dialog
861
+ mainLayout.addWidget(buttonBox, alignment=Qt.AlignmentFlag.AlignHCenter)
862
+
863
+ self.setGraphicElement(record, dialog)
754
864
  return self.nextPC()
755
865
 
756
866
  # Creates a message box but doesn't run it
757
867
  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
868
+ record['window'] = command['window']
869
+ record['style'] = command['style']
870
+ record['title'] = self.textify(command['title'])
871
+ record['message'] = self.textify(command['message'])
764
872
  return self.nextPC()
765
873
 
766
874
  def r_create(self, command):
@@ -776,14 +884,15 @@ class Graphics(Handler):
776
884
  elif keyword == 'multiline': return self.r_createMultiLineEdit(command, record)
777
885
  elif keyword == 'listbox': return self.r_createListWidget(command, record)
778
886
  elif keyword == 'combobox': return self.r_createComboBox(command, record)
779
- elif keyword == 'widget': return self.r_createWidget(command, record)
887
+ elif keyword == 'panel': return self.r_createPanel(command, record)
780
888
  elif keyword == 'dialog': return self.r_createDialog(command, record)
781
889
  elif keyword == 'messagebox': return self.r_createMessageBox(command, record)
782
890
  return None
783
891
 
784
892
  # Declare a dialog variable
785
893
  def k_dialog(self, command):
786
- return self.compileVariable(command, 'gui')
894
+ self.compiler.addValueType()
895
+ return self.compileVariable(command, 'ECDialog')
787
896
 
788
897
  def r_dialog(self, command):
789
898
  return self.nextPC()
@@ -797,7 +906,7 @@ class Graphics(Handler):
797
906
  return False
798
907
 
799
908
  def r_disable(self, command):
800
- self.getWidget(self.getVariable(command['name'])).setEnabled(False)
909
+ self.getInnerObject(self.getVariable(command['name'])).setEnabled(False) # type: ignore
801
910
  return self.nextPC()
802
911
 
803
912
  # Enable a widget
@@ -809,12 +918,13 @@ class Graphics(Handler):
809
918
  return False
810
919
 
811
920
  def r_enable(self, command):
812
- self.getWidget(self.getVariable(command['name'])).setEnabled(True)
921
+ self.getInnerObject(self.getVariable(command['name'])).setEnabled(True) # type: ignore
813
922
  return self.nextPC()
814
923
 
815
924
  # Create a group box
816
925
  def k_group(self, command):
817
- return self.compileVariable(command, 'gui')
926
+ self.compiler.addValueType()
927
+ return self.compileVariable(command, 'ECGroup')
818
928
 
819
929
  def r_group(self, command):
820
930
  return self.nextPC()
@@ -823,7 +933,8 @@ class Graphics(Handler):
823
933
  def k_hide(self, command):
824
934
  if self.nextIsSymbol():
825
935
  record = self.getSymbolRecord()
826
- if self.isWidget(record['keyword']):
936
+ if self.isObjectType(record, ECCoreWidget):
937
+ command['domain'] = record['domain']
827
938
  command['widget'] = record['name']
828
939
  self.add(command)
829
940
  return True
@@ -831,17 +942,18 @@ class Graphics(Handler):
831
942
 
832
943
  def r_hide(self, command):
833
944
  record = self.getVariable(command['widget'])
834
- if 'widget' in record: self.getWidget(record).hide()
945
+ self.getInnerObject(record).hide() # type: ignore
835
946
  return self.nextPC()
836
947
 
837
948
  # Initialize the graphics environment
838
949
  # Unused: def k_init(self, command):
839
950
 
840
951
  def r_init(self, command):
952
+ print('Initializing graphics...')
841
953
  self.app = QApplication(sys.argv)
842
954
  screen = QApplication.screens()[0].size().toTuple()
843
- self.program.screenWidth = screen[0]
844
- self.program.screenHeight = screen[1]
955
+ self.program.screenWidth = screen[0] # type: ignore
956
+ self.program.screenHeight = screen[1] # type: ignore
845
957
  print(f'Screen: {self.program.screenWidth}x{self.program.screenHeight}')
846
958
  # return self.nextPC()
847
959
  def on_last_window_closed():
@@ -857,52 +969,61 @@ class Graphics(Handler):
857
969
  timer.timeout.connect(flush)
858
970
  timer.start(10)
859
971
  QTimer.singleShot(500, init)
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()
860
977
  self.app.lastWindowClosed.connect(on_last_window_closed)
861
978
  self.app.exec()
862
979
 
863
980
  # Declare a label variable
864
981
  def k_label(self, command):
865
- return self.compileVariable(command, 'gui')
866
-
982
+ self.compiler.addValueType()
983
+ return self.compileVariable(command, 'ECLabel')
867
984
  def r_label(self, command):
868
985
  return self.nextPC()
869
986
 
870
987
  # Declare a layout variable
871
988
  def k_layout(self, command):
872
- return self.compileVariable(command, 'gui')
989
+ self.compiler.addValueType()
990
+ return self.compileVariable(command, 'ECLayout')
873
991
 
874
992
  def r_layout(self, command):
875
993
  return self.nextPC()
876
994
 
877
995
  # Declare a line input variable
878
996
  def k_lineinput(self, command):
879
- return self.compileVariable(command, 'gui')
997
+ self.compiler.addValueType()
998
+ return self.compileVariable(command, 'ECLineInput')
880
999
 
881
1000
  def r_lineinput(self, command):
882
1001
  return self.nextPC()
883
1002
 
884
1003
  # Declare a listbox input variable
885
1004
  def k_listbox(self, command):
886
- return self.compileVariable(command, 'gui')
1005
+ self.compiler.addValueType()
1006
+ return self.compileVariable(command, 'ECListBox')
887
1007
 
888
1008
  def r_listbox(self, command):
889
1009
  return self.nextPC()
890
1010
 
891
1011
  # Declare a messagebox variable
892
1012
  def k_messagebox(self, command):
893
- return self.compileVariable(command)
1013
+ self.compiler.addValueType()
1014
+ return self.compileVariable(command, 'ECMessageBox')
894
1015
 
895
1016
  def r_messagebox(self, command):
896
1017
  return self.nextPC()
897
1018
 
898
1019
  # Declare a multiline input variable
899
1020
  def k_multiline(self, command):
900
- return self.compileVariable(command, 'gui')
901
-
1021
+ self.compiler.addValueType()
1022
+ return self.compileVariable(command, 'ECMultiline')
902
1023
  def r_multiline(self, command):
903
1024
  return self.nextPC()
904
1025
 
905
- # on click {pushbutton}/{lineinput}/{multiline}
1026
+ # on click/tap {pushbutton}/{lineinput}/{multiline}
906
1027
  # on select {combobox}/{listbox}
907
1028
  # on tick
908
1029
  def k_on(self, command):
@@ -932,17 +1053,18 @@ class Graphics(Handler):
932
1053
 
933
1054
  token = self.nextToken()
934
1055
  command['type'] = token
935
- if token == 'click':
1056
+ if token in ['click', 'tap']:
936
1057
  if self.nextIsSymbol():
937
1058
  record = self.getSymbolRecord()
938
- if record['keyword'] in ['pushbutton', 'lineinput', 'multiline']:
1059
+ if isinstance(self.getObject(record), ECWidget):
1060
+ command['domain'] = record['domain']
939
1061
  command['name'] = record['name']
940
1062
  setupOn()
941
1063
  return True
942
1064
  elif token == 'select':
943
1065
  if self.nextIsSymbol():
944
1066
  record = self.getSymbolRecord()
945
- if record['keyword'] in ['combobox', 'listbox']:
1067
+ if isinstance(self.getObject(record), ECCoreWidget):
946
1068
  command['name'] = record['name']
947
1069
  setupOn()
948
1070
  return True
@@ -974,31 +1096,33 @@ class Graphics(Handler):
974
1096
  return False
975
1097
 
976
1098
  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
1099
  if command['type'] == 'tick':
985
1100
  self.runOnTick = command['runOnTick']
986
1101
  else:
987
1102
  record = self.getVariable(command['name'])
988
- widget = self.getWidget(record)
989
- keyword = record['keyword']
990
- if keyword == 'pushbutton':
991
- handler = partial(run, widget, record)
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)
992
1107
  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']))
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):
997
1120
  return self.nextPC()
998
1121
 
999
1122
  # Declare a pushbutton variable
1000
1123
  def k_pushbutton(self, command):
1001
- return self.compileVariable(command, 'gui')
1124
+ self.compiler.addValueType()
1125
+ return self.compileVariable(command, 'ECPushButton')
1002
1126
 
1003
1127
  def r_pushbutton(self, command):
1004
1128
  return self.nextPC()
@@ -1012,12 +1136,12 @@ class Graphics(Handler):
1012
1136
  self.skip(['from', 'in'])
1013
1137
  if self.nextIsSymbol():
1014
1138
  record = self.getSymbolRecord()
1015
- if record['keyword'] == 'combobox':
1139
+ if self.isObjectType(record, ECComboBox):
1016
1140
  command['variant'] = 'current'
1017
1141
  command['name'] = record['name']
1018
1142
  self.add(command)
1019
1143
  return True
1020
- elif record['keyword'] == 'listbox':
1144
+ elif self.isObjectType(record, ECListBox):
1021
1145
  command['variant'] = 'current'
1022
1146
  command['name'] = record['name']
1023
1147
  self.add(command)
@@ -1028,15 +1152,15 @@ class Graphics(Handler):
1028
1152
  variant = command['variant']
1029
1153
  record = self.getVariable(command['name'])
1030
1154
  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()
1155
+ if self.isObjectType(record, ECComboBox):
1156
+ widget = self.getInnerObject(record)
1157
+ widget.removeItem(widget.currentIndex()) # type: ignore
1158
+ if self.isObjectType(record, ECListBox):
1159
+ widget = self.getInnerObject(record)
1160
+ selectedItem = widget.currentItem() # type: ignore
1037
1161
  if selectedItem:
1038
- row = widget.row(selectedItem)
1039
- widget.takeItem(row)
1162
+ row = widget.row(selectedItem) # type: ignore
1163
+ widget.takeItem(row) # type: ignore
1040
1164
  return self.nextPC()
1041
1165
 
1042
1166
  # select index {n} [of] {combobox]}
@@ -1050,21 +1174,21 @@ class Graphics(Handler):
1050
1174
  self.skip('in')
1051
1175
  if self.nextIsSymbol():
1052
1176
  record = self.getSymbolRecord()
1053
- if record['keyword'] == 'combobox':
1177
+ if self.isObjectType(record, ECComboBox):
1054
1178
  command['widget'] = record['name']
1055
1179
  self.add(command)
1056
1180
  return True
1057
1181
  return False
1058
1182
 
1059
1183
  def r_select(self, command):
1060
- widget = self.getWidget(self.getVariable(command['widget']))
1184
+ widget = self.getInnerObject(self.getVariable(command['widget']))
1061
1185
  if 'index' in command:
1062
- index = self.getRuntimeValue(command['index'])
1186
+ index = self.textify(command['index'])
1063
1187
  else:
1064
- name = self.getRuntimeValue(command['name'])
1065
- index = widget.findText(name, Qt.MatchFixedString)
1188
+ name = self.textify(command['name'])
1189
+ index = widget.findText(name, Qt.MatchFlag.MatchFixedString) # type: ignore
1066
1190
  if index >= 0:
1067
- widget.setCurrentIndex(index)
1191
+ widget.setCurrentIndex(index) # type: ignore
1068
1192
  return self.nextPC()
1069
1193
 
1070
1194
  # set [the] width/height [of] {widget} [to] {value}
@@ -1084,7 +1208,8 @@ class Graphics(Handler):
1084
1208
  self.skip('of')
1085
1209
  if self.nextIsSymbol():
1086
1210
  record = self.getSymbolRecord()
1087
- if record['extra'] == 'gui':
1211
+ if self.isObjectType(record, ECCoreWidget):
1212
+ command['domain'] = record['domain']
1088
1213
  command['name'] = record['name']
1089
1214
  self.skip('to')
1090
1215
  command['value'] = self.nextValue()
@@ -1094,13 +1219,12 @@ class Graphics(Handler):
1094
1219
  self.skip('of')
1095
1220
  if self.nextIsSymbol():
1096
1221
  record = self.getSymbolRecord()
1097
- keyword = record['keyword']
1098
- if keyword in ['window', 'widget']:
1222
+ if self.isObjectType(record, (ECWindow, ECGroup, ECPanel)):
1099
1223
  command['name'] = record['name']
1100
1224
  self.skip('to')
1101
1225
  if self.nextIsSymbol():
1102
1226
  record = self.getSymbolRecord()
1103
- if record['keyword'] == 'layout':
1227
+ if self.isObjectType(record, ECLayout):
1104
1228
  command['layout'] = record['name']
1105
1229
  self.add(command)
1106
1230
  return True
@@ -1108,7 +1232,7 @@ class Graphics(Handler):
1108
1232
  self.skip('of')
1109
1233
  if self.nextIsSymbol():
1110
1234
  record = self.getSymbolRecord()
1111
- if record['keyword'] == 'layout':
1235
+ if self.isObjectType(record, ECLayout):
1112
1236
  command['name'] = record['name']
1113
1237
  self.skip('to')
1114
1238
  command['value'] = self.nextValue()
@@ -1118,7 +1242,7 @@ class Graphics(Handler):
1118
1242
  self.skip('of')
1119
1243
  if self.nextIsSymbol():
1120
1244
  record = self.getSymbolRecord()
1121
- if record['keyword'] in ['label', 'pushbutton', 'lineinput', 'multiline', 'element']:
1245
+ if self.isObjectType(record, (ECLabel, ECPushButton, ECLineInput, ECMultiline)):
1122
1246
  command['name'] = record['name']
1123
1247
  self.skip('to')
1124
1248
  command['value'] = self.nextValue()
@@ -1128,7 +1252,7 @@ class Graphics(Handler):
1128
1252
  self.skip('of')
1129
1253
  if self.nextIsSymbol():
1130
1254
  record = self.getSymbolRecord()
1131
- if record['keyword'] == 'checkbox':
1255
+ if self.isObjectType(record, ECCheckBox):
1132
1256
  command['name'] = record['name']
1133
1257
  self.skip('to')
1134
1258
  if self.peek() == 'checked':
@@ -1144,7 +1268,7 @@ class Graphics(Handler):
1144
1268
  self.skip('of')
1145
1269
  if self.nextIsSymbol():
1146
1270
  record = self.getSymbolRecord()
1147
- if record['extra'] == 'gui':
1271
+ if self.isObjectType(record, ECWidget):
1148
1272
  command['name'] = record['name']
1149
1273
  self.skip('to')
1150
1274
  command['value'] = self.nextValue()
@@ -1154,7 +1278,7 @@ class Graphics(Handler):
1154
1278
  self.skip('of')
1155
1279
  if self.nextIsSymbol():
1156
1280
  record = self.getSymbolRecord()
1157
- if record['extra'] == 'gui':
1281
+ if self.isObjectType(record, ECWidget):
1158
1282
  command['name'] = record['name']
1159
1283
  self.skip('to')
1160
1284
  flags = []
@@ -1167,7 +1291,7 @@ class Graphics(Handler):
1167
1291
  self.skip('of')
1168
1292
  if self.nextIsSymbol():
1169
1293
  record = self.getSymbolRecord()
1170
- if record['keyword'] == 'label':
1294
+ if self.isObjectType(record, ECLabel):
1171
1295
  command['name'] = record['name']
1172
1296
  self.skip('to')
1173
1297
  command['value'] = self.nextValue()
@@ -1177,7 +1301,7 @@ class Graphics(Handler):
1177
1301
  self.skip('of')
1178
1302
  if self.nextIsSymbol():
1179
1303
  record = self.getSymbolRecord()
1180
- if record['keyword'] == 'label':
1304
+ if self.isObjectType(record, ECLabel):
1181
1305
  command['name'] = record['name']
1182
1306
  self.skip('to')
1183
1307
  command['value'] = self.nextValue()
@@ -1188,7 +1312,7 @@ class Graphics(Handler):
1188
1312
  self.skip('of')
1189
1313
  if self.nextIsSymbol():
1190
1314
  record = self.getSymbolRecord()
1191
- if record['keyword'] in ['label', 'pushbutton', 'lineinput', 'multiline']:
1315
+ if self.isObjectType(record, (ECLabel, ECPushButton, ECLineInput, ECMultiline)):
1192
1316
  command['name'] = record['name']
1193
1317
  self.skip('to')
1194
1318
  command['value'] = self.nextValue()
@@ -1199,7 +1323,7 @@ class Graphics(Handler):
1199
1323
  return True
1200
1324
  elif self.isSymbol():
1201
1325
  record = self.getSymbolRecord()
1202
- if record['keyword'] == 'listbox':
1326
+ if self.isObjectType(record, ECListBox):
1203
1327
  command['what'] = 'listbox'
1204
1328
  command['name'] = record['name']
1205
1329
  self.skip('to')
@@ -1211,78 +1335,78 @@ class Graphics(Handler):
1211
1335
  def r_set(self, command):
1212
1336
  what = command['what']
1213
1337
  if what == 'height':
1214
- widget = self.getWidget(self.getVariable(command['name']))
1215
- widget.setFixedHeight(self.getRuntimeValue(command['value']))
1338
+ widget = self.getInnerObject(self.getVariable(command['name']))
1339
+ widget.setFixedHeight(self.textify(command['value'])) # type: ignore
1216
1340
  elif what == 'width':
1217
- widget = self.getWidget(self.getVariable(command['name']))
1218
- widget.setFixedWidth(self.getRuntimeValue(command['value']))
1341
+ widget = self.getInnerObject(self.getVariable(command['name']))
1342
+ widget.setFixedWidth(self.textify(command['value'])) # type: ignore
1219
1343
  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']
1344
+ target = self.getVariable(command['name'])
1345
+ object = target['object']
1346
+ layoutObject = self.getVariable(command['layout'])['object']
1347
+ self.checkObjectType(layoutObject, ECLayout)
1348
+ layout = self.getInnerObject(layoutObject)
1349
+ if isinstance(object, ECWindow):
1350
+ window = self.getInnerObject(object)
1226
1351
  container = QWidget()
1227
- container.setLayout(layout)
1228
- window.setCentralWidget(container)
1229
- elif keyword == 'widget':
1230
- widget = self.getWidget(record)
1231
- widget.setLayout(layout)
1352
+ container.setLayout(layout) # type: ignore
1353
+ self.getInnerObject(object).setCentralWidget(container) # type: ignore
1354
+ elif isinstance(object, (ECLayout, ECGroup, ECPanel)):
1355
+ self.getInnerObject(object).setLayout(layout) # type: ignore
1232
1356
  elif what == 'spacing':
1233
- layout = self.getWidget(self.getVariable(command['name']))
1234
- layout.setSpacing(self.getRuntimeValue(command['value']))
1357
+ layout = self.getInnerObject(self.getVariable(command['name']))
1358
+ layout.setSpacing(self.textify(command['value'])) # type: ignore
1235
1359
  elif what == 'text':
1236
1360
  record = self.getVariable(command['name'])
1237
- widget = self.getWidget(record)
1238
- text = self.getRuntimeValue(command['value'])
1361
+ widget = self.getInnerObject(record)
1362
+ text = self.textify(command['value'])
1239
1363
  keyword = record['keyword']
1240
1364
  setText = getattr(widget, "setText", None)
1241
1365
  if callable(setText):
1242
- widget.setText(text)
1243
- elif keyword == 'multiline':
1244
- widget.setPlainText(text)
1245
- if record['keyword'] == 'pushbutton':
1246
- widget.setAccessibleName(text)
1366
+ widget.setText(text) # type: ignore
1367
+ elif self.isObjectType(record, ECMultiline):
1368
+ widget.setPlainText(text) # type: ignore
1369
+ if self.isObjectType(record, ECPushButton):
1370
+ widget.setAccessibleName(text) # type: ignore
1247
1371
  elif what == 'state':
1248
1372
  record = self.getVariable(command['name'])
1249
- if record['keyword'] == 'checkbox':
1250
- state = self.getRuntimeValue(command['value'])
1251
- self.getWidget(record).setChecked(state)
1373
+ if self.isObjectType(record, ECCheckBox):
1374
+ state = self.textify(command['value'])
1375
+ self.getInnerObject(record).setChecked(state) # type: ignore
1252
1376
  elif what == 'alignment':
1253
1377
  widget = self.getVariable(command['name'])['widget']
1254
1378
  flags = command['value']
1255
1379
  alignment = 0
1256
1380
  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
1381
+ if flag == 'left': alignment |= Qt.AlignmentFlag.AlignLeft
1382
+ elif flag == 'hcenter': alignment |= Qt.AlignmentFlag.AlignHCenter
1383
+ elif flag == 'right': alignment |= Qt.AlignmentFlag.AlignRight
1384
+ elif flag == 'top': alignment |= Qt.AlignmentFlag.AlignTop
1385
+ elif flag == 'vcenter': alignment |= Qt.AlignmentFlag.AlignVCenter
1386
+ elif flag == 'bottom': alignment |= Qt.AlignmentFlag.AlignBottom
1387
+ elif flag == 'center': alignment |= Qt.AlignmentFlag.AlignCenter
1264
1388
  widget.setAlignment(alignment)
1265
1389
  elif what == 'style':
1266
1390
  record = self.getVariable(command['name'])
1267
- widget = self.getWidget(record)
1268
- styles = self.getRuntimeValue(command['value'])
1269
- widget.setStyleSheet(styles)
1391
+ widget = self.getInnerObject(record)
1392
+ styles = self.textify(command['value'])
1393
+ widget.setStyleSheet(styles) # type: ignore
1270
1394
  elif what == 'color':
1271
1395
  record = self.getVariable(command['name'])
1272
- widget = self.getWidget(record)
1273
- color = self.getRuntimeValue(command['value'])
1274
- widget.setStyleSheet(f"color: {color};")
1396
+ widget = self.getInnerObject(record)
1397
+ color = self.textify(command['value'])
1398
+ widget.setStyleSheet(f"color: {color};") # type: ignore
1275
1399
  elif what == 'background-color':
1276
1400
  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};")
1401
+ widget = self.getInnerObject(record)
1402
+ bg_color = self.textify(command['value'])
1403
+ widget.setStyleSheet(f"background-color: {bg_color};") # type: ignore
1280
1404
  elif what == 'listbox':
1281
1405
  record = self.getVariable(command['name'])
1282
- widget = self.getWidget(record)
1283
- value = self.getRuntimeValue(command['value'])
1284
- widget.clear()
1285
- widget.addItems(value)
1406
+ widget = self.getInnerObject(record)
1407
+ value = self.textify(command['value'])
1408
+ widget.clear() # type: ignore
1409
+ widget.addItems(value) # type: ignore
1286
1410
  return self.nextPC()
1287
1411
 
1288
1412
  # show {window}
@@ -1292,20 +1416,20 @@ class Graphics(Handler):
1292
1416
  def k_show(self, command):
1293
1417
  if self.nextIsSymbol():
1294
1418
  record = self.getSymbolRecord()
1295
- keyword = record['keyword']
1296
- if keyword == 'window':
1297
- command['window'] = record['name']
1419
+ if self.isObjectType(record, ECCoreWidget):
1420
+ command['domain'] = record['domain']
1421
+ command['name'] = record['name']
1298
1422
  self.add(command)
1299
1423
  return True
1300
- elif keyword == 'dialog':
1301
- command['dialog'] = record['name']
1424
+ elif self.isObjectType(record, ECWindow):
1425
+ command['window'] = record['name']
1302
1426
  self.add(command)
1303
1427
  return True
1304
- elif self.isWidget(keyword):
1305
- command['name'] = record['name']
1428
+ elif self.isObjectType(record, ECDialog):
1429
+ command['dialog'] = record['name']
1306
1430
  self.add(command)
1307
1431
  return True
1308
- elif keyword == 'messagebox':
1432
+ elif self.isObjectType(record, ECMessageBox):
1309
1433
  command['messagebox'] = record['name']
1310
1434
  self.skip('giving')
1311
1435
  if self.nextIsSymbol():
@@ -1316,95 +1440,65 @@ class Graphics(Handler):
1316
1440
 
1317
1441
  def r_show(self, command):
1318
1442
  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']
1443
+ record = self.getVariable(command['messagebox'])
1444
+ windowRecord = self.getVariable(record['window'])
1445
+ window = self.getInnerObject(windowRecord)
1446
+ style = record['style']
1447
+ title = record['title']
1448
+ message = record['message']
1449
+ target = self.getVariable(command['result'])
1325
1450
  if style == 'question':
1326
1451
  choice = QMessageBox.question(window, title, message)
1327
- result = 'Yes' if choice == QMessageBox.Yes else 'No'
1452
+ result = 'Yes' if choice == QMessageBox.StandardButton.Yes else 'No'
1328
1453
  elif style == 'yesnocancel':
1329
1454
  choice = QMessageBox.question(
1330
1455
  window,
1331
1456
  title,
1332
1457
  message,
1333
- QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel
1458
+ QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No | QMessageBox.StandardButton.Cancel
1334
1459
  )
1335
- if choice == QMessageBox.Yes:
1460
+ if choice == QMessageBox.StandardButton.Yes:
1336
1461
  result = 'Yes'
1337
- elif choice == QMessageBox.No:
1462
+ elif choice == QMessageBox.StandardButton.No:
1338
1463
  result = 'No'
1339
1464
  else:
1340
1465
  result = 'Cancel'
1341
1466
  elif style == 'warning':
1342
1467
  choice = QMessageBox.warning(window, title, message)
1343
- if choice == QMessageBox.Ok: result = 'OK'
1468
+ if choice == QMessageBox.StandardButton.Ok: result = 'OK'
1344
1469
  else: result = ''
1345
1470
  else: result = 'Cancel'
1346
- v = {}
1347
- v['type'] = 'text'
1348
- v['content'] = result
1349
- self.putSymbolValue(symbolRecord, v)
1471
+ v = ECValue(domain='graphics', type='str', content=result)
1472
+ self.putSymbolValue(target, v)
1350
1473
  elif 'window' in command:
1351
- window = self.getVariable(command['window'])['window']
1352
- window.show()
1474
+ window = self.getInnerObject(self.getVariable(command['window'])['object'])
1475
+ window.show() # type: ignore
1353
1476
  elif 'dialog' in command:
1354
1477
  record = self.getVariable(command['dialog'])
1355
- dialog = record['dialog']
1478
+ object = self.getObject(record)
1479
+ dialog = self.getInnerObject(record)
1356
1480
  if dialog.dialogType == 'generic':
1357
- record['result'] = dialog.exec()
1481
+ object.result = dialog.exec()
1358
1482
  elif dialog.dialogType == 'confirm':
1359
- record['result'] = True if dialog.exec() == QDialog.Accepted else False
1483
+ object.result = True if dialog.exec() == QDialog.DialogCode.Accepted else False
1484
+ pass
1360
1485
  elif dialog.dialogType == 'lineedit':
1361
- if dialog.exec() == QDialog.Accepted:
1362
- record['result'] = dialog.lineEdit.text()
1363
- else: record['result'] = dialog.value
1486
+ if dialog.exec() == QDialog.DialogCode.Accepted:
1487
+ object.result = dialog.lineEdit.text() # type: ignore
1488
+ else: object.result = dialog.value # type: ignore
1364
1489
  elif dialog.dialogType == 'multiline':
1365
- if dialog.exec() == QDialog.Accepted:
1366
- record['result'] = dialog.textEdit.toPlainText()
1367
- else: record['result'] = dialog.value
1490
+ if dialog.exec() == QDialog.DialogCode.Accepted:
1491
+ object.result = dialog.textEdit.toPlainText() # type: ignore
1492
+ else: object.result = dialog.value # type: ignore
1368
1493
  elif 'name' in command:
1369
1494
  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):
1495
+ self.getInnerObject(record).show() # type: ignore
1403
1496
  return self.nextPC()
1404
1497
 
1405
1498
  # Declare a window variable
1406
1499
  def k_window(self, command):
1407
- return self.compileVariable(command)
1500
+ self.compiler.addValueType()
1501
+ return self.compileVariable(command, 'ECWindow')
1408
1502
 
1409
1503
  def r_window(self, command):
1410
1504
  return self.nextPC()
@@ -1412,42 +1506,48 @@ class Graphics(Handler):
1412
1506
  #############################################################################
1413
1507
  # Compile a value in this domain
1414
1508
  def compileValue(self):
1415
- value = {}
1416
- value['domain'] = self.getName()
1509
+ value = ECValue(domain=self.getName())
1417
1510
  token = self.getToken()
1418
1511
  if self.isSymbol():
1512
+ value.setContent(token)
1419
1513
  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
-
1514
+ object = self.getObject(record)
1515
+ if isinstance(object, ECCoreWidget) and object.hasRuntimeValue():
1516
+ value.setType('object')
1517
+ return value
1518
+ else: return None
1426
1519
  else:
1427
1520
  if self.tokenIs('the'): token = self.nextToken()
1428
- if token == 'count':
1521
+ value.setType(token)
1522
+ if token in ['count', 'current', 'selected']:
1523
+ value.setType(token)
1524
+ if token == 'count':
1525
+ self.skip('of')
1526
+ elif token in ['current', 'selected']:
1527
+ token = self.nextToken()
1528
+ if token == 'item': self.skip('in')
1529
+ elif token == 'index': self.skip('of')
1530
+ if self.nextIsSymbol():
1531
+ record = self.getSymbolRecord()
1532
+ if self.isObjectType(record, ECListBox) or self.isObjectType(record, ECComboBox): # type: ignore
1533
+ value.setContent(ECValue(domain=self.getName(), type='object', content=record['name']))
1534
+ return value
1535
+ elif token == 'count':
1429
1536
  self.skip('of')
1430
1537
  if self.nextIsSymbol():
1431
- value['type'] = 'symbol'
1432
1538
  record = self.getSymbolRecord()
1433
- keyword = record['keyword']
1434
- if keyword in ['combobox', 'listbox']:
1435
- value['type'] = 'count'
1436
- value['name'] = record['name']
1539
+ if self.isObjectType(record, ECListBox) or self.isObjectType(record, ECComboBox): # type: ignore
1540
+ value.setContent(ECValue(domain=self.getName(), type='object', content=record['name']))
1437
1541
  return value
1438
-
1439
- elif token == 'current':
1440
- self.skip('item')
1441
- self.skip('in')
1542
+ elif token == 'text':
1543
+ self.skip('of')
1442
1544
  if self.nextIsSymbol():
1443
- value['type'] = 'symbol'
1444
1545
  record = self.getSymbolRecord()
1445
- keyword = record['keyword']
1446
- if keyword == 'listbox':
1447
- value['type'] = 'current'
1448
- value['name'] = record['name']
1546
+ if (
1547
+ self.isObjectType(record, (ECLabel, ECPushButton, ECMultiline, ECLineInput))
1548
+ ): # type: ignore
1549
+ value.setContent(ECValue(domain=self.getName(), type='object', content=record['name']))
1449
1550
  return value
1450
-
1451
1551
  return None
1452
1552
 
1453
1553
  #############################################################################
@@ -1459,80 +1559,102 @@ class Graphics(Handler):
1459
1559
  # Value handlers
1460
1560
 
1461
1561
  # 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()
1562
+ def v_symbol(self, record):
1563
+ record = self.getVariable(record['name'])
1564
+ keyword = record['keyword']
1565
+ if self.isObjectType(record, ECPushButton):
1566
+ pushbutton = self.getInnerObject(record)
1567
+ v = ECValue(domain=self.getName(), type='str', content=pushbutton.accessibleName())
1470
1568
  return v
1471
- elif keyword == 'lineinput':
1472
- lineinput = self.getWidget(symbolRecord)
1473
- v = {}
1474
- v['type'] = 'text'
1475
- v['content'] = lineinput.displayText()
1569
+ elif self.isObjectType(record, ECLineInput):
1570
+ lineinput = self.getInnerObject(record)
1571
+ v = ECValue(domain=self.getName(), type='str', content=lineinput.displayText())
1476
1572
  return v
1477
- elif keyword == 'multiline':
1478
- multiline = self.getWidget(symbolRecord)
1479
- v = {}
1480
- v['type'] = 'text'
1481
- v['content'] = multiline.toPlainText()
1573
+ elif self.isObjectType(record, ECMultiline):
1574
+ multiline = self.getInnerObject(record)
1575
+ v = ECValue(domain=self.getName(), type='str', content=multiline.toPlainText())
1482
1576
  return v
1483
- elif keyword == 'combobox':
1484
- combobox = self.getWidget(symbolRecord)
1485
- v = {}
1486
- v['type'] = 'text'
1487
- v['content'] = combobox.currentText()
1577
+ elif self.isObjectType(record, ECComboBox):
1578
+ combobox = self.getInnerObject(record)
1579
+ v = ECValue(domain=self.getName(), type='str', content=combobox.currentText())
1488
1580
  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
1581
+ elif self.isObjectType(record, ECListBox):
1582
+ listbox = self.getInnerObject(record)
1583
+ content = listbox.currentItem().text() # type: ignore
1584
+ v = ECValue(domain=self.getName(), type='str', content=content)
1495
1585
  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
1586
+ elif self.isObjectType(record, ECCheckBox):
1587
+ checkbox =self.getInnerObject(record)
1588
+ content = checkbox.isChecked() # type: ignore
1589
+ v = ECValue(domain=self.getName(), type='boolean', content=content)
1502
1590
  return v
1503
- elif keyword == 'dialog':
1504
- content = symbolRecord['result']
1505
- v = {}
1506
- v['type'] = 'text'
1507
- v['content'] = content
1591
+ elif self.isObjectType(record, ECDialog):
1592
+ content = record['result']
1593
+ v = ECValue(domain=self.getName(), type='str', content=content)
1508
1594
  return v
1509
1595
  return None
1510
1596
 
1511
1597
  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
1598
+ content = v.getContent()
1599
+ if isinstance(content, ECValue) and content.getType() == 'object':
1600
+ record = self.getVariable(content.getContent())
1601
+ object = self.getObject(record)
1602
+ if isinstance(object, (ECListBox, ECComboBox)):
1603
+ widget = self.getInnerObject(object)
1604
+ value = widget.count() # type: ignore
1605
+ return ECValue(domain=self.getName(), type='int', content=value) # type: ignore
1606
+ else: raise RuntimeError(self.program, f"Object is not a listbox or combobox")
1520
1607
 
1521
1608
  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
1609
+ content = v.getContent()
1610
+ if isinstance(content, ECValue) and content.getType() == 'object':
1611
+ record = self.getVariable(content.getContent())
1612
+ keyword = record['keyword']
1613
+ object = self.getObject(record)
1614
+ widget = self.getInnerObject(object)
1615
+ if isinstance(widget, (QListWidget)):
1616
+ content = widget.currentItem().text() # type: ignore
1617
+ return ECValue(domain=self.getName(), type='int', content=content)
1618
+ elif isinstance(widget, (QComboBox)):
1619
+ content = str(widget.currentText()) # type: ignore
1620
+ return ECValue(domain=self.getName(), type='int', content=content)
1621
+ else: raise RuntimeError(self.program, f"Object is not a listbox or combobox")
1622
+
1623
+ def v_element(self, v):
1624
+ return v.getContent()
1625
+
1626
+ def v_empty(self, v):
1627
+ if v.type == 'object':
1628
+ record = self.getVariable(v.getContent())
1629
+ object = self.getObject(record)
1630
+ value = object.isEmpty()
1631
+ return ECValue(domain=self.getName(), type='boolean', content=value) # type: ignore
1632
+ return None
1633
+
1634
+ def v_selected(self, v): return self.v_current(v)
1635
+
1636
+ def v_text(self, v):
1637
+ content = v.getContent()
1638
+ if isinstance(content, ECValue) and content.getType() == 'object':
1639
+ record = self.getVariable(content.getContent())
1640
+ object = self.getObject(record)
1641
+ value = object.getText()
1642
+ return ECValue(domain=self.getName(), type='int', content=value) # type: ignore
1643
+
1644
+ #############################################################################
1645
+ # Get the value of an unknown item (domain-specific)
1646
+ def getUnknownValue(self, value):
1647
+ if self.isObjectType(value, (ECLabelWidget, ECPushButtonWidget, ECLineEditWidget, ECListBoxWidget, ECComboBoxWidget)):
1648
+ return value.text() # type: ignore
1649
+ if self.isObjectType(value, (ECDialogWindow,)):
1650
+ return value.result() # type: ignore
1651
+ return None # Unable to get value
1530
1652
 
1531
1653
  #############################################################################
1532
1654
  # Compile a condition
1533
1655
  def compileCondition(self):
1534
- condition = Object()
1535
- condition.negate = False
1656
+ condition = ECValue()
1657
+ condition.negate = False # type: ignore
1536
1658
  return None
1537
1659
 
1538
1660
  #############################################################################