Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class Treeview(Base, ttk.Treeview):
- def __init__(self, parent, key, **kwargs):
- Base.__init__(self, parent, key, **kwargs)
- self.columns = columns = dict(kwargs.get('settings', ())).get('columns', ())
- self.headings = headings = dict(kwargs.get('settings', ())).get('headings', ())
- ttk.Treeview.__init__(self, parent, columns=tuple(range(1, len(columns))), **self.options_args)
- # self['columns'] = range(1, len(columns))
- self.column_sort = {}
- for index, column in enumerate(columns):
- self.column(f'#{index}', **dict(column))
- for index, heading in enumerate(headings):
- self.column_sort[f'#{index}'] = True
- self.heading(f'#{index}', **dict(heading))
- self.grid(**self.grid_args)
- parent.winfo_toplevel().style.configure("Treeview", fieldbackground="black")
- def on_click(event):
- region = self.identify("region", event.x, event.y)
- if region == "heading":
- column_number = self.identify_column(event.x)
- if column_number in self.column_sort:
- reverse = False if self.column_sort[column_number] else True
- self.column_sort[column_number] = reverse
- self.sort(column_number, reverse)
- if region == "separator":
- column_number = self.identify_column(event.x)
- self.separator_double_click(column_number)
- self.bind("<Double-1>", on_click)
- def __str__(self):
- return str(self.get_nodes())
- def cut(self):
- self.copy()
- self.remove()
- def copy(self):
- self.winfo_toplevel().clipboard_clear()
- self.winfo_toplevel().clipboard_append(str(self.selection()))
- def paste(self):
- _cache = Cache()
- items = sorted(literal_eval(self.winfo_toplevel().clipboard_get()))
- for node in items:
- dest_node = self.selection()[0]
- def walk(_node, _parent=''):
- nodes = _node.rsplit("_", 1)
- _target = f'{_parent}/{dest_node}_{nodes.pop()}'.lstrip('/')
- _cache.set(_target, **self.item(_node))
- children = self.get_children(_node)
- for child in children:
- walk(child, _target)
- walk(node)
- self.populate(self.selection()[0], **_cache.get())
- _cache.destroy()
- def sort(self, col, reverse):
- def do_sort(_col, _reverse):
- if col != '#0':
- _data = [(self.set(k, col), k) for k in self.get_children()]
- else:
- _data = [(self.item(k)['text'], k) for k in self.get_children()]
- _data.sort(reverse=reverse)
- for _index, (_value, _parent) in enumerate(_data):
- self.move(_parent, '', _index)
- self.heading(col, command=lambda: do_sort(col, not reverse))
- def walk(children):
- for child in children:
- if col != '#0':
- data = [(self.set(k, col), k) for k in self.get_children(child)]
- else:
- data = [(self.item(k)['text'], k) for k in self.get_children(child)]
- data.sort(reverse=reverse)
- for index, (val, parent) in enumerate(data):
- self.move(parent, child, index)
- if self.get_children(child):
- walk(self.get_children(child))
- walk(self.get_children())
- def add(self, parent, index=tk.END, **kwargs):
- try:
- self.insert(parent, index, **kwargs)
- except TclError as err:
- if 'already exists' in str(err):
- messagebox.showerror(
- title='Create Project',
- message=f'The name you entered," {kwargs.get("text", "")}" already exists. '
- f'Choose another name and try again.'
- )
- def append(self, parent, **kwargs):
- self.add(parent, tk.END, **kwargs)
- def remove(self):
- selection = self.selection()[0]
- _prev = self.prev(selection)
- _next = self.next(selection)
- self.delete(selection)
- if _next:
- self.selection_set(_next)
- else:
- _next = '_'.join(selection.split('_')[:-1])
- if not self.next(_next):
- _next = '_'.join(_next.split('_')[:-1])
- if not self.next(_next):
- self.select_tail()
- if self.next(_next):
- self.selection_set(self.next(_next))
- def populate(self, parent, index=tk.END, **data):
- _cache = Cache(**data)
- def walk(_cfg, iid, _parent):
- attrs = {}
- cfg = deepcopy(_cfg)
- for _key, value in _cfg.items():
- if not isinstance(value, dict):
- attrs[_key] = cfg.pop(_key)
- iid = f'{_parent}_{iid.split("_")[-1]}'.lstrip('_')
- try:
- self.insert(_parent, index, iid=iid, **attrs)
- except TclError as err:
- if 'already exists' in str(err):
- text = attrs["text"]
- messagebox.showerror(
- title='Create Projectx',
- message=f'The name you entered, "{text}" already exists. Choose another name and try again.'
- )
- return
- for _key, value in cfg.items():
- walk(value, f'{_key.split("_")[-1]}', iid)
- for key, node in data.items():
- walk(node, key, parent)
- def get_nodes(self, _uri=None):
- data = Cache()
- def walk(*args):
- parent = args[0]
- children = args[1]
- for child in children:
- uri = f'{parent}/{child}'
- data.set(uri, **self.item(child))
- child_children = self.get_children(child)
- if child_children:
- walk(uri, child_children)
- if _uri is not None and not isinstance(_uri, set):
- _uri = (_uri,)
- if _uri:
- for __uri in _uri:
- data.set(__uri, **self.item(__uri))
- walk(__uri, self.get_children(__uri))
- else:
- for _uri in self.get_children():
- data.set(_uri, **self.item(_uri))
- walk(_uri, self.get_children(_uri))
- return deepcopy(data.get())
- def separator_double_click(self, column):
- _cache = Cache(**self.get_nodes())
- _frame = ttk.Frame(self.winfo_toplevel())
- def get_size(item):
- _text = self.item(item).get('text') if column == '#0' else self.set(item, column)
- _lbl = tk.Label(_frame, text=_text)
- _lbl.grid()
- _frame.update_idletasks()
- _size = _lbl.winfo_width()
- _lbl.grid_forget()
- return _size
- def walk(_children, _largest=0):
- _depth = 0
- for _child in _children:
- _depth = len(_child.split('_'))
- if self.item(_child)['open']:
- return walk(self.get_children(_child))
- else:
- _size = get_size(_child) + 6
- if _size > _largest:
- _largest = _size
- return _largest, _depth
- width, depth = walk(self.get_children())
- if column == '#0':
- width += depth * 20
- self.column(column, width=width)
- def select_tail(self):
- def walk(children):
- if children:
- child = list(children).pop()
- if self.item(child)['open']:
- walk(self.get_children(child))
- if len(self.get_children(child)) == 0:
- self.selection_set(child)
- else:
- self.selection_set(child)
- walk(self.get_children())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement