Advertisement
Uno-Dan

Updated Again

Sep 12th, 2019
333
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 41.90 KB | None | 0 0
  1.  
  2. import tkinter as tk
  3. from tkinter import messagebox
  4.  
  5. from os import path
  6. from json import load
  7. from cache import Cache
  8. from widgets import Container, Dialog
  9. from menus import PopupMenu, MenuSeparator
  10. from copy import deepcopy
  11.  
  12. from content.pages.home.config.setup import setup
  13. from time import strftime, localtime
  14.  
  15. from tkinter import messagebox, TclError
  16.  
  17. ABS_PATH = path.dirname(path.realpath(__file__))
  18. PAGES_PATH = path.join(f'{ABS_PATH}', 'plugins')
  19.  
  20. IMAGES = path.join(f'{ABS_PATH}', 'images')
  21. CONFIG = path.join(f'{ABS_PATH}', 'config')
  22.  
  23. popups = {
  24.     'default': {
  25.         'type': 'PopupMenu',
  26.         'config': [
  27.             ('bd', 1),
  28.             ('font', 'helvetica 10'),
  29.             ('relief', 'raised'),
  30.             ('tearoff', 0),
  31.             ('foreground', '#000000'),
  32.             ('background', '#eff0f1'),
  33.             ('activeforeground', '#ffffff'),
  34.             ('activebackground', '#00aaff'),
  35.         ],
  36.         'cut': {
  37.             'type': 'MenuItem',
  38.             'options': [
  39.                 ('label', 'Cut'),
  40.                 ('image', 'drive-harddisk.png'),
  41.                 ('underline', 0),
  42.                 ('accelerator', 'Alt+D '),
  43.             ],
  44.         },
  45.         'copy': {
  46.             'type': 'MenuItem',
  47.             'options': [
  48.                 ('label', 'Copy'),
  49.                 ('image', 'drive-harddisk.png'),
  50.                 ('underline', 0),
  51.                 ('accelerator', 'Alt+D '),
  52.             ],
  53.         },
  54.         'paste': {
  55.             'type': 'MenuItem',
  56.             'options': [
  57.                 ('label', 'Paste'),
  58.                 ('image', 'drive-harddisk.png'),
  59.                 ('underline', 0),
  60.                 ('accelerator', 'Alt+D '),
  61.             ],
  62.         },
  63.         'sep1': {
  64.             'type': 'MenuSeparator',
  65.         },
  66.         'select_all': {
  67.             'type': 'MenuItem',
  68.             'options': [
  69.                 ('label', 'Select All'),
  70.                 ('image', 'drive-harddisk.png'),
  71.                 ('underline', 0),
  72.                 ('accelerator', 'Alt+D '),
  73.             ],
  74.         },
  75.     },
  76.     'treeview': {
  77.         'type': 'PopupMenu',
  78.         'config': [
  79.             ('bd', 1),
  80.             ('font', 'helvetica 10'),
  81.             ('relief', 'raised'),
  82.             ('tearoff', 0),
  83.             ('foreground', '#000000'),
  84.             ('background', '#eff0f1'),
  85.             ('activeforeground', '#ffffff'),
  86.             ('activebackground', '#00aaff'),
  87.         ],
  88.         'add_item': {
  89.             'type': 'MenuItem',
  90.             'options': [
  91.                 ('label', 'Add Item'),
  92.                 ('state', 'disabled'),
  93.                 ('image', 'drive-harddisk.png'),
  94.                 ('underline', 0),
  95.                 ('accelerator', 'Alt+D '),
  96.             ],
  97.         },
  98.         'add_project': {
  99.             'type': 'MenuItem',
  100.             'options': [
  101.                 ('label', 'Add Project'),
  102.                 ('image', 'drive-harddisk.png'),
  103.                 ('underline', 0),
  104.                 ('accelerator', 'Alt+D '),
  105.             ],
  106.         },
  107.         'sep1': {
  108.             'type': 'MenuSeparator',
  109.         },
  110.         'save': {
  111.             'type': 'MenuItem',
  112.             'options': [
  113.                 ('label', 'Save'),
  114.                 ('state', 'disabled'),
  115.                 ('image', 'drive-harddisk.png'),
  116.                 ('underline', 0),
  117.                 ('accelerator', 'Alt+D '),
  118.             ],
  119.         },
  120.         'save_all': {
  121.             'type': 'MenuItem',
  122.             'options': [
  123.                 ('label', 'Save All'),
  124.                 ('state', 'disabled'),
  125.                 ('image', 'drive-harddisk.png'),
  126.                 ('underline', 0),
  127.                 ('accelerator', 'Alt+D '),
  128.             ],
  129.         },
  130.         'sep2': {
  131.             'type': 'MenuSeparator',
  132.         },
  133.         'cut': {
  134.             'type': 'MenuItem',
  135.             'options': [
  136.                 ('label', 'Cut'),
  137.                 ('state', 'disabled'),
  138.                 ('image', 'drive-harddisk.png'),
  139.                 ('underline', 0),
  140.                 ('accelerator', 'Alt+D '),
  141.             ],
  142.         },
  143.         'copy': {
  144.             'type': 'MenuItem',
  145.             'options': [
  146.                 ('label', 'Copy'),
  147.                 ('state', 'disabled'),
  148.                 ('image', 'drive-harddisk.png'),
  149.                 ('underline', 0),
  150.                 ('accelerator', 'Alt+D '),
  151.             ],
  152.         },
  153.         'paste': {
  154.             'type': 'MenuItem',
  155.             'options': [
  156.                 ('label', 'Paste'),
  157.                 ('state', 'disabled'),
  158.                 ('image', 'drive-harddisk.png'),
  159.                 ('underline', 0),
  160.                 ('accelerator', 'Alt+D '),
  161.             ],
  162.         },
  163.         'sep3': {
  164.             'type': 'MenuSeparator',
  165.         },
  166.         'delete': {
  167.             'type': 'MenuItem',
  168.             'options': [
  169.                 ('label', 'Delete'),
  170.                 ('state', 'disabled'),
  171.                 ('image', 'drive-harddisk.png'),
  172.                 ('underline', 0),
  173.                 ('accelerator', 'Alt+D '),
  174.             ],
  175.         },
  176.     },
  177. }
  178.  
  179. dialogs = {
  180.     'add_item': {
  181.         'type': 'Dialog',
  182.         'title': 'Add Item',
  183.         'settings': [
  184.             ('options', (
  185.                 ('width', 400),
  186.             )),
  187.             ('columnconfigure', (
  188.                 (0, {'weight': 1}),
  189.             )),
  190.         ],
  191.         'body': {
  192.             'type': 'Frame',
  193.             'settings': [
  194.                 ('grid', (
  195.                     ('sticky', tk.NSEW),
  196.                 )),
  197.                 ('rowconfigure', (
  198.                     (0, {'weight': 1}),
  199.                 )),
  200.                 ('columnconfigure', (
  201.                     (0, {'weight': 1}),
  202.                 )),
  203.             ],
  204.             'section1': {
  205.                 'type': 'Frame',
  206.                 'settings': [
  207.                     ('grid', (
  208.                         ('padx', 5),
  209.                         ('pady', (10, 0)),
  210.                         ('sticky', tk.EW),
  211.                     )),
  212.                     ('rowconfigure', (
  213.                         (0, {'weight': 1}),
  214.                     )),
  215.                     ('columnconfigure', (
  216.                         (1, {'weight': 1}),
  217.                     )),
  218.                 ],
  219.                 'lbl_path1': {
  220.                     'type': 'Label',
  221.                     'settings': [
  222.                         ('grid', (
  223.                             ('pady', 5),
  224.                             ('sticky', tk.W),
  225.                         )),
  226.                         ('options', (
  227.                             ('text', 'Add a new item to'),
  228.                         )),
  229.                     ],
  230.                 },
  231.                 'lbl_path2': {
  232.                     'type': 'Label',
  233.                     'settings': [
  234.                         ('grid', (
  235.                             ('row', 0),
  236.                             ('column', 1),
  237.                             ('pady', 5),
  238.                             ('sticky', tk.W),
  239.                         )),
  240.                         ('options', (
  241.                             ('text', ''),
  242.                         )),
  243.                     ],
  244.                 },
  245.             },
  246.             'section2': {
  247.                 'type': 'Frame',
  248.                 'settings': [
  249.                     ('grid', (
  250.                         ('padx', (0, 15)),
  251.                         ('sticky', tk.EW),
  252.                     )),
  253.                     ('rowconfigure', (
  254.                         (0, {'weight': 1}),
  255.                     )),
  256.                     ('columnconfigure', (
  257.                         (1, {'weight': 1}),
  258.                     )),
  259.                 ],
  260.                 'lbl_name': {
  261.                     'type': 'Label',
  262.                     'settings': [
  263.                         ('grid', (
  264.                             ('row', 1),
  265.                             ('pady', (1, 0)),
  266.                             ('sticky', tk.E),
  267.                         )),
  268.                         ('options', (
  269.                             ('width', 8),
  270.                             ('anchor', tk.E),
  271.                             ('text', 'Name'),
  272.                         )),
  273.                     ],
  274.                 },
  275.                 'ent_name': {
  276.                     'type': 'Entry',
  277.                     'settings': [
  278.                         ('grid', (
  279.                             ('row', 1),
  280.                             ('column', 1),
  281.                             ('padx', (5, 0)),
  282.                             ('sticky', tk.EW),
  283.                         )),
  284.                     ],
  285.                 },
  286.                 'lbl_clear': {
  287.                     'type': 'Label',
  288.                     'settings': [
  289.                         ('grid', (
  290.                             ('row', 1),
  291.                             ('column', 991),
  292.                             ('pady', (2, 0)),
  293.                             ('sticky', tk.W),
  294.                         )),
  295.                         ('options', (
  296.                             ('text', 'clear'),
  297.                             ('cursor', 'hand1'),
  298.                             ('image', 'draw-eraser.png'),
  299.                         )),
  300.                     ],
  301.                 },
  302.             },
  303.             'section3': {
  304.                 'type': 'Frame',
  305.                 'settings': [
  306.                     ('grid', (
  307.                         ('pady', (10, 0)),
  308.                         ('sticky', tk.EW),
  309.                     )),
  310.                     ('rowconfigure', (
  311.                         (0, {'weight': 1}),
  312.                     )),
  313.                     ('columnconfigure', (
  314.                         (0, {'weight': 1}),
  315.                     )),
  316.                 ],
  317.                 'group1': {
  318.                     'type': 'Frame',
  319.                     'settings': [
  320.                         ('grid', (
  321.                             ('sticky', tk.NSEW),
  322.                         )),
  323.                         ('rowconfigure', (
  324.                             (0, {'weight': 1}),
  325.                         )),
  326.                         ('columnconfigure', (
  327.                             (1, {'weight': 1}),
  328.                         )),
  329.                     ],
  330.                     'lbl_type': {
  331.                         'type': 'Label',
  332.                         'settings': [
  333.                             ('grid', (
  334.                                 ('row', 1),
  335.                                 ('pady', (5, 0)),
  336.                             )),
  337.                             ('options', (
  338.                                 ('width', 8),
  339.                                 ('anchor', tk.E),
  340.                                 ('text', 'Type'),
  341.                             )),
  342.                         ],
  343.                     },
  344.                     'cbo_type': {
  345.                         'type': 'Combobox',
  346.                         'settings': [
  347.                             ('grid', (
  348.                                 ('row', 1),
  349.                                 ('column', 1),
  350.                                 ('padx', (5, 0)),
  351.                                 ('pady', (5, 0)),
  352.                                 ('sticky', tk.EW),
  353.                             )),
  354.                             ('options', (
  355.                                 ('value', 'Menu Item'),
  356.                                 ('values', ('Menu Item', 'Check Box', 'Radio Button')),
  357.                             )),
  358.                         ],
  359.                     },
  360.                     'lbl_default_value': {
  361.                         'type': 'Label',
  362.                         'settings': [
  363.                             ('grid', (
  364.                                 ('row', 2),
  365.                                 ('column', 0),
  366.                                 ('pady', (10, 0)),
  367.                             )),
  368.                             ('options', (
  369.                                 ('anchor', tk.E),
  370.                                 ('width', 8),
  371.                                 ('text', 'Value'),
  372.                             )),
  373.                         ],
  374.                     },
  375.                     'wrapper1': {
  376.                         'type': 'Frame',
  377.                         'settings': [
  378.                             ('grid', (
  379.                                 ('row', 2),
  380.                                 ('column', 1),
  381.                                 ('padx', (5, 0)),
  382.                                 ('pady', (10, 0)),
  383.                                 ('columnspan', 2),
  384.                                 ('sticky', tk.EW),
  385.                             )),
  386.                             ('rowconfigure', (
  387.                                 (0, {'weight': 1}),
  388.                             )),
  389.                             ('columnconfigure', (
  390.                                 (2, {'weight': 1}),
  391.                             )),
  392.                         ],
  393.                         'rad_default_value': {
  394.                             'type': 'Radiobutton',
  395.                             'settings': [
  396.                                 ('options', (
  397.                                     ('value', 1),
  398.                                 )),
  399.                             ],
  400.                             'items': [
  401.                                 ('item1', (
  402.                                     ('grid', (
  403.                                         ('row', 2),
  404.                                         ('column', 1),
  405.                                         ('padx', (5, 0)),
  406.                                         ('sticky', tk.EW),
  407.                                     )),
  408.                                     ('options', (
  409.                                         ('text', 'True'),
  410.                                         ('value', 1),
  411.                                     )),
  412.                                 )),
  413.                                 ('item2', (
  414.                                     ('grid', (
  415.                                         ('row', 2),
  416.                                         ('column', 2),
  417.                                         ('padx', (5, 0)),
  418.                                         ('sticky', tk.EW),
  419.                                     )),
  420.                                     ('options', (
  421.                                         ('text', 'False'),
  422.                                         ('value', 0),
  423.                                     )),
  424.                                 )),
  425.                             ],
  426.                         },
  427.                     },
  428.                 },
  429.                 'group2': {
  430.                     'type': 'Frame',
  431.                     'settings': [
  432.                         ('grid', (
  433.                             ('row', 0),
  434.                             ('column', 1),
  435.                             ('padx', 10),
  436.                             ('pady', (5, 0)),
  437.                             ('sticky', tk.NSEW),
  438.                         )),
  439.                         ('rowconfigure', (
  440.                             (1, {'weight': 1}),
  441.                         )),
  442.                         ('columnconfigure', (
  443.                             (0, {'weight': 1}),
  444.                         )),
  445.                     ],
  446.                     'ckb_update_navigator': {
  447.                         'type': 'Checkbutton',
  448.                         'settings': [
  449.                             ('grid', (
  450.                                 ('columnspan', 990),
  451.                                 ('padx', (5, 0)),
  452.                                 ('sticky', tk.EW),
  453.                             )),
  454.                             ('options', (
  455.                                 ('value', False),
  456.                                 ('onvalue', True),
  457.                                 ('offvalue', False),
  458.                                 ('text', 'Set Focus in Navigator'),
  459.                             )),
  460.                         ],
  461.                     },
  462.                 },
  463.             },
  464.             'section4': {
  465.                 'type': 'Frame',
  466.                 'settings': [
  467.                     ('grid', (
  468.                         ('padx', 5),
  469.                         ('pady', (10, 5)),
  470.                         ('sticky', tk.SE),
  471.                     )),
  472.                     ('rowconfigure', (
  473.                         (0, {'weight': 1}),
  474.                     )),
  475.                     ('columnconfigure', (
  476.                         (0, {'weight': 1}),
  477.                     )),
  478.                 ],
  479.                 'ok': {
  480.                     'type': 'Button',
  481.                     'settings': [
  482.                         ('grid', (
  483.                             ('sticky', tk.W),
  484.                         )),
  485.                         ('options', (
  486.                             ('text', 'Ok'),
  487.                         )),
  488.                     ],
  489.                 },
  490.                 'cancel': {
  491.                     'type': 'Button',
  492.                     'settings': [
  493.                         ('grid', (
  494.                             ('row', 0),
  495.                             ('column', 1),
  496.                             ('padx', (5, 0)),
  497.                         )),
  498.                         ('options', (
  499.                             ('text', 'Cancel'),
  500.                         )),
  501.                     ],
  502.                 },
  503.             },
  504.         },
  505.     },
  506.     'add_project': {
  507.         'type': 'Dialog',
  508.         'title': 'Add Project',
  509.         'settings': [
  510.             ('options', (
  511.                 ('width', 400),
  512.             )),
  513.             ('columnconfigure', (
  514.                 (0, {'weight': 1}),
  515.             )),
  516.         ],
  517.         'body': {
  518.             'type': 'Frame',
  519.             'settings': [
  520.                 ('grid', (
  521.                     ('sticky', tk.NSEW),
  522.                 )),
  523.                 ('rowconfigure', (
  524.                     (0, {'weight': 1}),
  525.                 )),
  526.                 ('columnconfigure', (
  527.                     (0, {'weight': 1}),
  528.                 )),
  529.             ],
  530.             'section1': {
  531.                 'type': 'Frame',
  532.                 'settings': [
  533.                     ('grid', (
  534.                         ('padx', (0, 15)),
  535.                         ('pady', (20, 0)),
  536.                         ('sticky', tk.EW),
  537.                     )),
  538.                     ('rowconfigure', (
  539.                         (0, {'weight': 1}),
  540.                     )),
  541.                     ('columnconfigure', (
  542.                         (1, {'weight': 1}),
  543.                     )),
  544.                 ],
  545.                 'lbl_name': {
  546.                     'type': 'Label',
  547.                     'settings': [
  548.                         ('grid', (
  549.                             ('row', 1),
  550.                             ('pady', (1, 0)),
  551.                             ('sticky', tk.E),
  552.                         )),
  553.                         ('options', (
  554.                             ('width', 7),
  555.                             ('anchor', tk.E),
  556.                             ('text', 'Name'),
  557.                         )),
  558.                     ],
  559.                 },
  560.                 'ent_name': {
  561.                     'type': 'Entry',
  562.                     'settings': [
  563.                         ('grid', (
  564.                             ('row', 1),
  565.                             ('column', 1),
  566.                             ('padx', (5, 0)),
  567.                             ('sticky', tk.EW),
  568.                         )),
  569.                     ],
  570.                 },
  571.                 'lbl_clear': {
  572.                     'type': 'Label',
  573.                     'settings': [
  574.                         ('grid', (
  575.                             ('row', 1),
  576.                             ('column', 991),
  577.                             ('pady', (2, 0)),
  578.                             ('sticky', tk.W),
  579.                         )),
  580.                         ('options', (
  581.                             ('text', 'clear'),
  582.                             ('cursor', 'hand1'),
  583.                             ('image', 'draw-eraser.png'),
  584.                         )),
  585.                     ],
  586.                 },
  587.             },
  588.             'section2': {
  589.                 'type': 'Frame',
  590.                 'settings': [
  591.                     ('grid', (
  592.                         ('pady', (10, 0)),
  593.                         ('sticky', tk.EW),
  594.                     )),
  595.                     ('rowconfigure', (
  596.                         (0, {'weight': 1}),
  597.                     )),
  598.                     ('columnconfigure', (
  599.                         (0, {'weight': 1}),
  600.                     )),
  601.                 ],
  602.                 'group1': {
  603.                     'type': 'Frame',
  604.                     'settings': [
  605.                         ('grid', (
  606.                             ('sticky', tk.EW),
  607.                         )),
  608.                         ('rowconfigure', (
  609.                             (1, {'weight': 1}),
  610.                         )),
  611.                         ('columnconfigure', (
  612.                             (1, {'weight': 1}),
  613.                         )),
  614.                     ],
  615.                     'lbl_type': {
  616.                         'type': 'Label',
  617.                         'settings': [
  618.                             ('grid', (
  619.                                 ('pady', (5, 0)),
  620.                             )),
  621.                             ('options', (
  622.                                 ('width', 7),
  623.                                 ('anchor', tk.E),
  624.                                 ('text', 'Type'),
  625.                             )),
  626.                         ],
  627.                     },
  628.                     'cbo_type': {
  629.                         'type': 'Combobox',
  630.                         'settings': [
  631.                             ('grid', (
  632.                                 ('row', 0),
  633.                                 ('column', 1),
  634.                                 ('padx', (5, 0)),
  635.                                 ('pady', (5, 0)),
  636.                                 ('sticky', tk.EW),
  637.                             )),
  638.                             ('options', (
  639.                                 ('value', 'Menubar'),
  640.                                 ('values', ('Menubar', 'Popup Menu', 'Menu Button')),
  641.                             )),
  642.                         ],
  643.                     },
  644.                 },
  645.                 'group2': {
  646.                     'type': 'Frame',
  647.                     'settings': [
  648.                         ('grid', (
  649.                             ('row', 0),
  650.                             ('column', 1),
  651.                             ('padx', 10),
  652.                             ('pady', (5, 0)),
  653.                             ('sticky', tk.NSEW),
  654.                         )),
  655.                         ('rowconfigure', (
  656.                             (1, {'weight': 1}),
  657.                         )),
  658.                         ('columnconfigure', (
  659.                             (0, {'weight': 1}),
  660.                         )),
  661.                     ],
  662.                     'ckb_update_navigator': {
  663.                         'type': 'Checkbutton',
  664.                         'settings': [
  665.                             ('grid', (
  666.                                 ('columnspan', 990),
  667.                                 ('padx', (5, 0)),
  668.                                 ('sticky', tk.EW),
  669.                             )),
  670.                             ('options', (
  671.                                 ('value', False),
  672.                                 ('onvalue', True),
  673.                                 ('offvalue', False),
  674.                                 ('text', 'Set Focus in Navigator'),
  675.                             )),
  676.                         ],
  677.                     },
  678.                 },
  679.             },
  680.             'section3': {
  681.                 'type': 'Frame',
  682.                 'settings': [
  683.                     ('grid', (
  684.                         ('padx', 5),
  685.                         ('pady', (15, 5)),
  686.                         ('sticky', tk.SE),
  687.                     )),
  688.                     ('rowconfigure', (
  689.                         (0, {'weight': 1}),
  690.                     )),
  691.                     ('columnconfigure', (
  692.                         (0, {'weight': 1}),
  693.                     )),
  694.                 ],
  695.                 'ok': {
  696.                     'type': 'Button',
  697.                     'settings': [
  698.                         ('grid', (
  699.                             ('sticky', tk.W),
  700.                         )),
  701.                         ('options', (
  702.                             ('text', 'Ok'),
  703.                         )),
  704.                     ],
  705.                 },
  706.                 'cancel': {
  707.                     'type': 'Button',
  708.                     'settings': [
  709.                         ('grid', (
  710.                             ('row', 0),
  711.                             ('column', 1),
  712.                             ('padx', (5, 0)),
  713.                         )),
  714.                         ('options', (
  715.                             ('text', 'Cancel'),
  716.                         )),
  717.                     ],
  718.                 },
  719.             },
  720.         },
  721.     },
  722. }
  723.  
  724.  
  725. def uri2dict(uri, value):
  726.     node = output = {}
  727.  
  728.     for _path in uri.split('/'):
  729.         node[_path] = node = {}
  730.  
  731.     c = Cache(**output)
  732.     c.set(uri, value)
  733.     return c.get()
  734.  
  735.  
  736. def dump(data, indent=None):
  737.     indent = indent if indent else '.'
  738.  
  739.     print('-------------------------------------------------------------------------------------------------------')
  740.     if data:
  741.         def walk(_data, count):
  742.             count += 1
  743.             for key, value in _data.items():
  744.                 if isinstance(value, dict):
  745.                     print(indent * count, key)
  746.                     walk(value, count)
  747.                 else:
  748.                     if isinstance(value, str):
  749.                         value = f'"{value}"'
  750.                     print(indent * count, key, f'value={value}')
  751.  
  752.         walk(data, 0)
  753.     else:
  754.         print(' (No Data)')
  755.  
  756.     print('-------------------------------------------------------------------------------------------------------')
  757.  
  758.  
  759. class Plugin(Container):
  760.     def __init__(self, parent, key):
  761.         Container.__init__(self, parent, key, **setup)
  762.         self.data = \
  763.             self.cache = None
  764.  
  765.         x = Cache(**{'aa/bb': 11})
  766.         x.dump()
  767.         exit()
  768.  
  769.         self.popups = {}
  770.         self.parent = parent
  771.  
  772.     def execute(self):
  773.         self.cache = Cache(**popups)
  774.  
  775.         def popup_defaults_cut():
  776.             self.winfo_toplevel().focus_get().event_generate('<Control-x>')
  777.  
  778.         def popup_defaults_copy():
  779.             self.winfo_toplevel().focus_get().event_generate('<Control-c>')
  780.  
  781.         def popup_defaults_paste():
  782.             self.winfo_toplevel().focus_get().event_generate('<Control-v>')
  783.  
  784.         def popup_defaults_select_all():
  785.             self.winfo_toplevel().focus_get().event_generate('<Control-a>')
  786.  
  787.         def dlg_add_project():
  788.             def btn_ok(event):
  789.                 dlg.destroy()
  790.                 ent_name = dlg.element('body/section1/ent_name').get()
  791.                 cbo_type = dlg.element('body/section2/group1/cbo_type').get()
  792.                 ckb_set_focus = dlg.element('body/section2/group2/ckb_update_navigator').get()
  793.                 if not ent_name:
  794.                     tk.messagebox.showerror(
  795.                         title='Create Project',
  796.                         message='You have not entered a project name. Please enter a name and try again.'
  797.                     )
  798.                     return
  799.  
  800.                 last_modification = strftime('%a, %d %b %Y %H:%M:%S', localtime())
  801.                 tv.append('', text=ent_name, iid=ent_name, values=[cbo_type, '', last_modification])
  802.                 pane.element('left/path/ent_path').set_value(f'/{ent_name}')
  803.                 pane.element('right/section1/line1/ent_name').set_value(ent_name)
  804.                 pane.element('right/section1/line1/ent_name').config(state=tk.NORMAL)
  805.                 pane.element('right/section2/group1/cbo_type').set_value(cbo_type)
  806.  
  807.                 pane.element('right/section2').grid()
  808.                 pane.element('right/section2/group1').grid()
  809.  
  810.                 if ckb_set_focus:
  811.                     tv.see(ent_name)
  812.                     tv.selection_set(ent_name)
  813.  
  814.             def btn_cancel(event):
  815.                 dlg.destroy()
  816.  
  817.             def ckb_navigator():
  818.                 val = navigator.get()
  819.                 settings = list(
  820.                     dialogs['add_project']['body']['section2']['group2']['ckb_update_navigator']['settings']
  821.                 )
  822.                 settings_dict = dict(settings)
  823.  
  824.                 options = dict(settings_dict.get('options'))
  825.                 options['value'] = val
  826.  
  827.                 settings_dict['options'] = tuple(options.items())
  828.                 dialogs['add_project']['body']['section2']['group2']['ckb_update_navigator'].update(
  829.                     **{'settings': tuple(settings_dict.items())}
  830.                 )
  831.  
  832.             dlg = Dialog(self.winfo_toplevel(), 'add_project', **dialogs['add_project'])
  833.             dlg.element('body/section3/ok').bind('<Button-1>', btn_ok)
  834.             dlg.element('body/section3/cancel').bind('<Button-1>', btn_cancel)
  835.  
  836.             navigator = dlg.element('body/section2/group2/ckb_update_navigator')
  837.             navigator.config(command=ckb_navigator)
  838.  
  839.             dlg.grab_set()
  840.             dlg.wait_window()
  841.  
  842.         def dlg_tv_add_item():
  843.             def ok_item(event):
  844.                 dlg.destroy()
  845.                 section2 = self.element('body/pane/right/section2')
  846.                 section2.grid()
  847.  
  848.                 ent_name = dlg.element('body/section2/ent_name').get()
  849.                 cbo_type = dlg.element('body/section3/group1/cbo_type').get()
  850.                 ckb_set_focus = dlg.element('body/section3/group2/ckb_update_navigator').get()
  851.  
  852.                 if not ent_name:
  853.                     tk.messagebox.showerror(
  854.                         title='Add Item',
  855.                         message='You have not entered the item name. Please enter a name and try again.'
  856.                     )
  857.                     return
  858.  
  859.                 tv = pane.element('left/treeview')
  860.                 parent_id = tv.selection()[0]
  861.                 child_id = f'{parent_id}_{ent_name}'
  862.  
  863.                 if cbo_type:
  864.                     cbo = pane.element('right/section2/group2/cbo_type').set_value(cbo_type)
  865.  
  866.                 last_modification = strftime('%a, %d %b %Y %H:%M:%S', localtime())
  867.                 tv.append(parent_id, iid=child_id, text=ent_name, values=[cbo_type, '', last_modification])
  868.  
  869.                 pane.element('right/section2').grid()
  870.                 pane.element('right/section2/group2').grid()
  871.  
  872.                 if ckb_set_focus:
  873.                     tv.see(child_id)
  874.                     tv.selection_set(child_id)
  875.  
  876.                 if tv.item(parent_id,)['values'][0] != 'Menubar':
  877.                     values = tv.item(parent_id)['values']
  878.                     values[0] = 'Sub Menu'
  879.                     tv.item(parent_id, values=values)
  880.  
  881.                 pane.element('left/path/ent_path').set_value(f'/{parent_id.replace("_", "/")}/{ent_name}')
  882.                 pane.element('right/section1/line1/ent_name').config(state='readonly')
  883.  
  884.             def cancel_item(event):
  885.                 dlg.destroy()
  886.  
  887.             def update_navigator():
  888.                 val = navigator.get()
  889.                 settings = list(dialogs['add_item']['body']['section3']['group2']['ckb_update_navigator']['settings'])
  890.                 settings_dict = dict(settings)
  891.  
  892.                 options = dict(settings_dict.get('options'))
  893.                 options['value'] = val
  894.  
  895.                 settings_dict['options'] = tuple(options.items())
  896.                 dialogs['add_item']['body']['section3']['group2']['ckb_update_navigator'].update(
  897.                     **{'settings': tuple(settings_dict.items())}
  898.                 )
  899.  
  900.             dlg = Dialog(self.winfo_toplevel(), 'add_item', **dialogs['add_item'])
  901.             dlg.element('body/section4/ok').bind('<Button-1>', ok_item)
  902.             dlg.element('body/section4/cancel').bind('<Button-1>', cancel_item)
  903.             navigator = dlg.element('body/section3/group2/ckb_update_navigator')
  904.             navigator.config(command=update_navigator)
  905.  
  906.             dlg.grab_set()
  907.             dlg.grab_set()
  908.             dlg.wait_window()
  909.  
  910.         def entry_delete(event):
  911.             event.widget.target.clear()
  912.  
  913.         def validate_entry(value):
  914.             if not value:
  915.                 return True
  916.             char = value[0] if len(value) == 1 else value[-1]
  917.  
  918.             if char.isalnum() or char == '_':
  919.                 if len(value) >= 2 and value[-1] == '_' and value[-2] == '_':
  920.                     return False
  921.                 return True
  922.  
  923.             return False
  924.  
  925.         def tv_cut():
  926.             tv.cut()
  927.  
  928.         def tv_copy():
  929.             tv.copy()
  930.  
  931.         def tv_paste():
  932.             tv.paste()
  933.  
  934.         def tv_remove():
  935.             tv.remove()
  936.  
  937.         def tv_save():
  938.             _cache = Cache()
  939.             _cache.load(path.join(CONFIG, 'treeview.json'))
  940.  
  941.             project = tv.selection()[0]
  942.             for _project in tv.get_children():
  943.                 if _project == project:
  944.                     _cache.set(project, tv.get_nodes(project).get(project))
  945.                     _cache.save(path.join(CONFIG, 'treeview.json'))
  946.                     break
  947.  
  948.         def tv_save_all():
  949.             _cache = Cache(**tv.get_nodes())
  950.             _cache.save(path.join(CONFIG, 'treeview.json'))
  951.  
  952.         def tv_selected(event=None):
  953.             selection = tv.selection()[0]
  954.             pane.element('right/section1/line1/ent_name').set_value(selection.split('_', 1)[0])
  955.  
  956.             section2 = pane.element('right/section2')
  957.             section2.element('group1/cbo_type').set_value(tv.item(tv.selection()[0])['values'][0])
  958.             pane.element('left/path/ent_path').set_value(f'/{selection.replace("_", "/")}')
  959.  
  960.             if tv.item(selection):
  961.                 if tv.item(selection)['values'][0] in ('Menubar', 'Popup Menu', 'Menu Button'):
  962.                     pane.element('right/section2/group2').grid_remove()
  963.                     pane.element('right/section2/group1').grid()
  964.                     pane.element('right/section2/group1/cbo_type').set_value(tv.item(selection)['values'][0])
  965.                     pane.element('right/section1/line1/ent_name').config(state=tk.NORMAL)
  966.                 else:
  967.                     pane.element('right/section2/group1').grid_remove()
  968.                     pane.element('right/section2/group2').grid()
  969.                     pane.element('right/section2/group2/cbo_type').set_value(tv.item(selection)['values'][0])
  970.                     pane.element('right/section1/line1/ent_name').config(state='readonly')
  971.  
  972.         def btn_update_project(event):
  973.             prj_name = pane.element('right/section1/line1/ent_name').get()
  974.             prj_type = pane.element('right/section2/group1/cbo_type').get()
  975.  
  976.             select = tv.selection()[0]
  977.             _cache = Cache(**tv.get_nodes(select))
  978.             index = tv.index(select)
  979.             tv.delete(select)
  980.             _cache.get(select)['text'] = prj_name
  981.             values = _cache.get(select)['values']
  982.             values[0] = prj_type
  983.             _cache.get(select)['values'] = values
  984.             tv.populate('', index, **{prj_name: _cache.get(select)})
  985.  
  986.         def pane_btn_update_project():
  987.             if tv.selection():
  988.                 dlg = Dialog(self.winfo_toplevel(), 'add_item', **dialogs['add_item'])
  989.                 lbl_path2 = dlg.element('body/section1/lbl_path2')
  990.                 lbl_path2.set_value(f'/{tv.selection()[0]}')
  991.                 self.winfo_toplevel().wait_window(dlg)
  992.             else:
  993.                 tk.messagebox.showerror(
  994.                     title='Create Projectssss',
  995.                     message='The project name you entered, already exists. Choose another name and try again.'
  996.                 )
  997.  
  998.             # name = dlg.element('body/section1/ent_name')
  999.             # name.cfg = popups.get('default')
  1000.  
  1001.         pane = self.element('body/pane')
  1002.         tv = pane.element('left/treeview')
  1003.  
  1004.         file = path.join(CONFIG, 'treeview.json')
  1005.         if path.exists(file):
  1006.             with open(file) as f:
  1007.                 tv.populate('', **load(f))
  1008.  
  1009.         images = ('left/path/lbl_clear', )
  1010.  
  1011.         callbacks = {
  1012.             'left/path/lbl_clear': {
  1013.                 'target': 'left/path/ent_path',
  1014.                 'bindings': [
  1015.                     ('<Button-1>', entry_delete),
  1016.                 ],
  1017.             },
  1018.             'right/section1/line1/ent_name': {
  1019.                 'config': [
  1020.                     ('validate', 'key'),
  1021.                     ('validatecommand', (self.parent.register(validate_entry), '%P')),
  1022.                 ],
  1023.                 'bindings': [
  1024.                     ('<Return>', btn_update_project),
  1025.                     ('<KP_Enter>', btn_update_project),
  1026.                 ],
  1027.             },
  1028.             'right/footer/btn_update': {
  1029.                 'target': 'right/section1/ent_name',
  1030.                 'bindings': [
  1031.                     ('<Button-1>', btn_update_project),
  1032.                 ],
  1033.             },
  1034.             'right/footer/btn_delete': {
  1035.                 'target': 'right/section1/ent_name',
  1036.                 'bindings': [
  1037.                     ('<Button-1>', pane_btn_update_project),
  1038.                 ],
  1039.             },
  1040.             'left/treeview': {
  1041.                 'bindings': [
  1042.                     ('<<TreeviewSelect>>', tv_selected),
  1043.                 ],
  1044.             },
  1045.         }
  1046.  
  1047.         popup_defaults = dict((
  1048.             ('default/cut/options', ('command', popup_defaults_cut)),
  1049.             ('default/copy/options', ('command', popup_defaults_copy)),
  1050.             ('default/paste/options', ('command', popup_defaults_paste)),
  1051.             ('default/select_all/options', ('command', popup_defaults_select_all)),
  1052.         ))
  1053.         popup_commands = {
  1054.             'path': {'widget': self.element('body/pane/left/path/ent_path'), 'commands': popup_defaults},
  1055.             'ent_name': {'widget': self.element('body/pane/right/section1/line1/ent_name'), 'commands': popup_defaults},
  1056.         }
  1057.  
  1058.         tv_commands = dict((
  1059.             ('treeview/save/options', ('command', tv_save)),
  1060.             ('treeview/save_all/options', ('command', tv_save_all)),
  1061.             ('treeview/copy/options', ('command', tv_copy)),
  1062.             ('treeview/paste/options', ('command', tv_paste)),
  1063.             ('treeview/cut/options', ('command', tv_cut)),
  1064.             ('treeview/delete/options', ('command', tv_remove)),
  1065.             ('treeview/add_item/options', ('command', dlg_tv_add_item)),
  1066.             ('treeview/add_project/options', ('command', dlg_add_project)),
  1067.         ))
  1068.  
  1069.         self.create_images(images)
  1070.         self.configure_callbacks(callbacks)
  1071.         self.configure_popups(popup_commands)
  1072.         self.configure_treeview_popup(tv, tv_commands)
  1073.  
  1074.         return self
  1075.  
  1076.     @staticmethod
  1077.     def context_menu(event):
  1078.         try:
  1079.             key = event.widget.key
  1080.             event.widget.focus()
  1081.             PopupMenu(event.widget, key, **{key: event.widget.cfg}).tk_popup(event.x_root, event.y_root)
  1082.         except tk.TclError:
  1083.             pass
  1084.  
  1085.     def create_images(self, images, size=22):
  1086.         for uri in images:
  1087.             wdg = self.element('body/pane').element(uri)
  1088.             if wdg.image_name:
  1089.                 file = path.join(IMAGES, str(size), 'png', wdg.image_name)
  1090.                 wdg.options_args['image'] = tk.PhotoImage(file=file) if path.exists(file) else None
  1091.                 wdg.config(image=wdg.options_args['image'])
  1092.  
  1093.     def configure_popups(self, data):
  1094.         def context_menu(event):
  1095.             try:
  1096.                 _key = event.widget.key
  1097.                 event.widget.focus()
  1098.                 self.popups[_key] = PopupMenu(event.widget, _key, **{_key: event.widget.cfg}).tk_popup(event.x_root, event.y_root)
  1099.  
  1100.             except tk.TclError:
  1101.                 pass
  1102.  
  1103.         for key, popup in data.items():
  1104.             widget = popup.get('widget')
  1105.             widget.commands = popup.get('commands')
  1106.  
  1107.             for _uri, command in widget.commands.items():
  1108.                 opts = self.cache.get(_uri)
  1109.                 if not opts:
  1110.                     opts = self.cache.get(f'default/{_uri.split("/", 1)[1]}')
  1111.                 if opts:
  1112.                     opts.append(command)
  1113.  
  1114.             widget.cfg = popups.get(key, popups.get('default'))
  1115.             widget.bind(f'<Button-3>', context_menu)
  1116.  
  1117.     def configure_treeview_popup(self, parent, data):
  1118.  
  1119.         def test(event):
  1120.             key = event.widget.key
  1121.             parent.cfg = popups.get('treeview', ())
  1122.             self.update_idletasks()
  1123.             try:
  1124.                 tv = self.element('body/pane/left/treeview')
  1125.  
  1126.                 event.widget.focus()
  1127.                 popup = PopupMenu(event.widget, key, **{key: event.widget.cfg})
  1128.                 popup.tk_popup(event.x_root, event.y_root)
  1129.  
  1130.                 if parent.selection():
  1131.                     for k, p in popup.get().items():
  1132.                         if not isinstance(p, MenuSeparator):
  1133.                             popup.entryconfig(p.index, state='normal')
  1134.                 else:
  1135.                     popup.entryconfig(popup.get('add_project').index, state='normal')
  1136.  
  1137.                 item = tv.identify('item', event.x, event.y)
  1138.                 if item:
  1139.                     tv.selection_set(item)
  1140.  
  1141.             except tk.TclError:
  1142.                 pass
  1143.  
  1144.         for _uri, command in data.items():
  1145.             opts = self.cache.get(_uri)
  1146.             if opts:
  1147.                 opts.append(command)
  1148.  
  1149.         parent.bind(f'<Button-3>', test)
  1150.  
  1151.     def configure_callbacks(self, callbacks):
  1152.         pane = self.element('body/pane')
  1153.  
  1154.         for uri, options in callbacks.items():
  1155.             wdg = pane.element(uri)
  1156.             for binding in options.get('bindings', ()):
  1157.                 wdg.bind(binding[0], binding[1])
  1158.  
  1159.             wdg.config(**dict(options.get('config', ())))
  1160.             wdg.target = pane.element(options.get('target')) if 'target' in options else wdg
  1161.  
  1162.     def show(self):
  1163.         for k, n in self.parent.nodes.items():
  1164.             if self.key != k:
  1165.                 n.grid_remove()
  1166.  
  1167.         self.grid(**self.grid_args)
  1168.  
  1169.         return self
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement