>
>     s = g.app.gui.getTextFromClipboard()
>     undoType = 'Paste As Clone'
>     c.endEditing()
>     if not s or not c.canPasteOutline(s):
>         return # This should never happen.
>     isLeo = g.match(s, 0, g.app.prolog_prefix_string)
>     vnodeInfoDict = computeVnodeInfoDict(c)
>     # create a *position* to be pasted.
>     if isLeo:
>         pasted = c.fileCommands.getLeoOutlineFromClipboard(s,
>  reassignIndices)


This part of code is present in almost all three kinds of paste functions 
as you have refactored them. However, if you look into c.canPasteOutline 
you will see that it repeats almost all of the above. It checks to see if s 
is None and if so it takes value from clipboard, then it checks if it 
starts with g.app_prolog_prefix_string and if everything is checked returns 
True. In order to avoid code duplication some other duplication have been 
made. And it is not easy to spot the duplication and unnecessary code 
unless you really dive into this code.

Proposing three different methods for three kinds of paste commands, I 
haven't imagined them to be like those. This is just first layer of 
decomposing code. For example in all three implementations you are using 
c.fileCommands.getOutlineFromClipboard passing kw flag again. And also same 
switch is passed to undo methods. Instead, I would recommend further 
decomposition down the road. 

By the way, getOutlineFromClipboard ends with call to c.selectPosition(p) 
where p is newly pasted node. In the above implementations there is also 
call to select the same position. 

Also, getOutlineFromClipboard creates at first v node, and then creates a 
position to hold this v node, then in the above implementations, calls 
methods of the position class moveToNthChildOf or linkAsNthChildOf which 
are delegating their jobs to p.v methods. It would be much simpler if 
getOutlineFromClipboard returns v instance, and then just make link with 
parent_v. 

A variable named undoType is introduced in first two methods, just to be 
used once in the end. It would suffice to use constant string instead. This 
variable is necessary if pasteOutline performs both kinds of operation. By 
separating functions this variable can be eliminated and code complexity 
further reduced. 

For undoing paste-retaining-clones it would be enough to just cut the link 
between parent_v and the pasted v node. By definition all nodes inside the 
pasted outline are exactly the same after paste command. The only 
difference is one more parent element in v.parents and just in top level 
pasted node. That is why I strongly suspect that computing a copied bunch 
is unnecessary too.

copiedBunchList = computeCopiedBunchList(c, pasted, vnodeInfoDict)
undoData = c.undoer.beforeInsertNode(c.p,
                pasteAsClone=True, copiedBunchList=copiedBunchList)
    
And there again is a method c.undoer.beforeInsertNode which needs kw flags 
pasteAsClone to be passed. I would recommend also to have 
c.undoer.beforePasteClone and c.undoer.afterPasteClone. which should be 
extremely simply. 

After all if there are common parts of these three kinds of paste methods 
then we can extract them and have:

def pasteOutlineRetainingClones(self, p):
    (childIndex, undodata, txt,...) = prePasteNodeCommon(p,
                                        c.undoer.beforePasteRetainingClone)
    ...
    # specific to retaining clones variant
    v = getVnodeFromString(txt) # somehow see our discussion on #862

    if v:
        postPasteNodeCommon(p, v, undodata, 
c.undoer.afterPasteRetainingClone)

def pasteOutline(self, p):
    (childIndex, undodata, txt, ...) = prePasteNodeCommon(p,
                                        c.undoer.beforePasteNoClone)
    ...
    # specific to paste no clones

    v = getVnodeFromStringWithNewIndices(txt)

    if v:
        postPasteNodeCommon(p, v, c.undoer.afterPasteNoClone)

def pasteFromString(self, p, txt):
    (childIndex, undodata, dummy, ...) = prePasteNodeCommon(p,
                                        lambda *args: None,
                                        txt)
    ...
    # specific to paste from string

    v = getVnodeFromStringWithNewIndices(txt)

    # no undo


def prePasteNodeCommon(p, undoMethod):
    c.endEditing()
    ...
    # decide where to paste: parent_v and childIndex
    # based on expanded/collapsed state of current position
    ...
    txt = g.app.gui.getTextFromClipboard()
    undodata = undoMethod(c.undoer, ...)
    return childIndex, undodata, txt, ...

def postPasteNodeCommon(p, v, undodata, undoMethod):

    # make link
    v.parents.append(p.v)
    p.v.children.insert(childIndex, v)

    undoMethod(c.undoer, undodata)

This is not complete code just a blueprint. But implemented this way would 
look much better and point out in more contrast the difference from the 
current implementation.


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 post to this group, send email to leo-editor@googlegroups.com.
Visit this group at https://groups.google.com/group/leo-editor.
For more options, visit https://groups.google.com/d/optout.

Reply via email to