This might not be the best possible name but it reflects an idea that came
from Seth Jonson in another thread.
The idea is to clone all those nodes that are present in the outline
outside copied tree. All nodes that are located only under the copied tree
should not be cloned unless they have clones under the copied tree. In
essence this is just what paste-node command does plus it keeps identity of
all nodes that have clones elsewhere in the outline outside the copied tree.
Here is the code:
from xml.etree import ElementTree as ET
import leo.core.leoNodes as leoNodes
c.frame.log.clearTab('Log')
def paste_as_template(p):
def newgnx():
ni = g.app.nodeIndices
t_s = ni.update()
return f"{ni.userId}.{t_s}.{ni.lastIndex:d}"
def skip_root(v):
if v.gnx != root_gnx:
yield v
for ch in v.children:
yield from skip_root(ch)
def translate_gnx(gnx):
if gnx in outside:
return gnx
return newgnx()
gnx2v = c.fileCommands.gnxDict
def getv(gnx):
v = gnx2v.get(gnx)
if v is None:
return leoNodes.VNode(c, gnx), True
return v, False
def viter(pargnx, xv):
chgnx = xv.attrib.get('t')
b = bodies[chgnx]
gnx = translation.get(chgnx)
if gnx in seen:
yield pargnx, gnx, heads[gnx], b
else:
seen.add(gnx)
h = xv[0].text
heads[gnx] = h
yield pargnx, gnx, h, b
for xch in xv[1:]:
yield from viter(gnx, xch)
def dumptree(): # just for debuging
levs = {'':-1}
for pgnx, gnx, h, b in viter('', xvnodes[0]):
lev = levs[pgnx] + 1
levs[gnx] = lev
g.es(f'{"----" * lev}[{gnx}]{h}')
def do_paste(vpar, index):
vpargnx = vpar.gnx
rows = viter(vpargnx, xvnodes[0])
pgnx, gnx, h, b = next(rows)
v, _ = getv(gnx)
v.h = h
v.b = b
vpar.children.insert(index, v)
v.parents.append(vpar)
pasted = v
for pgnx, gnx, h, b in rows:
v, isNew = getv(gnx)
if isNew:
v.h = h
v.b = b
vpar = getv(pgnx)[0]
vpar.children.append(v)
v.parents.append(vpar)
return pasted
def undoHelper():
v = vpar.children.pop(index)
v.parents.remove(vpar)
c.redraw(bunch.p)
def redoHelper():
vpar.children.insert(index, pasted)
pasted.parents.append(vpar)
c.redraw(newp)
xroot = ET.fromstring(g.app.gui.getTextFromClipboard())
#xroot = ET.fromstring(clipboard_text())
xvnodes = xroot.find('vnodes')
xtnodes = xroot.find('tnodes')
bodies = {x.attrib['tx']:x.text for x in xtnodes}
root_gnx = xvnodes[0].attrib.get('t')
outside = {x.gnx:x for x in skip_root(c.hiddenRootNode)}
translation = {x:translate_gnx(x) for x in bodies.keys()}
seen = set()
heads = {}
dumptree()
bunch = c.undoer.createCommonBunch(p)
if p.isExpanded():
vpar = p.v
index = 0
parStack = p.stack + [(p.v, p._childIndex)]
else:
parStack = p.stack
vpar = p.stack[-1][0] if p.stack else c.hiddenRootNode
index = p._childIndex + 1
seen.clear()
pasted = do_paste(vpar, index)
newp = leoNodes.Position(pasted, index, parStack)
bunch.undoHelper = undoHelper
bunch.redoHelper = redoHelper
bunch.undoType = 'paste-retaining-outside-clones'
c.undoer.pushBead(bunch)
c.redraw(newp)
paste_as_template(p)
The command is undoable.
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/14528440-f602-4a39-8915-0ab140fd73fa%40googlegroups.com.