// 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.0 (2021.06.18)"; 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 nextGroup = GetNextGroup(groups, groupIndex, direction); var firstGroupItem = nextGroup.members(0); //GetNextGroup assures the group contains elements 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; } //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)); }