easycoder 250722.4__tar.gz → 250723.1__tar.gz

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.

Potentially problematic release.


This version of easycoder might be problematic. Click here for more details.

Files changed (172) hide show
  1. {easycoder-250722.4 → easycoder-250723.1}/.gitignore +0 -1
  2. {easycoder-250722.4 → easycoder-250723.1}/PKG-INFO +3 -2
  3. {easycoder-250722.4 → easycoder-250723.1}/easycoder/__init__.py +3 -3
  4. {easycoder-250722.4 → easycoder-250723.1}/easycoder/ec_core.py +2 -1
  5. easycoder-250723.1/easycoder/ec_keyboard.py +392 -0
  6. {easycoder-250722.4 → easycoder-250723.1}/easycoder/ec_pyside.py +3 -1
  7. easycoder-250723.1/plugins/sql.py +164 -0
  8. easycoder-250723.1/test.py +5 -0
  9. easycoder-250723.1/testsql.py +7 -0
  10. easycoder-250723.1/testui.py +7 -0
  11. {easycoder-250722.4 → easycoder-250723.1}/LICENSE +0 -0
  12. {easycoder-250722.4 → easycoder-250723.1}/README.md +0 -0
  13. {easycoder-250722.4 → easycoder-250723.1}/backdrop.jpg +0 -0
  14. {easycoder-250722.4 → easycoder-250723.1}/doc/README.md +0 -0
  15. {easycoder-250722.4 → easycoder-250723.1}/doc/core/README.md +0 -0
  16. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/boolean.md +0 -0
  17. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/empty.md +0 -0
  18. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/ends.md +0 -0
  19. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/even.md +0 -0
  20. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/exists.md +0 -0
  21. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/greater.md +0 -0
  22. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/hasProperty.md +0 -0
  23. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/includes.md +0 -0
  24. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/is.md +0 -0
  25. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/less.md +0 -0
  26. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/list.md +0 -0
  27. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/none.md +0 -0
  28. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/not.md +0 -0
  29. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/numeric.md +0 -0
  30. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/object.md +0 -0
  31. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/odd.md +0 -0
  32. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/starts.md +0 -0
  33. {easycoder-250722.4 → easycoder-250723.1}/doc/core/conditions/string.md +0 -0
  34. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/add.md +0 -0
  35. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/append.md +0 -0
  36. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/assert.md +0 -0
  37. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/begin.md +0 -0
  38. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/clear.md +0 -0
  39. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/close.md +0 -0
  40. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/create.md +0 -0
  41. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/debug.md +0 -0
  42. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/decrement.md +0 -0
  43. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/delete.md +0 -0
  44. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/divide.md +0 -0
  45. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/exit.md +0 -0
  46. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/file.md +0 -0
  47. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/fork.md +0 -0
  48. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/get.md +0 -0
  49. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/go.md +0 -0
  50. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/gosub.md +0 -0
  51. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/if.md +0 -0
  52. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/import.md +0 -0
  53. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/increment.md +0 -0
  54. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/index.md +0 -0
  55. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/init.md +0 -0
  56. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/input.md +0 -0
  57. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/load.md +0 -0
  58. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/lock.md +0 -0
  59. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/log.md +0 -0
  60. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/module.md +0 -0
  61. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/multiply.md +0 -0
  62. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/negate.md +0 -0
  63. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/on.md +0 -0
  64. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/open.md +0 -0
  65. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/pop.md +0 -0
  66. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/post.md +0 -0
  67. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/print.md +0 -0
  68. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/push.md +0 -0
  69. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/put.md +0 -0
  70. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/read.md +0 -0
  71. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/release.md +0 -0
  72. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/replace.md +0 -0
  73. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/return.md +0 -0
  74. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/run.md +0 -0
  75. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/save.md +0 -0
  76. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/script.md +0 -0
  77. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/send.md +0 -0
  78. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/set.md +0 -0
  79. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/shuffle.md +0 -0
  80. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/split.md +0 -0
  81. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/stack.md +0 -0
  82. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/stop.md +0 -0
  83. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/system.md +0 -0
  84. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/take.md +0 -0
  85. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/toggle.md +0 -0
  86. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/truncate.md +0 -0
  87. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/unlock.md +0 -0
  88. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/use.md +0 -0
  89. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/variable.md +0 -0
  90. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/wait.md +0 -0
  91. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/while.md +0 -0
  92. {easycoder-250722.4 → easycoder-250723.1}/doc/core/keywords/write.md +0 -0
  93. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/arg.md +0 -0
  94. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/args.md +0 -0
  95. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/cos.md +0 -0
  96. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/datime.md +0 -0
  97. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/decode.md +0 -0
  98. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/element.md +0 -0
  99. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/elements.md +0 -0
  100. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/empty.md +0 -0
  101. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/encode.md +0 -0
  102. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/error.md +0 -0
  103. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/files.md +0 -0
  104. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/float.md +0 -0
  105. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/from.md +0 -0
  106. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/hash.md +0 -0
  107. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/index.md +0 -0
  108. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/integer.md +0 -0
  109. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/json.md +0 -0
  110. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/keys.md +0 -0
  111. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/left.md +0 -0
  112. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/length.md +0 -0
  113. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/lowercase.md +0 -0
  114. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/memory.md +0 -0
  115. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/modification.md +0 -0
  116. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/modulo.md +0 -0
  117. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/newline.md +0 -0
  118. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/now.md +0 -0
  119. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/position.md +0 -0
  120. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/property.md +0 -0
  121. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/random.md +0 -0
  122. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/right.md +0 -0
  123. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/sin.md +0 -0
  124. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/stringify.md +0 -0
  125. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/tab.md +0 -0
  126. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/tan.md +0 -0
  127. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/timestamp.md +0 -0
  128. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/today.md +0 -0
  129. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/trim.md +0 -0
  130. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/type.md +0 -0
  131. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/uppercase.md +0 -0
  132. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/value.md +0 -0
  133. {easycoder-250722.4 → easycoder-250723.1}/doc/core/values/weekday.md +0 -0
  134. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/README.md +0 -0
  135. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/keywords/attach.md +0 -0
  136. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/keywords/close.md +0 -0
  137. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/keywords/create.md +0 -0
  138. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/keywords/ellipse.md +0 -0
  139. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/keywords/image.md +0 -0
  140. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/keywords/move.md +0 -0
  141. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/keywords/on.md +0 -0
  142. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/keywords/rectangle.md +0 -0
  143. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/keywords/render.md +0 -0
  144. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/keywords/run.md +0 -0
  145. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/keywords/set.md +0 -0
  146. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/keywords/text.md +0 -0
  147. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/values/attribute.md +0 -0
  148. {easycoder-250722.4 → easycoder-250723.1}/doc/graphics/values/window.md +0 -0
  149. {easycoder-250722.4 → easycoder-250723.1}/easycoder/ec_classes.py +0 -0
  150. {easycoder-250722.4 → easycoder-250723.1}/easycoder/ec_compiler.py +0 -0
  151. {easycoder-250722.4 → easycoder-250723.1}/easycoder/ec_condition.py +0 -0
  152. {easycoder-250722.4 → easycoder-250723.1}/easycoder/ec_handler.py +0 -0
  153. {easycoder-250722.4 → easycoder-250723.1}/easycoder/ec_program.py +0 -0
  154. {easycoder-250722.4 → easycoder-250723.1}/easycoder/ec_timestamp.py +0 -0
  155. {easycoder-250722.4 → easycoder-250723.1}/easycoder/ec_value.py +0 -0
  156. {easycoder-250722.4 → easycoder-250723.1}/images/Semoigo Dawn.jpg +0 -0
  157. {easycoder-250722.4 → easycoder-250723.1}/json/graphics-demo.json +0 -0
  158. {easycoder-250722.4 → easycoder-250723.1}/plugins/ec_keyboard.py +0 -0
  159. {easycoder-250722.4 → easycoder-250723.1}/plugins/ec_p100.py +0 -0
  160. {easycoder-250722.4 → easycoder-250723.1}/plugins/ec_pyside6.py +0 -0
  161. {easycoder-250722.4 → easycoder-250723.1}/plugins/points.py +0 -0
  162. {easycoder-250722.4 → easycoder-250723.1}/pyproject.toml +0 -0
  163. {easycoder-250722.4 → easycoder-250723.1}/scripts/benchmark.ecs +0 -0
  164. {easycoder-250722.4 → easycoder-250723.1}/scripts/config.ecg +0 -0
  165. {easycoder-250722.4 → easycoder-250723.1}/scripts/ec_keyboard.py +0 -0
  166. {easycoder-250722.4 → easycoder-250723.1}/scripts/findxr.ecs +0 -0
  167. {easycoder-250722.4 → easycoder-250723.1}/scripts/fizzbuzz.ecs +0 -0
  168. {easycoder-250722.4 → easycoder-250723.1}/scripts/hello.ecs +0 -0
  169. {easycoder-250722.4 → easycoder-250723.1}/scripts/points.ecs +0 -0
  170. {easycoder-250722.4 → easycoder-250723.1}/scripts/test.ecs +0 -0
  171. {easycoder-250722.4 → easycoder-250723.1}/scripts/tests.ecs +0 -0
  172. {easycoder-250722.4 → easycoder-250723.1}/testrc.py +0 -0
