Buttons conditional upon folder content

2024年3月1日

demonstrate the concept of conditional buttons, the visibility of which depends on the content of the current folder.

This requirement has been discussed many times on this forum. Yet I don’t see a complete working example.

Native solution: Content Type Formats

Directory Opus can detect content type by itself. You can create a file type group named “Latex files”, and then edit format.

In Edit Format, you can display a toobar specific for this content type. In this case, when 1% of files end with *.tex, DO dislays an additional toolbar named “Latex”. In this Latex toolbar, you can add Latex specific buttons. Nice, hah?

Nevertheless, the native content type formats are not additive, meaning a folder cannot be both Latex format and git format. DO cannot add a conditional Latex toolbar, and add another conditional git toolbar. One only conditional toolbar will be available.

The second drawback of this approach is that it doesn’t detect subfolders. Content Type Format Detection doesn’t check if there is a subfolder named .git, hence unable to apply a “git” format and add a “git” toolbar.

Buttons visible for git repositories

The gist is that, the button “Remote Origin” shows if the current folder is managed by git, i.e., there is a sub folder named .git. The button disappears elsewhere to avoid cluttering the toobar.

As suggested in some places, the visibility of the button is controlled by reading a variable isInGit; another script git-repo-detector.js runs the dirty content detection and sets the variable.

<?xml version="1.0"?>
<button backcol="none" display="both" label_pos="right" textcol="none">
	<label>Remote Origin</label>
	<icon1>/hostpictures/icons/Git-Icon-1788C.ico,0</icon1>
	<function type="batch">
		<instruction>@hideif:!$tab:isInGit</instruction>
		<instruction />
		<instruction>for /f &quot;tokens=*&quot; %%a in (&apos;git  -C {sourcepath} remote get-url origin&apos;) do set url=%%a</instruction>
		<instruction>start &quot;&quot; &quot;%url%&quot;</instruction>
	</function>
</button>

Paste the above XML code into the toolbar.[1]

Then save the following JScript code in git-repo-detector.js and install the script in DO.

// JScript

function OnInit(data) {
	data.name = "Git repo detector";
	data.desc = "Check if the current folder is managed by Git";
	data.version = "0.1";
	data.copyright = "by gqqnbig";
}

function OnAfterFolderChange(data) {
	if (!data.result)
		return;

	var tab = data.tab;
	//DOpus.Output(tab.path);
	// Check at most 3 levels up
	isInGit = DOpus.FSUtil().exists(tab.path + "/.git") ||
              DOpus.FSUtil().exists(tab.path + "/../.git") ||
              DOpus.FSUtil().exists(tab.path + "/../../.git");

	// Reduce the frequency of updating button states.
	if (tab.Vars.Exists("isInGit") && isInGit) {
	} else if (!tab.Vars.Exists("isInGit") && isInGit) {
		tab.vars.Set("isInGit", true);
		DOpus.Create.Command.UpdateToggle();
	} else if (tab.Vars.Exists("isInGit") && !isInGit) {
		tab.vars.Delete("isInGit");
		DOpus.Create.Command.UpdateToggle();
	} else {
		// !tab.Vars.Exists("isInGit") && !isInGit
		// do nothing
	}


	//DOpus.Output(isInGit);
}

Buttons visible for LaTex folders

The following XML and JScript demonstrate a button that is only visible if the current folder has at least one *.tex file. In this case, the button opens the Latex documentation index page.

<?xml version="1.0"?>
<button backcol="none" display="label" label_pos="right" textcol="none">
	<label>Latex Help</label>
	<icon1>#newcommand</icon1>
	<function type="normal">
		<instruction>@hideif:!$tab:hasTex</instruction>
		<instruction />
		<instruction>D:\texlive23\doc.html</instruction>
	</function>
</button>

Then save the following JScript code in tex-repo-detector.js and install the script in DO.

// JScript

function OnInit(data) {
	data.name = "Tex repo detector";
	data.desc = "Check if the current folder has latex files";
	data.version = "0.1";
	data.copyright = "by gqqnbig";
}

function OnAfterFolderChange(data) {
	if (!data.result)
		return;

	var tab = data.tab;


	// DOpus.Output(tab.path);
	var hasTex = hasTexFiles(tab.path);
	DOpus.Output(hasTex);

	// Reduce the frequency of updating button states.
	if (tab.Vars.Exists("hasTex") && hasTex) {
	} else if (!tab.Vars.Exists("hasTex") && hasTex) {
		tab.vars.Set("hasTex", true);
		DOpus.Create.Command.UpdateToggle();
	} else if (tab.Vars.Exists("hasTex") && !hasTex) {
		tab.vars.Delete("hasTex");
		DOpus.Create.Command.UpdateToggle();
	} else {
		// !tab.Vars.Exists("isInGit") && !isInGit
		// do nothing
	}


	//DOpus.Output(hasTex);
}

function hasTexFiles(path) {
	var wild = DOpus.FSUtil().NewWild("*.tex", "f");
	var files = DOpus.FSUtil().ReadDir(path);
	while (!files.complete) {
		var folderItem = files.Next();
		if (folderItem.is_dir)
			continue;

		if (wild.Match(folderItem.name))
			return true;
	}
	return false;
}

参考资料

  1. Leo. How to use buttons and scripts from this forum. . 2024-02-01 [2024-03-02].