Erratic behaviour using setsourcetab to target Select in Dual panes

Whilst developing a script that operates on both sides of a dual lister I came across "interesting" behaviour. In an attempt to understand/demonstrate what was happening I wrote a JavaScript command that sends two sequential Select commands to the right pane and then the same two commands to the left pane. The following sequence of screen grabs shows what happens when the command is run in various modes.

  • In all examples, the first command sent to both right and left panes is Select FIRST TYPE=files.
  • In "invert" examples the second command is Select INVERT and in non-invert examples the command is SELECT SIMILAR.
  • In "func" examples the func.command object is used and in non-func examples a DOpus.command object is used.
  • The starting point for each test is a single tab in a single lister using what is effectively a vanilla configuration.

The first test (SIMILAR) does what I expect in the right pane and apparently does nothing in the left pane.

The second test (INVERT) does what I expect in the right pane and apparently does nothing in the left pane.

The 3rd test (SIMILAR + func) appears to Select FIRST correctly in both panes but fails to Select SIMILAR in either.

The 4th test (INVERT + func) does what I expect.

The test script is attached as is the test command launch toolbar. In addition to the questions raised by the difference between func and DOpus command behaviour, and INVERT vs SIMILAR, I should also note that when I run the same tests using my regular configuration instead of the vanilla configuration used here, the outcomes are equally erratic but not the same as described above. One thing at a time..... :grinning:

qnd.js.txt (2.5 KB)
qnd.dop (1.1 KB)

function OnInit(initData)
{
	initData.name = "qnd";
	initData.version = "2.0 (December 1st, 2018)";
	initData.desc = "Just Testing";
	initData.copyright = "(c) 2018 Aussie";
	initData.default_enable = true;
	
	initData.vars("name") = initData.name;
	initData.vars("version") = initData.version;
	initData.vars("minver") = "12";
	
	var cmd = initData.AddCommand();
	cmd.name = initData.name;
	cmd.method = "do_main";
	cmd.desc = initData.desc;
	cmd.label = initData.name;
	cmd.template = "func/s,invert/s";
	
	initData.config_desc = DOpus.create.map();
	initData.config.dbg = true;
	initData.config_desc("dbg") = 'Write trace information to "Other" log.';
}

//-- Global Variables

var d, f, fsu;
var dbg;
var dlg;

//-- Main script code

function do_main(ScriptCommandData){	
	// Debug ?
	dbg = debug();
	// Establish minimum version requirements
	if (!minver()) return;
	
	fsu = DOpus.FSUtil;
	d = ScriptCommandData;
	dlg = d.func.dlg;
	
	var thislister = d.func.sourcetab.lister;
	var cmdobj = (d.func.args.got_arg.func) ? d.func.command : DOpus.create.command;
	var selopt = (d.func.args.got_arg.invert) ? "INVERT" : "SIMILAR";
	if (!thislister.dual) cmdobj.runcommand("Go CURRENT OPENINDUAL");
	thislister.Update();
	var pfx = (d.func.args.got_arg.func) ? "func" : "DOpus";
	pfx = pfx+".command: "; 
	var cmdstr1 = "Select FIRST TYPE=files";
	var cmdstr2 = "Select "+selopt;
	cmdobj.setsourcetab(thislister.desttab);
	var tgt1 = (thislister.desttab.right) ? "right" : "left";
	if (dbg) DOpus.output("==> "+tgt1);
	cmdobj.runcommand(cmdstr1);
	if (dbg) DOpus.output(pfx+cmdstr1);
	cmdobj.runcommand(cmdstr2);
	if (dbg) DOpus.output(pfx+cmdstr2);
	cmdobj.setsourcetab(thislister.activetab);
	var tgt1 = (thislister.activetab.right) ? "right" : "left";
	if (dbg) DOpus.output("==> "+tgt1);
	cmdobj.runcommand(cmdstr1);
	if (dbg) DOpus.output(pfx+cmdstr1);
	cmdobj.runcommand(cmdstr2);
	if (dbg) DOpus.output(pfx+cmdstr2);
}

//-- Functions called from main script code

function debug(){
	var dbg = (typeof Script.config.dbg=="undefined") ? true : Script.config.dbg;
	if (dbg){
		var str = (Script.vars.exists("version")) ? Script.vars("version") : "1.0";
		DOpus.output("version " + str + " starting..");
	}
	return dbg;
}

function minver(){
	var minver = (Script.vars.exists("minver")) ? Script.vars("minver") : "12";
	var isokay = DOpus.version.AtLeast(minver);
	if (!isokay){
		var str = "Requires DOpus version " + minver + " or later."
		DOpus.output(str, true);
	}
	return isokay;
}

The files are being selected correctly but then those in the source tab are deselected almost immediately. This is kind of by design (the Command object is designed to deselect the files it uses unless you set its deselect property to true), however it's also a bug in that in this case, the Command object isn't actually using any files itself.

We'll fix the bug in the next update. In the mean time, you can work around it by adding the following two lines to the script:

	cmdobj.deselect = false;
	d.func.command.deselect = false;