@@ -1,4 +1,3 @@
1
1
  */__pycache__/*
2
2
  *.code-workspace
3
- *.py
4
3
  *.ecs
@@ -1,11 +1,12 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: easycoder
3
- Version: 250722.4
3
+ Version: 250723.1
4
4
  Summary: Rapid scripting in English
5
5
  Keywords: compiler,scripting,prototyping,programming,coding,python,low code,hypertalk,computer language,learn to code
6
6
  Author-email: Graham Trott <gtanyware@gmail.com>
7
7
  Description-Content-Type: text/markdown
8
8
  Classifier: License :: OSI Approved :: MIT License
9
+ License-File: LICENSE
9
10
  Requires-Dist: pytz
10
11
  Requires-Dist: requests
11
12
  Requires-Dist: psutil
@@ -5,10 +5,10 @@ from .ec_compiler import *
5
5
  from .ec_condition import *
6
6
  from .ec_core import *
7
7
  from .ec_handler import *
8
+ from .ec_keyboard import *
8
9
  from .ec_program import *
10
+ from .ec_pyside import *
9
11
  from .ec_timestamp import *
10
12
  from .ec_value import *
11
- from .ec_pyside import *
12
- from .ec_keyboard import *
13
13
 
14
- __version__ = "250722.4"
14
+ __version__ = "250723.1"
@@ -2,7 +2,6 @@ import json, math, hashlib, threading, os, subprocess, sys, time
2
2
  import numbers, base64, binascii, random, requests, paramiko
3
3
  from psutil import Process
4
4
  from datetime import datetime
5
- from random import randrange
6
5
  from .ec_classes import FatalError, RuntimeWarning, RuntimeError, AssertionError, NoValueError, NoValueRuntimeError, Condition, Object
7
6
  from .ec_handler import Handler
8
7
  from .ec_timestamp import getTimestamp
@@ -1804,6 +1803,8 @@ class Core(Handler):
1804
1803
  from .ec_pyside import Graphics
1805
1804
  self.program.graphics = Graphics
1806
1805
  self.program.useClass(Graphics)
1806
+ # from .ec_keyboard import Keyboard
1807
+ # self.program.useClass(Keyboard)
1807
1808
  return True
1808
1809
  return False
1809
1810
 
@@ -0,0 +1,392 @@
1
+
2
+ from .ec_handler import Handler
3
+ from PySide6.QtWidgets import (
4
+ QDialog,
5
+ QVBoxLayout,
6
+ QHBoxLayout,
7
+ QPushButton,
8
+ QWidget,
9
+ QStackedWidget,
10
+ QSpacerItem,
11
+ QSizePolicy,
12
+ QGraphicsDropShadowEffect
13
+ )
14
+ from PySide6.QtGui import QFont, QIcon
15
+ from PySide6.QtCore import Qt, QTimer
16
+
17
+ class Keyboard(Handler):
18
+
19
+ def __init__(self, program, receiver, parent=None):
20
+ Handler.__init__(self, program.compiler)
21
+
22
+ self.program = program
23
+
24
+ dialog = QDialog()
25
+
26
+ # dialog.setWindowTitle('')
27
+ dialog.setWindowFlags(Qt.FramelessWindowHint)
28
+ dialog.setModal(True)
29
+ dialog.setFixedSize(500, 250)
30
+ dialog.setStyleSheet('background-color: white;border:1px solid black;')
31
+
32
+ # Add drop shadow
33
+ shadow = QGraphicsDropShadowEffect(dialog)
34
+ shadow.setBlurRadius(40)
35
+ shadow.setOffset(0, 4)
36
+ shadow.setColor(Qt.black)
37
+ dialog.setGraphicsEffect(shadow)
38
+
39
+ # Add the keyboard
40
+ layout = QVBoxLayout(dialog)
41
+ layout.addWidget(VirtualKeyboard(42, receiver, dialog.reject))
42
+
43
+ # Position at bottom of parent window
44
+ dialog.show() # Ensure geometry is calculated
45
+ if parent:
46
+ parent_pos = parent.mapToGlobal(parent.rect().bottomLeft())
47
+ x = parent_pos.x() + (parent.width - dialog.width()) / 2
48
+ y = parent_pos.y() - dialog.height() - 40
49
+ dialog.move(x, y)
50
+
51
+ dialog.exec()
52
+
53
+
54
+ class TextReceiver():
55
+ def __init__(self, field):
56
+ self.field = field
57
+
58
+ def add_character(self, char):
59
+ """
60
+ Add a character to the text field.
61
+
62
+ :param char: A single character to add to the field.
63
+ """
64
+ char = char.replace('&&', '&')
65
+ if len(char) == 1:
66
+ self.field.setText(self.field.text() + char)
67
+ else:
68
+ raise ValueError("Only single characters are allowed.")
69
+
70
+ def backspace(self):
71
+ """
72
+ Remove the last character from the text field.
73
+ If the field is already empty, do nothing.
74
+ """
75
+ current_text = self.field.text()
76
+ if current_text:
77
+ self.field.setText(current_text[:-1])
78
+
79
+ def get_content(self):
80
+ """
81
+ Return the current content of the text field.
82
+
83
+ :return: The current text in the field.
84
+ """
85
+ return self.field.text()
86
+
87
+ class KeyboardButton(QPushButton):
88
+ def __init__(self, width, height, onClick, text=None, icon=None):
89
+ if text != None: text = text.replace('&','&&')
90
+ super().__init__(text)
91
+ self.setFixedSize(width, height)
92
+ self.setFont(QFont("Arial", height // 2)) # Font size is half the button height
93
+ self.setStyleSheet(f"""
94
+ QPushButton {{
95
+ background-color: white;
96
+ border: none;
97
+ border-radius: {int(height * 0.2)}px; /* Rounded corners */
98
+ }}
99
+ QPushButton:pressed {{
100
+ background-color: #ddd; /* Slightly darker background when pressed */
101
+ }}
102
+ """)
103
+
104
+ if icon:
105
+ self.setIcon(QIcon(icon))
106
+ self.setIconSize(self.size())
107
+
108
+ self.clicked.connect(lambda: self.animate_button(onClick, text))
109
+
110
+ def animate_button(self, onClick, text):
111
+ # Move the button 2 pixels down and right
112
+ self.move(self.x() + 2, self.y() + 2)
113
+ QTimer.singleShot(200, lambda: self.move(self.x() - 2, self.y() - 2)) # Move back after 200ms
114
+ onClick(text)
115
+
116
+ class KeyboardRow(QHBoxLayout):
117
+ def __init__(self, items):
118
+ super().__init__()
119
+ for item in items:
120
+ if isinstance(item, QWidget):
121
+ self.addWidget(item)
122
+ elif isinstance(item, QSpacerItem):
123
+ self.addSpacerItem(item)
124
+
125
+ class KeyboardView(QVBoxLayout):
126
+ def __init__(self, rows):
127
+ super().__init__()
128
+ for row in rows:
129
+ self.addLayout(row)
130
+
131
+ class VirtualKeyboard(QStackedWidget):
132
+ def __init__(self, buttonHeight, textField, onFinished=None):
133
+ super().__init__()
134
+ self.buttonHeight = buttonHeight
135
+ self.textField = textField
136
+ self.onFinished = onFinished
137
+ self.setStyleSheet('background-color: #ccc;border:none;')
138
+
139
+ # Create the 4 keyboard layouts
140
+ self.addKeyboardLayout0()
141
+ self.addKeyboardLayout1()
142
+ self.addKeyboardLayout2()
143
+ self.addKeyboardLayout3()
144
+
145
+ def addKeyboardLayout0(self):
146
+ rowList = []
147
+
148
+ # Row 1: Numbers
149
+ # row1 = KeyboardRow([KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '1234567890'])
150
+ # rowList.append(row1)
151
+
152
+ # Row 2: qwertyuiop
153
+ row2 = KeyboardRow([
154
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
155
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'qwertyuiop'],
156
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
157
+ ])
158
+ rowList.append(row2)
159
+
160
+ # Row 3: asdfghjkl with horizontal stretches
161
+ row3 = KeyboardRow([
162
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
163
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'asdfghjkl'],
164
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
165
+ ])
166
+ rowList.append(row3)
167
+
168
+ # Row 4: Shift, ZXC..., Backspace
169
+ row4 = KeyboardRow([
170
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
171
+ KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickShift, None, 'img/up.png'),
172
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
173
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'zxcvbnm'],
174
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
175
+ KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickBack, None, 'img/back.png'),
176
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
177
+ ])
178
+ rowList.append(row4)
179
+
180
+ # Row 5: Numbers, Space, Enter
181
+ row5 = KeyboardRow([
182
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
183
+ KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickNumbers, None, 'img/numbers.png'),
184
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
185
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
186
+ KeyboardButton(self.buttonHeight * 5, self.buttonHeight, self.onClickSpace, None, 'skeyboard/pace.png'),
187
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, "."),
188
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
189
+ KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
190
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
191
+ ])
192
+ rowList.append(row5)
193
+
194
+ # Add the rows to the KeyboardView
195
+ keyboardView = KeyboardView(rowList)
196
+ container = QWidget()
197
+ container.setLayout(keyboardView)
198
+ self.addWidget(container)
199
+
200
+ def addKeyboardLayout1(self):
201
+ rowList = []
202
+
203
+ # Row 1: Numbers
204
+ # row1 = KeyboardRow([KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '1234567890'])
205
+ # rowList.append(row1)
206
+
207
+ # Row 2: Uppercase QWERTY
208
+ row2 = KeyboardRow([
209
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
210
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'QWERTYUIOP'],
211
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
212
+ ])
213
+ rowList.append(row2)
214
+
215
+ # Row 3: Uppercase ASDFGHJKL with horizontal stretches
216
+ row3 = KeyboardRow([
217
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
218
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'ASDFGHJKL'],
219
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
220
+ ])
221
+ rowList.append(row3)
222
+
223
+ # Row 4: Shift, Uppercase ZXC..., Backspace
224
+ row4 = KeyboardRow([
225
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
226
+ KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickShift, None, 'img/up.png'),
227
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
228
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in 'ZXCVBNM'],
229
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
230
+ KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickBack, None, 'img/back.png'),
231
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
232
+ ])
233
+ rowList.append(row4)
234
+
235
+ # Row 5: Numbers, Space, Enter
236
+ row5 = KeyboardRow([
237
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum),
238
+ KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickNumbers, None, 'img/numbers.png'),
239
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
240
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
241
+ KeyboardButton(self.buttonHeight * 5, self.buttonHeight, self.onClickSpace, None, 'img/space.png'),
242
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, "."),
243
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
244
+ KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
245
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
246
+ ])
247
+ rowList.append(row5)
248
+
249
+ # Add the rows to the KeyboardView
250
+ keyboardView = KeyboardView(rowList)
251
+ container = QWidget()
252
+ container.setLayout(keyboardView)
253
+ self.addWidget(container)
254
+
255
+ def addKeyboardLayout2(self):
256
+ rowList = []
257
+
258
+ # Row 1: Numbers
259
+ row1 = KeyboardRow([
260
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
261
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '1234567890'],
262
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
263
+ ])
264
+ rowList.append(row1)
265
+
266
+ # Row 2: Symbols
267
+ row2 = KeyboardRow([
268
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
269
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '@#£&_-()=%'],
270
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
271
+ ])
272
+ rowList.append(row2)
273
+
274
+ # Row 3: Symbols with horizontal stretches
275
+ row3 = KeyboardRow([
276
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
277
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickSymbols, None, 'img/symbols.png'),
278
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
279
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '"*\'/:!?+'],
280
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
281
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickBack, None, 'img/back.png'),
282
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
283
+ ])
284
+ rowList.append(row3)
285
+
286
+ # Row 4: Numbers, Space, Enter
287
+ row4 = KeyboardRow([
288
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
289
+ KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickLetters, None, 'img/letters.png'),
290
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
291
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
292
+ KeyboardButton(self.buttonHeight * 6, self.buttonHeight, self.onClickSpace, None, 'img/space.png'),
293
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, "."),
294
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
295
+ KeyboardButton(self.buttonHeight * 1.5, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
296
+ QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum)
297
+ ])
298
+ rowList.append(row4)
299
+
300
+ # Add the rows to the KeyboardView
301
+ keyboardView = KeyboardView(rowList)
302
+ container = QWidget()
303
+ container.setLayout(keyboardView)
304
+ self.addWidget(container)
305
+
306
+ def addKeyboardLayout3(self):
307
+ rowList = []
308
+
309
+ # Row 1: Extended symbols
310
+ row1 = KeyboardRow([
311
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
312
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '$€¥¢©®µ~¿¡'],
313
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
314
+ ])
315
+ rowList.append(row1)
316
+
317
+ # Row 2: Additional symbols
318
+ row2 = KeyboardRow([
319
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
320
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '¼½¾[]{}<>^'],
321
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
322
+ ])
323
+ rowList.append(row2)
324
+
325
+ # Row 3: Symbols with horizontal stretches
326
+ row3 = KeyboardRow([
327
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
328
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickNumbers, None, 'img/numbers.png'),
329
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
330
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '`;÷\\∣|¬±'],
331
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
332
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickBack, None, 'img/back.png'),
333
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
334
+ ])
335
+ rowList.append(row3)
336
+
337
+ # Row 4: Numbers, Space, Enter
338
+ row4 = KeyboardRow([
339
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum),
340
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickLetters, None, 'img/letters.png'),
341
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
342
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, ","),
343
+ KeyboardButton(self.buttonHeight * 3, self.buttonHeight, self.onClickSpace, None, 'img/space.png'),
344
+ QSpacerItem(self.buttonHeight * 0.05, 0, QSizePolicy.Fixed, QSizePolicy.Minimum),
345
+ *[KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickChar, char) for char in '✕§¶°'],
346
+ KeyboardButton(self.buttonHeight, self.buttonHeight, self.onClickEnter, None, 'img/enter.png'),
347
+ QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
348
+ ])
349
+ rowList.append(row4)
350
+
351
+ # Add the rows to the KeyboardView
352
+ keyboardView = KeyboardView(rowList)
353
+ container = QWidget()
354
+ container.setLayout(keyboardView)
355
+ self.addWidget(container)
356
+
357
+ # Callback functions
358
+ def onClickChar(self,keycode):
359
+ # print(f"Key pressed: {keycode}")
360
+ self.textField.add_character(keycode)
361
+
362
+ def onClickShift(self,keycode):
363
+ # print("Shift pressed")
364
+ if self.currentIndex() == 0:
365
+ self.setCurrentIndex(1)
366
+ elif self.currentIndex() == 1:
367
+ self.setCurrentIndex(0)
368
+
369
+ def onClickLetters(self,keycode):
370
+ # print("Letters pressed")
371
+ self.setCurrentIndex(0)
372
+
373
+ def onClickNumbers(self,keycode):
374
+ # print("Numbers pressed")
375
+ self.setCurrentIndex(2)
376
+
377
+ def onClickSymbols(self,keycode):
378
+ # print("Symbols pressed")
379
+ self.setCurrentIndex(3)
380
+
381
+ def onClickBack(self,keycode):
382
+ # print("Backspace pressed")
383
+ self.textField.backspace()
384
+
385
+ def onClickSpace(self,keycode):
386
+ # print("Space pressed")
387
+ self.textField.add_character(' ')
388
+
389
+ def onClickEnter(self,keycode):
390
+ # print("Enter pressed")
391
+ # print(self.textField.get_content())
392
+ if self.onFinished: self.onFinished()
@@ -1,5 +1,7 @@
1
1
  import sys
2
- from easycoder import Handler, RuntimeError
2
+ from .ec_handler import Handler
3
+ from .ec_classes import RuntimeError
4
+ from .ec_keyboard import Keyboard
3
5
  from PySide6.QtCore import Qt, QTimer
4
6
  from PySide6.QtGui import QPixmap
5
7
  from PySide6.QtWidgets import (
@@ -0,0 +1,164 @@
1
+ from easycoder import Handler, FatalError, RuntimeError, json
2
+
3
+ class SQL(Handler):
4
+
5
+ def __init__(self, compiler):
6
+ Handler.__init__(self, compiler)
7
+
8
+ def getName(self):
9
+ return 'sql'
10
+
11
+ #############################################################################
12
+ # Keyword handlers
13
+
14
+ # create {table} {name} [with ...]
15
+ # {name} {flag(s)} {type} [default {value}] [and ..]
16
+ def k_create(self, command):
17
+ if self.nextIsSymbol():
18
+ record = self.getSymbolRecord()
19
+ if record['keyword'] == 'table':
20
+ command['target'] = record['name']
21
+ command['tableName'] = self.nextValue()
22
+ keys = []
23
+ while self.peek() in ['key', 'include']:
24
+ item = {}
25
+ token = self.nextToken()
26
+ if token == 'include':
27
+ item['include'] = self.nextValue()
28
+ else:
29
+ item['name'] = self.nextValue()
30
+ token = self.peek()
31
+ if token == 'primary':
32
+ item['primary'] = True
33
+ self.nextToken()
34
+ if token == 'secondary':
35
+ item['secondary'] = True
36
+ self.nextToken()
37
+ elif token == 'required':
38
+ item['required'] = True
39
+ self.nextToken()
40
+ elif token == 'auto':
41
+ item['required'] = True
42
+ self.nextToken()
43
+ item['type'] = self.nextToken()
44
+ if self.peek() in ['default', '=']:
45
+ self.nextToken()
46
+ item['default'] = self.nextValue()
47
+ elif self.peek() == 'check':
48
+ self.nextToken()
49
+ item['check'] = self.nextValue()
50
+ keys.append(item)
51
+ command['keys'] = keys
52
+ self.add(command)
53
+ return True
54
+ return False
55
+
56
+ def r_create(self, command):
57
+ record = self.getVariable(command['target'])
58
+ self.putSymbolValue(record, command)
59
+ return self.nextPC()
60
+
61
+ def k_get(self, command):
62
+ if self.nextIsSymbol():
63
+ record = self.getSymbolRecord()
64
+ if record['hasValue']:
65
+ command['target'] = record['name']
66
+ self.skip('from')
67
+ if self.nextIsSymbol():
68
+ record = self.getSymbolRecord()
69
+ if record['keyword'] == 'table':
70
+ command['entity'] = record['name']
71
+ if self.peek() == 'as':
72
+ self.nextToken()
73
+ command['form'] = self.nextToken()
74
+ else: command['form'] = 'sql'
75
+ self.add(command)
76
+ return True
77
+ return False
78
+
79
+ def r_get(self, command):
80
+ target = self.getVariable(command['target'])
81
+ entity = self.getVariable(command['entity'])
82
+ form = command['form']
83
+ keyword = entity['keyword']
84
+ if keyword == 'table':
85
+ value = self.getSymbolValue(entity)
86
+ tableName = self.getRuntimeValue(value['tableName'])
87
+ output = []
88
+ if form == 'sql':
89
+ # -------------------------------------------------------------
90
+ # Here are the rules for generating SQL
91
+ output.append(f'DROP TABLE IF EXISTS {tableName} CASCADE;')
92
+ output.append(f'CREATE TABLE {tableName} {{')
93
+ secondary = False
94
+ includes = []
95
+ keys = entity['value'][entity['index']]['keys']
96
+ for index, key in enumerate(keys):
97
+ item = []
98
+ if 'include' in key:
99
+ name = self.getRuntimeValue(key['include'])
100
+ includes.append(f'{name}_id')
101
+ item = f'{name}_id BIGINT REFERENCES {name}'
102
+ else:
103
+ if 'secondary' in key:
104
+ secondary = True
105
+ output.append(' id BIGSERIAL PRIMARY KEY,')
106
+ item.append(self.getRuntimeValue(key['name']))
107
+ type = key['type']
108
+ if type == 'string': type = 'text'
109
+ elif type == 'datetime': type = 'timestamptz'
110
+ elif type == 'u64': type = 'bigint'
111
+ item.append(type.upper())
112
+ if secondary:
113
+ item.append('UNIQUE NOT NULL')
114
+ secondary = False
115
+ if 'primary' in key: item.append('PRIMARY KEY')
116
+ if 'required' in key: item.append('NOT NULL')
117
+ if 'default' in key:
118
+ default = self.getRuntimeValue(key['default'])
119
+ item.append(f'DEFAULT \'{default}\'')
120
+ if 'check' in key:
121
+ check = self.getRuntimeValue(key['check'])
122
+ item.append(f'CHECK ({check})')
123
+ item = ' '.join(item)
124
+ if index < len(keys) - 1 or len(includes) > 0: item = f'{item},'
125
+ output.append(f' {item}')
126
+ if len(includes) > 0:
127
+ includes = ', '.join(includes)
128
+ item = f' PRIMARY KEY ({includes})'
129
+ output.append(item)
130
+ output.append('};')
131
+ # -------------------------------------------------------------
132
+ v = {}
133
+ v['type'] = 'text'
134
+ v['content'] = '\n'.join(output)
135
+ self.putSymbolValue(target, v)
136
+ return self.nextPC()
137
+
138
+ def k_table(self, command):
139
+ return self.compileVariable(command, False)
140
+
141
+ def r_table(self, command):
142
+ return self.nextPC()
143
+
144
+ #############################################################################
145
+ # Compile a value in this domain
146
+ def compileValue(self):
147
+ return None
148
+
149
+ #############################################################################
150
+ # Modify a value or leave it unchanged.
151
+ def modifyValue(self, value):
152
+ return value
153
+
154
+ #############################################################################
155
+ # Value handlers
156
+
157
+ #############################################################################
158
+ # Compile a condition
159
+ def compileCondition(self):
160
+ condition = {}
161
+ return condition
162
+
163
+ #############################################################################
164
+ # Condition handlers
@@ -0,0 +1,5 @@
1
+ #!/bin/python3
2
+
3
+ from easycoder import Program
4
+
5
+ Program('test.ecs').start()
@@ -0,0 +1,7 @@
1
+ #!/bin/python3
2
+
3
+ import os
4
+ from easycoder import Program
5
+
6
+ os.chdir('../..')
7
+ Program('testsql.ecs').start()
@@ -0,0 +1,7 @@
1
+ #!/bin/python3
2
+
3
+ import os
4
+ from easycoder import Program
5
+
6
+ os.chdir('../../rbr/roombyroom/Controller/ui')
7
+ Program('rbr_ui.ecs').start()
File without changes
File without changes
File without changes
File without changes