easycoder 250826.2__py2.py3-none-any.whl → 251104.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
easycoder/__init__.py CHANGED
@@ -12,4 +12,4 @@ from .ec_pyside import *
12
12
  from .ec_timestamp import *
13
13
  from .ec_value import *
14
14
 
15
- __version__ = "250826.2"
15
+ __version__ = "251104.1"
easycoder/ec_classes.py CHANGED
@@ -16,7 +16,6 @@ class AssertionError:
16
16
  def __init__(self, program, msg=None):
17
17
  code = program.code[program.pc]
18
18
  lino = code['lino']
19
- script = program.script.lines[lino].strip()
20
19
  message = f'Assertion Error in {program.name} at line {lino + 1}'
21
20
  if msg != None:
22
21
  message += f': {msg}'
@@ -58,8 +57,5 @@ class Token:
58
57
  self.lino = lino
59
58
  self.token = token
60
59
 
61
- class Condition():
62
- negate = False
63
-
64
60
  class Object():
65
61
  pass
easycoder/ec_compiler.py CHANGED
@@ -1,4 +1,4 @@
1
- from .ec_classes import Token, FatalError
1
+ from .ec_classes import FatalError
2
2
  from .ec_value import Value
3
3
  from .ec_condition import Condition
4
4
 
@@ -18,9 +18,11 @@ class Compiler:
18
18
  self.debugCompile = False
19
19
  self.valueTypes = {}
20
20
 
21
- def getPC(self):
21
+ # Get the current code size. Used during compilation
22
+ def getCodeSize(self):
22
23
  return len(self.program.code)
23
24
 
25
+ # Get the current index (the program counter)
24
26
  def getIndex(self):
25
27
  return self.index
26
28
 
@@ -39,6 +41,7 @@ class Compiler:
39
41
  self.index += 1
40
42
  return self.getToken()
41
43
 
44
+ # Peek ahead to see the next token without advancing the index
42
45
  def peek(self):
43
46
  try:
44
47
  return self.tokens[self.index + 1].token
@@ -68,19 +71,23 @@ class Compiler:
68
71
  self.index += 1
69
72
  return self.condition.compileCondition()
70
73
 
74
+ # Test if the current token has a specified value
71
75
  def tokenIs(self, value):
72
76
  return self.getToken() == value
73
77
 
78
+ # Test if the next token has the specified value
74
79
  def nextIs(self, value):
75
80
  return self.nextToken() == value
76
81
 
82
+ # Get the command at a given pc in the code list
77
83
  def getCommandAt(self, pc):
78
84
  return self.program.code[pc]
79
85
 
80
86
  # Add a command to the code list
81
- def add(self, command):
87
+ def addCommand(self, command):
82
88
  self.code.append(command)
83
89
 
90
+ # Test if the current token is a symbol
84
91
  def isSymbol(self):
85
92
  token = self.getToken()
86
93
  try:
@@ -89,10 +96,12 @@ class Compiler:
89
96
  return False
90
97
  return True
91
98
 
99
+ # Test if the next token is a symbol
92
100
  def nextIsSymbol(self):
93
101
  self.next()
94
102
  return self.isSymbol()
95
103
 
104
+ # Skip the next token if it matches the value given
96
105
  def skip(self, token):
97
106
  next = self.peek()
98
107
  if type(token) == list:
@@ -102,21 +111,26 @@ class Compiler:
102
111
  return
103
112
  elif next == token: self.nextToken()
104
113
 
114
+ # Rewind to a given position in the code list
105
115
  def rewindTo(self, index):
106
116
  self.index = index
107
117
 
118
+ # Get source line number containing the current token
108
119
  def getLino(self):
109
120
  if self.index >= len(self.tokens):
110
121
  return 0
111
122
  return self.tokens[self.index].lino
112
123
 
124
+ # Issue a warning
113
125
  def warning(self, message):
114
126
  self.warnings.append(f'Warning at line {self.getLino() + 1} of {self.program.name}: {message}')
115
127
 
128
+ # Print all warnings
116
129
  def showWarnings(self):
117
130
  for warning in self.warnings:
118
131
  print(warning)
