diff options
Diffstat (limited to 'alot/foreign/urwidtrees/nested.py')
-rw-r--r-- | alot/foreign/urwidtrees/nested.py | 366 |
1 files changed, 0 insertions, 366 deletions
diff --git a/alot/foreign/urwidtrees/nested.py b/alot/foreign/urwidtrees/nested.py deleted file mode 100644 index 8d254e07..00000000 --- a/alot/foreign/urwidtrees/nested.py +++ /dev/null @@ -1,366 +0,0 @@ -# Copyright (C) 2013 Patrick Totzke <patricktotzke@gmail.com> -# This file is released under the GNU GPL, version 3 or a later revision. -from tree import Tree -from decoration import DecoratedTree, CollapseMixin - - -class NestedTree(Tree): - """ - A Tree that wraps around Trees that may contain list walkers or other - trees. The wrapped tree may contain normal widgets as well. List walkers - and subtree contents will be expanded into the tree presented by this - wrapper. - - This wrapper's positions are tuples of positions of the original and - subtrees: For example, `(X,Y,Z)` points at position Z in tree/list at - position Y in tree/list at position X in the original tree. - - NestedTree transparently behaves like a collapsible DecoratedTree. - """ - @property - def root(self): - root = (self._tree.root,) - rcontent = self._tree[self._tree.root] - if isinstance(rcontent, Tree): - root = root + (rcontent.root,) - return root - - def _sanitize_position(self, pos, tree=None): - """ - Ensure a position tuple until the result does not - point to a :class:`Tree` any more. - """ - if pos is not None: - tree = tree or self._tree - entry = self._lookup_entry(tree, pos) - if isinstance(entry, Tree): - pos = pos + self._sanitize_position((entry.root,), tree=entry) - return pos - - def __init__(self, tree, interpret_covered=False): - self._tree = tree - self._interpret_covered = interpret_covered - - def _lookup_entry(self, tree, pos): - if len(pos) == 0: - entry = tree[tree.root] - else: - entry = tree[pos[0]] - if len(pos) > 1 and isinstance(entry, Tree): - subtree = entry - entry = self._lookup_entry(subtree, pos[1:]) - return entry - - def _depth(self, tree, pos, outmost_only=True): - depth = self._tree.depth(pos[1:]) - if not outmost_only: - entry = self._tree[pos[0]] - if isinstance(entry, Tree) and len(pos) > 1: - depth += self._depth(entry, pos[1:], outmost_only=False) - return depth - - def depth(self, pos, outmost=True): - return self._depth(self._tree, pos) - - def __getitem__(self, pos): - return self._lookup_entry(self._tree, pos) - - # DecoratedTree API - def _get_decorated_entry(self, tree, pos, widget=None, is_first=True): - entry = tree[pos[0]] - if len(pos) > 1 and isinstance(entry, Tree): - subtree = entry - entry = self._get_decorated_entry( - subtree, pos[1:], widget, is_first) - else: - entry = widget or entry - if isinstance(tree, (DecoratedTree, NestedTree)): # has decorate-API - isf = len(pos) < 2 - if not isf and isinstance(tree[pos[0]], Tree): - isf = (tree[pos[0]].parent_position(pos[1]) - is None) or not is_first - entry = tree.decorate(pos[0], entry, is_first=isf) - return entry - - def get_decorated(self, pos): - return self._get_decorated_entry(self._tree, pos) - - def decorate(self, pos, widget, is_first=True): - return self._get_decorated_entry(self._tree, pos, widget, is_first) - - # Collapse API - def _get_subtree_for(self, pos): - """returns Tree that manages pos[-1]""" - res = self._tree - candidate = self._lookup_entry(self._tree, pos[:-1]) - if isinstance(candidate, Tree): - res = candidate - return res - - def collapsible(self, pos): - res = False - subtree = self._get_subtree_for(pos) - if isinstance(subtree, (CollapseMixin, NestedTree)): - res = subtree.collapsible(pos[-1]) - return res - - def is_collapsed(self, pos): - res = False - subtree = self._get_subtree_for(pos) - if isinstance(subtree, (CollapseMixin, NestedTree)): - res = subtree.is_collapsed(pos[-1]) - return res - - def toggle_collapsed(self, pos): - subtree = self._get_subtree_for(pos) - if isinstance(subtree, (CollapseMixin, NestedTree)): - subtree.toggle_collapsed(pos) - - def collapse(self, pos): - subtree = self._get_subtree_for(pos) - if isinstance(subtree, (CollapseMixin, NestedTree)): - subtree.collapse(pos[-1]) - - def collapse_all(self): - self._collapse_all(self._tree, self.root) - - def _collapse_all(self, tree, pos=None): - if pos is not None: - if isinstance(tree, (CollapseMixin, NestedTree)): - tree.expand_all() - - if len(pos) > 1: - self._collapse_all(tree[pos[0]], pos[1:]) - nextpos = tree.next_position(pos[0]) - if nextpos is not None: - nentry = tree[nextpos] - if isinstance(nentry, Tree): - self._collapse_all(nentry, (nentry.root,)) - self._collapse_all(tree, (nextpos,)) - if isinstance(tree, (CollapseMixin, NestedTree)): - tree.collapse_all() - - def expand(self, pos): - subtree = self._get_subtree_for(pos) - if isinstance(subtree, (CollapseMixin, NestedTree)): - subtree.expand(pos[-1]) - - def expand_all(self): - self._expand_all(self._tree, self.root) - - def _expand_all(self, tree, pos=None): - if pos is not None: - if isinstance(tree, (CollapseMixin, NestedTree)): - tree.expand_all() - if len(pos) > 1: - self._expand_all(tree[pos[0]], pos[1:]) - nextpos = tree.next_position(pos[0]) - if nextpos is not None: - nentry = tree[nextpos] - if isinstance(nentry, Tree): - self._expand_all(nentry, (nentry.root,)) - self._expand_all(tree, (nextpos,)) - if isinstance(tree, (CollapseMixin, NestedTree)): - tree.expand_all() - - def is_leaf(self, pos, outmost_only=False): - return self.first_child_position(pos, outmost_only) is None - - ################################################ - # Tree API - ################################################ - def parent_position(self, pos): - candidate_pos = self._parent_position(self._tree, pos) - # return sanitized path (ensure it points to content, not a subtree) - return self._sanitize_position(candidate_pos) - - def _parent_position(self, tree, pos): - candidate_pos = None - if len(pos) > 1: - # get the deepest subtree - subtree_pos = pos[:-1] - subtree = self._lookup_entry(tree, subtree_pos) - # get parent for our position in this subtree - least_pos = pos[-1] - subparent_pos = subtree.parent_position(least_pos) - if subparent_pos is not None: - # in case there is one, we are done, the position we look for - # is the path up to the subtree plus the local parent position. - candidate_pos = subtree_pos + (subparent_pos,) - else: - # otherwise we recur and look for subtree's parent in the next - # outer tree - candidate_pos = self._parent_position(self._tree, subtree_pos) - else: - # there is only one position in the path, we return its parent in - # the outmost tree - outer_parent = self._tree.parent_position(pos[0]) - if outer_parent is not None: - # result needs to be valid position (tuple of local positions) - candidate_pos = outer_parent, - return candidate_pos - - def first_child_position(self, pos, outmost_only=False): - childpos = self._first_child_position(self._tree, pos, outmost_only) - return self._sanitize_position(childpos, self._tree) - - def _first_child_position(self, tree, pos, outmost_only=False): - childpos = None - # get content at first path element in outmost tree - entry = tree[pos[0]] - if isinstance(entry, Tree) and not outmost_only and len(pos) > 1: - # this points to a tree and we don't check the outmost tree only - # recur: get first child in the subtree for remaining path - subchild = self._first_child_position(entry, pos[1:]) - if subchild is not None: - # found a childposition, re-append the path up to this subtree - childpos = (pos[0],) + subchild - return childpos - else: - # continue in the next outer tree only if we do not drop - # "covered" parts and the position path points to a parent-less - # position in the subtree. - if (entry.parent_position(pos[1]) is not None or not - self._interpret_covered): - return None - - # return the first child of the outmost tree - outerchild = tree.first_child_position(pos[0]) - if outerchild is not None: - childpos = outerchild, - return childpos - - def last_child_position(self, pos, outmost_only=False): - childpos = self._last_child_position(self._tree, pos, outmost_only) - return self._sanitize_position(childpos, self._tree) - - def _last_child_position(self, tree, pos, outmost_only=False): - childpos = None - # get content at first path element in outmost tree - entry = tree[pos[0]] - if isinstance(entry, Tree) and not outmost_only and len(pos) > 1: - # this points to a tree and we don't check the outmost tree only - - # get last child in the outmost tree if we do not drop "covered" - # parts and the position path points to a root of the subtree. - if self._interpret_covered: - if entry.parent_position(pos[1]) is None: - # return the last child of the outmost tree - outerchild = tree.last_child_position(pos[0]) - if outerchild is not None: - childpos = outerchild, - - # continue as if we have not found anything yet - if childpos is None: - # recur: get last child in the subtree for remaining path - subchild = self._last_child_position(entry, pos[1:]) - if subchild is not None: - # found a childposition, re-prepend path up to this subtree - childpos = (pos[0],) + subchild - else: - # outmost position element does not point to a tree: - # return the last child of the outmost tree - outerchild = tree.last_child_position(pos[0]) - if outerchild is not None: - childpos = outerchild, - return childpos - - def _next_sibling_position(self, tree, pos): - candidate = None - if len(pos) > 1: - # if position path does not point to position in outmost tree, - # first get the subtree as pointed out by first dimension, recur - # and check if some inner tree already returns a sibling - subtree = tree[pos[0]] - subsibling_pos = self._next_sibling_position(subtree, pos[1:]) - if subsibling_pos is not None: - # we found our sibling, prepend the path up to the subtree - candidate = pos[:1] + subsibling_pos - else: - # no deeper tree has sibling. If inner position is root node - # the sibling in the outer tree is a valid candidate - subparent = subtree.parent_position(pos[1]) - if subparent is None: - # check if outer tree defines sibling - next_sib = tree.next_sibling_position(pos[0]) - if next_sib is not None: - # it has, we found our candidate - candidate = next_sib, - # if the inner position has depth 1, then the first child - # of its parent in the outer tree can be seen as candidate for - # this position next sibling. Those live in the shadow of the - # inner tree and are hidden unless requested otherwise - elif subtree.parent_position(subparent) is None and \ - self._interpret_covered: - # we respect "covered" stuff and inner position has depth 1 - # get (possibly nested) first child in outer tree - candidate = self._first_child_position(tree, pos[:1]) - - else: - # the position path points to the outmost tree - # just return its next sibling in the outmost tree - next_sib = tree.next_sibling_position(pos[0]) - if next_sib is not None: - candidate = next_sib, - return candidate - - def next_sibling_position(self, pos): - candidate = self._next_sibling_position(self._tree, pos) - return self._sanitize_position(candidate, self._tree) - - def _prev_sibling_position(self, tree, pos): - candidate = None - if len(pos) > 1: - # if position path does not point to position in outmost tree, - # first get the subtree as pointed out by first dimension, recur - # and check if some inner tree already returns a sibling - subtree = tree[pos[0]] - subsibling_pos = self._prev_sibling_position(subtree, pos[1:]) - if subsibling_pos is not None: - # we found our sibling, prepend the path up to the subtree - candidate = pos[:1] + subsibling_pos - else: - # no deeper tree has sibling. If inner position is root node - # the sibling in the outer tree is a valid candidate - subparent = subtree.parent_position(pos[1]) - if subparent is None: - prev_sib = tree.prev_sibling_position(pos[0]) - if prev_sib is not None: - candidate = prev_sib, - return candidate - # my position could be "hidden" by being child of a - # position pointing to a Tree object (which is then unfolded). - if self._interpret_covered: - # we respect "covered" stuff: - # if parent is Tree, return last child of its (last) root - parent_pos = self._parent_position(tree, pos) - if parent_pos is not None: - parent = self._lookup_entry(self._tree, parent_pos) - if isinstance(parent, Tree): - sib = parent.last_sibling_position(parent.root) - candidate = parent.last_child_position(sib) - if candidate is not None: - candidate = parent_pos + (candidate,) - else: - # pos points to position in outmost tree - prev_sib = tree.prev_sibling_position(pos[0]) - if prev_sib is not None: - candidate = prev_sib, - # In case our new candidate points to a Tree, pick its last root node - if candidate is not None: - entry = self._lookup_entry(tree, candidate) - if isinstance(entry, Tree): - candidate = (candidate) + (entry.last_sibling_position(entry.root),) - return candidate - - def prev_sibling_position(self, pos): - candidate = self._prev_sibling_position(self._tree, pos) - return self._sanitize_position(candidate, self._tree) - - def last_decendant(self, pos): - def lastd(pos): - c = self.last_child_position(pos) - if c is not None: - c = self.last_sibling_position(c) - return c - return self._last_in_direction(pos, lastd) |