meerk40t 0.9.3001__py2.py3-none-any.whl → 0.9.7010__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.
Files changed (445) hide show
  1. meerk40t/__init__.py +1 -1
  2. meerk40t/balormk/balor_params.py +167 -167
  3. meerk40t/balormk/clone_loader.py +457 -457
  4. meerk40t/balormk/controller.py +1566 -1512
  5. meerk40t/balormk/cylindermod.py +64 -0
  6. meerk40t/balormk/device.py +966 -1959
  7. meerk40t/balormk/driver.py +778 -591
  8. meerk40t/balormk/galvo_commands.py +1195 -0
  9. meerk40t/balormk/gui/balorconfig.py +237 -111
  10. meerk40t/balormk/gui/balorcontroller.py +191 -184
  11. meerk40t/balormk/gui/baloroperationproperties.py +116 -115
  12. meerk40t/balormk/gui/corscene.py +845 -0
  13. meerk40t/balormk/gui/gui.py +179 -147
  14. meerk40t/balormk/livelightjob.py +466 -382
  15. meerk40t/balormk/mock_connection.py +131 -109
  16. meerk40t/balormk/plugin.py +133 -135
  17. meerk40t/balormk/usb_connection.py +306 -301
  18. meerk40t/camera/__init__.py +1 -1
  19. meerk40t/camera/camera.py +514 -397
  20. meerk40t/camera/gui/camerapanel.py +1241 -1095
  21. meerk40t/camera/gui/gui.py +58 -58
  22. meerk40t/camera/plugin.py +441 -399
  23. meerk40t/ch341/__init__.py +27 -27
  24. meerk40t/ch341/ch341device.py +628 -628
  25. meerk40t/ch341/libusb.py +595 -589
  26. meerk40t/ch341/mock.py +171 -171
  27. meerk40t/ch341/windriver.py +157 -157
  28. meerk40t/constants.py +13 -0
  29. meerk40t/core/__init__.py +1 -1
  30. meerk40t/core/bindalias.py +550 -539
  31. meerk40t/core/core.py +47 -47
  32. meerk40t/core/cutcode/cubiccut.py +73 -73
  33. meerk40t/core/cutcode/cutcode.py +315 -312
  34. meerk40t/core/cutcode/cutgroup.py +141 -137
  35. meerk40t/core/cutcode/cutobject.py +192 -185
  36. meerk40t/core/cutcode/dwellcut.py +37 -37
  37. meerk40t/core/cutcode/gotocut.py +29 -29
  38. meerk40t/core/cutcode/homecut.py +29 -29
  39. meerk40t/core/cutcode/inputcut.py +34 -34
  40. meerk40t/core/cutcode/linecut.py +33 -33
  41. meerk40t/core/cutcode/outputcut.py +34 -34
  42. meerk40t/core/cutcode/plotcut.py +335 -335
  43. meerk40t/core/cutcode/quadcut.py +61 -61
  44. meerk40t/core/cutcode/rastercut.py +168 -148
  45. meerk40t/core/cutcode/waitcut.py +34 -34
  46. meerk40t/core/cutplan.py +1843 -1316
  47. meerk40t/core/drivers.py +330 -329
  48. meerk40t/core/elements/align.py +801 -669
  49. meerk40t/core/elements/branches.py +1844 -1507
  50. meerk40t/core/elements/clipboard.py +229 -219
  51. meerk40t/core/elements/element_treeops.py +4561 -2837
  52. meerk40t/core/elements/element_types.py +125 -105
  53. meerk40t/core/elements/elements.py +4329 -3617
  54. meerk40t/core/elements/files.py +117 -64
  55. meerk40t/core/elements/geometry.py +473 -224
  56. meerk40t/core/elements/grid.py +467 -316
  57. meerk40t/core/elements/materials.py +158 -94
  58. meerk40t/core/elements/notes.py +50 -38
  59. meerk40t/core/elements/offset_clpr.py +933 -912
  60. meerk40t/core/elements/offset_mk.py +963 -955
  61. meerk40t/core/elements/penbox.py +339 -267
  62. meerk40t/core/elements/placements.py +300 -83
  63. meerk40t/core/elements/render.py +785 -687
  64. meerk40t/core/elements/shapes.py +2618 -2092
  65. meerk40t/core/elements/trace.py +651 -563
  66. meerk40t/core/elements/tree_commands.py +415 -409
  67. meerk40t/core/elements/undo_redo.py +116 -58
  68. meerk40t/core/elements/wordlist.py +319 -200
  69. meerk40t/core/exceptions.py +9 -9
  70. meerk40t/core/laserjob.py +220 -220
  71. meerk40t/core/logging.py +63 -63
  72. meerk40t/core/node/blobnode.py +83 -86
  73. meerk40t/core/node/bootstrap.py +105 -103
  74. meerk40t/core/node/branch_elems.py +40 -31
  75. meerk40t/core/node/branch_ops.py +45 -38
  76. meerk40t/core/node/branch_regmark.py +48 -41
  77. meerk40t/core/node/cutnode.py +29 -32
  78. meerk40t/core/node/effect_hatch.py +375 -257
  79. meerk40t/core/node/effect_warp.py +398 -0
  80. meerk40t/core/node/effect_wobble.py +441 -309
  81. meerk40t/core/node/elem_ellipse.py +404 -309
  82. meerk40t/core/node/elem_image.py +1082 -801
  83. meerk40t/core/node/elem_line.py +358 -292
  84. meerk40t/core/node/elem_path.py +259 -201
  85. meerk40t/core/node/elem_point.py +129 -102
  86. meerk40t/core/node/elem_polyline.py +310 -246
  87. meerk40t/core/node/elem_rect.py +376 -286
  88. meerk40t/core/node/elem_text.py +445 -418
  89. meerk40t/core/node/filenode.py +59 -40
  90. meerk40t/core/node/groupnode.py +138 -74
  91. meerk40t/core/node/image_processed.py +777 -766
  92. meerk40t/core/node/image_raster.py +156 -113
  93. meerk40t/core/node/layernode.py +31 -31
  94. meerk40t/core/node/mixins.py +135 -107
  95. meerk40t/core/node/node.py +1427 -1304
  96. meerk40t/core/node/nutils.py +117 -114
  97. meerk40t/core/node/op_cut.py +462 -335
  98. meerk40t/core/node/op_dots.py +296 -251
  99. meerk40t/core/node/op_engrave.py +414 -311
  100. meerk40t/core/node/op_image.py +755 -369
  101. meerk40t/core/node/op_raster.py +787 -522
  102. meerk40t/core/node/place_current.py +37 -40
  103. meerk40t/core/node/place_point.py +329 -126
  104. meerk40t/core/node/refnode.py +58 -47
  105. meerk40t/core/node/rootnode.py +225 -219
  106. meerk40t/core/node/util_console.py +48 -48
  107. meerk40t/core/node/util_goto.py +84 -65
  108. meerk40t/core/node/util_home.py +61 -61
  109. meerk40t/core/node/util_input.py +102 -102
  110. meerk40t/core/node/util_output.py +102 -102
  111. meerk40t/core/node/util_wait.py +65 -65
  112. meerk40t/core/parameters.py +709 -707
  113. meerk40t/core/planner.py +875 -785
  114. meerk40t/core/plotplanner.py +656 -652
  115. meerk40t/core/space.py +120 -113
  116. meerk40t/core/spoolers.py +706 -705
  117. meerk40t/core/svg_io.py +1836 -1549
  118. meerk40t/core/treeop.py +534 -445
  119. meerk40t/core/undos.py +278 -124
  120. meerk40t/core/units.py +784 -680
  121. meerk40t/core/view.py +393 -322
  122. meerk40t/core/webhelp.py +62 -62
  123. meerk40t/core/wordlist.py +513 -504
  124. meerk40t/cylinder/cylinder.py +247 -0
  125. meerk40t/cylinder/gui/cylindersettings.py +41 -0
  126. meerk40t/cylinder/gui/gui.py +24 -0
  127. meerk40t/device/__init__.py +1 -1
  128. meerk40t/device/basedevice.py +322 -123
  129. meerk40t/device/devicechoices.py +50 -0
  130. meerk40t/device/dummydevice.py +163 -128
  131. meerk40t/device/gui/defaultactions.py +618 -602
  132. meerk40t/device/gui/effectspanel.py +114 -0
  133. meerk40t/device/gui/formatterpanel.py +253 -290
  134. meerk40t/device/gui/warningpanel.py +337 -260
  135. meerk40t/device/mixins.py +13 -13
  136. meerk40t/dxf/__init__.py +1 -1
  137. meerk40t/dxf/dxf_io.py +766 -554
  138. meerk40t/dxf/plugin.py +47 -35
  139. meerk40t/external_plugins.py +79 -79
  140. meerk40t/external_plugins_build.py +28 -28
  141. meerk40t/extra/cag.py +112 -116
  142. meerk40t/extra/coolant.py +403 -0
  143. meerk40t/extra/encode_detect.py +198 -0
  144. meerk40t/extra/ezd.py +1165 -1165
  145. meerk40t/extra/hershey.py +835 -340
  146. meerk40t/extra/imageactions.py +322 -316
  147. meerk40t/extra/inkscape.py +630 -622
  148. meerk40t/extra/lbrn.py +424 -424
  149. meerk40t/extra/outerworld.py +284 -0
  150. meerk40t/extra/param_functions.py +1542 -1556
  151. meerk40t/extra/potrace.py +257 -253
  152. meerk40t/extra/serial_exchange.py +118 -0
  153. meerk40t/extra/updater.py +602 -453
  154. meerk40t/extra/vectrace.py +147 -146
  155. meerk40t/extra/winsleep.py +83 -83
  156. meerk40t/extra/xcs_reader.py +597 -0
  157. meerk40t/fill/fills.py +781 -335
  158. meerk40t/fill/patternfill.py +1061 -1061
  159. meerk40t/fill/patterns.py +614 -567
  160. meerk40t/grbl/control.py +87 -87
  161. meerk40t/grbl/controller.py +990 -903
  162. meerk40t/grbl/device.py +1081 -768
  163. meerk40t/grbl/driver.py +989 -771
  164. meerk40t/grbl/emulator.py +532 -497
  165. meerk40t/grbl/gcodejob.py +783 -767
  166. meerk40t/grbl/gui/grblconfiguration.py +373 -298
  167. meerk40t/grbl/gui/grblcontroller.py +485 -271
  168. meerk40t/grbl/gui/grblhardwareconfig.py +269 -153
  169. meerk40t/grbl/gui/grbloperationconfig.py +105 -0
  170. meerk40t/grbl/gui/gui.py +147 -116
  171. meerk40t/grbl/interpreter.py +44 -44
  172. meerk40t/grbl/loader.py +22 -22
  173. meerk40t/grbl/mock_connection.py +56 -56
  174. meerk40t/grbl/plugin.py +294 -264
  175. meerk40t/grbl/serial_connection.py +93 -88
  176. meerk40t/grbl/tcp_connection.py +81 -79
  177. meerk40t/grbl/ws_connection.py +112 -0
  178. meerk40t/gui/__init__.py +1 -1
  179. meerk40t/gui/about.py +2042 -296
  180. meerk40t/gui/alignment.py +1644 -1608
  181. meerk40t/gui/autoexec.py +199 -0
  182. meerk40t/gui/basicops.py +791 -670
  183. meerk40t/gui/bufferview.py +77 -71
  184. meerk40t/gui/busy.py +170 -133
  185. meerk40t/gui/choicepropertypanel.py +1673 -1469
  186. meerk40t/gui/consolepanel.py +706 -542
  187. meerk40t/gui/devicepanel.py +687 -581
  188. meerk40t/gui/dialogoptions.py +110 -107
  189. meerk40t/gui/executejob.py +316 -306
  190. meerk40t/gui/fonts.py +90 -90
  191. meerk40t/gui/functionwrapper.py +252 -0
  192. meerk40t/gui/gui_mixins.py +729 -0
  193. meerk40t/gui/guicolors.py +205 -182
  194. meerk40t/gui/help_assets/help_assets.py +218 -201
  195. meerk40t/gui/helper.py +154 -0
  196. meerk40t/gui/hersheymanager.py +1430 -846
  197. meerk40t/gui/icons.py +3422 -2747
  198. meerk40t/gui/imagesplitter.py +555 -508
  199. meerk40t/gui/keymap.py +354 -344
  200. meerk40t/gui/laserpanel.py +892 -806
  201. meerk40t/gui/laserrender.py +1470 -1232
  202. meerk40t/gui/lasertoolpanel.py +805 -793
  203. meerk40t/gui/magnetoptions.py +436 -0
  204. meerk40t/gui/materialmanager.py +2917 -0
  205. meerk40t/gui/materialtest.py +1722 -1694
  206. meerk40t/gui/mkdebug.py +646 -359
  207. meerk40t/gui/mwindow.py +163 -140
  208. meerk40t/gui/navigationpanels.py +2605 -2467
  209. meerk40t/gui/notes.py +143 -142
  210. meerk40t/gui/opassignment.py +414 -410
  211. meerk40t/gui/operation_info.py +310 -299
  212. meerk40t/gui/plugin.py +494 -328
  213. meerk40t/gui/position.py +714 -669
  214. meerk40t/gui/preferences.py +901 -650
  215. meerk40t/gui/propertypanels/attributes.py +1461 -1131
  216. meerk40t/gui/propertypanels/blobproperty.py +117 -114
  217. meerk40t/gui/propertypanels/consoleproperty.py +83 -80
  218. meerk40t/gui/propertypanels/gotoproperty.py +77 -0
  219. meerk40t/gui/propertypanels/groupproperties.py +223 -217
  220. meerk40t/gui/propertypanels/hatchproperty.py +489 -469
  221. meerk40t/gui/propertypanels/imageproperty.py +2244 -1384
  222. meerk40t/gui/propertypanels/inputproperty.py +59 -58
  223. meerk40t/gui/propertypanels/opbranchproperties.py +82 -80
  224. meerk40t/gui/propertypanels/operationpropertymain.py +1890 -1638
  225. meerk40t/gui/propertypanels/outputproperty.py +59 -58
  226. meerk40t/gui/propertypanels/pathproperty.py +389 -380
  227. meerk40t/gui/propertypanels/placementproperty.py +1214 -383
  228. meerk40t/gui/propertypanels/pointproperty.py +140 -136
  229. meerk40t/gui/propertypanels/propertywindow.py +313 -181
  230. meerk40t/gui/propertypanels/rasterwizardpanels.py +996 -912
  231. meerk40t/gui/propertypanels/regbranchproperties.py +76 -0
  232. meerk40t/gui/propertypanels/textproperty.py +770 -755
  233. meerk40t/gui/propertypanels/waitproperty.py +56 -55
  234. meerk40t/gui/propertypanels/warpproperty.py +121 -0
  235. meerk40t/gui/propertypanels/wobbleproperty.py +255 -204
  236. meerk40t/gui/ribbon.py +2468 -2210
  237. meerk40t/gui/scene/scene.py +1100 -1051
  238. meerk40t/gui/scene/sceneconst.py +22 -22
  239. meerk40t/gui/scene/scenepanel.py +439 -349
  240. meerk40t/gui/scene/scenespacewidget.py +365 -365
  241. meerk40t/gui/scene/widget.py +518 -505
  242. meerk40t/gui/scenewidgets/affinemover.py +215 -215
  243. meerk40t/gui/scenewidgets/attractionwidget.py +315 -309
  244. meerk40t/gui/scenewidgets/bedwidget.py +120 -97
  245. meerk40t/gui/scenewidgets/elementswidget.py +137 -107
  246. meerk40t/gui/scenewidgets/gridwidget.py +785 -745
  247. meerk40t/gui/scenewidgets/guidewidget.py +765 -765
  248. meerk40t/gui/scenewidgets/laserpathwidget.py +66 -66
  249. meerk40t/gui/scenewidgets/machineoriginwidget.py +86 -86
  250. meerk40t/gui/scenewidgets/nodeselector.py +28 -28
  251. meerk40t/gui/scenewidgets/rectselectwidget.py +589 -346
  252. meerk40t/gui/scenewidgets/relocatewidget.py +33 -33
  253. meerk40t/gui/scenewidgets/reticlewidget.py +83 -83
  254. meerk40t/gui/scenewidgets/selectionwidget.py +2952 -2756
  255. meerk40t/gui/simpleui.py +357 -333
  256. meerk40t/gui/simulation.py +2431 -2094
  257. meerk40t/gui/snapoptions.py +208 -203
  258. meerk40t/gui/spoolerpanel.py +1227 -1180
  259. meerk40t/gui/statusbarwidgets/defaultoperations.py +480 -353
  260. meerk40t/gui/statusbarwidgets/infowidget.py +520 -483
  261. meerk40t/gui/statusbarwidgets/opassignwidget.py +356 -355
  262. meerk40t/gui/statusbarwidgets/selectionwidget.py +172 -171
  263. meerk40t/gui/statusbarwidgets/shapepropwidget.py +754 -236
  264. meerk40t/gui/statusbarwidgets/statusbar.py +272 -260
  265. meerk40t/gui/statusbarwidgets/statusbarwidget.py +268 -270
  266. meerk40t/gui/statusbarwidgets/strokewidget.py +267 -251
  267. meerk40t/gui/themes.py +200 -78
  268. meerk40t/gui/tips.py +591 -0
  269. meerk40t/gui/toolwidgets/circlebrush.py +35 -35
  270. meerk40t/gui/toolwidgets/toolcircle.py +248 -242
  271. meerk40t/gui/toolwidgets/toolcontainer.py +82 -77
  272. meerk40t/gui/toolwidgets/tooldraw.py +97 -90
  273. meerk40t/gui/toolwidgets/toolellipse.py +219 -212
  274. meerk40t/gui/toolwidgets/toolimagecut.py +25 -132
  275. meerk40t/gui/toolwidgets/toolline.py +39 -144
  276. meerk40t/gui/toolwidgets/toollinetext.py +79 -236
  277. meerk40t/gui/toolwidgets/toollinetext_inline.py +296 -0
  278. meerk40t/gui/toolwidgets/toolmeasure.py +160 -216
  279. meerk40t/gui/toolwidgets/toolnodeedit.py +2088 -2074
  280. meerk40t/gui/toolwidgets/toolnodemove.py +92 -94
  281. meerk40t/gui/toolwidgets/toolparameter.py +754 -668
  282. meerk40t/gui/toolwidgets/toolplacement.py +108 -108
  283. meerk40t/gui/toolwidgets/toolpoint.py +68 -59
  284. meerk40t/gui/toolwidgets/toolpointlistbuilder.py +294 -0
  285. meerk40t/gui/toolwidgets/toolpointmove.py +183 -0
  286. meerk40t/gui/toolwidgets/toolpolygon.py +288 -403
  287. meerk40t/gui/toolwidgets/toolpolyline.py +38 -196
  288. meerk40t/gui/toolwidgets/toolrect.py +211 -207
  289. meerk40t/gui/toolwidgets/toolrelocate.py +72 -72
  290. meerk40t/gui/toolwidgets/toolribbon.py +598 -113
  291. meerk40t/gui/toolwidgets/tooltabedit.py +546 -0
  292. meerk40t/gui/toolwidgets/tooltext.py +98 -89
  293. meerk40t/gui/toolwidgets/toolvector.py +213 -204
  294. meerk40t/gui/toolwidgets/toolwidget.py +39 -39
  295. meerk40t/gui/usbconnect.py +98 -91
  296. meerk40t/gui/utilitywidgets/buttonwidget.py +18 -18
  297. meerk40t/gui/utilitywidgets/checkboxwidget.py +90 -90
  298. meerk40t/gui/utilitywidgets/controlwidget.py +14 -14
  299. meerk40t/gui/utilitywidgets/cyclocycloidwidget.py +343 -340
  300. meerk40t/gui/utilitywidgets/debugwidgets.py +148 -0
  301. meerk40t/gui/utilitywidgets/handlewidget.py +27 -27
  302. meerk40t/gui/utilitywidgets/harmonograph.py +450 -447
  303. meerk40t/gui/utilitywidgets/openclosewidget.py +40 -40
  304. meerk40t/gui/utilitywidgets/rotationwidget.py +54 -54
  305. meerk40t/gui/utilitywidgets/scalewidget.py +75 -75
  306. meerk40t/gui/utilitywidgets/seekbarwidget.py +183 -183
  307. meerk40t/gui/utilitywidgets/togglewidget.py +142 -142
  308. meerk40t/gui/utilitywidgets/toolbarwidget.py +8 -8
  309. meerk40t/gui/wordlisteditor.py +985 -931
  310. meerk40t/gui/wxmeerk40t.py +1444 -1169
  311. meerk40t/gui/wxmmain.py +5578 -4112
  312. meerk40t/gui/wxmribbon.py +1591 -1076
  313. meerk40t/gui/wxmscene.py +1635 -1453
  314. meerk40t/gui/wxmtree.py +2410 -2089
  315. meerk40t/gui/wxutils.py +1769 -1099
  316. meerk40t/gui/zmatrix.py +102 -102
  317. meerk40t/image/__init__.py +1 -1
  318. meerk40t/image/dither.py +429 -0
  319. meerk40t/image/imagetools.py +2778 -2269
  320. meerk40t/internal_plugins.py +150 -130
  321. meerk40t/kernel/__init__.py +63 -12
  322. meerk40t/kernel/channel.py +259 -212
  323. meerk40t/kernel/context.py +538 -538
  324. meerk40t/kernel/exceptions.py +41 -41
  325. meerk40t/kernel/functions.py +463 -414
  326. meerk40t/kernel/jobs.py +100 -100
  327. meerk40t/kernel/kernel.py +3809 -3571
  328. meerk40t/kernel/lifecycles.py +71 -71
  329. meerk40t/kernel/module.py +49 -49
  330. meerk40t/kernel/service.py +147 -147
  331. meerk40t/kernel/settings.py +383 -343
  332. meerk40t/lihuiyu/controller.py +883 -876
  333. meerk40t/lihuiyu/device.py +1181 -1069
  334. meerk40t/lihuiyu/driver.py +1466 -1372
  335. meerk40t/lihuiyu/gui/gui.py +127 -106
  336. meerk40t/lihuiyu/gui/lhyaccelgui.py +377 -363
  337. meerk40t/lihuiyu/gui/lhycontrollergui.py +741 -651
  338. meerk40t/lihuiyu/gui/lhydrivergui.py +470 -446
  339. meerk40t/lihuiyu/gui/lhyoperationproperties.py +238 -237
  340. meerk40t/lihuiyu/gui/tcpcontroller.py +226 -190
  341. meerk40t/lihuiyu/interpreter.py +53 -53
  342. meerk40t/lihuiyu/laserspeed.py +450 -450
  343. meerk40t/lihuiyu/loader.py +90 -90
  344. meerk40t/lihuiyu/parser.py +404 -404
  345. meerk40t/lihuiyu/plugin.py +101 -102
  346. meerk40t/lihuiyu/tcp_connection.py +111 -109
  347. meerk40t/main.py +231 -165
  348. meerk40t/moshi/builder.py +788 -781
  349. meerk40t/moshi/controller.py +505 -499
  350. meerk40t/moshi/device.py +495 -442
  351. meerk40t/moshi/driver.py +862 -696
  352. meerk40t/moshi/gui/gui.py +78 -76
  353. meerk40t/moshi/gui/moshicontrollergui.py +538 -522
  354. meerk40t/moshi/gui/moshidrivergui.py +87 -75
  355. meerk40t/moshi/plugin.py +43 -43
  356. meerk40t/network/console_server.py +102 -57
  357. meerk40t/network/kernelserver.py +10 -9
  358. meerk40t/network/tcp_server.py +142 -140
  359. meerk40t/network/udp_server.py +103 -77
  360. meerk40t/network/web_server.py +390 -0
  361. meerk40t/newly/controller.py +1158 -1144
  362. meerk40t/newly/device.py +874 -732
  363. meerk40t/newly/driver.py +540 -412
  364. meerk40t/newly/gui/gui.py +219 -188
  365. meerk40t/newly/gui/newlyconfig.py +116 -101
  366. meerk40t/newly/gui/newlycontroller.py +193 -186
  367. meerk40t/newly/gui/operationproperties.py +51 -51
  368. meerk40t/newly/mock_connection.py +82 -82
  369. meerk40t/newly/newly_params.py +56 -56
  370. meerk40t/newly/plugin.py +1214 -1246
  371. meerk40t/newly/usb_connection.py +322 -322
  372. meerk40t/rotary/gui/gui.py +52 -46
  373. meerk40t/rotary/gui/rotarysettings.py +240 -232
  374. meerk40t/rotary/rotary.py +202 -98
  375. meerk40t/ruida/control.py +291 -91
  376. meerk40t/ruida/controller.py +138 -1088
  377. meerk40t/ruida/device.py +672 -231
  378. meerk40t/ruida/driver.py +534 -472
  379. meerk40t/ruida/emulator.py +1494 -1491
  380. meerk40t/ruida/exceptions.py +4 -4
  381. meerk40t/ruida/gui/gui.py +71 -76
  382. meerk40t/ruida/gui/ruidaconfig.py +239 -72
  383. meerk40t/ruida/gui/ruidacontroller.py +187 -184
  384. meerk40t/ruida/gui/ruidaoperationproperties.py +48 -47
  385. meerk40t/ruida/loader.py +54 -52
  386. meerk40t/ruida/mock_connection.py +57 -109
  387. meerk40t/ruida/plugin.py +124 -87
  388. meerk40t/ruida/rdjob.py +2084 -945
  389. meerk40t/ruida/serial_connection.py +116 -0
  390. meerk40t/ruida/tcp_connection.py +146 -0
  391. meerk40t/ruida/udp_connection.py +73 -0
  392. meerk40t/svgelements.py +9671 -9669
  393. meerk40t/tools/driver_to_path.py +584 -579
  394. meerk40t/tools/geomstr.py +5583 -4680
  395. meerk40t/tools/jhfparser.py +357 -292
  396. meerk40t/tools/kerftest.py +904 -890
  397. meerk40t/tools/livinghinges.py +1168 -1033
  398. meerk40t/tools/pathtools.py +987 -949
  399. meerk40t/tools/pmatrix.py +234 -0
  400. meerk40t/tools/pointfinder.py +942 -942
  401. meerk40t/tools/polybool.py +940 -940
  402. meerk40t/tools/rasterplotter.py +1660 -547
  403. meerk40t/tools/shxparser.py +989 -901
  404. meerk40t/tools/ttfparser.py +726 -446
  405. meerk40t/tools/zinglplotter.py +595 -593
  406. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/LICENSE +21 -21
  407. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/METADATA +150 -139
  408. meerk40t-0.9.7010.dist-info/RECORD +445 -0
  409. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/WHEEL +1 -1
  410. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/top_level.txt +0 -1
  411. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/zip-safe +1 -1
  412. meerk40t/balormk/elementlightjob.py +0 -159
  413. meerk40t-0.9.3001.dist-info/RECORD +0 -437
  414. test/bootstrap.py +0 -63
  415. test/test_cli.py +0 -12
  416. test/test_core_cutcode.py +0 -418
  417. test/test_core_elements.py +0 -144
  418. test/test_core_plotplanner.py +0 -397
  419. test/test_core_viewports.py +0 -312
  420. test/test_drivers_grbl.py +0 -108
  421. test/test_drivers_lihuiyu.py +0 -443
  422. test/test_drivers_newly.py +0 -113
  423. test/test_element_degenerate_points.py +0 -43
  424. test/test_elements_classify.py +0 -97
  425. test/test_elements_penbox.py +0 -22
  426. test/test_file_svg.py +0 -176
  427. test/test_fill.py +0 -155
  428. test/test_geomstr.py +0 -1523
  429. test/test_geomstr_nodes.py +0 -18
  430. test/test_imagetools_actualize.py +0 -306
  431. test/test_imagetools_wizard.py +0 -258
  432. test/test_kernel.py +0 -200
  433. test/test_laser_speeds.py +0 -3303
  434. test/test_length.py +0 -57
  435. test/test_lifecycle.py +0 -66
  436. test/test_operations.py +0 -251
  437. test/test_operations_hatch.py +0 -57
  438. test/test_ruida.py +0 -19
  439. test/test_spooler.py +0 -22
  440. test/test_tools_rasterplotter.py +0 -29
  441. test/test_wobble.py +0 -133
  442. test/test_zingl.py +0 -124
  443. {test → meerk40t/cylinder}/__init__.py +0 -0
  444. /meerk40t/{core/element_commands.py → cylinder/gui/__init__.py} +0 -0
  445. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7010.dist-info}/entry_points.txt +0 -0
