Command: FileGroupNavigation - Navigate between filegroups (previous/next)

TL;DR
A script/buttons for navigating through filegroups.
It allows to

  • set the direction of navigation (previous, next)
  • set the stepsize (how many groups to skip, default = 1)
  • collapse every other group so you just see the group you navigated to
  • loop the navigation (starting at the beginning when navigating over the end and vice versa)

Usecase
I often work with grouped files (by filename which represents the date, so one group per day). When going through the folder contents the groups help to get an overview, but finding a certain date can become difficult if there are many groups. This script helps me stepping through the groups, even more helpful is that it can be configured to collapse all other groups except the currently focused one.

Usage
The command is called

FileGroupNavigation

so the basic command for navigating to the next group is

FileGroupNavigation NAVIGATE next

and to the previous group

FileGroupNavigation NAVIGATE previous

Further parameters are the stepsize, which defines how many groups you want to go forward/backward (default is next; so going to the next or previous group). Use positive numbers otherwise it probably will flip the behaviour of "next/previous".

FileGroupNavigation NAVIGATE next STEP=2

for going to the after next group.

And the last parameter is for collapsing the other groups so just the focused group is expanded and you can concentrate on its content. Default is off (so not collapsing others).

FileGroupNavigation NAVIGATE next COLLAPSEOTHERS

Resources/Installation
Installation Guide

Version 1.0 - 18.06.2021

Button for going to previous group (@disablenosel because the next group is calculated from the selected file). Copy to menu when in customize mode

<?xml version="1.0"?>
<button backcol="none" display="icon" label_pos="right" textcol="none">
	<label>Previous Group</label>
	<icon1>#viewerprev</icon1>
	<function type="normal">
		<instruction>@disablenosel </instruction>
		<instruction>FileGroupNavigation NAVIGATE PREVIOUS COLLAPSEOTHERS</instruction>
	</function>
</button>

And a button for going to the next group

<?xml version="1.0"?>
<button backcol="none" display="icon" label_pos="right" textcol="none">
	<label>Next Group</label>
	<icon1>#viewernext</icon1>
	<function type="normal">
		<instruction>@disablenosel </instruction>
		<instruction>FileGroupNavigation NAVIGATE NEXT COLLAPSEOTHERS</instruction>
	</function>
</button>

Code

// Command.FileGroupNavigation
// (c) 2021 Felix

// This is a script for Directory Opus.
// See https://www.gpsoft.com.au/DScripts/redirect.asp?page=scripts for development information.



// Called by Directory Opus to initialize the script
function OnInit(initData)
{
	initData.name = "Command.FileGroupNavigation";
	initData.version = "1.1 (2021.06.22)";
	initData.copyright = "(c) 2021 Felix";
	initData.url = "https://resource.dopus.com/t/command-filegroupnavigation-navigate-in-filegroups-previous-next/38735";
	initData.desc = "Navigating between filegroups";
	initData.default_enable = true;
	initData.min_version = "12.0";

	var cmd = initData.AddCommand();
	cmd.name = "FileGroupNavigation";
	cmd.method = "OnFileGroupNavigation";
	cmd.desc = "Navigating between filegroups";
	cmd.label = "OnFileGroupNavigation";
	//https://www.gpsoft.com.au/help/opus12/index.html#!Documents/Argument_Types.htm
	//https://www.gpsoft.com.au/help/opus12/index.html#!Documents/Internal_Command_Arguments.htm
	cmd.template = "NAVIGATE/K[previous,next],STEP/N,COLLAPSEOTHERS/S";
	cmd.hide = false;
	cmd.icon = "script";
}


// Implement the OnFileGroupNavigation command
function OnFileGroupNavigation(scriptCmdData)
{
	var direction = 0; //how many groups to skip, default is +-1
	var collapseOthers = false; //collapse non focused groups
	var stepSize = 1;
	
	var args = scriptCmdData.func.args;
	var navigateArg = args.NAVIGATE;
	var stepArg = args.STEP;
	var collapseArg = args.COLLAPSEOTHERS;
	if(navigateArg)
    {
		navigateArg = navigateArg.toLowerCase();
		if(navigateArg == "previous") 
			direction = -1;
		else if(navigateArg == "next")
			direction = 1;
	}
	if(stepArg)
	{
		try
		{
			stepSize = parseInt(stepArg);
		}
		catch(e) { stepSize = 1; Log(e); }
	}
	if(collapseArg)
	{
		collapseOthers = true;
	}
	if(direction != 0)
		GroupNavigation(scriptCmdData.func, direction * stepSize, collapseOthers);
}

function GroupNavigation(func, direction, collapseOthers)
{
	var tab = func.sourcetab;
	tab.Update();
	
	var groups = tab.filegroups;
	if(groups.count > 0)
	{
		var focusedItem = tab.GetFocusItem();
		var containinigGroup = focusedItem.filegroup;
		if(containinigGroup != null)
		{				
			var groupIndex = GetGroupIndex(containinigGroup, groups);
			if(groupIndex > -1)
			{
				var nextGroupResult =  GetNextGroup(groups, groupIndex, direction);
				var nextGroup = nextGroupResult.group;
				var firstGroupItem = nextGroup.members(0); //GetNextGroup assures the group contains elements
				
				Log("File: " + focusedItem + ", Group: " + containinigGroup + " [" + groupIndex + "] => Nextgroup: " + nextGroup + " [" + nextGroupResult.index + "], Item: " + firstGroupItem);

				var cmd = func.command;
				cmd.RunCommand("SELECT NONE");
				ClearCommand(cmd);
				tab.Update();

				cmd.AddFile(firstGroupItem);
				cmd.RunCommand("Select FROMSCRIPT EXACT MAKEVISIBLE SETFOCUS");		
				if(collapseOthers)
				{
					ClearCommand(cmd);

					cmd.AddLine("Go GROUPCOLLAPSE *");
					cmd.Run();
				}
				ClearCommand(cmd);
				cmd.RunCommand("Go GROUPEXPAND \"" + nextGroup + "\""); //Make sure it is definitly expanded
				tab.Update();
			}
		}
	}
}

//clear the command for reuse
function ClearCommand(cmd)
{
	cmd.Clear();
	cmd.ClearFailed();
	cmd.ClearFiles();
}

//Get the index of the current group of the tabs group
function GetGroupIndex(group, groups)
{
	var index = 0;
	
	for (var groupEnum = new Enumerator(groups); !groupEnum.atEnd(); groupEnum.moveNext())
	{
		var groupItem = groupEnum.item();
		if(groupItem.id === group.id)
			return index;
		index++;
	}
	return -1; // not found
}

//get the next group according to stepsize (default 1). Direction (forward/backward) is defined by the sign
function GetNextGroup(groups, currentIndex, navigationDirection)
{
	var index = mod((currentIndex + navigationDirection), groups.count);
	var group = groups(index);
	while(group.count == 0)
	{
		index = mod((index + navigationDirection), groups.count);
		group = groups(index);
	}
	return {group: group, index: index};
}

//https://stackoverflow.com/questions/4467539/javascript-modulo-gives-a-negative-result-for-negative-numbers
//Allowing negative mod for looping in arrays
function mod(n, m) 
{
  return ((n % m) + m) % m;
}

function Log(msg)
{
	DOpus.output(String(msg));
}

Version History

3 Likes