119
132
 
133
+ # Get the symbol record for the current token (assumes it is a symbol name)
120
134
  def getSymbolRecord(self):
121
135
  token = self.getToken()
122
136
  if not token in self.symbols:
@@ -128,18 +142,23 @@ class Compiler:
128
142
  symbolRecord['used'] = True
129
143
  return symbolRecord
130
144
 
145
+ # Add a value type
131
146
  def addValueType(self):
132
147
  self.valueTypes[self.getToken()] = True
133
148
 
149
+ # Test if a given value is in the value types list
134
150
  def hasValue(self, type):
135
151
  return type in self.valueTypes
136
152
 
153
+ # Compile a program label (a symbol ending with ':')
137
154
  def compileLabel(self, command):
138
155
  return self.compileSymbol(command, self.getToken())
139
156
 
157
+ # Compile a variable
140
158
  def compileVariable(self, command, extra=None):
141
159
  return self.compileSymbol(command, self.nextToken(), extra)
142
160
 
161
+ # Compile a symbol
143
162
  def compileSymbol(self, command, name, extra=None):
144
163
  try:
145
164
  v = self.symbols[name]
@@ -148,7 +167,7 @@ class Compiler:
148
167
  if v:
149
168
  FatalError(self, f'Duplicate symbol name "{name}"')
150
169
  return False
151
- self.symbols[name] = self.getPC()
170
+ self.symbols[name] = self.getCodeSize()
152
171
  command['program'] = self.program
153
172
  command['type'] = 'symbol'
154
173
  command['name'] = name
@@ -161,7 +180,7 @@ class Compiler:
161
180
  command['locked'] = False
162
181
  command['extra'] = extra
163
182
  if 'keyword' in command: command['hasValue'] = self.hasValue(command['keyword'])
164
- self.add(command)
183
+ self.addCommand(command)
165
184
  return True
166
185
 
167
186
  # Compile the current token
@@ -171,6 +190,10 @@ class Compiler:
171
190
  # print(f'Compile {token}')
172
191
  if not token:
173
192
  return False
193
+ if len(self.code) == 0:
194
+ if self.program.parent == None and hasattr(self.program, 'usingGraphics'):
195
+ cmd = {'domain': 'graphics', 'keyword': 'init', 'debug': False}
196
+ self.code.append(cmd)
174
197
  mark = self.getIndex()
175
198
  for domain in self.program.getDomains():
176
199
  handler = domain.keywordHandler(token)
@@ -195,7 +218,7 @@ class Compiler:
195
218
  keyword = self.getToken()
196
219
  if not keyword:
197
220
  return False
198
- # print(f'Compile keyword "{keyword}"')
221
+ # print(f'Compile keyword "{keyword}"')
199
222
  if keyword.endswith(':'):
200
223
  command = {}
201
224
  command['domain'] = None
@@ -209,9 +232,8 @@ class Compiler:
209
232
  self.index = index
210
233
  while True:
211
234
  token = self.tokens[self.index]
212
- keyword = token.token
235
+ # keyword = token.token
213
236
  if self.debugCompile: print(self.script.lines[token.lino])
214
- # print(f'{keyword} - {line}')
215
237
  # if keyword != 'else':
216
238
  if self.compileOne() == True:
217
239
  if self.index == len(self.tokens) - 1:
@@ -222,5 +244,10 @@ class Compiler:
222
244
  else:
223
245
  return False
224
246
 
247
+ # Compile fom the current location, stopping on any of a list of tokens
225
248
  def compileFromHere(self, stopOn):
226
249
  return self.compileFrom(self.getIndex(), stopOn)
250
+
251
+ # Compile from the start of the script
252
+ def compileFromStart(self):
253
+ return self.compileFrom(0, [])
easycoder/ec_condition.py CHANGED
@@ -19,7 +19,7 @@ class Condition:
19
19
  condition.domain= domain.getName()
20
20
  return condition
21
21
  self.rewindTo(mark)
22
- return None
22
+ return None
23
23
 
24
24
  def testCondition(self, condition):
25
25
  handler = self.program.domainIndex[condition.domain]
