Toolbar STATE=Center and Folder Toolbar Conflict

I have a particular folder for which I have a dedicated toolbar. I want the toolbar to:

  1. appear at a particular place in the lister depending on two conditions:
  • Is it dual file display?
    *If yes, then place vertically between the two file displays
    *If no, then place vertically to the right of the file display
  • Is the view pane open?
    *If yes AND in dual file display, then place the toolbar vertically between the two file displays
    *If yes AND is single file display, then place the toolbar vertically between the single file display and the view pane (i.e. LEFT of view pane)
  1. Disappear once the particular folder is closed

While I can assign a toolbar to the particular folder via Preferences > Toolbars > Folder Toolbars, I cannot dictate the toolbar's position based on the above conditions as the assignable positions are limited to Top, Bottom, Left, and Right.

I have tried to overcome this by assigning a toolbar set, which cannot be assigned a position here because it is saved as a set, but get the same result.

I can use a button with the following syntax to position and toggle the toolbars while opening the folder:

@if:Set Dual=On 
Toolbar "Toolbar" STATE=center LINE=0 TOGGLE
@if:else
Toolbar "Toolbar Name" STATE=viewpane LINE=0 TOGGLE
@if:common
Go "Folder Path" NEWTAB=findexisting OPENINLEFT

However, the TOGGLE action on both lines above conflicts with the Preferences > Toolbars > Folder Toolbars setting for that folder and does not close the folder.

Removing the TOGGLE action on both lines above allows the toolbar to close when the folder is closed. However, when the view pane is open with a single file, the toolbar appears to the right of the view pane, not the left as expected with the STATE=viewpane setting.

How do I accomplish both the toolbar position based on conditions and toolbar open/close requirements with the folder?

An OnAfterFolderChange event could handle 1+2 at once. You'd only need a regular toolbar, not a folder-specific toolbar.

Scripting is not exactly in my wheelhouse, but will take a look. Any examples you could point me to? Thanks!

Check this script if it gets the logic right.

function OnInit(initData) {
    initData.name = 'ToggleToolbar';
    initData.version = '2024-08-25';
    initData.url = 'https://resource.dopus.com/t/toolbar-state-center-and-folder-toolbar-conflict/52475';
    initData.desc = 'Toggle toolbar for a folder';
    initData.default_enable = true;
    initData.min_version = '12.0';
}

var fsu = DOpus.FSUtil();
var theFolder = String(fsu.Resolve('/dopusdata'));
var theToolbar = 'theToolbar';

function OnAfterFolderChange(afterFolderChangeData) {
    if (!afterFolderChangeData.result) return;
    var tab = afterFolderChangeData.tab;
    if (!tab) return;
    if (!tab.path) return;

    var cmd = DOpus.Create().Command();
    cmd.SetSourceTab(tab);

    if (String(tab.path) != theFolder && String(tab.lister.desttab.path) != theFolder) {
        cmd.RunCommand('Toolbar ' +
            ' NAME="' + theToolbar + '"' +
            ' CLOSE');
    } else {
        if (tab.lister.dual) {
            cmd.RunCommand('Toolbar ' +
                ' NAME="' + theToolbar + '"' +
                ' STATE=center' +
                ' LINE=0');
        } else {
            cmd.RunCommand('Toolbar ' +
                ' NAME="' + theToolbar + '"' +
                ' STATE=viewpane ' +
                ' LINE=0');
        }
    }
}

EventToggleToolbar.js.txt

Thanks for this!

It works when opening the folder, either via an existing tab or new tab. When closing the folder opened in a new tab, the toolbar remains open.

Would this particular scenario require OnCloseTab, or is there something more to be done in the OnAfterFolderChange function?

I see... Try appending this OnActivateTab event:

function OnActivateTab(activateTabData) {
    var tab = activateTabData.newtab;
    if (!tab) return;
    if (!tab.path) return;

    if (String(tab.path) != theFolder && String(tab.lister.desttab.path) != theFolder) {
        var cmd = DOpus.Create().Command();
        cmd.SetSourceTab(tab);
        cmd.RunCommand('Toolbar ' +
            ' NAME="' + theToolbar + '"' +
            ' CLOSE');
    }
}
1 Like

