Compare tab contents in dual display mode

Here's a simple script for comparing tab contents in dual display mode.

This script compares the files in source and destination tabs and selects the files that do no exist in other tab or differ by size.

By default only file names are compared and differences are selected. This is similar to the stock commands in the Edit > Select Other menu of Opus 12. But you can do some additional things with the script by adding arguments.

Use these arguments to change script behaviour:

  • SIZE - compare file size
  • CREATE - compare creation time
  • MODIFY - compare modification time
  • INVERT - select files that are same

Examples:

(There were screenshots here but the external URLs no longer work.)

CompareTabs

CompareTabs SIZE

CompareTabs SIZE CREATE

CompareTabs SIZE CREATE MODIFY

CompareTabs SIZE CREATE MODIFY INVERT

Download:

  • Latest: v0.2 - Compare Tabs.js.txt (2.7 KB)
  • Download the file, then drag it to the list under Preferences / Toolbars / Scripts.

Older, original version:

Script Code:

The script code for v0.2 is reproduced below, for easy reference:

/*
Compare tabs in dual display mode (requires DOpus version >=11.0.9)
By default only file name is compared and differences are selected.
Use these arguments to change script behaviour:
SIZE - compare file size
CREATE - compare creation time
MODIFY - compare modification time
INVERT - select files that are same
*/

function OnInit(data) {
    var cmd = data.AddCommand();
    data.version = "v0.2";
    cmd.name = "CompareTabs";
    cmd.method = "OnCompareTabs";
    cmd.label = data.name = "Compare Tabs";
    cmd.desc = data.desc = "Compare tabs in dual display mode.";
    cmd.template = "SIZE/S,CREATE/S,MODIFY/S,INVERT/S";
    data.default_enable = true;
    return false;
}

function OnCompareTabs(data) {
    if (!data.func.desttab) return; // do nothing if not in dual panel mode

    var src = {}, dst = {}, srcdup = {}, dstdup = {};

    // add all files from source tab to src array
    var srcEnum = new Enumerator(data.func.sourcetab.files);
    while (!srcEnum.atEnd()) {
        var item = srcEnum.item();
        src[item.name] = item;
        srcEnum.moveNext();
    }

    // add different files from destination tab to dst array and others to dstdup array
    var dstEnum = new Enumerator(data.func.desttab.files);
    while (!dstEnum.atEnd()) {
        item = dstEnum.item();
        var isDuplicate = item.name in src;
        if (isDuplicate && data.func.args.got_arg.size) isDuplicate = src[item.name].size - item.size == 0;
        if (isDuplicate && data.func.args.got_arg.create) isDuplicate = src[item.name].create - item.create == 0;
        if (isDuplicate && data.func.args.got_arg.modify) isDuplicate = src[item.name].modify - item.modify == 0;
        if (isDuplicate) dstdup[item.name] = item;
        else dst[item.name] = item;
        dstEnum.moveNext();
    }
    
    // move duplicates from src array to srcdup array
    for (var k in src) if (k in dstdup) {
        srcdup[k] = src[k];
        delete src[k];
    }
    
    // add files from src or srcdup to select command depending on INVERT argument
    data.func.command.ClearFiles();
    if (data.func.args.got_arg.invert) for (k in srcdup) data.func.command.AddFile(srcdup[k]);
    else for (k in src) data.func.command.AddFile(src[k]);
    data.func.command.RunCommand("Select FROMSCRIPT DESELECTNOMATCH");

    // add files from dst or dstdup to select command depending on INVERT argument
    data.func.command.SetSourceTab(data.func.desttab);
    data.func.command.ClearFiles();
    if (data.func.args.got_arg.invert) for (k in dstdup) data.func.command.AddFile(dstdup[k]);
    else for (k in dst) data.func.command.AddFile(dst[k]);
    data.func.command.RunCommand("Select FROMSCRIPT DESELECTNOMATCH");
}
3 Likes

Nice script! (I split it from the original thread because I thought it belonged in a thread of it's own).

The desttab thing is a bug, we'll fix this in a future beta. (The desttab issue no longer affects current versions, and the script above was updated accordingly.)

This is a very useful script. I have taken the liberty of modifying it to add an option to select identical files.

(Note that this is based on the original script version. The script in the post above has been updated to incorporate some of these ideas.)

CompareTabs ... selects non-identical files (the default operation)
CompareTabs SAME ... selects identical files

function OnInit(data) {
   var cmd = data.AddCommand();
   cmd.name = "CompareTabs";
   cmd.method = "OnCompareTabs";
   cmd.label = data.name = "Compare Tabs";
   cmd.desc = data.desc = "Compare tabs in dual display mode and select files differing in name or size.";
   cmd.template = "SAME/S";
   data.default_enable = true;
   return false;
}

function OnCompareTabs(data) {
   var lister = data.func.sourcetab.lister; // get lister object from source tab
   if (!lister.dual) return; // do nothing if not in dual panel mode

   var src = {}, dst = {}, dup = {};
   
   var SelCmd1 = "Select FROMSCRIPT DESELECTNOMATCH";
   var SelCmd2 = "Select INVERT TYPE=Files";
   
   // add all files from source tab to src array
   var srcEnum = new Enumerator(lister.activetab.files);
   while (!srcEnum.atEnd()) {
      var item = srcEnum.item();
      src[item.name] = item;
      srcEnum.moveNext();
   }
   
   // add different files from destination tab to dst array and others to dup array
   var dstEnum = new Enumerator(lister.desttab.files);
   while (!dstEnum.atEnd()) {
      item = dstEnum.item();
      if (!(item.name in src) || (src[item.name].size - item.size)) dst[item.name] = item;
      else dup[item.name] = item;
      dstEnum.moveNext();
   }
   
   // add files from src that are not in dup to select command
   data.func.command.ClearFiles();
   for (var k in src) if (!(k in dup)) data.func.command.AddFile(src[k]);
   // Select DIFFERENT files
   data.func.command.RunCommand(SelCmd1);
   // Invert selection if user requested SAME instead of (default) DIFFERENT
   if (data.func.args.got_arg.same) data.func.command.RunCommand(SelCmd2);
   
   // add all files from dst to select command
   data.func.command.SetSourceTab(lister.desttab);
   data.func.command.ClearFiles();
   for (k in dst) data.func.command.AddFile(dst[k]);
   // Select DIFFERENT files
   data.func.command.RunCommand(SelCmd1);
   // Invert selection if user requested SAME instead of (default) DIFFERENT
   if (data.func.args.got_arg.same) data.func.command.RunCommand(SelCmd2);
}

Regards, AB

Thanks for providing this script.
Would it be possible to make it also working in Flatview mode and also with folders? That would be really great.

1 Like

Jon, thanks for a quick data.func.desttab fix. Now using this instead of lister tabs.
AB, thanks for extending the functionality with SAME argument. I modified the script even further to include several more arguments. And as secondary select command for inverting the selection introduced a visible glitch I decided to compile the list of selected files directly and use only single select instead.
Kundal, I'll look into adding support for flat view as well.

You'll find a modified version 0.2 above, in the root post.

What is the command of the script for the toolbar button? The path to the Compare Tabs.js file?

You can find the command in Command Editor for a hotkey or a button.

[External screenshots removed as they no longer work.]

Nice & useful script. Thanks.

Hi, Thanks for the script but I cant see it in the tools menu.

You need to put it there yourself, watch the button editor window screenshot at the bottom, to see an example command.

Congratulations, this script is really great, but if you also take folders into consideration, it would be perfect!!!