easycoder/ec_core.py CHANGED
@@ -1,8 +1,9 @@
1
1
  import json, math, hashlib, threading, os, subprocess, time
2
2
  import numbers, base64, binascii, random, requests, paramiko
3
+ from copy import deepcopy
3
4
  from psutil import Process
4
5
  from datetime import datetime
5
- from .ec_classes import FatalError, RuntimeWarning, RuntimeError, AssertionError, NoValueError, NoValueRuntimeError, Condition, Object
6
+ from .ec_classes import FatalError, RuntimeWarning, RuntimeError, AssertionError, NoValueError, NoValueRuntimeError, Object
6
7
  from .ec_handler import Handler
7
8
  from .ec_timestamp import getTimestamp
8
9
 
@@ -30,13 +31,13 @@ class Core(Handler):
30
31
  cmd['keyword'] = 'gotoPC'
31
32
  cmd['goto'] = 0
32
33
  cmd['debug'] = False
33
- skip = self.getPC()
34
+ skip = self.getCodeSize()
34
35
  self.add(cmd)
35
36
  # Process the 'or'
36
- self.getCommandAt(orHere)['or'] = self.getPC()
37
+ self.getCommandAt(orHere)['or'] = self.getCodeSize()
37
38
  self.compileOne()
38
39
  # Fixup the skip
39
- self.getCommandAt(skip)['goto'] = self.getPC()
40
+ self.getCommandAt(skip)['goto'] = self.getCodeSize()
40
41
 
41
42
  #############################################################################
42
43
  # Keyword handlers
@@ -159,23 +160,25 @@ class Core(Handler):
159
160
  else:
160
161
  return self.compileFromHere(['end'])
161
162
 
162
- # Clear (set false)
163
163
  # clear {variable}
164
164
  def k_clear(self, command):
165
165
  if self.nextIsSymbol():
166
166
  target = self.getSymbolRecord()
167
- if target['hasValue']:
168
- command['target'] = target['name']
167
+ command['target'] = target['name']
168
+ if target['hasValue'] or target['keyword'] == 'ssh':
169
169
  self.add(command)
170
170
  return True
171
171
  return False
172
172
 
173
173
  def r_clear(self, command):
174
174
  target = self.getVariable(command['target'])
175
- val = {}
176
- val['type'] = 'boolean'
177
- val['content'] = False
178
- self.putSymbolValue(target, val)
175
+ if target['keyword'] == 'ssh':
176
+ target['ssh'] = None
177
+ else:
178
+ val = {}
179
+ val['type'] = 'boolean'
180
+ val['content'] = False
181
+ self.putSymbolValue(target, val)
179
182
  return self.nextPC()
180
183
 
181
184
  # Close a file
@@ -276,7 +279,7 @@ class Core(Handler):
276
279
  return self.incdec(command, '-')
277
280
 
278
281
  # Delete a file or a property
279
- # delete {filename}
282
+ # delete file {filename}
280
283
  # delete property {value} of {variable}
281
284
  # delete element {name} of {variable}
282
285
  def k_delete(self, command):
@@ -305,8 +308,8 @@ class Core(Handler):
305
308
  type = command['type']
306
309
  if type == 'file':
307
310
  filename = self.getRuntimeValue(command['filename'])
308
- if os.path.isfile(filename):
309
- os.remove(filename)
311
+ if filename != None:
312
+ if os.path.isfile(filename): os.remove(filename)
310
313
  elif type == 'property':
311
314
  key = self.getRuntimeValue(command['key'])
312
315
  symbolRecord = self.getVariable(command['var'])
@@ -320,7 +323,8 @@ class Core(Handler):
320
323
  symbolRecord = self.getVariable(command['var'])
321
324
  value = self.getSymbolValue(symbolRecord)
322
325
  content = value['content']
323
- content.remove(key)
326
+ if key >= 0 and key < len(content): del(content[key])
327
+ else: RuntimeError(self.program, f'Index {key} out of range')
324
328
  value['content'] = content
325
329
  self.putSymbolValue(symbolRecord, value)
326
330
  return self.nextPC()