Thank you! I owe you a beverage of your choice... :wink:

1 Like

Happy toggling and cheers! :beers:

2 Likes

@lxp @Chuck
Thankyou ! Very nicely done.
I'll be using this.

One limitation I'm trying to resolve is subfolders for the identified folder. Entering a subfolder closes the toolbar. I would prefer it remain open for subfolders, as well.

Trying to use startsWith() to identify the start of the path, but getting the following error at line 25 where startsWith() is used:

Error at line 25, position 2
Object doesn't support this property or method (0x800a01b6)

The code:

function OnInit(initData) {
    initData.name = 'ToggleToolbar2';
    initData.version = '2024-08-25';
    initData.url = 'https://resource.dopus.com/t/toolbar-state-center-and-folder-toolbar-conflict/52475';
    initData.desc = 'Toggle toolbar for a folder';
    initData.default_enable = true;
    initData.min_version = '12.0';
}

var fsu = DOpus.FSUtil();
var theFolder = String(fsu.Resolve('H:\\Library - Stuff'));
var theToolbar = 'Stuff';

function OnAfterFolderChange(afterFolderChangeData) {
    if (!afterFolderChangeData.result) return;
    var tab = afterFolderChangeData.tab;
    if (!tab) return;
    if (!tab.path) return;

    var cmd = DOpus.Create().Command();
    cmd.SetSourceTab(tab);
	var tabString = String(tab.path);
	
	if (tabString.startsWith("H:\\Library - Stuff")) {    //ERROR OCCURS HERE
		if (tab.lister.dual) {
            cmd.RunCommand('Toolbar ' +
                ' NAME="' + theToolbar + '"' +
                ' STATE=center' +
                ' LINE=0');
        } else {
            cmd.RunCommand('Toolbar ' +
                ' NAME="' + theToolbar + '"' +
                ' STATE=viewpane ' +
                ' LINE=0');
        }
	} else {
		cmd.RunCommand('Toolbar ' +
            ' NAME="' + theToolbar + '"' +
            ' CLOSE');
    }
}

Any ideas?

startsWith is one of those string methods that is not implemented in JScript.
Quick workaround : use match(regexp)

EDIT : in your example, that would probably be like :

if (tabString.match(/^H:\\Library - Stuff/))

FSUtil.ComparePath is usually the best way for a script to check if one path is the same or a child of another.

Thanks @PassThePeas and @Leo for the suggestions! I have the ComparePath approach working, but want to fine-tune a bit before posting.

1 Like

@Chuck
I have it working here too.
Tab switching could use a refresh and there are a few other small problems to work out.

function OnInit(initData) {
    initData.name = 'ToggleToolbar';
    initData.version = '2024-08-31';
    initData.url = 'https://resource.dopus.com/t/toolbar-state-center-and-folder-toolbar-conflict/52475';
    initData.desc = 'Toggle toolbar for a folder';
    initData.default_enable = true;
    initData.min_version = '12.0';
}

var fsu = DOpus.FSUtil();
var theFolder = String(fsu.Resolve('/dopusdata'));
var theToolbar = 'Drives';

function OnAfterFolderChange(afterFolderChangeData) {
    if (!afterFolderChangeData.result) return;
    var tab = afterFolderChangeData.tab;
    if (!tab) return;
    if (!tab.path) return;

    var cmd = DOpus.Create().Command();
    cmd.SetSourceTab(tab);

      if (!fsu.ComparePath(String(tab.path),theFolder,"p") && !fsu.ComparePath(String(tab.lister.desttab.path),theFolder,"p")) {
        cmd.RunCommand('Toolbar ' +
            ' NAME="' + theToolbar + '"' +
            ' CLOSE');
    } else {
        if (tab.lister.dual) {
            cmd.RunCommand('Toolbar ' +
                ' NAME="' + theToolbar + '"' +
                ' STATE=center' +
                ' LINE=0');
        } else {
            cmd.RunCommand('Toolbar ' +
                ' NAME="' + theToolbar + '"' +
                ' STATE=viewpane ' +
                ' LINE=0');
        }
    }
}
function OnActivateTab(activateTabData) {
    var tab = activateTabData.newtab;
    if (!tab) return;
    if (!tab.path) return;

      if (!fsu.ComparePath(String(tab.path),theFolder,"p") && !fsu.ComparePath(String(tab.lister.desttab.path),theFolder,"p")) {
        var cmd = DOpus.Create().Command();
        cmd.SetSourceTab(tab);
        cmd.RunCommand('Toolbar ' +
            ' NAME="' + theToolbar + '"' +
            ' CLOSE');
    }
}

