meerk40t 0.9.3001__py2.py3-none-any.whl → 0.9.7020__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 (446) 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 +1194 -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 +1858 -1507
  50. meerk40t/core/elements/clipboard.py +229 -219
  51. meerk40t/core/elements/element_treeops.py +4595 -2837
  52. meerk40t/core/elements/element_types.py +125 -105
  53. meerk40t/core/elements/elements.py +4315 -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 +934 -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/testcases.py +105 -0
  66. meerk40t/core/elements/trace.py +651 -563
  67. meerk40t/core/elements/tree_commands.py +415 -409
  68. meerk40t/core/elements/undo_redo.py +116 -58
  69. meerk40t/core/elements/wordlist.py +319 -200
  70. meerk40t/core/exceptions.py +9 -9
  71. meerk40t/core/laserjob.py +220 -220
  72. meerk40t/core/logging.py +63 -63
  73. meerk40t/core/node/blobnode.py +83 -86
  74. meerk40t/core/node/bootstrap.py +105 -103
  75. meerk40t/core/node/branch_elems.py +40 -31
  76. meerk40t/core/node/branch_ops.py +45 -38
  77. meerk40t/core/node/branch_regmark.py +48 -41
  78. meerk40t/core/node/cutnode.py +29 -32
  79. meerk40t/core/node/effect_hatch.py +375 -257
  80. meerk40t/core/node/effect_warp.py +398 -0
  81. meerk40t/core/node/effect_wobble.py +441 -309
  82. meerk40t/core/node/elem_ellipse.py +404 -309
  83. meerk40t/core/node/elem_image.py +1082 -801
  84. meerk40t/core/node/elem_line.py +358 -292
  85. meerk40t/core/node/elem_path.py +259 -201
  86. meerk40t/core/node/elem_point.py +129 -102
  87. meerk40t/core/node/elem_polyline.py +310 -246
  88. meerk40t/core/node/elem_rect.py +376 -286
  89. meerk40t/core/node/elem_text.py +445 -418
  90. meerk40t/core/node/filenode.py +59 -40
  91. meerk40t/core/node/groupnode.py +138 -74
  92. meerk40t/core/node/image_processed.py +777 -766
  93. meerk40t/core/node/image_raster.py +156 -113
  94. meerk40t/core/node/layernode.py +31 -31
  95. meerk40t/core/node/mixins.py +135 -107
  96. meerk40t/core/node/node.py +1427 -1304
  97. meerk40t/core/node/nutils.py +117 -114
  98. meerk40t/core/node/op_cut.py +463 -335
  99. meerk40t/core/node/op_dots.py +296 -251
  100. meerk40t/core/node/op_engrave.py +414 -311
  101. meerk40t/core/node/op_image.py +755 -369
  102. meerk40t/core/node/op_raster.py +787 -522
  103. meerk40t/core/node/place_current.py +37 -40
  104. meerk40t/core/node/place_point.py +329 -126
  105. meerk40t/core/node/refnode.py +58 -47
  106. meerk40t/core/node/rootnode.py +225 -219
  107. meerk40t/core/node/util_console.py +48 -48
  108. meerk40t/core/node/util_goto.py +84 -65
  109. meerk40t/core/node/util_home.py +61 -61
  110. meerk40t/core/node/util_input.py +102 -102
  111. meerk40t/core/node/util_output.py +102 -102
  112. meerk40t/core/node/util_wait.py +65 -65
  113. meerk40t/core/parameters.py +709 -707
  114. meerk40t/core/planner.py +875 -785
  115. meerk40t/core/plotplanner.py +656 -652
  116. meerk40t/core/space.py +120 -113
  117. meerk40t/core/spoolers.py +706 -705
  118. meerk40t/core/svg_io.py +1836 -1549
  119. meerk40t/core/treeop.py +534 -445
  120. meerk40t/core/undos.py +278 -124
  121. meerk40t/core/units.py +784 -680
  122. meerk40t/core/view.py +393 -322
  123. meerk40t/core/webhelp.py +62 -62
  124. meerk40t/core/wordlist.py +513 -504
  125. meerk40t/cylinder/cylinder.py +247 -0
  126. meerk40t/cylinder/gui/cylindersettings.py +41 -0
  127. meerk40t/cylinder/gui/gui.py +24 -0
  128. meerk40t/device/__init__.py +1 -1
  129. meerk40t/device/basedevice.py +322 -123
  130. meerk40t/device/devicechoices.py +50 -0
  131. meerk40t/device/dummydevice.py +163 -128
  132. meerk40t/device/gui/defaultactions.py +618 -602
  133. meerk40t/device/gui/effectspanel.py +114 -0
  134. meerk40t/device/gui/formatterpanel.py +253 -290
  135. meerk40t/device/gui/warningpanel.py +337 -260
  136. meerk40t/device/mixins.py +13 -13
  137. meerk40t/dxf/__init__.py +1 -1
  138. meerk40t/dxf/dxf_io.py +766 -554
  139. meerk40t/dxf/plugin.py +47 -35
  140. meerk40t/external_plugins.py +79 -79
  141. meerk40t/external_plugins_build.py +28 -28
  142. meerk40t/extra/cag.py +112 -116
  143. meerk40t/extra/coolant.py +403 -0
  144. meerk40t/extra/encode_detect.py +204 -0
  145. meerk40t/extra/ezd.py +1165 -1165
  146. meerk40t/extra/hershey.py +834 -340
  147. meerk40t/extra/imageactions.py +322 -316
  148. meerk40t/extra/inkscape.py +628 -622
  149. meerk40t/extra/lbrn.py +424 -424
  150. meerk40t/extra/outerworld.py +283 -0
  151. meerk40t/extra/param_functions.py +1542 -1556
  152. meerk40t/extra/potrace.py +257 -253
  153. meerk40t/extra/serial_exchange.py +118 -0
  154. meerk40t/extra/updater.py +602 -453
  155. meerk40t/extra/vectrace.py +147 -146
  156. meerk40t/extra/winsleep.py +83 -83
  157. meerk40t/extra/xcs_reader.py +597 -0
  158. meerk40t/fill/fills.py +781 -335
  159. meerk40t/fill/patternfill.py +1061 -1061
  160. meerk40t/fill/patterns.py +614 -567
  161. meerk40t/grbl/control.py +87 -87
  162. meerk40t/grbl/controller.py +990 -903
  163. meerk40t/grbl/device.py +1084 -768
  164. meerk40t/grbl/driver.py +989 -771
  165. meerk40t/grbl/emulator.py +532 -497
  166. meerk40t/grbl/gcodejob.py +783 -767
  167. meerk40t/grbl/gui/grblconfiguration.py +373 -298
  168. meerk40t/grbl/gui/grblcontroller.py +485 -271
  169. meerk40t/grbl/gui/grblhardwareconfig.py +269 -153
  170. meerk40t/grbl/gui/grbloperationconfig.py +105 -0
  171. meerk40t/grbl/gui/gui.py +147 -116
  172. meerk40t/grbl/interpreter.py +44 -44
  173. meerk40t/grbl/loader.py +22 -22
  174. meerk40t/grbl/mock_connection.py +56 -56
  175. meerk40t/grbl/plugin.py +294 -264
  176. meerk40t/grbl/serial_connection.py +93 -88
  177. meerk40t/grbl/tcp_connection.py +81 -79
  178. meerk40t/grbl/ws_connection.py +112 -0
  179. meerk40t/gui/__init__.py +1 -1
  180. meerk40t/gui/about.py +2042 -296
  181. meerk40t/gui/alignment.py +1644 -1608
  182. meerk40t/gui/autoexec.py +199 -0
  183. meerk40t/gui/basicops.py +791 -670
  184. meerk40t/gui/bufferview.py +77 -71
  185. meerk40t/gui/busy.py +232 -133
  186. meerk40t/gui/choicepropertypanel.py +1662 -1469
  187. meerk40t/gui/consolepanel.py +706 -542
  188. meerk40t/gui/devicepanel.py +687 -581
  189. meerk40t/gui/dialogoptions.py +110 -107
  190. meerk40t/gui/executejob.py +316 -306
  191. meerk40t/gui/fonts.py +90 -90
  192. meerk40t/gui/functionwrapper.py +252 -0
  193. meerk40t/gui/gui_mixins.py +729 -0
  194. meerk40t/gui/guicolors.py +205 -182
  195. meerk40t/gui/help_assets/help_assets.py +218 -201
  196. meerk40t/gui/helper.py +154 -0
  197. meerk40t/gui/hersheymanager.py +1440 -846
  198. meerk40t/gui/icons.py +3422 -2747
  199. meerk40t/gui/imagesplitter.py +555 -508
  200. meerk40t/gui/keymap.py +354 -344
  201. meerk40t/gui/laserpanel.py +897 -806
  202. meerk40t/gui/laserrender.py +1470 -1232
  203. meerk40t/gui/lasertoolpanel.py +805 -793
  204. meerk40t/gui/magnetoptions.py +436 -0
  205. meerk40t/gui/materialmanager.py +2944 -0
  206. meerk40t/gui/materialtest.py +1722 -1694
  207. meerk40t/gui/mkdebug.py +646 -359
  208. meerk40t/gui/mwindow.py +163 -140
  209. meerk40t/gui/navigationpanels.py +2605 -2467
  210. meerk40t/gui/notes.py +143 -142
  211. meerk40t/gui/opassignment.py +414 -410
  212. meerk40t/gui/operation_info.py +310 -299
  213. meerk40t/gui/plugin.py +500 -328
  214. meerk40t/gui/position.py +714 -669
  215. meerk40t/gui/preferences.py +901 -650
  216. meerk40t/gui/propertypanels/attributes.py +1461 -1131
  217. meerk40t/gui/propertypanels/blobproperty.py +117 -114
  218. meerk40t/gui/propertypanels/consoleproperty.py +83 -80
  219. meerk40t/gui/propertypanels/gotoproperty.py +77 -0
  220. meerk40t/gui/propertypanels/groupproperties.py +223 -217
  221. meerk40t/gui/propertypanels/hatchproperty.py +489 -469
  222. meerk40t/gui/propertypanels/imageproperty.py +2244 -1384
  223. meerk40t/gui/propertypanels/inputproperty.py +59 -58
  224. meerk40t/gui/propertypanels/opbranchproperties.py +82 -80
  225. meerk40t/gui/propertypanels/operationpropertymain.py +1890 -1638
  226. meerk40t/gui/propertypanels/outputproperty.py +59 -58
  227. meerk40t/gui/propertypanels/pathproperty.py +389 -380
  228. meerk40t/gui/propertypanels/placementproperty.py +1214 -383
  229. meerk40t/gui/propertypanels/pointproperty.py +140 -136
  230. meerk40t/gui/propertypanels/propertywindow.py +313 -181
  231. meerk40t/gui/propertypanels/rasterwizardpanels.py +996 -912
  232. meerk40t/gui/propertypanels/regbranchproperties.py +76 -0
  233. meerk40t/gui/propertypanels/textproperty.py +770 -755
  234. meerk40t/gui/propertypanels/waitproperty.py +56 -55
  235. meerk40t/gui/propertypanels/warpproperty.py +121 -0
  236. meerk40t/gui/propertypanels/wobbleproperty.py +255 -204
  237. meerk40t/gui/ribbon.py +2471 -2210
  238. meerk40t/gui/scene/scene.py +1100 -1051
  239. meerk40t/gui/scene/sceneconst.py +22 -22
  240. meerk40t/gui/scene/scenepanel.py +439 -349
  241. meerk40t/gui/scene/scenespacewidget.py +365 -365
  242. meerk40t/gui/scene/widget.py +518 -505
  243. meerk40t/gui/scenewidgets/affinemover.py +215 -215
  244. meerk40t/gui/scenewidgets/attractionwidget.py +315 -309
  245. meerk40t/gui/scenewidgets/bedwidget.py +120 -97
  246. meerk40t/gui/scenewidgets/elementswidget.py +137 -107
  247. meerk40t/gui/scenewidgets/gridwidget.py +785 -745
  248. meerk40t/gui/scenewidgets/guidewidget.py +765 -765
  249. meerk40t/gui/scenewidgets/laserpathwidget.py +66 -66
  250. meerk40t/gui/scenewidgets/machineoriginwidget.py +86 -86
  251. meerk40t/gui/scenewidgets/nodeselector.py +28 -28
  252. meerk40t/gui/scenewidgets/rectselectwidget.py +592 -346
  253. meerk40t/gui/scenewidgets/relocatewidget.py +33 -33
  254. meerk40t/gui/scenewidgets/reticlewidget.py +83 -83
  255. meerk40t/gui/scenewidgets/selectionwidget.py +2958 -2756
  256. meerk40t/gui/simpleui.py +362 -333
  257. meerk40t/gui/simulation.py +2451 -2094
  258. meerk40t/gui/snapoptions.py +208 -203
  259. meerk40t/gui/spoolerpanel.py +1227 -1180
  260. meerk40t/gui/statusbarwidgets/defaultoperations.py +480 -353
  261. meerk40t/gui/statusbarwidgets/infowidget.py +520 -483
  262. meerk40t/gui/statusbarwidgets/opassignwidget.py +356 -355
  263. meerk40t/gui/statusbarwidgets/selectionwidget.py +172 -171
  264. meerk40t/gui/statusbarwidgets/shapepropwidget.py +754 -236
  265. meerk40t/gui/statusbarwidgets/statusbar.py +272 -260
  266. meerk40t/gui/statusbarwidgets/statusbarwidget.py +268 -270
  267. meerk40t/gui/statusbarwidgets/strokewidget.py +267 -251
  268. meerk40t/gui/themes.py +200 -78
  269. meerk40t/gui/tips.py +590 -0
  270. meerk40t/gui/toolwidgets/circlebrush.py +35 -35
  271. meerk40t/gui/toolwidgets/toolcircle.py +248 -242
  272. meerk40t/gui/toolwidgets/toolcontainer.py +82 -77
  273. meerk40t/gui/toolwidgets/tooldraw.py +97 -90
  274. meerk40t/gui/toolwidgets/toolellipse.py +219 -212
  275. meerk40t/gui/toolwidgets/toolimagecut.py +25 -132
  276. meerk40t/gui/toolwidgets/toolline.py +39 -144
  277. meerk40t/gui/toolwidgets/toollinetext.py +79 -236
  278. meerk40t/gui/toolwidgets/toollinetext_inline.py +296 -0
  279. meerk40t/gui/toolwidgets/toolmeasure.py +163 -216
  280. meerk40t/gui/toolwidgets/toolnodeedit.py +2088 -2074
  281. meerk40t/gui/toolwidgets/toolnodemove.py +92 -94
  282. meerk40t/gui/toolwidgets/toolparameter.py +754 -668
  283. meerk40t/gui/toolwidgets/toolplacement.py +108 -108
  284. meerk40t/gui/toolwidgets/toolpoint.py +68 -59
  285. meerk40t/gui/toolwidgets/toolpointlistbuilder.py +294 -0
  286. meerk40t/gui/toolwidgets/toolpointmove.py +183 -0
  287. meerk40t/gui/toolwidgets/toolpolygon.py +288 -403
  288. meerk40t/gui/toolwidgets/toolpolyline.py +38 -196
  289. meerk40t/gui/toolwidgets/toolrect.py +211 -207
  290. meerk40t/gui/toolwidgets/toolrelocate.py +72 -72
  291. meerk40t/gui/toolwidgets/toolribbon.py +598 -113
  292. meerk40t/gui/toolwidgets/tooltabedit.py +546 -0
  293. meerk40t/gui/toolwidgets/tooltext.py +98 -89
  294. meerk40t/gui/toolwidgets/toolvector.py +213 -204
  295. meerk40t/gui/toolwidgets/toolwidget.py +39 -39
  296. meerk40t/gui/usbconnect.py +98 -91
  297. meerk40t/gui/utilitywidgets/buttonwidget.py +18 -18
  298. meerk40t/gui/utilitywidgets/checkboxwidget.py +90 -90
  299. meerk40t/gui/utilitywidgets/controlwidget.py +14 -14
  300. meerk40t/gui/utilitywidgets/cyclocycloidwidget.py +343 -340
  301. meerk40t/gui/utilitywidgets/debugwidgets.py +148 -0
  302. meerk40t/gui/utilitywidgets/handlewidget.py +27 -27
  303. meerk40t/gui/utilitywidgets/harmonograph.py +450 -447
  304. meerk40t/gui/utilitywidgets/openclosewidget.py +40 -40
  305. meerk40t/gui/utilitywidgets/rotationwidget.py +54 -54
  306. meerk40t/gui/utilitywidgets/scalewidget.py +75 -75
  307. meerk40t/gui/utilitywidgets/seekbarwidget.py +183 -183
  308. meerk40t/gui/utilitywidgets/togglewidget.py +142 -142
  309. meerk40t/gui/utilitywidgets/toolbarwidget.py +8 -8
  310. meerk40t/gui/wordlisteditor.py +985 -931
  311. meerk40t/gui/wxmeerk40t.py +1447 -1169
  312. meerk40t/gui/wxmmain.py +5644 -4112
  313. meerk40t/gui/wxmribbon.py +1591 -1076
  314. meerk40t/gui/wxmscene.py +1631 -1453
  315. meerk40t/gui/wxmtree.py +2416 -2089
  316. meerk40t/gui/wxutils.py +1769 -1099
  317. meerk40t/gui/zmatrix.py +102 -102
  318. meerk40t/image/__init__.py +1 -1
  319. meerk40t/image/dither.py +429 -0
  320. meerk40t/image/imagetools.py +2793 -2269
  321. meerk40t/internal_plugins.py +150 -130
  322. meerk40t/kernel/__init__.py +63 -12
  323. meerk40t/kernel/channel.py +259 -212
  324. meerk40t/kernel/context.py +538 -538
  325. meerk40t/kernel/exceptions.py +41 -41
  326. meerk40t/kernel/functions.py +463 -414
  327. meerk40t/kernel/jobs.py +100 -100
  328. meerk40t/kernel/kernel.py +3828 -3571
  329. meerk40t/kernel/lifecycles.py +71 -71
  330. meerk40t/kernel/module.py +49 -49
  331. meerk40t/kernel/service.py +147 -147
  332. meerk40t/kernel/settings.py +383 -343
  333. meerk40t/lihuiyu/controller.py +883 -876
  334. meerk40t/lihuiyu/device.py +1181 -1069
  335. meerk40t/lihuiyu/driver.py +1466 -1372
  336. meerk40t/lihuiyu/gui/gui.py +127 -106
  337. meerk40t/lihuiyu/gui/lhyaccelgui.py +377 -363
  338. meerk40t/lihuiyu/gui/lhycontrollergui.py +741 -651
  339. meerk40t/lihuiyu/gui/lhydrivergui.py +470 -446
  340. meerk40t/lihuiyu/gui/lhyoperationproperties.py +238 -237
  341. meerk40t/lihuiyu/gui/tcpcontroller.py +226 -190
  342. meerk40t/lihuiyu/interpreter.py +53 -53
  343. meerk40t/lihuiyu/laserspeed.py +450 -450
  344. meerk40t/lihuiyu/loader.py +90 -90
  345. meerk40t/lihuiyu/parser.py +404 -404
  346. meerk40t/lihuiyu/plugin.py +101 -102
  347. meerk40t/lihuiyu/tcp_connection.py +111 -109
  348. meerk40t/main.py +231 -165
  349. meerk40t/moshi/builder.py +788 -781
  350. meerk40t/moshi/controller.py +505 -499
  351. meerk40t/moshi/device.py +495 -442
  352. meerk40t/moshi/driver.py +862 -696
  353. meerk40t/moshi/gui/gui.py +78 -76
  354. meerk40t/moshi/gui/moshicontrollergui.py +538 -522
  355. meerk40t/moshi/gui/moshidrivergui.py +87 -75
  356. meerk40t/moshi/plugin.py +43 -43
  357. meerk40t/network/console_server.py +140 -57
  358. meerk40t/network/kernelserver.py +10 -9
  359. meerk40t/network/tcp_server.py +142 -140
  360. meerk40t/network/udp_server.py +103 -77
  361. meerk40t/network/web_server.py +404 -0
  362. meerk40t/newly/controller.py +1158 -1144
  363. meerk40t/newly/device.py +874 -732
  364. meerk40t/newly/driver.py +540 -412
  365. meerk40t/newly/gui/gui.py +219 -188
  366. meerk40t/newly/gui/newlyconfig.py +116 -101
  367. meerk40t/newly/gui/newlycontroller.py +193 -186
  368. meerk40t/newly/gui/operationproperties.py +51 -51
  369. meerk40t/newly/mock_connection.py +82 -82
  370. meerk40t/newly/newly_params.py +56 -56
  371. meerk40t/newly/plugin.py +1214 -1246
  372. meerk40t/newly/usb_connection.py +322 -322
  373. meerk40t/rotary/gui/gui.py +52 -46
  374. meerk40t/rotary/gui/rotarysettings.py +240 -232
  375. meerk40t/rotary/rotary.py +202 -98
  376. meerk40t/ruida/control.py +291 -91
  377. meerk40t/ruida/controller.py +138 -1088
  378. meerk40t/ruida/device.py +676 -231
  379. meerk40t/ruida/driver.py +534 -472
  380. meerk40t/ruida/emulator.py +1494 -1491
  381. meerk40t/ruida/exceptions.py +4 -4
  382. meerk40t/ruida/gui/gui.py +71 -76
  383. meerk40t/ruida/gui/ruidaconfig.py +239 -72
  384. meerk40t/ruida/gui/ruidacontroller.py +187 -184
  385. meerk40t/ruida/gui/ruidaoperationproperties.py +48 -47
  386. meerk40t/ruida/loader.py +54 -52
  387. meerk40t/ruida/mock_connection.py +57 -109
  388. meerk40t/ruida/plugin.py +124 -87
  389. meerk40t/ruida/rdjob.py +2084 -945
  390. meerk40t/ruida/serial_connection.py +116 -0
  391. meerk40t/ruida/tcp_connection.py +146 -0
  392. meerk40t/ruida/udp_connection.py +73 -0
  393. meerk40t/svgelements.py +9671 -9669
  394. meerk40t/tools/driver_to_path.py +584 -579
  395. meerk40t/tools/geomstr.py +5583 -4680
  396. meerk40t/tools/jhfparser.py +357 -292
  397. meerk40t/tools/kerftest.py +904 -890
  398. meerk40t/tools/livinghinges.py +1168 -1033
  399. meerk40t/tools/pathtools.py +987 -949
  400. meerk40t/tools/pmatrix.py +234 -0
  401. meerk40t/tools/pointfinder.py +942 -942
  402. meerk40t/tools/polybool.py +941 -940
  403. meerk40t/tools/rasterplotter.py +1660 -547
  404. meerk40t/tools/shxparser.py +1047 -901
  405. meerk40t/tools/ttfparser.py +726 -446
  406. meerk40t/tools/zinglplotter.py +595 -593
  407. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/LICENSE +21 -21
  408. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/METADATA +150 -139
  409. meerk40t-0.9.7020.dist-info/RECORD +446 -0
  410. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/WHEEL +1 -1
  411. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/top_level.txt +0 -1
  412. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.dist-info}/zip-safe +1 -1
  413. meerk40t/balormk/elementlightjob.py +0 -159
  414. meerk40t-0.9.3001.dist-info/RECORD +0 -437
  415. test/bootstrap.py +0 -63
  416. test/test_cli.py +0 -12
  417. test/test_core_cutcode.py +0 -418
  418. test/test_core_elements.py +0 -144
  419. test/test_core_plotplanner.py +0 -397
  420. test/test_core_viewports.py +0 -312
  421. test/test_drivers_grbl.py +0 -108
  422. test/test_drivers_lihuiyu.py +0 -443
  423. test/test_drivers_newly.py +0 -113
  424. test/test_element_degenerate_points.py +0 -43
  425. test/test_elements_classify.py +0 -97
  426. test/test_elements_penbox.py +0 -22
  427. test/test_file_svg.py +0 -176
  428. test/test_fill.py +0 -155
  429. test/test_geomstr.py +0 -1523
  430. test/test_geomstr_nodes.py +0 -18
  431. test/test_imagetools_actualize.py +0 -306
  432. test/test_imagetools_wizard.py +0 -258
  433. test/test_kernel.py +0 -200
  434. test/test_laser_speeds.py +0 -3303
  435. test/test_length.py +0 -57
  436. test/test_lifecycle.py +0 -66
  437. test/test_operations.py +0 -251
  438. test/test_operations_hatch.py +0 -57
  439. test/test_ruida.py +0 -19
  440. test/test_spooler.py +0 -22
  441. test/test_tools_rasterplotter.py +0 -29
  442. test/test_wobble.py +0 -133
  443. test/test_zingl.py +0 -124
  444. {test → meerk40t/cylinder}/__init__.py +0 -0
  445. /meerk40t/{core/element_commands.py → cylinder/gui/__init__.py} +0 -0
  446. {meerk40t-0.9.3001.dist-info → meerk40t-0.9.7020.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