meerk40t/core/treeop.py CHANGED
@@ -1,445 +1,534 @@
1
- """
2
- Tree Operation decorators help define the Tree Operations found mostly in element_treeop class. We create dynamic menus
3
- and thus need to classify the various different methods to access a node, without actually creating giant and
4
- redundant code for each command on each code type.
5
-
6
- These functions are overwhelmingly decorators. The `tree_operation` decorator sets the default values for the function
7
- and all the other decorators set those values.
8
-
9
- This data is expected to be called in a menu, but can be called via the console or through other methods.
10
- """
11
-
12
- import functools
13
-
14
-
15
- def tree_calc(value_name, calc_func):
16
- """
17
- Decorate a calc function.
18
-
19
- A calculator function will be called for each `value` in values or iterator, and will be permitted to calculate
20
- some dynamic value from that function.
21
-
22
- @param value_name:
23
- @param calc_func:
24
- @return:
25
- """
26
-
27
- def decor(func):
28
- func.calcs.append((value_name, calc_func))
29
- return func
30
-
31
- return decor
32
-
33
-
34
- def tree_values(value_name, values):
35
- """
36
- Append explicit list of values and value_name to the function.
37
- @param value_name:
38
- @param values:
39
- @return:
40
- """
41
-
42
- def decor(func):
43
- func.value_name = value_name
44
- func.values = values
45
- return func
46
-
47
- return decor
48
-
49
-
50
- def tree_iterate(value_name, start, stop, step=1):
51
- """
52
- Append range list of values to function.
53
-
54
- @param value_name:
55
- @param start: Start value
56
- @param stop: stop value
57
- @param step: step amount
58
- @return:
59
- """
60
-
61
- def decor(func):
62
- func.value_name = value_name
63
- func.values = range(start, stop, step)
64
- return func
65
-
66
- return decor
67
-
68
-
69
- def tree_radio(radio_function):
70
- """
71
- Append radio value to the operation for menus.
72
-
73
- @param radio_function:
74
- @return:
75
- """
76
-
77
- def decor(func):
78
- func.radio = radio_function
79
- return func
80
-
81
- return decor
82
-
83
-
84
- def tree_check(check_function):
85
- """
86
- Append checkbox function to the operation for menus.
87
-
88
- @param check_function:
89
- @return:
90
- """
91
-
92
- def decor(func):
93
- func.check = check_function
94
- return func
95
-
96
- return decor
97
-
98
-
99
- def tree_submenu(submenu):
100
- """
101
- Decorate a submenu on to the operation for menus.
102
-
103
- @param submenu: submenu to use.
104
- @return:
105
- """
106
-
107
- def decor(func):
108
- func.submenu = submenu
109
- return func
110
-
111
- return decor
112
-
113
-
114
- def tree_prompt(attr, prompt, data_type=str):
115
- """
116
- Decorate a tree_prompt for the operations for menu, this function will request this information from the user
117
- before calling the tree_operation function with the given attr.
118
-
119
- @param attr:
120
- @param prompt:
121
- @param data_type:
122
- @return:
123
- """
124
-
125
- def decor(func):
126
- func.user_prompt.append(
127
- {
128
- "attr": attr,
129
- "prompt": prompt,
130
- "type": data_type,
131
- }
132
- )
133
- return func
134
-
135
- return decor
136
-
137
-
138
- def tree_conditional(conditional):
139
- """
140
- Decorate a conditional to the operation for menus.
141
-
142
- Each conditional decorated to a function must pass for this menu item to show to the user.
143
-
144
- @param conditional:
145
- @return:
146
- """
147
-
148
- def decor(func):
149
- func.conditionals.append(conditional)
150
- return func
151
-
152
- return decor
153
-
154
-
155
- def tree_conditional_try(conditional):
156
- """
157
- Decorate a try conditional on this operation for menu.
158
-
159
- Try conditionals will not crash for the node, and can query states that may not exist.
160
-
161
- @param conditional:
162
- @return:
163
- """
164
-
165
- def decor(func):
166
- func.try_conditionals.append(conditional)
167
- return func
168
-
169
- return decor
170
-
171
-
172
- def tree_reference(node):
173
- """
174
- Decorate a reference to on the tree.
175
- @param node:
176
- @return:
177
- """
178
-
179
- def decor(func):
180
- func.reference = node
181
- return func
182
-
183
- return decor
184
-
185
-
186
- def tree_separator_after():
187
- """
188
- Decorator to flag this operation as having a separator after it.
189
-
190
- @return:
191
- """
192
-
193
- def decor(func):
194
- func.separate_after = True
195
- return func
196
-
197
- return decor
198
-
199
-
200
- def tree_separator_before():
201
- """
202
- Decorator to flag this operation as having a separator before it.
203
-
204
- @return:
205
- """
206
-
207
- def decor(func):
208
- func.separate_before = True
209
- return func
210
-
211
- return decor
212
-
213
-
214
- def tree_operation(
215
- registration, name, node_type=None, help=None, enable=True, **kwargs
216
- ):
217
- """
218
- Main tree registration decorator. Registers the tree operation with the given help and set the enabled state.
219
-
220
- @param registration: This is either a service or a kernel.
221
- @param name: Name of the tree operation being registered (required)
222
- @param node_type: types of node this operation applies to.
223
- @param help: Help data to be displayed in menu or other help information locations.
224
- @param enable: Should this be enabled.
225
- @param kwargs: Any remaining keywords.
226
- @return:
227
- """
228
-
229
- def decorator(func):
230
- @functools.wraps(func)
231
- def inner(node, **ik):
232
- """
233
- Wrapped inner function executes the operation.
234
-
235
- @param node:
236
- @param ik:
237
- @return:
238
- """
239
- returned = func(node, **ik, **kwargs)
240
- return returned
241
-
242
- if isinstance(node_type, tuple):
243
- ins = node_type
244
- else:
245
- ins = (node_type,)
246
-
247
- # inner.long_help = func.__doc__
248
- inner.help = help
249
-
250
- # Tuple of node types this applies to.
251
- inner.node_type = ins
252
-
253
- # Name of function.
254
- inner.name = name
255
-
256
- # attached radio commands.
257
- inner.radio = None
258
-
259
- # submenu of the operation
260
- inner.submenu = None
261
-
262
- # Optional information
263
- inner.reference = None
264
-
265
- # Should add a separator after this function.
266
- inner.separate_after = False
267
-
268
- # Should add a separator before this function.
269
- inner.separate_before = False
270
-
271
- # Conditionals required to be true to enable function.
272
- inner.conditionals = list()
273
-
274
- # Conditional attempted in a try-execute block (these may throw errors)
275
- inner.try_conditionals = list()
276
-
277
- # Prompt the user to discover this information.
278
- inner.user_prompt = list()
279
-
280
- # Calculations for the values.
281
- inner.calcs = list()
282
-
283
- # List of accepted values.
284
- inner.values = [0]
285
-
286
- # Function enabled/disabled
287
- inner.enabled = enable
288
-
289
- # Registered name is the same as the function name this is attached to.
290
- registered_name = inner.__name__
291
-
292
- for _in in ins:
293
- # Register tree/node/name for each node within the registration.
294
- p = f"tree/{_in}/{registered_name}"
295
- if p in registration._registered:
296
- # We used the name so we may not have duplicate tree operations with the same name.
297
- raise NameError(f"A function of this name was already registered: {p}")
298
- registration.register(p, inner)
299
- return inner
300
-
301
- # Return the entire decorator.
302
- return decorator
303
-
304
-
305
- def get_tree_operation(registration):
306
- """
307
- Returns a tree op for all the function calls with the registration already set.
308
-
309
- @param registration:
310
- @return:
311
- """
312
-
313
- def treeop(name, node_type=None, help=None, enable=True, **kwargs):
314
- return tree_operation(
315
- registration, name, node_type=node_type, help=help, enable=enable, **kwargs
316
- )
317
-
318
- return treeop
319
-
320
-
321
- def tree_operations_for_node(registration, node):
322
- """
323
- Generator to produce all tree operations for the given node.
324
-
325
- @param registration: kernel or service on which to find these operations
326
- @param node:
327
- @return:
328
- """
329
- if node.type is None:
330
- return
331
- for func, m, sname in registration.find("tree", node.type, ".*"):
332
- reject = False
333
- for cond in func.conditionals:
334
- # Do not provide this if the conditionals fail.
335
- if not cond(node):
336
- reject = True
337
- break
338
- if reject:
339
- continue
340
- for cond in func.try_conditionals:
341
- # Do not provide this if the try conditional fail. Crash is a pass.
342
- try:
343
- if not cond(node):
344
- reject = True
345
- break
346
- except Exception:
347
- continue
348
- if reject:
349
- continue
350
- node_name = (
351
- str(node.name)
352
- if (hasattr(node, "name") and node.name is not None)
353
- else str(node.label)
354
- )
355
- node_label = (
356
- str(node.name)
357
- if (hasattr(node, "name") and node.name is not None)
358
- else str(node.label)
359
- )
360
-
361
- def unescaped(filename):
362
- """
363
- Provide unescaped name/label.
364
- OS dependency is moot.
365
-
366
- @param filename:
367
- @return:
368
- """
369
- from platform import system
370
-
371
- OS_NAME = system()
372
- if OS_NAME == "Windows":
373
- newstring = filename.replace("&", "&&")
374
- else:
375
- newstring = filename.replace("&", "&&")
376
- return newstring
377
-
378
- # Create the operation calling dictionary.
379
- func_dict = {
380
- "name": unescaped(node_name),
381
- "label": unescaped(node_label),
382
- }
383
-
384
- # @tree_values / @tree_iterate values to be appended to function dictionary.
385
- iterator = func.values
386
- if iterator is None:
387
- iterator = [0]
388
- else:
389
- try:
390
- iterator = list(iterator())
391
- except TypeError:
392
- pass
393
-
394
- for i, value in enumerate(iterator):
395
- # Every value in the func.values gets an operation for the node.
396
- func_dict["iterator"] = i
397
- func_dict["value"] = value
398
- try:
399
- func_dict[func.value_name] = value
400
- except AttributeError:
401
- pass
402
-
403
- for calc in func.calcs:
404
- # Calculators are done called for the given value, result is set in the call dictionary.
405
- key, c = calc
406
- value = c(value)
407
- func_dict[key] = value
408
- if func.radio is not None:
409
- # Sets the radio state by the radio function.
410
- try:
411
- func.radio_state = func.radio(node, **func_dict)
412
- except:
413
- func.radio_state = False
414
- else:
415
- func.radio_state = None
416
-
417
- if hasattr(func, "check") and func.check is not None:
418
- # Sets the checkbox state by the checkbox function.
419
- try:
420
- func.check_state = func.check(node, **func_dict)
421
- except:
422
- func.check_state = False
423
- else:
424
- func.check_state = None
425
-
426
- # Function name is formatted such that any {} format brackets are filled with their values.
427
- name = func.name.format_map(func_dict)
428
-
429
- # Set the function and real name and provide it to the caller.
430
- func.func_dict = func_dict
431
- func.real_name = name
432
- yield func
433
-
434
-
435
- def get_tree_operation_for_node(registration):
436
- """
437
- Provide treeops for the given registration without needing to provide the registration each time, only the node.
438
- @param registration:
439
- @return:
440
- """
441
-
442
- def treeop(node):
443
- return tree_operations_for_node(registration, node)
444
-
445
- return treeop
1
+ """
2
+ Tree Operation decorators help define the Tree Operations found mostly in element_treeop class. We create dynamic menus
3
+ and thus need to classify the various different methods to access a node, without actually creating giant and
4
+ redundant code for each command on each code type.
5
+
6
+ These functions are overwhelmingly decorators. The `tree_operation` decorator sets the default values for the function
7
+ and all the other decorators set those values.
8
+
9
+ This data is expected to be called in a menu, but can be called via the console or through other methods.
10
+ """
11
+
12
+ import functools
13
+
14
+ ZZDEFAULT = "ZZZZZZZZZZ"
15
+
16
+ def tree_calc(value_name, calc_func):
17
+ """
18
+ Decorate a calc function.
19
+
20
+ A calculator function will be called for each `value` in values or iterator, and will be permitted to calculate
21
+ some dynamic value from that function.
22
+
23
+ @param value_name:
24
+ @param calc_func:
25
+ @return:
26
+ """
27
+
28
+ def decor(func):
29
+ func.calcs.append((value_name, calc_func))
30
+ return func
31
+
32
+ return decor
33
+
34
+
35
+ def tree_submenu_list(submenus):
36
+ """
37
+ Add a list of submenu information to be used for tree_values
38
+ tree_values will look for the corresponding index in value_submenues
39
+ to establish whether this item shall be put in a submenu structure
40
+ start defines the root menu hierarchy (tree_submenu will be ignored!)
41
+ You can specify a multi-level hierarchy by spearating the hierarchy
42
+ levels by pipe symbol '|'.
43
+ so "File|Preferences|Devices"
44
+ would have
45
+ File
46
+ +-Preferences
47
+ +- Devices
48
+ - Value 1
49
+ - Value 2
50
+ - Value 3
51
+ """
52
+
53
+ def decor(func):
54
+ func.submenu_generator = submenus
55
+ return func
56
+
57
+ return decor
58
+
59
+
60
+ def tree_values(value_name, values):
61
+ """
62
+ Append explicit list of values and value_name to the function.
63
+ @param value_name:
64
+ @param values:
65
+ @return:
66
+ """
67
+
68
+ def decor(func):
69
+ func.value_name = value_name
70
+ func.values = values
71
+ return func
72
+
73
+ return decor
74
+
75
+
76
+ def tree_iterate(value_name, start, stop, step=1):
77
+ """
78
+ Append range list of values to function.
79
+
80
+ @param value_name:
81
+ @param start: Start value
82
+ @param stop: stop value
83
+ @param step: step amount
84
+ @return:
85
+ """
86
+
87
+ def decor(func):
88
+ func.value_name = value_name
89
+ func.values = range(start, stop, step)
90
+ return func
91
+
92
+ return decor
93
+
94
+
95
+ def tree_radio(radio_function):
96
+ """
97
+ Append radio value to the operation for menus.
98
+
99
+ @param radio_function:
100
+ @return:
101
+ """
102
+
103
+ def decor(func):
104
+ func.radio = radio_function
105
+ return func
106
+
107
+ return decor
108
+
109
+
110
+ def tree_check(check_function):
111
+ """
112
+ Append checkbox function to the operation for menus.
113
+
114
+ @param check_function:
115
+ @return:
116
+ """
117
+
118
+ def decor(func):
119
+ func.check = check_function
120
+ return func
121
+
122
+ return decor
123
+
124
+
125
+ def tree_submenu(submenu):
126
+ """
127
+ Decorate a submenu on to the operation for menus.
128
+
129
+ @param submenu: submenu to use.
130
+ @return:
131
+ """
132
+
133
+ def decor(func):
134
+ func.submenu = submenu
135
+ return func
136
+
137
+ return decor
138
+
139
+
140
+ def tree_prompt(attr, prompt, data_type=str):
141
+ """
142
+ Decorate a tree_prompt for the operations for menu, this function will request this information from the user
143
+ before calling the tree_operation function with the given attr.
144
+
145
+ @param attr:
146
+ @param prompt:
147
+ @param data_type:
148
+ @return:
149
+ """
150
+
151
+ def decor(func):
152
+ func.user_prompt.append(
153
+ {
154
+ "attr": attr,
155
+ "prompt": prompt,
156
+ "type": data_type,
157
+ }
158
+ )
159
+ return func
160
+
161
+ return decor
162
+
163
+
164
+ def tree_conditional(conditional):
165
+ """
166
+ Decorate a conditional to the operation for menus.
167
+
168
+ Each conditional decorated to a function must pass for this menu item to show to the user.
169
+
170
+ @param conditional:
171
+ @return:
172
+ """
173
+
174
+ def decor(func):
175
+ func.conditionals.append(conditional)
176
+ return func
177
+
178
+ return decor
179
+
180
+
181
+ def tree_conditional_try(conditional):
182
+ """
183
+ Decorate a try conditional on this operation for menu.
184
+
185
+ Try conditionals will not crash for the node, and can query states that may not exist.
186
+
187
+ @param conditional:
188
+ @return:
189
+ """
190
+
191
+ def decor(func):
192
+ func.try_conditionals.append(conditional)
193
+ return func
194
+
195
+ return decor
196
+
197
+
198
+ def tree_reference(node):
199
+ """
200
+ Decorate a reference to on the tree.
201
+ @param node:
202
+ @return:
203
+ """
204
+
205
+ def decor(func):
206
+ func.reference = node
207
+ return func
208
+
209
+ return decor
210
+
211
+
212
+ def tree_separator_after():
213
+ """
214
+ Decorator to flag this operation as having a separator after it.
215
+
216
+ @return:
217
+ """
218
+
219
+ def decor(func):
220
+ func.separate_after = True
221
+ return func
222
+
223
+ return decor
224
+
225
+
226
+ def tree_separator_before():
227
+ """
228
+ Decorator to flag this operation as having a separator before it.
229
+
230
+ @return:
231
+ """
232
+
233
+ def decor(func):
234
+ func.separate_before = True
235
+ return func
236
+
237
+ return decor
238
+
239
+
240
+ def tree_operation(
241
+ registration, name, node_type=None, help=None, enable=True, grouping=None, **kwargs
242
+ ):
243
+ """
244
+ Main tree registration decorator. Registers the tree operation with the given help and set the enabled state.
245
+
246
+ @param registration: This is either a service or a kernel.
247
+ @param name: Name of the tree operation being registered (required)
248
+ @param node_type: types of node this operation applies to.
249
+ @param help: Help data to be displayed in menu or other help information locations.
250
+ @param enable: Should this be enabled.
251
+ @param grouping: Hint how to group items together
252
+ @param kwargs: Any remaining keywords.
253
+ @return:
254
+ """
255
+
256
+ def decorator(func):
257
+ @functools.wraps(func)
258
+ def inner(node, **ik):
259
+ """
260
+ Wrapped inner function executes the operation.
261
+
262
+ @param node:
263
+ @param ik:
264
+ @return:
265
+ """
266
+ returned = func(node, **ik, **kwargs)
267
+ return returned
268
+
269
+ if isinstance(node_type, tuple):
270
+ ins = node_type
271
+ else:
272
+ ins = (node_type,)
273
+
274
+ # inner.long_help = func.__doc__
275
+ inner.help = help
276
+
277
+ # Tuple of node types this applies to.
278
+ inner.node_type = ins
279
+
280
+ # Name of function.
281
+ inner.name = name
282
+
283
+ # attached radio commands.
284
+ inner.radio = None
285
+
286
+ # submenu of the operation
287
+ inner.submenu = None
288
+
289
+ # Optional information
290
+ inner.reference = None
291
+
292
+ # Should add a separator after this function.
293
+ inner.separate_after = False
294
+
295
+ # Should add a separator before this function.
296
+ inner.separate_before = False
297
+
298
+ inner.grouping = grouping
299
+
300
+ # Conditionals required to be true to enable function.
301
+ inner.conditionals = list()
302
+
303
+ # Conditional attempted in a try-execute block (these may throw errors)
304
+ inner.try_conditionals = list()
305
+
306
+ # Prompt the user to discover this information.
307
+ inner.user_prompt = list()
308
+
309
+ # Calculations for the values.
310
+ inner.calcs = list()
311
+
312
+ # List of accepted values.
313
+ inner.values = [0]
314
+ inner.submenu_generator = None
315
+
316
+ # Function enabled/disabled
317
+ inner.enabled = enable
318
+
319
+ # Registered name is the same as the function name this is attached to.
320
+ registered_name = inner.__name__
321
+
322
+ for _in in ins:
323
+ # Register tree/node/name for each node within the registration.
324
+ p = f"tree/{_in}/{registered_name}"
325
+ if p in registration._registered:
326
+ # We used the name, so we may not have duplicate tree operations with the same name.
327
+ raise NameError(f"A function of this name was already registered: {p}")
328
+ registration.register(p, inner)
329
+ return inner
330
+
331
+ # Return the entire decorator.
332
+ return decorator
333
+
334
+
335
+ def get_tree_operation(registration):
336
+ """
337
+ Returns a tree op for all the function calls with the registration already set.
338
+
339
+ @param registration:
340
+ @return:
341
+ """
342
+
343
+ def treeop(name, node_type=None, help=None, enable=True, **kwargs):
344
+ return tree_operation(
345
+ registration, name, node_type=node_type, help=help, enable=enable, **kwargs
346
+ )
347
+
348
+ return treeop
349
+
350
+
351
+ def tree_operations_for_node(registration, node):
352
+ """
353
+ Generator to produce all tree operations for the given node.
354
+
355
+ @param registration: kernel or service on which to find these operations
356
+ @param node:
357
+ @return:
358
+ """
359
+ if node.type is None:
360
+ return
361
+ mylist = list()
362
+ # print ("Before sort")
363
+ idx = 0
364
+ for func, m, sname in registration.find("tree", node.type, ".*"):
365
+ if func.submenu is None:
366
+ func.submenu = ""
367
+ # print (f"{idx} - {sname} - {func.submenu} - {func.grouping}")
368
+ if hasattr(func, "grouping"):
369
+ mylist.append((func, m, sname, ZZDEFAULT if func.grouping is None else func.grouping))
370
+ else:
371
+ mylist.append((func, m, sname, ZZDEFAULT))
372
+ idx += 1
373
+ mylist = sorted(
374
+ sorted(mylist, key=lambda d: d[0].submenu),
375
+ key=lambda d: d[3],
376
+ )
377
+ last_grouping = ""
378
+ for func, m, sname, grouping in mylist:
379
+ if grouping != last_grouping and last_grouping != "":
380
+ func.separate_before = True
381
+ last_grouping = func.grouping
382
+
383
+ # print ("After sort")
384
+ last_separator = None
385
+ idx = -1
386
+ for func, m, sname, grouping in mylist:
387
+ idx += 1
388
+ # print (f"{idx} - {sname} - {func.submenu} - {func.grouping} - {last_separator} {func.separate_before if hasattr(func, 'separate_before') else '---'}")
389
+ if last_separator is not None and hasattr(func, "separate_before"):
390
+ func.separate_before = func.separate_before or last_separator
391
+
392
+ reject = False
393
+ for cond in func.conditionals:
394
+ # Do not provide this if the conditionals fail.
395
+ if not cond(node):
396
+ reject = True
397
+ # print (f"Reject 1, was {last_separator} will become {func.separate_before if hasattr(func, 'separate_before') else '---'}")
398
+ if hasattr(func, "separate_before"):
399
+ if last_separator is not None:
400
+ last_separator = last_separator or func.separate_before
401
+ else:
402
+ last_separator = func.separate_before
403
+ break
404
+ if reject:
405
+ continue
406
+ for cond in func.try_conditionals:
407
+ # Do not provide this if the try conditional fail. Crash is a pass.
408
+ try:
409
+ if not cond(node):
410
+ # print (f"Reject 2, was {last_separator} will become {func.separate_before if hasattr(func, 'separate_before') else '---'}")
411
+ if hasattr(func, "separate_before"):
412
+ if last_separator is not None:
413
+ last_separator = last_separator or func.separate_before
414
+ else:
415
+ last_separator = func.separate_before
416
+ reject = True
417
+ break
418
+ except Exception:
419
+ continue
420
+ if reject:
421
+ continue
422
+ node_name = (
423
+ str(node.name)
424
+ if (hasattr(node, "name") and node.name is not None)
425
+ else str(node.label)
426
+ )
427
+ node_label = (
428
+ str(node.name)
429
+ if (hasattr(node, "name") and node.name is not None)
430
+ else str(node.label)
431
+ )
432
+
433
+ def unescaped(filename):
434
+ """
435
+ Provide unescaped name/label.
436
+ OS dependency is moot.
437
+
438
+ @param filename:
439
+ @return:
440
+ """
441
+ from platform import system
442
+
443
+ OS_NAME = system()
444
+ if OS_NAME == "Windows":
445
+ newstring = filename.replace("&", "&&")
446
+ else:
447
+ newstring = filename.replace("&", "&&")
448
+ return newstring
449
+
450
+ # Create the operation calling dictionary.
451
+ func_dict = {
452
+ "name": unescaped(node_name),
453
+ "label": unescaped(node_label),
454
+ }
455
+
456
+ # @tree_values / @tree_iterate values to be appended to function dictionary.
457
+ iterator = func.values
458
+ if iterator is None:
459
+ iterator = [0]
460
+ else:
461
+ try:
462
+ iterator = list(iterator())
463
+ except TypeError:
464
+ pass
465
+
466
+ value_submenus = []
467
+ if func.submenu_generator:
468
+ if isinstance(func.submenu_generator, (list, tuple)):
469
+ value_submenus = func.submenu_generator
470
+ else:
471
+ try:
472
+ value_submenus = func.submenu_generator()
473
+ except (AttributeError, TypeError) as e:
474
+ print(f"Error while generating submenus: {e}")
475
+ pass
476
+ # print(value_submenus)
477
+ for i, value in enumerate(iterator):
478
+ # Every value in the func.values gets an operation for the node.
479
+ func_dict["iterator"] = i
480
+ func_dict["value"] = value
481
+ if len(value_submenus) > 0:
482
+ try:
483
+ func.submenu = value_submenus[i]
484
+ except IndexError:
485
+ print("Wrong index...")
486
+ pass
487
+ try:
488
+ func_dict[func.value_name] = value
489
+ except AttributeError:
490
+ pass
491
+
492
+ for calc in func.calcs:
493
+ # Calculators are done called for the given value, result is set in the call dictionary.
494
+ key, c = calc
495
+ value = c(value)
496
+ func_dict[key] = value
497
+ if func.radio is not None:
498
+ # Sets the radio state by the radio function.
499
+ try:
500
+ func.radio_state = func.radio(node, **func_dict)
501
+ except:
502
+ func.radio_state = False
503
+ else:
504
+ func.radio_state = None
505
+
506
+ if hasattr(func, "check") and func.check is not None:
507
+ # Sets the checkbox state by the checkbox function.
508
+ try:
509
+ func.check_state = func.check(node, **func_dict)
510
+ except:
511
+ func.check_state = False
512
+ else:
513
+ func.check_state = None
514
+
515
+ # Function name is formatted such that any {} format brackets are filled with their values.
516
+ name = func.name.format_map(func_dict)
517
+
518
+ # Set the function and real name and provide it to the caller.
519
+ func.func_dict = func_dict
520
+ func.real_name = name
521
+ yield func
522
+ last_separator = None
523
+
524
+ def get_tree_operation_for_node(registration):
525
+ """
526
+ Provide treeops for the given registration without needing to provide the registration each time, only the node.
527
+ @param registration:
528
+ @return:
529
+ """
530
+
531
+ def treeop(node):
532
+ return tree_operations_for_node(registration, node)
533
+
534
+ return treeop