I have only had it working for 15 minutes.
Ooops, I left it hard coded for the Drives Toolbar.

That's very similar to what I have, along with the config piece to address the hard-coding concern:

function OnInit(initData) {
    initData.name = 'ToggleToolbars';
    initData.version = '2024-08-30';
    initData.url = 'https://resource.dopus.com/t/toolbar-state-center-and-folder-toolbar-conflict/52475';
    initData.desc = 'Toggle toolbar for a folder';
    initData.default_enable = true;
    initData.min_version = '12.0';
	initData.config_desc = DOpus.Create.Map();
	initData.Config["Folder 1"] = "";
	initData.config_desc("Folder 1") = "Enter the target folder";
	initData.Config["Toolbar 1"] = "";
	initData.config_desc("Toolbar 1") = "Enter the target toolbar";
}

var fsu = DOpus.FSUtil();
var folder1 = Script.Config["Folder 1"];
var toolbar1 = Script.Config["Toolbar 1"]; 

function OnAfterFolderChange(afterFolderChangeData) {
    if (!afterFolderChangeData.result) return;
    var tab = afterFolderChangeData.tab;
    if (!tab) return;
    if (!tab.path) return;

    var cmd = DOpus.Create().Command();
    cmd.SetSourceTab(tab);
	var tabString = String(tab.path);
	
	if (fsu.ComparePath(tabString, folder1, "p")) {
		if (tab.lister.dual) {
            cmd.RunCommand('Toolbar ' +
                ' NAME="' + toolbar1 + '"' +
                ' STATE=center' +
                ' LINE=0');
        } else {
            cmd.RunCommand('Toolbar ' +
                ' NAME="' + toolbar1 + '"' +
                ' STATE=viewpane ' +
                ' LINE=0');
        }
	} else {
		cmd.RunCommand('Toolbar ' +
            ' NAME="' + toolbar1 + '"' +
            ' CLOSE');
    }
}
	
function OnActivateTab(activateTabData) {
    var tab = activateTabData.newtab;
    if (!tab) return;
    if (!tab.path) return;

if (fsu.ComparePath(tabString, folder1, "p")) {
		if (tab.lister.dual) {
            cmd.RunCommand('Toolbar ' +
                ' NAME="' + toolbar1 + '"' +
                ' STATE=center' +
                ' LINE=0');
        } else {
            cmd.RunCommand('Toolbar ' +
                ' NAME="' + toolbar1 + '"' +
                ' STATE=viewpane ' +
                ' LINE=0');
        }
	} else {
		cmd.RunCommand('Toolbar ' +
            ' NAME="' + toolbar1 + '"' +
            ' CLOSE');
    }
}

I do see an issue with mine in dual file display when opening a new tab in the same file display as the coded folder/toolbar. The toolbar closes when setting focus on the new tab, but does not reopen when returning focus to original tab.

Need to work that out.

I think this works:

function OnInit(initData) {
    initData.name = 'ToggleToolbarNew';
    initData.version = '2024-08-30';
    initData.url = 'https://resource.dopus.com/t/toolbar-state-center-and-folder-toolbar-conflict/52475';
    initData.desc = 'Toggle toolbar for a folder';
    initData.default_enable = true;
    initData.min_version = '12.0';
	initData.config_desc = DOpus.Create.Map();
	initData.Config["Folder"] = "";
	initData.config_desc("Folder") = "Enter the target folder";
	initData.Config["Toolbar"] = "";
	initData.config_desc("Toolbar") = "Enter the target toolbar";
}

