Scripting: How to control dest tab after switching to dual?

Hi,

in DOpus 11.1 Beta 2, I want to write a script for copying some specific files from several folders. In the first dialog I added a checkbox that lets me choose if I want to open a new lister for this or if I prefer to use the current one.

Everything works if I use a new lister or if I use the current one when it already is in dual-display mode. If I want to use the current lister and it is not yet in dual-display mode when starting the script, I have difficulties to get the destination tab under control after switching to dual-display mode in the script using

clickData.func.command.RunCommand('Set DUAL=horiz,dest');

Using

clickData.func.desttab.Update();

leads to an error message in the log:

(translated from German).

clickData.func.command.SetDestTab(clickData.func.command.results.newtabs(0));

leads to the error message

("out of bounds"?).

When I use

clickData.func.command.SetDest(mainIconDir);

(with mainIconDir being a path) I can not access the contents of the tab with

var enumDirs = new Enumerator(clickData.func.desttab.dirs);

I then get the error message

I even tried

clickData.func.command.SetDestTab(clickData.func.sourcetab.lister.desttab);

but with the same result.

Well, how can I control the destination tab? I doesn't seem to exist in the single-display lister, but it also doesn't seem to be created in a way that makes it accessible via clickData.func.command.results.newtabs(0).

Here's a part of the script (it doesn't do anything yet, and I'm still experimenting with the new scripting interface, so some things might not be perfect :wink:):

[code]@script jscript

function OnClick(clickData) {
var dialog = DOpus.Dlg();
dialog.window = DOpus.listers[0];
dialog.icon = 'question';
dialog.title = 'Auswahl der Iconset-Sammlung';
dialog.message = 'Bitte wählen Sie die übergeordnete Iconset-Sammlung aus:';
dialog.buttons = 'OK|Abbrechen';
dialog.choices = DOpus.NewVector(
'Axialis Pure Flat 2013 Toolbar Stock Icons',
'Axialis Ribbon & Toolbar Stock Icons'
);
dialog.selection = 0;
dialog.options(0).label = 'Neuen Lister öffnen'

var dialogResponse = dialog.Show();
if (!dialogResponse) {
    return;
}

var axialisDir     = 'C:\\Users\\My Name\\Documents\\Axialis Librarian\\Icons';
var mainIconDir    = axialisDir + '\\' + dialog.choices(dialog.selection);
var basicIconsDir  = mainIconDir + '\\- Basic Icons -';
var chosenIconsDir = basicIconsDir + '\\_Temp';
var openNewLister  = dialog.options(0).state;

if (openNewLister) {
    clickData.func.command.RunCommand('Go NEW=dualhoriz "' + chosenIconsDir + '" DUALPATH "' + mainIconDir + '"');
} else {
    var isDual = clickData.func.command.IsSet('DUAL=on');
    if (!isDual) {
        clickData.func.command.RunCommand('Set DUAL=horiz,dest');
        //clickData.func.command.SetDestTab(clickData.func.command.results.newtabs(0));
        //clickData.func.command.SetDest(mainIconDir);
        //clickData.func.command.SetDestTab(clickData.func.sourcetab.lister.desttab);
    }
    clickData.func.command.RunCommand('Set SOURCE=left');
    clickData.func.command.RunCommand('Go "' + chosenIconsDir + '"');
    clickData.func.command.RunCommand('Go "' + mainIconDir + '" OPENINDUAL=horiz');
}

var dialog     = DOpus.Dlg();
dialog.window  = DOpus.listers[0];
dialog.icon    = 'question';
dialog.title   = 'Auswahl des Iconsets';
dialog.message = 'Bitte wählen Sie das Iconset aus:';
dialog.choices = DOpus.NewVector();

if (openNewLister) {
    var newLister = clickData.func.command.results.newlisters(0);
    var command = DOpus.NewCommand();
    command.SetSourceTab(newLister.activetab);
    command.SetDestTab(newLister.desttab);
    var enumDirs = new Enumerator(newLister.desttab.dirs);
} else {
    var command  = clickData.func.command;
    //clickData.func.desttab.Update();
    var enumDirs = new Enumerator(clickData.func.desttab.dirs);
}

enumDirs.moveFirst();
while (enumDirs.atEnd() == false) {
    if ('- Basic Icons -' != enumDirs.item().name) {
        dialog.choices.push_back(enumDirs.item().name);
    }
    enumDirs.moveNext();
}
dialog.selection = 0;

var dialogResponse = dialog.Show();
if (!dialogResponse) {
    return;
}

var iconsetDir = mainIconDir + '\\' + dialog.choices(dialog.selection);

command.RunCommand('Go "' + iconsetDir + '" OPENINRIGHT=horiz');
command.RunCommand('Select ALLFILES');
command.RunCommand('Set SOURCE=right');

dialog.title   = 'Starte Kopieren der Axialis-Icons';
dialog.message = 'Ausgesuchte Dateien im oberen Lister (Destination) markiert, übergeordnetes Iconset-Verzeichnis im unteren Lister (Source) geöffnet?';
dialog.choices.clear();
dialog.selection = 0;

dialogResponse = dialog.Show();

if (!dialogResponse) {
    return;
}

var iconsetDirContents = DOpus.FSUtil().ReadDir(iconsetDir, true),
    dirItem,
    subDir,
    iconsetDirLength;
while (!iconsetDirContents.complete) {
    dirItem = iconsetDirContents.Next();
    if (dirItem.is_dir) {
        iconsetDirLength = (iconsetDir + '').length;
        subDir           = dirItem + '';
        subDir           = subDir.substring(iconsetDirLength + 1);
        DOpus.Output(subDir);
        // copy icons using "Select DESTTOSOURCE=noext DESELECTNOMATCH"
    }
}

dialog.title   = 'Skript beendet';
dialog.message = 'Alle Dateien des Iconsets wurden kopiert.';
dialog.buttons = 'OK';
dialog.Show();

}[/code]
Thanks in advance for any help!

