I don't fully understand your previous post. Here is an example script that 
shows how expanded/collapsed state can be deduced without 
v.expandedPositions.
def p_to_count(p):
    v = p.v
    if len(v.parents) == 1:
        return 0
    for i, p1 in enumerate(sorted(c.all_positions_for_v(v))):
        if p1 == p:
            return i
    return -1 # position isn't valid

class ExpandController:
    def __init__(self, c):
        counts = {}
        self._expanded = expanded = set()
        for _p in c.all_positions():
            i = counts.get(_p.v, 0)
            if _p.isExpanded():
                expanded.add((_p.v, i))
            counts[_p.v] = i + 1

    def should_be_expanded(self, p):
        v = p.v
        i = p_to_count(p)
        return (v, i) in self._expanded

    def expand_position(self, p):
        i = p_to_count(p)
        if i > -1:
            v = p.v
            self._expanded.add((v, i))

    def collapse_position(self, p):
        i = p_to_count(p)
        if i > -1:
            v = p.v
            self._expanded.remove((v, i))

    def toggle_position(self, p):
        i = p_to_count(p)
        if i > -1:
            v = p.v
            if (v, i) in self._expanded:
                self._expanded.remove((v, i))
            else:
                self._expanded.add((v, i))

# now let's test if both methods give the same result
ec = ExpandController(c)
expandables = [x for x in c.all_positions() if x.v.children]
    # only nodes that have children can be expanded
for p1 in expandables:
    a = p1.isExpanded()
    assert a == ec.should_be_expanded(p1), repr((p_to_count(p1), a, p1))
    if a: # let's toggle position using p methods
        p1.contract()
    else:
        p1.expand()
    ec.toggle_position(p1) # let's toggle in ExpandController too
    assert p1.isExpanded() == p1.isExpanded()
    if a: # return to the previous state
        p1.expand()
    else:
        p1.contract()
    ec.toggle_position(p1) # in ExpandController too

g.es('all tests pass')


The script creates an ExpandController which copies the expanded/collapsed 
state from the Leo during the init.
Then it creates a list of all positions that have children, because only 
those positions can be expanded/collapsed.
Then for each position in this list check to see if both methods give the 
same expanded state. Additionally it
toggles the state checks the results are still the same, and toggles once 
more to restore the previous state.

The script doesn't try to change the outline to see if the expanded state 
would survive, but I am pretty sure that ExpandController is more immune to 
the outline changes than the v.expandedPositions method.

Vitalije

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/leo-editor/19cbf32d-26bf-4899-a00a-a361288f1412o%40googlegroups.com.

Reply via email to