@@ -464,7 +468,7 @@ class Core(Handler):
464
468
  if url != None:
465
469
  command['url'] = url
466
470
  command['or'] = None
467
- get = self.getPC()
471
+ get = self.getCodeSize()
468
472
  if self.peek() == 'timeout':
469
473
  self.nextToken()
470
474
  command['timeout'] = self.nextValue()
@@ -552,7 +556,7 @@ class Core(Handler):
552
556
  command['condition'] = self.nextCondition()
553
557
  self.add(command)
554
558
  self.nextToken()
555
- pcElse = self.getPC()
559
+ pcElse = self.getCodeSize()
556
560
  cmd = {}
557
561
  cmd['lino'] = command['lino']
558
562
  cmd['domain'] = 'core'
@@ -565,7 +569,7 @@ class Core(Handler):
565
569
  if self.peek() == 'else':
566
570
  self.nextToken()
567
571
  # Add a 'goto' to skip the 'else'
568
- pcNext = self.getPC()
572
+ pcNext = self.getCodeSize()
569
573
  cmd = {}
570
574
  cmd['lino'] = command['lino']
571
575
  cmd['domain'] = 'core'
@@ -574,15 +578,15 @@ class Core(Handler):
574
578
  cmd['debug'] = False
575
579
  self.add(cmd)
576
580
  # Fixup the link to the 'else' branch
577
- self.getCommandAt(pcElse)['goto'] = self.getPC()
581
+ self.getCommandAt(pcElse)['goto'] = self.getCodeSize()
578
582
  # Process the 'else' branch
579
583
  self.nextToken()
580
584
  self.compileOne()
581
585
  # Fixup the pcNext 'goto'
582
- self.getCommandAt(pcNext)['goto'] = self.getPC()
586
+ self.getCommandAt(pcNext)['goto'] = self.getCodeSize()
583
587
  else:
584
588
  # We're already at the next command
585
- self.getCommandAt(pcElse)['goto'] = self.getPC()
589
+ self.getCommandAt(pcElse)['goto'] = self.getCodeSize()
586
590
  return True
587
591
 
588
592
  def r_if(self, command):
@@ -601,7 +605,7 @@ class Core(Handler):
601
605
  name = self.nextToken()
602
606
  item = [keyword, name]
603
607
  imports.append(item)
604
- self.symbols[name] = self.getPC()
608
+ self.symbols[name] = self.getCodeSize()
605
609
  variable = {}
606
610
  variable['domain'] = None
607
611
  variable['name'] = name
@@ -743,7 +747,7 @@ class Core(Handler):
743
747
  else:
744
748
  command['file'] = self.getValue()
745
749
  command['or'] = None
746
- load = self.getPC()
750
+ load = self.getCodeSize()
747
751
  self.processOr(command, load)
748
752
  return True
749
753
  else:
@@ -912,7 +916,7 @@ class Core(Handler):
912
916
  cmd['debug'] = False
913
917
  self.add(cmd)
914
918
  # Fixup the link
915
- command['goto'] = self.getPC()
919
+ command['goto'] = self.getCodeSize()
916
920
  return True
917
921
  return False
918
922
 
@@ -1003,7 +1007,7 @@ class Core(Handler):
1003
1007
  else:
1004
1008
  command['result'] = None
1005
1009
  command['or'] = None
1006
- post = self.getPC()
1010
+ post = self.getCodeSize()
1007
1011
  self.processOr(command, post)
1008
1012
  return True
1009
1013
 
@@ -1076,7 +1080,7 @@ class Core(Handler):
1076
1080
  return False
1077
1081
 
1078
1082
  def r_push(self, command):
1079
- value = self.getRuntimeValue(command['value'])
1083
+ value = deepcopy(self.getRuntimeValue(command['value']))
1080
1084
  stackRecord = self.getVariable(command['to'])
1081
1085
  if stackRecord['keyword'] != 'stack':
1082
1086
  RuntimeError(self.program, f'{stackRecord["name"]} is not a stack')
@@ -1102,7 +1106,7 @@ class Core(Handler):
1102
1106
  FatalError(self.compiler, f'Symbol {symbolRecord["name"]} is not a value holder')
