Merge Folders and Collections

This script merges the contents of the selected folders or file collections into one of them, which can be picked from a drop-down menu.

The Switch button toggles the drop-down menu between the folders' names and their paths.

// https://resource.dopus.com/t/merge-folders-and-collections/41476

// 2022-06-14

function OnClick(clickData) {
    var cmd = clickData.func.command;
    var tab = clickData.func.sourcetab;
    var dlg = clickData.func.Dlg();
    var fsu = DOpus.FSUtil();

    cmd.deselect = false;

    if (tab.selected_dirs.count < 2) {
        dlg.Request('Please select at least two folders!', 'OK');
        return;
    }

    var dirItems = DOpus.Create().Vector();
    var dirNames = DOpus.Create().Vector();
    for (var e = new Enumerator(tab.selected_dirs); !e.atEnd(); e.moveNext()) {
        var item = e.item();
        dirItems.push_back(item);
        dirNames.push_back(item.name);
    }

    dlg.title = 'Merge Folders';
    dlg.message = 'Please select the destination folder:';
    dlg.buttons = 'OK|&Switch|Cancel';
    dlg.selection = 0;
    var showPath = false;
    do {
        dlg.choices = showPath ? dirItems : dirNames;
        var userChoice = dlg.Show();
        if (userChoice == 2) showPath = !showPath;
    } while (userChoice == 2);

    if (userChoice != 1) return;

    var s = dlg.selection;
    var dstPath = dirItems(s).path;
    var dstFolder = dirItems(s).name;
    var dstColl = dirItems(s);
    dirItems.erase(s);

    if (String(dstPath).substring(0, 7) == 'coll://') {
        for (var e = new Enumerator(dirItems); !e.atEnd(); e.moveNext()) {
            var coll = e.item();
            cmd.SetFiles(fsu.ReadDir(coll).Next(-1));
            cmd.RunCommand('Copy TO="' + dstColl + '" COPYTOCOLL=member');
        }
        cmd.SetFiles(dirItems);
        cmd.RunCommand('Delete QUIET');
    } else {
        cmd.SetFiles(dirItems);
        cmd.RunCommand('Copy MOVE AS="' + dstFolder + '" TO="' + dstPath + '" WHENEXISTS=rename,merge');
        cmd.RunCommand('Go PATH="' + dstPath + '\\' + dstFolder + '" OPENCONTAINER');
    }
}
Button as XML
<?xml version="1.0"?>
<button backcol="none" display="both" textcol="none">
	<label>Merge Folders</label>
	<icon1>#move</icon1>
	<function type="script">
		<instruction>@script JScript</instruction>
		<instruction>// https://resource.dopus.com/t/merge-folders-and-collections/41476</instruction>
		<instruction />
		<instruction>// 2022-06-14</instruction>
		<instruction />
		<instruction>function OnClick(clickData) {</instruction>
		<instruction>    var cmd = clickData.func.command;</instruction>
		<instruction>    var tab = clickData.func.sourcetab;</instruction>
		<instruction>    var dlg = clickData.func.Dlg();</instruction>
		<instruction>    var fsu = DOpus.FSUtil();</instruction>
		<instruction />
		<instruction>    cmd.deselect = false;</instruction>
		<instruction />
		<instruction>    if (tab.selected_dirs.count &lt; 2) {</instruction>
		<instruction>        dlg.Request(&apos;Please select at least two folders!&apos;, &apos;OK&apos;);</instruction>
		<instruction>        return;</instruction>
		<instruction>    }</instruction>
		<instruction />
		<instruction>    var dirItems = DOpus.Create().Vector();</instruction>
		<instruction>    var dirNames = DOpus.Create().Vector();</instruction>
		<instruction>    for (var e = new Enumerator(tab.selected_dirs); !e.atEnd(); e.moveNext()) {</instruction>
		<instruction>        var item = e.item();</instruction>
		<instruction>        dirItems.push_back(item);</instruction>
		<instruction>        dirNames.push_back(item.name);</instruction>
		<instruction>    }</instruction>
		<instruction />
		<instruction>    dlg.title = &apos;Merge Folders&apos;;</instruction>
		<instruction>    dlg.message = &apos;Please select the destination folder:&apos;;</instruction>
		<instruction>    dlg.buttons = &apos;OK|&amp;Switch|Cancel&apos;;</instruction>
		<instruction>    dlg.selection = 0;</instruction>
		<instruction>    var showPath = false;</instruction>
		<instruction>    do {</instruction>
		<instruction>        dlg.choices = showPath ? dirItems : dirNames;</instruction>
		<instruction>        var userChoice = dlg.Show();</instruction>
		<instruction>        if (userChoice == 2) showPath = !showPath;</instruction>
		<instruction>    } while (userChoice == 2);</instruction>
		<instruction />
		<instruction>    if (userChoice != 1) return;</instruction>
		<instruction />
		<instruction>    var s = dlg.selection;</instruction>
		<instruction>    var dstPath = dirItems(s).path;</instruction>
		<instruction>    var dstFolder = dirItems(s).name;</instruction>
		<instruction>    var dstColl = dirItems(s);</instruction>
		<instruction>    dirItems.erase(s);</instruction>
		<instruction />
		<instruction>    if (String(dstPath).substring(0, 7) == &apos;coll://&apos;) {</instruction>
		<instruction>        for (var e = new Enumerator(dirItems); !e.atEnd(); e.moveNext()) {</instruction>
		<instruction>            var coll = e.item();</instruction>
		<instruction>            cmd.SetFiles(fsu.ReadDir(coll).Next(-1));</instruction>
		<instruction>            cmd.RunCommand(&apos;Copy TO=&quot;&apos; + dstColl + &apos;&quot; COPYTOCOLL=member&apos;);</instruction>
		<instruction>        }</instruction>
		<instruction>        cmd.SetFiles(dirItems);</instruction>
		<instruction>        cmd.RunCommand(&apos;Delete QUIET&apos;);</instruction>
		<instruction>    } else {</instruction>
		<instruction>        cmd.SetFiles(dirItems);</instruction>
		<instruction>        cmd.RunCommand(&apos;Copy MOVE AS=&quot;&apos; + dstFolder + &apos;&quot; TO=&quot;&apos; + dstPath + &apos;&quot; WHENEXISTS=rename,merge&apos;);</instruction>
		<instruction>        cmd.RunCommand(&apos;Go PATH=&quot;&apos; + dstPath + &apos;\\&apos; + dstFolder + &apos;&quot; OPENCONTAINER&apos;);</instruction>
		<instruction>    }</instruction>
		<instruction>}</instruction>
	</function>
</button>

11 Likes

Thanks for the script, bookmarked and added as a new button which may come in handy anytime soon!

Thankou very much for this script.
It works very well as far as I have been brave enough to test it.

I'm not certain how it will eventually end up on a toolbar.
One Directory Opus Command that may be useful with this is
'Close Alllisters=collapse' .

The command Collapses the tabs of all listers to the active lister and closes all but the active lister.
Left Tabs are rendered left and Right Tabs are rendered right, but the listers merge to one Lister.