Cheers,
Jan

Do you need to open a tab at all? It's not needed just to copy some files. (You don't even need a lister to copy files, if you don't want one.)

Well, maybe not...

I purchase the Axialis stock icon sets when they are published, one of each of the two collections every one or two months. They contain different file formats, different states (normal, "hot", and disabled), and different sizes. Such an icon set consists of some "basic" icons and quite a bunch of modified icons (with small overlays).

It is really difficult not to lose track, so I copy all the basic icons to an additional directory - in all formats and sizes. This is a tiresome task, so I first copy the hand-picked basic icons of a new icon set to a temporary directory and then use the nice "Select DESTTOSOURCE=noext DESELECTNOMATCH" functionality to select just the basic icons of a folder, then I can copy them. This has to be done for every subfolder.

In order to use this, I need a source and a destination tab, don't I? If you have a better idea, please let me know... :wink:

As I said, this works in a new lister as well as an existing lister in dual-display mode, so it's not absolutely necessary to find a solution for this, but I also use this as an "excuse" to learn something about the new scripting interface. I have a working solution for DOpus 10, but it is very, very inelegant and also sometimes had some timing problems, so I chose this for my first steps.

Cheers,
Jan

You don't need to rely on the lister and Select DESTTOSOURCE to select things, you have a programming language which can do the same things (e.g. list the files in two folders, then remove those in both folders from the first list).

That's more effort, of course, but it'll give a nicer result that just does what you want without windows opening and changing your folders and selections.

If you do want to do it the other way, I'm not sure what the answer is, which is why I've not commented on that. I've not had a chance yet to look into it in depth.

Well, sure, but I didn't want to reinvent the wheel while DOpus has just the functionality i need already built-in. If it isn't possible, I'll first complete the version I'm working on (for new listers and for those that are in dual-display mode) and then write a second version that is independent from listers. As I said, I'm also doing this for exercising purposes. :wink:

Well, at least it should be possible to control the new tab that is opened when switching to dual-display mode, so I'd be interested in a solution anyway. If there is no way, please take this as a feature request.

Thanks for your help, Leo! :slight_smile:

Cheers,
Jan

Does Steje's new DO11: Script to open/close related folder tabs automatically do the kind of thing you were trying to get working? It might contain the technique you need.

Thanks for the honorable mention!

In the script that Leo mentions, I'm creating a new command object with DOpus.CreateCommand. You're doing things via clickData.func.command though, but just the same you can try checking your 'clickData.func.command' Results object for any newtabs after you use it to 'Set DUAL'... but in a brief test, I couldn't get that to work either:

[code]@language jscript

