Installation
Download the .osp below, then open Preferences / Toolbars / Scripts, and drag it to the list of scripts.
Beyond Compare.osp (14.9 KB)
After that, go to Settings > Customize Toolbars > Commands and there will be a new Compare command which you can drag to your toolbar:
The command will do different things depending on what is (or isn't) selected in the file displays, as explained below.
History
The latest version is attached above. Click the relevant links for full details of earlier versions.
- Original version posted on 21st January, 2014
- Updated on 22nd January to add support for checked files/folders (check box mode)
- Version 2.1 (rewrite) posted as an Opus Script Package on 9th April, 2014
- Version 2.2 (add proper versioning) posted as an Opus Script Package on 10th April, 2014
- Version 2.2 LD posted on 30th April by Leo Davidson. Includes a number of refinements and improvements. See linked post for full details.
- Version 2.3 AB posted on 2nd May.
- Version 2.4 AB posted on 12th June. Minor fix to minimum Opus version check.
- Version 2.4 AB (at the top of this post), and the 2.2 LD fork (here) have both been updated to include icons for high DPI systems. No other changes. 12th October 2017.
- Version 2.4 AB (at the top of this post), and the 2.2 LD fork (here) updated again to fix an issue with large icons and high DPI.
I regularly use Beyond Compare to check for differences between versions of files and to synchronise folders. For a long time I have used a toolbar with a variety of buttons to compare two SOURCE files, compare a SOURCE file and a DEST file, compare a SOURCE folder and a DEST folder, etc..
With the introduction of script support in Opus 11 it seemed like a good time to merge all of these discrete buttons into a single "smart" button which examines the environment (e.g. SOURCE only, SOURCE/DEST or DUAL, how many files/folders checked or selected in SOURCE and DEST) and then executes Beyond Compare with the relevant option. For example, if exactly two files are checked or selected in SOURCE, compare these files, or if one folder is checked or selected in SOURCE and one folder in DEST then compare them.
Original button code as follows. (N.B. This has long since been superseded. See above for the latest package.) The only customisation required is to identify where bcompare.exe is on your system. At the time the original code was developed, Beyond Compare v3 was the current version and Beyond Compare 4 was in public Beta so I made provision for switching easily between versions.
Caveat: I used this exercise as an opportunity to learn some JavaScript so my novice code may be a bit clumsy.
// JavaScript button code to provide a smart front end to Beyond Compare
// See http://www.scootersoftware.com for more information regarding Beyond Compare
// Contributed by "AussieBoykie", January 2014
//
// Depending on the presence or absence of DEST and what files/folders are checked or selected in SOURCE and DEST
// the "smart" logic triggers one of the following actions:
//
// Compare the first checked or selected SOURCE file and the second checked or selected SOURCE file
// Compare the first checked or selected SOURCE folder and the second checked or selected SOURCE folder
// or...
// Compare the single checked or selected SOURCE file and the single checked or selected DEST file (if they are different files)
// Compare the single checked or selected SOURCE folder and the single checked or selected DEST folder (if they are different folders)
// or...
// Compare the current SOURCE folder and DEST folder (if they are different folders)
// or...
// Display the Beyond Compare main menu
//
// Before first use, the end user should edit BCCmd (see below) to point to the location of BCompare.exe on the user's system
function OnClick(ClickData)
{
// Define shorthand for the clicked button's command object
var objCmd = ClickData.Func.Command;
// Test the setting of a global variable "debug"
// which is used to control debug output
var debug = objCmd.IsSet("$glob:debug");
// Set boolean flags according to the current SOURCE and DEST check box modes
var SCBMode = objCmd.IsSet("CHECKBOXMODE=On");
if (debug) {DOpus.OutputString("Source CHECKBOXMODE is " + SCBMode)};
var oldSource = objCmd.sourcetab;
if (typeof objCmd.desttab == 'object')
{
objCmd.SetSourceTab(objCmd.desttab);
var DCBMode = objCmd.IsSet("CHECKBOXMODE=On");
if (debug) {DOpus.OutputString("Dest CHECKBOXMODE is " + DCBMode)};
objCmd.SetSourceTab(oldSource);
}
else {var DCBMode = false};
// Test the setting of a global variable "BCBeta" and define the base Beyond Compare command accordingly
// This provides a mechanism for switching between Beyond Compare versions
var BCCmd;
var BCBeta = objCmd.IsSet("$glob:BCBeta");
if (BCBeta)
{
BCCmd = "/homeroot\\utilities\\bc4\\bcompare.exe";
if (debug) {DOpus.OutputString("BCBeta is TRUE")};
}
else
{
BCCmd = "/homeroot\\utilities\\bc3\\bcompare.exe";
if (debug) {DOpus.OutputString("BCBeta is FALSE")};
};
var cmd = BCCmd;
// Get some information about which files and/or folders are checked or selected in the SOURCE tab
var sfiles;
var sdirs;
var sitems;
if (!SCBMode)
{
sfiles = objCmd.sourcetab.stats.selfiles;
sdirs = objCmd.sourcetab.stats.seldirs;
sitems = objCmd.sourcetab.stats.selitems;
}
else
{
sfiles = objCmd.sourcetab.stats.checkedfiles;
sdirs = objCmd.sourcetab.stats.checkeddirs;
sitems = objCmd.sourcetab.stats.checkeditems;
};
if (debug) {DOpus.OutputString("sitems/sfiles/sdirs = " + sitems + "/" + sfiles + "/" + sdirs)};
// Get some information about which files and/or folders are selected in the DEST tab
// Target (DEST) may or may not exist
// Default to zero destination files and folders if no DEST exists
var dfiles = 0;
var ddirs = 0;
var ditems = 0;
if (typeof objCmd.desttab == 'object')
{
if (!DCBMode)
{
dfiles = objCmd.desttab.stats.selfiles;
ddirs = objCmd.desttab.stats.seldirs;
ditems = objCmd.desttab.stats.selitems;
}
else
{
dfiles = objCmd.desttab.stats.checkedfiles;
ddirs = objCmd.desttab.stats.checkeddirs;
ditems = objCmd.desttab.stats.checkeditems;
};
};
if (debug) {DOpus.OutputString("ditems/dfiles/ddirs = " + ditems + "/" + dfiles + "/" + ddirs)};
var s1; var s2;
// If exactly two files or two folders are checked (in check box mode) or selected in SOURCE
// then prepare a BC command to trigger a Source/Source compare
if (sitems == 2 && sfiles != sdirs)
{
s1 = String(objCmd.sourcetab.selected(0));
s2 = String(objCmd.sourcetab.selected(1));
cmd = BCCmd + ' "' + s1 + '"' + ' "' + s2 + '"';
if (debug) {DOpus.OutputString("Compare Source/Source")};
}
// Otherwise...
// If one file or one folder is selected in both SOURCE and DEST and they are not exactly the same file/folder
// then prepare a BC command to trigger a compare
else if (sitems == 1 && ditems == 1 && sfiles == dfiles)
{
s1 = String(objCmd.sourcetab.selected(0));
s2 = String(objCmd.desttab.selected(0));
if (s1 != s2)
{
cmd = BCCmd + ' "' + s1 + '"' + ' "' + s2 + '"';
if (debug) {DOpus.OutputString("Compare Source/Target")};
}
}
// Otherwise...
// If DEST exists and is not the same as SOURCE then prepare a BC command to trigger a Source/Dest folder compare
else if (typeof objCmd.desttab == 'object' && (objCmd.sourcetab.path != objCmd.desttab.path))
{
cmd = BCCmd + ' "' + objCmd.sourcetab.path + '"' + ' "' + objCmd.desttab.path + '"';
if (debug) {DOpus.OutputString("Compare Source/Target folders")};
};
// Execute the relevant command
if (debug) {DOpus.OutputString(cmd)};
objCmd.RunCommand(cmd);
}
Regards, AB