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>

6 Likes

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