var fsu = DOpus.FSUtil();
var theFolder = Script.Config["Folder"];
var theToolbar = Script.Config["Toolbar"]; 
var tab;
var cmd = DOpus.Create().Command();

function ToggleToolbar(lister) {
	tab = lister.activetab;
	cmd.SetSourceTab(tab);
	if (!tab) return;
    if (!tab.path) return;
		
	if (!fsu.ComparePath(String(tab.lister.activetab.path),theFolder,"p") && !fsu.ComparePath(String(tab.lister.desttab.path),theFolder,"p")) {
		cmd.RunCommand('Toolbar ' + ' NAME="' + theToolbar + '"' + ' CLOSE');
	} else {
		if (tab.lister.dual) {
            cmd.RunCommand('Toolbar ' + ' NAME="' + theToolbar + '"' + ' STATE=center' + ' LINE=0');
        } else {
            cmd.RunCommand('Toolbar ' + ' NAME="' + theToolbar + '"' + ' STATE=viewpane ' + ' LINE=0');	
    	}
	}	
}

function OnActivateTab(activateTabData) {
	ToggleToolbar(activateTabData.newtab.lister);
}

function OnSourceDestChange(sourceDestChangeData) {
	ToggleToolbar(sourceDestChangeData.tab.lister);
}

function OnAfterFolderChange(afterFolderChangeData) {
	ToggleToolbar(afterFolderChangeData.tab.lister);
}

@Chuck
Thanks again. This script is working better now and the code looks much cleaner.

There is still a problem with closing either file display in a dual display lister.
If the viewpane is open on the right, the toolbar ends up to the right of the viewpane.
Go back to dual display works fine though.

There is a similar problem with a single display lister with the viewpane open on the right.
Going to dual display does not change the position of the toolbar to center.

I tried finding a workaround for this, but I'm not familiar enough with the scripting yet.
I'm only guessing hacks, and they are wrong answers.

@David I validated some issues, one intermittent, and have revised the code to the best of my limited ability. There still exist three key scenarios in which the script will not position the toolbar as expected:

  1. Dual file display, close one file display, open viewer pane: toolbar stays to right of viewer pane

  1. Dual file display, open viewer pane, close one file display, go back to dual display: toolbar stays to left of viewer pane instead of center of dual file displays

  1. Single file display, open viewer pane: toolbar stays to right of viewer pane instead of moving between file display and viewer pane

@lxp @Leo @Jon
Seems like there may be a problem with respecting STATE=viewpane. Would appreciate your feedback. Here's the code:

function OnInit(initData) {
    initData.name = 'ToggleToolbarNew';
    initData.version = '2024-08-30';
    initData.url = 'https://resource.dopus.com/t/toolbar-state-center-and-folder-toolbar-conflict/52475';
    initData.desc = 'Toggle toolbar for a folder';
    initData.default_enable = true;
    initData.min_version = '12.0';
	initData.config_desc = DOpus.Create.Map();
	initData.Config["Folder"] = "";
	initData.config_desc("Folder") = "Enter the target folder";
	initData.Config["Toolbar"] = "";
	initData.config_desc("Toolbar") = "Enter the target toolbar";
}

var fsu = DOpus.FSUtil();
var theFolder = Script.Config["Folder"];
var theToolbar = Script.Config["Toolbar"]; 
var tab;
var cmd = DOpus.Create().Command();