1103
1107
  else:
1104
1108
  command['or'] = None
1105
- self.processOr(command, self.getPC())
1109
+ self.processOr(command, self.getCodeSize())
1106
1110
  return True
1107
1111
  else:
1108
1112
  FatalError(self.compiler, f'Symbol {self.getToken()} is not a variable')
@@ -1270,7 +1274,7 @@ class Core(Handler):
1270
1274
  else:
1271
1275
  command['file'] = self.getValue()
1272
1276
  command['or'] = None
1273
- save = self.getPC()
1277
+ save = self.getCodeSize()
1274
1278
  self.processOr(command, save)
1275
1279
  return True
1276
1280
 
@@ -1503,8 +1507,11 @@ class Core(Handler):
1503
1507
  ssh = paramiko.SSHClient()
1504
1508
  target['ssh'] = ssh
1505
1509
  ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
1506
- ssh.connect(host, username=user, password=password)
1507
- target['sftp'] = ssh.open_sftp()
1510
+ try:
1511
+ ssh.connect(host, username=user, password=password, timeout=10)
1512
+ target['sftp'] = ssh.open_sftp()
1513
+ except:
1514
+ target['error'] = f'Unable to connect to {host} (timeout)'
1508
1515
  return self.nextPC()
1509
1516
 
1510
1517
  # Shuffle a list
@@ -1762,12 +1769,17 @@ class Core(Handler):
1762
1769
  self.program.importPlugin(f'{source}:{clazz}')
1763
1770
  return True
1764
1771
  return False
1765
- elif self.nextIs('graphics'):
1766
- print('Loading graphics module')
1767
- from .ec_pyside import Graphics
1768
- self.program.graphics = Graphics
1769
- self.program.useClass(Graphics)
1770
- return True
1772
+ else:
1773
+ token = self.nextToken()
1774
+ if token in ['graphics', 'debugger']:
1775
+ if not hasattr(self.program, 'usingGraphics'):
1776
+ print('Loading graphics module')
1777
+ from .ec_pyside import Graphics
1778
+ self.program.graphics = Graphics
1779
+ self.program.useClass(Graphics)
1780
+ self.program.usingGraphics = True
1781
+ if token == 'debugger': self.program.debugging = True
1782
+ return True
1771
1783
  return False
1772
1784
 
1773
1785
  # Declare a general-purpose variable
@@ -1811,10 +1823,10 @@ class Core(Handler):
1811
1823
  return None
1812
1824
  # token = self.getToken()
1813
1825
  command['condition'] = code
1814
- test = self.getPC()
1826
+ test = self.getCodeSize()
1815
1827
  self.add(command)
1816
1828
  # Set up a goto for when the test fails
1817
- fail = self.getPC()
1829
+ fail = self.getCodeSize()
1818
1830
  cmd = {}
1819
1831
  cmd['lino'] = command['lino']
1820
1832
  cmd['domain'] = 'core'
@@ -1835,7 +1847,7 @@ class Core(Handler):
1835
1847
  cmd['debug'] = False
1836
1848
  self.add(cmd)
1837
1849
  # Fixup the 'goto' on completion
1838
- self.getCommandAt(fail)['goto'] = self.getPC()
1850
+ self.getCommandAt(fail)['goto'] = self.getCodeSize()
1839
1851
  return True
1840
1852
 
1841
1853
  def r_while(self, command):
@@ -2108,14 +2120,24 @@ class Core(Handler):
2108
2120
  return value
2109
2121
 
2110
2122
  if token == 'error':
2111
- if self.peek() == 'code':
2123
+ token = self.peek()
2124
+ if token == 'code':
2112
2125
  self.nextToken()
2113
2126
  value['item'] = 'errorCode'
2114
2127
  return value
2115
- if self.peek() == 'reason':
2128
+ elif token == 'reason':
2116
2129
  self.nextToken()
2117
2130
  value['item'] = 'errorReason'
2118
2131
  return value