1 Like

Thanks @Jon, that certainly improves things for a DOpus.command object but not for a func.command object. Hopefully I have implemented your changes correctly.

With your changes in place and DESELECTNOMATCH added to the initial Select FIRST command, and with the same folder open in both sides and nothing originally selected:

If I execute qnd, qnd invert and qnd again in sequence, everything works as expected . However, when I do the same with qnd func, qnd func invert and qnd func in sequence, results are as shown below the updated test command.

qnd.js.txt (2.8 KB)

qnd func starting with nothing initially selected. I expected both .js files to be selected by Select SIMILAR.

qnd func invert, executed without clearing the previous selection. Seems to be okay.

qnd func (again), executed without clearing the previous selection. Again, an unexpected outcome.

function OnInit(initData)
{
	initData.name = "qnd";
	initData.version = "2.1 (December 3rd, 2018)";
	initData.desc = "Just Testing";
	initData.copyright = "(c) 2018 Aussie";
	initData.default_enable = true;
	
	initData.vars("name") = initData.name;
	initData.vars("version") = initData.version;
	initData.vars("minver") = "12";
	
	var cmd = initData.AddCommand();
	cmd.name = initData.name;
	cmd.method = "do_main";
	cmd.desc = initData.desc;
	cmd.label = initData.name;
	cmd.template = "func/s,invert/s";
	
	initData.config_desc = DOpus.create.map();
	initData.config.dbg = true;
	initData.config_desc("dbg") = 'Write trace information to "Other" log.';
}

//-- Global Variables

var d, f, fsu;
var dbg;
var dlg;

//-- Main script code

function do_main(ScriptCommandData){	
	// Debug ?
	dbg = debug();
	// Establish minimum version requirements
	if (!minver()) return;
	
	fsu = DOpus.FSUtil;
	d = ScriptCommandData;
	dlg = d.func.dlg;
	
	// See https://resource.dopus.com/t/erratic-behaviour-using-setsourcetab-to-target-select-in-dual-panes/30631/2
	d.func.command.deselect = false;
	var thislister = d.func.sourcetab.lister;
	var cmdobj = (d.func.args.got_arg.func) ? d.func.command : DOpus.create.command;
	// See https://resource.dopus.com/t/erratic-behaviour-using-setsourcetab-to-target-select-in-dual-panes/30631/2
	cmdobj.deselect = false;
	d.func.command.deselect = false;
	var selopt = (d.func.args.got_arg.invert) ? "INVERT" : "SIMILAR";
	if (!thislister.dual) cmdobj.runcommand("Go CURRENT OPENINDUAL");
	thislister.Update();
	var pfx = (d.func.args.got_arg.func) ? "func" : "DOpus";
	pfx = pfx+".command: "; 
	var cmdstr1 = "Select FIRST TYPE=files DESELECTNOMATCH";
	var cmdstr2 = "Select "+selopt;
	cmdobj.setsourcetab(thislister.desttab);
	var tgt1 = (thislister.desttab.right) ? "right" : "left";
	if (dbg) DOpus.output("==> "+tgt1);
	cmdobj.runcommand(cmdstr1);
	if (dbg) DOpus.output(pfx+cmdstr1);
	cmdobj.runcommand(cmdstr2);
	if (dbg) DOpus.output(pfx+cmdstr2);
	cmdobj.setsourcetab(thislister.activetab);
	var tgt1 = (thislister.activetab.right) ? "right" : "left";
	if (dbg) DOpus.output("==> "+tgt1);
	cmdobj.runcommand(cmdstr1);
	if (dbg) DOpus.output(pfx+cmdstr1);
	cmdobj.runcommand(cmdstr2);
	if (dbg) DOpus.output(pfx+cmdstr2);
}

//-- Functions called from main script code

function debug(){
	var dbg = (typeof Script.config.dbg=="undefined") ? true : Script.config.dbg;
	if (dbg){
		var str = (Script.vars.exists("version")) ? Script.vars("version") : "1.0";
		DOpus.output("version " + str + " starting..");
	}
	return dbg;
}

function minver(){
	var minver = (Script.vars.exists("minver")) ? Script.vars("minver") : "12";
	var isokay = DOpus.version.AtLeast(minver);
	if (!isokay){
		var str = "Requires DOpus version " + minver + " or later."
		DOpus.output(str, true);
	}
	return isokay;
}

The difference is due to the fact that the Command object that you get from func.command has its view of the file selection locked in when its created, whereas the one you get from DOpus.command doesn't.

Select SIMILAR needs selected files to work on, but in this instance the Command object "knows" it doesn't have any.

The solution is to update the Command object's file list after running the Select FIRST command.

cmdobj.runcommand(cmdstr1);
// update for dest tab
thislister.desttab.Update();
cmdobj.SetFiles(thislister.desttab.selected);

....

cmdobj.runcommand(cmdstr1);
// update for source tab
thislister.activetab.Update();
cmdobj.SetFiles(thislister.activetab.selected);
1 Like

Thanks @Jon for the detailed explanation. I had a feeling that tab.Update() needed to be in the mix.