function ToggleToolbar(lister) {
	tab = lister.activetab;
	cmd.SetSourceTab(tab);
	if (!tab) return;
 	if (!tab.path) return;

	if (tab.lister.dual == 1) {
		DOpus.Output('Dual (=1) = ' + tab.lister.dual);
		DOpus.Output('Viewpane = ' + tab.lister.viewpane);
		if (fsu.ComparePath(String(tab.lister.activetab.path),theFolder,"p") || fsu.ComparePath(String(tab.lister.desttab.path),theFolder,"p")) {
	            cmd.RunCommand('Toolbar ' + ' NAME="' + theToolbar + '"' + ' STATE=center' + ' LINE=0');
	        } else {      
				cmd.RunCommand('Toolbar ' + ' NAME="' + theToolbar + '"' + ' CLOSE');
			}
		} else if (tab.lister.dual == 2) {
			DOpus.Output('Dual (=2) = ' + tab.lister.dual);	
			if (fsu.ComparePath(String(tab.lister.activetab.path),theFolder,"p") || fsu.ComparePath(String(tab.lister.desttab.path),theFolder,"p")) {
	    	        cmd.RunCommand('Toolbar ' + ' NAME="' + theToolbar + '"' + ' STATE=center' + ' LINE=0');
	        	} else {      
					cmd.RunCommand('Toolbar ' + ' NAME="' + theToolbar + '"' + ' CLOSE');
				}
		} else {
			DOpus.Output('Dual (=0) = ' + tab.lister.dual);
			if (fsu.ComparePath(String(tab.lister.activetab.path),theFolder,"p") && (tab.lister.viewpane == 0)) {
				DOpus.Output('Viewpane (=0) = ' + tab.lister.viewpane);	
				cmd.RunCommand('Toolbar ' + ' NAME="' + theToolbar + '"' + ' STATE=right' + ' LINE=0');
			} else if (fsu.ComparePath(String(tab.lister.activetab.path),theFolder,"p") && (tab.lister.viewpane == 1)) {
				DOpus.Output('Viewpane (=1) = ' + tab.lister.viewpane);
				cmd.RunCommand('Toolbar ' + ' NAME="' + theToolbar + '"' + ' STATE=viewpane' + ' LINE=0');
			} else if (fsu.ComparePath(String(tab.lister.activetab.path),theFolder,"p") && (tab.lister.viewpane == 2)) {
				DOpus.Output('Viewpane (=2) = ' + tab.lister.viewpane);
				cmd.RunCommand('Toolbar ' + ' NAME="' + theToolbar + '"' + ' STATE=viewpane' + ' LINE=0');
			} else {
				cmd.RunCommand('Toolbar ' + ' NAME="' + theToolbar + '"' + ' CLOSE');					
		}
	}		
}
		
//function OnActivateTab(activateTabData) {
//	DOpus.Output('OnActivateTab');	
//	ToggleToolbar(activateTabData.newtab.lister);
//}

//function OnSourceDestChange(sourceDestChangeData) {
//	DOpus.Output('OnSourceDestChange');	
//	ToggleToolbar(sourceDestChangeData.tab.lister);
//}

function OnAfterFolderChange(afterFolderChangeData) {
	DOpus.Output('OnAfterFolderChange');	
	ToggleToolbar(afterFolderChangeData.tab.lister);
}

//function OnCloseTab(closeTabData) {
//	DOpus.Output('OnCloseTab');	
//	ToggleToolbar(closeTabData.tab.lister);
//}

function OnOpenTab(openTabData) {
	DOpus.Output('OnOpenTab');	
	ToggleToolbar(openTabData.tab.lister);
}

//function OnOpenLister(openListerData) {
//	DOpus.Output('OnOpenLister');	
//	ToggleToolbar(openListerData.lister);
//}

function OnListerUIChange(listerUIChangeData) {
	DOpus.Output('OnListerUIChange = ' + listerUIChangeData.change);	
	ToggleToolbar(listerUIChangeData.lister);
}

//function OnStyleSelected(StyleSelectedData) {
//	DOpus.Output('OnStyleSelected');	
//	ToggleToolbar(styleSelectedData.lister);
//}	

function OnTabClick(tabClickData) {
	DOpus.Output('OnTabClick');	
	ToggleToolbar(tabClickData.tab.lister);
}

Yes, feels a bit like that. But this wasn't always the case in my testing. It could also be a timing problem because of the numerous events to which the script reacts. You could zone in on the issue by adding NOSCRIPT to the commands and rejecting events by inserting e.g.

if (listerUIChangeData.change == 'toolbars') return;

Thanks for the suggestion. Will give it a go.