function OnClick(clickData)
{
clickData.func.command.RunCommand("Set DUAL=horiz,dest");
if (clickData.func.command.Results.result = 1)
{
DOpus.Output("Got a valid command Result");
}
}[/code]
...from a Script Function button throws:

Error at line 6, position 4 A method was called unexpectedly (0x8000ffff)
And you've otherwise tried accessing Results.newtabs as well and having that throw errors as well - so, not sure.

Thinking this through logically though. I'm not surprised you were getting errors when trying to reference the desttab following your RunCommand. If you think about it, the snapshot of the tab and lister objects at the time you click on the button didn't have a valid desstab object. Try doing something like clickData.func.sourcetab.lister.Update() first, then stay in the lister context to check for an updated desttab object (i.e. clickData.func.sourcetab.lister.desttab) along with trying clickData.func.desttab.

Well, it contains something that I wanted to try, but then I didn't... :unamused:

So thanks for pointing this out to me.

[quote="steje"]TYou're doing things via clickData.func.command though, but just the same you can try checking your 'clickData.func.command' Results object for any newtabs after you use it to 'Set DUAL'... but in a brief test, I couldn't get that to work either:

[code]@language jscript

function OnClick(clickData)
{
clickData.func.command.RunCommand("Set DUAL=horiz,dest");
if (clickData.func.command.Results.result = 1)
{
DOpus.Output("Got a valid command Result");
}
}[/code]
...from a Script Function button throws:

Error at line 6, position 4 A method was called unexpectedly (0x8000ffff)
And you've otherwise tried accessing Results.newtabs as well and having that throw errors as well - so, not sure.[/quote]
Well, the error occurs because in

if (clickData.func.command.Results.result = 1)

you used "=" instead of "==", I guess. I tried

[code]@language jscript

function OnClick(clickData)
{
clickData.func.command.RunCommand('Set DUAL=horiz,dest');
if (clickData.func.command.results.result == 1) {
DOpus.Output('Got a valid command Result');
}
}[/code]
and it worked. But when I try to use the new tab like this:

[code]@language jscript

function OnClick(clickData)
{
clickData.func.command.RunCommand('Set DUAL=horiz,dest');
if (clickData.func.command.results.result == 1) {
DOpus.Output('Got a valid command Result');
clickData.func.command.SetDestTab(clickData.func.command.results.newtabs(0));
}
}[/code]
I get the error message "Index out of bounds" (or something like that - as I said, I'm translating from German).

When I looked at your code as Leo suggested, I saw that you used something similar that obviously worked in your case, so I tried it:

[code]@language jscript

function OnClick(clickData)
{
clickData.func.command.RunCommand('Go "C:\Windows" NEWTAB=nofocus OPENINDUAL=horiz');
if (clickData.func.command.results.result == 1) {
DOpus.Output('Got a valid command Result');
clickData.func.command.SetDestTab(clickData.func.command.results.newtabs(0));
}
}[/code]
And in this case, there's no error message. I didn't have the time to work on it any further, but this should help me to solve my problem.

Yes, thanks for your help; I'll experiment some more with this. But as the code I provided above shows, there seems to be a difference in the way the dual display is opened. While "Go path NEWTAB OPENINDUAL" opens a new tab explicitly, which results in a new tab in the Results object, "Set DUAL=on" does this implicitly, and there's no new tab in the Result object, although I had expected that. Maybe this could be changed in later builds.

Cheers,
Jan

Woops, yeah I guess I copied that block of code out of a vbscript and just added semi-colons :blush:.

Yes, I had also previously found there to be some cases where the Results object didn't have some of what you might think would be in there depending on the command run. But I suspect you are right and they are not filling in the newtabs collection object with whatever default tab gets opened from running a 'Set DUAL' command. I agree that GPSoft should consider changing it so that other commands than explicit 'Go' commands populate that newtabs collection... 'Set DUAL' is one, others might include the 'Prefs' commands for layout and styles, etc.

I think the set dual thing has been fixed for the next update, although I haven't confirmed it on my own machine.

■■■■ happens. :wink: (LOL, what a nice automatic replacement for "you-know-what happens"! :grin: Is this phpBB standard?)

At least I don't see a reason why this should be avoided "by design".

That would be great!

Many thanks to both of you! :slight_smile:

Cheers,
Jan