Well after `one_clone = one.clone()`, position `three` becomes invalid, 
because `one.clone()` inserts cloned node above the node `three`. If you 
add:
three._childIndex += 1


after `one_clone = one.clone()`, there will be no error after executing 
script.

If I were you I would make all tree changes using v-nodes, and for making 
things undoable I would create my own undoHelper and redoHelper. Here is 
for example one of your scripts that we have discussed before:

import time
import leo.core.leoNodes as leoNodes
def findFtlistAncestor(p):
    p = p.copy()
    while p and not p.h.startswith('@ftlist'):
        p = p.parent()
    return p


def moveToTopAndCloneToAtDay(c, p):
    """
        Move the node identified by position p to the first child of
        an ancestor @ftlist node and also clone it to a sibling @day
        node with date matching today's date
    """
    ftlist = findFtlistAncestor(p)
    if not ftlist:
        g.es("Not in ftlist tree")
        return {}
    vft = ftlist.v
    before = make_snapshot(vft)
    v = p.v
    if vft in v.parents:
        i = vft.children.index(v)
        del vft.children[i]
        vft.children.insert(0, v)
    else:
        vft.children.insert(0, v)
        v.parents.append(vft)
    today = "@day " +  time.strftime("%Y-%m-%d", time.gmtime())
    for i, ch in enumerate(vft.children):
        if ch.h == today:
            break
    else:
        i = len(vft.children)
        ch = leoNodes.vnode(c)
        ch.h = today
        vft.children.append(ch)
        ch.parents.append(vft)
    if ch in v.parents:
        i = ch.children.index(v)
        del ch.children[i]
        ch.children.insert(0, v)
    else:
        ch.children.insert(0, v)
        v.parents.append(ch)
    return ftlist, before, make_snapshot(vft)


def from_snapshot(data):
    for v, children, parents in data:
        v.children[:] = children
        v.parents[:] = parents


def make_snapshot(v0):
    def it(v):
        yield v, tuple(v.children), tuple(v.parents)
        # if you need to keep track of headlines and boides too
        # yield v, tuple(v.children), tuple(v.parents), v.h, v.b
        for ch in v.children:
            yield from it(ch)
    return tuple(it(v0))


def do_change():
    undo_data = c.undoer.createCommonBunch(p)
    undo_data.kind = 'my-special-operation'
    undo_data.undoType = 'my-special-operation'
    ftlist, before, after = moveToTopAndCloneToAtDay(c, p)
    undo_data.before = before
    undo_data.after = after
    undo_data.ftlist = ftlist
    undo_data.undoHelper = lambda:from_snapshot(undo_data.before) or c.
redraw(undo_data.p)
    undo_data.redoHelper = lambda:from_snapshot(undo_data.after) or c.redraw
(undo_data.ftlist.firstChild())
    c.undoer.pushBead(undo_data)
    c.redraw(ftlist.firstChild())

do_change()

If you make a script button of this code, you can try your action and its 
undo/redo functionality on some of the descendants of your @ftlist tree.

HTH 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 leo-editor+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/leo-editor/20942315-145c-4dff-83ea-d0b6a1a39afe%40googlegroups.com.

Reply via email to