2132
+ elif token in ['in', 'of']:
2133
+ self.nextToken()
2134
+ if self.nextIsSymbol():
2135
+ record = self.getSymbolRecord()
2136
+ if record['keyword'] == 'ssh':
2137
+ value['item'] = 'sshError'
2138
+ value['name'] = record['name']
2139
+ return value
2140
+ return None
2119
2141
 
2120
2142
  if token == 'type':
2121
2143
  if self.nextIs('of'):
@@ -2279,6 +2301,10 @@ class Core(Handler):
2279
2301
  elif v['item'] == 'errorReason':
2280
2302
  value['type'] = 'text'
2281
2303
  value['content'] = errorReason
2304
+ elif v['item'] == 'sshError':
2305
+ record = self.getVariable(v['name'])
2306
+ value['type'] = 'text'
2307
+ value['content'] = record['error'] if 'error' in record else ''
2282
2308
  return value
2283
2309
 
2284
2310
  def v_files(self, v):
@@ -2430,7 +2456,7 @@ class Core(Handler):
2430
2456
  def v_now(self, v):
2431
2457
  value = {}
2432
2458
  value['type'] = 'int'
2433
- value['content'] = getTimestamp(time.time())
2459
+ value['content'] = int(time.time())
2434
2460
  return value
2435
2461
 
2436
2462
  def v_position(self, v):
@@ -2510,7 +2536,7 @@ class Core(Handler):
2510
2536
  elif keyword == 'ssh':
2511
2537
  v = {}
2512
2538
  v['type'] = 'boolean'
2513
- v['content'] = True if 'ssh' in symbolRecord else False
2539
+ v['content'] = True if 'ssh' in symbolRecord and symbolRecord['ssh'] != None else False
2514
2540
  return v
2515
2541
  else:
2516
2542
  return None
@@ -2611,18 +2637,39 @@ class Core(Handler):
2611
2637
  #############################################################################
2612
2638
  # Compile a condition
2613
2639
  def compileCondition(self):
2614
- condition = Condition()
2640
+ condition = Object()
2641
+ condition.negate = False
2642
+
2643
+ token = self.getToken()
2615
2644
 
2616
- if self.getToken() == 'not':
2645
+ if token == 'not':
2617
2646
  condition.type = 'not'
2618
2647
  condition.value = self.nextValue()
2619
2648
  return condition
2620
2649
 
2621
- if self.getToken() == 'file':
2650
+ elif token == 'error':
2651
+ self.nextToken()
2652
+ self.skip('in')
2653
+ if self.nextIsSymbol():
2654
+ record = self.getSymbolRecord()
2655
+ if record['keyword'] == 'ssh':
2656
+ condition.type = 'sshError'
2657
+ condition.target = record['name']
2658
+ return condition
2659
+ return None
2660
+
2661
+ elif token == 'file':
2622
2662
  path = self.nextValue()
2623
2663
  condition.path = path
2624
2664
  condition.type = 'exists'
2625
- token = self.nextToken()
2665
+ self.skip('on')
2666
+ if self.nextIsSymbol():
2667
+ record = self.getSymbolRecord()
2668
+ if record['keyword'] == 'ssh':
2669
+ condition.type = 'sshExists'
2670
+ condition.target = record['name']
2671
+ token = self.nextToken()
2672
+ else: token = self.getToken()
2626
2673
  if token == 'exists':
2627
2674
  return condition
2628
2675
  elif token == 'does':
@@ -2798,6 +2845,24 @@ class Core(Handler):
2798
2845
 
2799
2846
  def c_odd(self, condition):
2800
2847
  return self.getRuntimeValue(condition.value1) % 2 == 1
2848
+
2849
+ def c_sshError(self, condition):
2850
+ target = self.getVariable(condition.target)
2851
+ errormsg = target['error'] if 'error' in target else None
2852
+ condition.errormsg = errormsg
2853
+ test = errormsg != None
2854
+ return not test if condition.negate else test
2855
+
2856
+ def c_sshExists(self, condition):
2857
+ path = self.getRuntimeValue(condition.path)
2858
+ ssh = self.getVariable(condition.target)
2859
+ sftp = ssh['sftp']
2860
+ try:
2861
+ with sftp.open(path, 'r') as remote_file: remote_file.read().decode()
2862
+ comparison = True
2863
+ except:
2864
+ comparison = False
2865
+ return not comparison if condition.negate else comparison
2801
2866
 
