mirror of
https://github.com/arsenetar/dupeguru.git
synced 2026-01-22 14:41:39 +00:00
Added hscommon repo as a subtree
This commit is contained in:
166
hscommon/gui/tree.py
Normal file
166
hscommon/gui/tree.py
Normal file
@@ -0,0 +1,166 @@
|
||||
# Copyright 2013 Hardcoded Software (http://www.hardcoded.net)
|
||||
#
|
||||
# This software is licensed under the "BSD" License as described in the "LICENSE" file,
|
||||
# which should be included with this package. The terms are also available at
|
||||
# http://www.hardcoded.net/licenses/bsd_license
|
||||
|
||||
from collections import MutableSequence
|
||||
|
||||
from .base import GUIObject
|
||||
|
||||
class Node(MutableSequence):
|
||||
def __init__(self, name):
|
||||
self._name = name
|
||||
self._parent = None
|
||||
self._path = None
|
||||
self._children = []
|
||||
|
||||
def __repr__(self):
|
||||
return '<Node %r>' % self.name
|
||||
|
||||
#--- MutableSequence overrides
|
||||
def __delitem__(self, key):
|
||||
self._children.__delitem__(key)
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._children.__getitem__(key)
|
||||
|
||||
def __len__(self):
|
||||
return len(self._children)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self._children.__setitem__(key, value)
|
||||
|
||||
def append(self, node):
|
||||
self._children.append(node)
|
||||
node._parent = self
|
||||
node._path = None
|
||||
|
||||
def insert(self, index, node):
|
||||
self._children.insert(index, node)
|
||||
node._parent = self
|
||||
node._path = None
|
||||
|
||||
#--- Public
|
||||
def clear(self):
|
||||
del self[:]
|
||||
|
||||
def find(self, predicate, include_self=True):
|
||||
try:
|
||||
return next(self.findall(predicate, include_self=include_self))
|
||||
except StopIteration:
|
||||
return None
|
||||
|
||||
def findall(self, predicate, include_self=True):
|
||||
if include_self and predicate(self):
|
||||
yield self
|
||||
for child in self:
|
||||
for found in child.findall(predicate, include_self=True):
|
||||
yield found
|
||||
|
||||
def get_node(self, index_path):
|
||||
result = self
|
||||
if index_path:
|
||||
for index in index_path:
|
||||
result = result[index]
|
||||
return result
|
||||
|
||||
def get_path(self, target_node):
|
||||
if target_node is None:
|
||||
return None
|
||||
return target_node.path
|
||||
|
||||
@property
|
||||
def children_count(self):
|
||||
return len(self)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def parent(self):
|
||||
return self._parent
|
||||
|
||||
@property
|
||||
def path(self):
|
||||
if self._path is None:
|
||||
if self._parent is None:
|
||||
self._path = []
|
||||
else:
|
||||
self._path = self._parent.path + [self._parent.index(self)]
|
||||
return self._path
|
||||
|
||||
@property
|
||||
def root(self):
|
||||
if self._parent is None:
|
||||
return self
|
||||
else:
|
||||
return self._parent.root
|
||||
|
||||
|
||||
class Tree(Node, GUIObject):
|
||||
def __init__(self):
|
||||
Node.__init__(self, '')
|
||||
GUIObject.__init__(self)
|
||||
self._selected_nodes = []
|
||||
|
||||
#--- Virtual
|
||||
def _select_nodes(self, nodes):
|
||||
# all selection changes go through this method, so you can override this if you want to
|
||||
# customize the tree's behavior.
|
||||
self._selected_nodes = nodes
|
||||
|
||||
#--- Override
|
||||
def _view_updated(self):
|
||||
self.view.refresh()
|
||||
|
||||
#--- Public
|
||||
def clear(self):
|
||||
self._selected_nodes = []
|
||||
Node.clear(self)
|
||||
|
||||
@property
|
||||
def selected_node(self):
|
||||
return self._selected_nodes[0] if self._selected_nodes else None
|
||||
|
||||
@selected_node.setter
|
||||
def selected_node(self, node):
|
||||
if node is not None:
|
||||
self._select_nodes([node])
|
||||
else:
|
||||
self._select_nodes([])
|
||||
|
||||
@property
|
||||
def selected_nodes(self):
|
||||
return self._selected_nodes
|
||||
|
||||
@selected_nodes.setter
|
||||
def selected_nodes(self, nodes):
|
||||
self._select_nodes(nodes)
|
||||
|
||||
@property
|
||||
def selected_path(self):
|
||||
return self.get_path(self.selected_node)
|
||||
|
||||
@selected_path.setter
|
||||
def selected_path(self, index_path):
|
||||
if index_path is not None:
|
||||
self.selected_paths = [index_path]
|
||||
else:
|
||||
self._select_nodes([])
|
||||
|
||||
@property
|
||||
def selected_paths(self):
|
||||
return list(map(self.get_path, self._selected_nodes))
|
||||
|
||||
@selected_paths.setter
|
||||
def selected_paths(self, index_paths):
|
||||
nodes = []
|
||||
for path in index_paths:
|
||||
try:
|
||||
nodes.append(self.get_node(path))
|
||||
except IndexError:
|
||||
pass
|
||||
self._select_nodes(nodes)
|
||||
|
||||
Reference in New Issue
Block a user