Menu

[scripts sharing] Make a node the first or last child

lilive
2021-05-08
2021-05-16
  • lilive

    lilive - 2021-05-08

    Hello,
    From time to time, I need to move a node to make it the first or last child of its parent. I just wrote a couple of scripts that do it, and they seems to work.
    Once installed, they add 2 menu entries in the menu Edit > Move & sort (as usual, you can bind them to any keyboard shortcut).
    They work for a single node or for a multiple selection.

     
  • Jochen Kall

    Jochen Kall - 2021-05-11

    Hi lilive,

    when I saw your post I remembered I had the same problem a while ago and found an API for that:

    node.moveTo(node.getParent(),-1) // moves node to last position
    node.moveTo(node.getParent(),0) // moves node to first position
    

    [edit]
    scrap that , you use moveTo already in the script :D sorry about that, then I don't think I understand the problem yet you are solving.

    Jochen

     

    Last edit: Jochen Kall 2021-05-11
  • lilive

    lilive - 2021-05-13

    Hi Jochen,
    But thank you for the

    node.moveTo(node.getParent(),-1)
    

    You teach me the use of -1 to put the node at the last position.
    My scripts take care of preserving the order of the nodes when multiple nodes are moved at the same time, regardless of the order they have been selected. That's why they are not simple one line scripts. Your solution is perfect for one node at a time moving.

     
  • Jochen Kall

    Jochen Kall - 2021-05-13

    Hi lilive,

    now I get it, guess there is no more elegant way that preserves order and selection while moving nodes like that.

    Well one more thing caught my eye, the way you implemented it doesn't work properly if the selected nodes don't share the same parent node, since it moves all selected nodes to the parent of the node the script actually executes on.

    Small tweak to fix that:

    // @ExecutionModes({ON_SELECTED_NODE})
    nodes=c.getSortedSelection(true)
    nodes.reverse().each{it.moveTo(it.getParent(),0)}
    c.select(nodes)
    

    Jochen

     
  • lilive

    lilive - 2021-05-16

    it doesn't work properly if the selected nodes don't share the same parent node

    Indeed. Thank you Jochen. Maybe I prefer to handle the situation with an error message, the same as the "Move node (Parents sibling)" command :

    // @ExecutionModes({on_single_node="/main_menu/edit/menu_moveNode"})
    parent = node.parent
    nodes = c.getSortedSelection( true )
    if( nodes.find{ it.parent != parent } ){
        ui.informationMessage(
            ui.frame, "All nodes must have the same parent to use this fonction.",
            "Freeplane", javax.swing.JOptionPane.ERROR_MESSAGE
        )
    } else {
        nodes.reverse().each{ it.moveTo( parent, 0 ) }
        c.select( nodes )
    }
    

    Also, I think there is no need to use @ExecutionModes({ON_SELECTED_NODE}). With this option, the script is called once for every selected node. If you select 3 nodes, and run the command, each node will be moved 3 times to the first place. This is why I use ON_SINGLE_NODE.

     
  • Jochen Kall

    Jochen Kall - 2021-05-16

    Hi lilive,

    yap, ON_SINGLE_NODE is correct of course, I was trying to get it done with a one liner using an ON_SELECTED_NODE trigger at first, and forgot switching it back when I changed it following the realization that it won't be possible to retain the selection that way :P