2802
2867
  def c_starts(self, condition):
2803
2868
  value1 = self.getRuntimeValue(condition.value1)
easycoder/ec_handler.py CHANGED
@@ -22,8 +22,8 @@ class Handler:
22
22
  self.compileVariable = compiler.compileVariable
23
23
  self.rewindTo = compiler.rewindTo
24
24
  self.warning = compiler.warning
25
- self.getPC = compiler.getPC
26
- self.add = compiler.add
25
+ self.getCodeSize = compiler.getCodeSize
26
+ self.add = compiler.addCommand
27
27
  self.getCommandAt = compiler.getCommandAt
28
28
  self.compileOne = compiler.compileOne
29
29
  self.compileFromHere = compiler.compileFromHere
easycoder/ec_keyboard.py CHANGED
@@ -158,6 +158,8 @@ class KeyboardView(QVBoxLayout):
158
158
  for row in rows:
159
159
  self.addLayout(row)
160
160
 
161
+ ###############################################################################
162
+ # VirtualKeyboard Class
161
163
  class VirtualKeyboard(QStackedWidget):
162
164
  def __init__(self, keyboardType, buttonHeight, receiver, onFinished):
163
165
  super().__init__()
@@ -173,6 +175,8 @@ class VirtualKeyboard(QStackedWidget):
173
175
  self.addKeyboardLayout2()
174
176
  self.addKeyboardLayout3()
175
177
 
178
+ ###########################################################################
179
+ # Add the first keyboard layout (lowercase letters)
176
180
  def addKeyboardLayout0(self):
177
181
  rowList = []
178
182
 
@@ -214,7 +218,7 @@ class VirtualKeyboard(QStackedWidget):
214
218
  KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickNumbers, None, 'img/numbers.png'),
215
219
  QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
216
220
  KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
217
- KeyboardButton(self.buttonHeight * 5, self.buttonHeight, self.onClickSpace, None, 'skeyboard/pace.png'),
221
+ KeyboardButton(self.buttonHeight * 5, self.buttonHeight, self.onClickSpace, None, 'keyboard/space.png'),
218
222
  KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, "."),
219
223
  QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
220
224
  KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
@@ -228,6 +232,8 @@ class VirtualKeyboard(QStackedWidget):
228
232
  container.setLayout(keyboardView)
229
233
  self.addWidget(container)
230
234
 
235
+ ###########################################################################
236
+ # Add the second keyboard layout (uppercase letters)
231
237
  def addKeyboardLayout1(self):
232
238
  rowList = []
233
239
 
@@ -283,6 +289,8 @@ class VirtualKeyboard(QStackedWidget):
283
289
  container.setLayout(keyboardView)
284
290
  self.addWidget(container)
285
291
 
292
+ ###########################################################################
293
+ # Add the third keyboard layout (numbers and symbols)
286
294
  def addKeyboardLayout2(self):
287
295
  rowList = []
288
296
 
@@ -320,11 +328,11 @@ class VirtualKeyboard(QStackedWidget):
320
328
  KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickLetters, None, 'img/letters.png'),
321
329
  QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
322
330
  KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
323
- KeyboardButton(self.buttonHeight * 6, self.buttonHeight, self.onClickSpace, None, 'img/space.png'),
331
+ KeyboardButton(self.buttonHeight * 5.2, self.buttonHeight, self.onClickSpace, None, 'keyboard/space.png'),
324
332
  KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, "."),
325
333
  QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
326
334
  KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
327
- QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
335
+ QSpacerItem(10, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
328
336
  ])
329
337
  rowList.append(row4)
330
338
 
@@ -334,6 +342,8 @@ class VirtualKeyboard(QStackedWidget):
334
342
  container.setLayout(keyboardView)
335
343
  self.addWidget(container)
336
344
 
345
+ ###########################################################################
346
+ # Add the fourth keyboard layout (additional symbols)
337
347
  def addKeyboardLayout3(self):
338
348
  rowList = []
339
349