Viewer Select - Make file display track standalone viewer

No longer needed for Directory Opus 13 and above

If you're using Directory Opus 13, don't use this script.

Instead, use the built-in Lister-Linked Viewer feature.

Lister-Linked Viewers can be toggled more easily than this script. They also have the option of linking both ways, so selections in the file display change the viewer, and changing images in the viewer changes what's selected in the file display.


Overview

This script add-in makes it so the file display will track the selected file in the standalone image viewer.

This only affects the folder tab which is active when the viewer opens, and only if that tab stays in (or returns to) the same folder. So it should not get in the way of using multiple tabs, or in situations where you move into other folders.

Here's a quick video (no audio) showing the script in action:


Installation

Requires Directory Opus 12.2 or above.
Works best with Directory Opus 12.22.3 or above.

  • Download: Viewer_Select.js.txt (3.8 KB) (v1.4 04/Dec/2020)
  • Open Settings > Preferences / Toolbars / Scripts.
  • Drag Viewer_Select.js.txt to the list of scripts.

Toggling The Script

If you don't always want the script to be active, you can add a toggle button on your viewer toolbar (or a hotkey, and so on). Here's how to create a toolbar toggle button:

This aspect requires Directory Opus 12.22.3 or above.

  • Open the viewer, right-click an empty space on the toolbar at the top, and choose Customize.
  • Right-click an empty space again and choose New > New Button.
  • Set the Image and Label to whatever you want.
  • Click Advanced to put the button editor into multi-line mode.
  • Paste this as the command:
    @toggle:invert
    Prefs SCRIPTDISABLE="Viewer_Select.js*"
    
  • Click OK in the button editor and then OK in the Customize dialog to save the change and leave toobar editing mode.

History

1.4 (04/Dec/2020):

  • If Checkbox Mode is turned on in the file display, the checkbox states will be left alone and the actual selection will change instead. Now you can check/uncheck items while keeping the current item in sync with the viewer.
  • This requires Opus 12.22.3 or above, but the script still works in older versions, just with the old behavior.

1.3 (09/Jan/2017):

  • Changed how the script works so that it is more reliable, and in particular works with files within archives.
  • These changes were also required to ensure the script still works with Opus 12.3.3 and above. Old versions of the script inadvertently depended on things which are being tidied up in the next Opus update.

1.2 (22/Dec/2016):

  • Uses viewer.parenttab property introduced in Opus 12.2 as a better way to find the folder tab.
  • Slightly less overhead.
  • Fixed script log error message when viewing files in archives. (May need an Opus code-change to make the script work fully there.)

1.0 (06/Sep/2016):

  • Initial version.

Script Code (JScript)

The script code from the download above is reproduced below. This is for people browsing the forum for scripting techniques. You do not need to care about this code if you just want to use the script.

// Viewer Select
// (c) 2016-2020 Leo Davidson

// This is a script for Directory Opus.
// See https://www.gpsoft.com.au/DScripts/redirect.asp?page=scripts for development information.
// See https://resource.dopus.com/t/viewer-select-make-file-display-track-standalone-viewer/23320/1 for information about this specific script.

// Called by Directory Opus to initialize the script
function OnInit(initData)
{
	initData.name = "Viewer Select";
	initData.version = "1.4";
	initData.copyright = "(c) 2016-2020 Leo Davidson";
	initData.url = "https://resource.dopus.com/t/viewer-select-make-file-display-track-standalone-viewer/23320/1";
	initData.desc = "The file display selection will track the standalone viewer's current file.";
	initData.default_enable = true;
	initData.min_version = "12.2";
	
	initData.vars.Set("VMapPaths", DOpus.Create.Map());
	initData.vars("VMapPaths").persist = false;
}

// Called when an event takes place in the standalone viewer
function OnViewerEvent(viewerEventData)
{
	var viewer   = viewerEventData.viewer;
	var tab      = viewer.parenttab;
	var mapPaths = Script.vars("VMapPaths").value;

	if (viewerEventData.event == "load")
	{
		if (!mapPaths.exists(viewer))
		{
			// For the first file, verify the tab contains the file we open with.
			// If it doesn't, the viewer may have been launched from outside of Opus,
			// or via a command which explicitly displays a file from a path which isn't
			// visible in the folder tab. Those situations still associate the viewer with
			// a lister/tab if one exists, and we want to leave those tabs alone.

			if (TabContainsFile(tab, viewer.current))
			{
				mapPaths(viewer) = tab.path + ""; // Store string, not Path object.
			}
			else
			{
				mapPaths(viewer) = ""; // Make a note to ignore this viewer.
			}
		}

		var path = mapPaths(viewer);
		var file = viewerEventData.item;

		// Still in the starting folder?
		if (typeof tab  != "undefined"
		&&  typeof path != "undefined"
		&&  typeof file != "undefined"
		&&  path != ""
		&&  tab.path == path)
		{

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

			cmd.AddFile(file);
			var cmdLine = "Select FROMSCRIPT SETFOCUS DESELECTNOMATCH";
			if (DOpus.Version.AtLeast("12.22.3"))
			{
				cmdLine += " IGNORECHECKBOXMODE";
			}
			cmd.RunCommand(cmdLine);
		}

		return;
	}

	if (viewerEventData.event == "destroy")
	{
		mapPaths.erase(viewer);
		return;
	}
}

function TabContainsFile(tab, item)
{
	// Workaround to avoid error if no valid file is passed.

	if (typeof tab  == "undefined"
	||  typeof item == "undefined")
	{
		return false;
	}

	// Simple test is usually enough. Is the tab showing the folder the file is in?
	// (It's possible the file is hidden, but that would be weird in this context, so we ignore that.)

	if (DOpus.FSUtil.ComparePath(DOpus.FSUtil.Resolve(tab.path), item.path))
	{
		return true;
	}

	// To work in collections, libraries and flat view, we need to go through the actual list of files.
	// This could be slow as we don't currently have a quicker way than looping through the files.

	var itemPathString = item + "";

	// It'll usually be a selected file if the viewer opened via double-click. Try them first.

	for (var eItems = new Enumerator(tab.selected_files); !eItems.atEnd(); eItems.moveNext())
	{
		// Compare the path strings, not the item objects.
		if ((eItems.item() + "") == itemPathString)
		{
			return true;
		}
	}

	for (var eItems = new Enumerator(tab.files); !eItems.atEnd(); eItems.moveNext())
	{
		// Compare the path strings, not the item objects.
		// Skip selected files as we already checked them.
		if (!eItems.item().selected && (eItems.item() + "") == itemPathString)
		{
			return true;
		}
	}

	return false;
}

Alternative

If you don't want the folder tab's selection to follow the viewer all the time, but want to be able to quickly select the viewer's current file on-demand, create a viewer toolbar button or hotkey which runs this command:

Show VIEWERCMD=selectfile

That will select the viewer's current file in the window that launched the viewer (or open a new window if there isn't one).

The alternative command does not require the script at all.

4 Likes

Excellent, thanks.
Note that script doesnt work for me if images are in librarie.

I'd like a toggle in viewer preferences "Keep viewer in sync with the launching lister".

Root post updated with v1.2, fairly minor changes:

1.2 (22/Dec/2016):

  • Uses viewer.parenttab property introduced in Opus 12.2 as a better way to find the folder tab.
  • Slightly less overhead.
  • Fixed script log error message when viewing files in archives. (May need an Opus code-change to make the script work fully there.)

To make things easier to read, I've cleaned up the thread and removed completed discussions & thanks etc. (appreciated!), consolidating any extra info into the root post.

I noticed I hadn't really responded to these two comments, which got a bit lost in the others:

Is that still the case for you? I checked libraries while updating the script/post, and they seem to work OK for me.

There is an issue with archives, which Kundal reported, and I've added a workaround so it no longer triggers an error message. (Script still doesn't work in them, but won't cause problems in them either. I think we need to do a code change on the Opus side to make the script work fully within archives.)

For a toggle within Preferences, you can toggle the script itself under Preferences / Toolbars / Scripts.

You could also have a variable and a button which toggles it, and have the script look at the variable to see if it should do anything or not, if you wanted a toggle button/hotkey in the viewer or lister toolbars/menus.

Root post updated with v1.3. It's recommended you update the script, if you use it. The old version will stop working in Opus 12.3.3 and above.

  • 1.3 (09/Jan/2017):
    • Changed how the script works so that it is more reliable, and in particular works with files within archives.
    • These changes were also required to ensure the script still works with Opus 12.3.3 and above. Old versions of the script inadvertently depended on things which are being tidied up in the next Opus update.

3 posts were split to a new topic: Reuse existing viewer window

Came here because the version I used threw errors in the console all the time, it still was v1.0.
v1.3 does not anymore, thank you! o)

Took the chance to update by using (updated, yet unreleased) ScriptWizard, 1st real life test passed!
The tidy version information you provide here make this possible, thanks for that as well! o)

I'm running DO v12.6 (script requires min_version = "12.2" so I assume it should be OK) but I'm not getting any interaction between the "View in Directory Opus" viewer window and the lister window.

Using the "Viewer Pane" it seems to work as expected.

IE, selecting other items in the lister does not update the viewer…

The “viewer pane” works just fine though…

The script makes the file display track the file currently displayed by the standalone viewer window, not the other way around.

8 posts were split to a new topic: JScript Engine is broken on my machine

well, its works for me, Thanks,
But I am trying to add toggle with Show VIEWERCMD=selectfile,toggle But It's doesnt works.

VIEWCMD=mark,toggle is for toggling file marking. toggle doesn't do anything when combined with selectfile.

1 Like

Very nice and useful, especially if one wants viewer on a second monitor, where viewer pane does not seem to detach.
I tried creating a button with the code in fist post, but it does not work in latest opus version.
Anything i may be doing wrong?
Show VIEWERCMD=selectfile

That command still works in the latest version (checked with 12.20.2). It's part of the default viewer toolbar these days.

It should open (or bring to the front) a lister in the same folder as the viewer's current file, and select the file.

So, I press this button with the code above but the viewer does not follow selected files as you nice video shows, are there any other suggestions to get it working?

The video shows what the script does.

The alternative button does a lot less, but may be enough, depending on what you want.

I want a button ideally to make standalone viewer follow selected files in the Lister.
As I do not want this behavior always happening, if there is a way to toggle it on and off would be great.
I tried the script and it does the opposite. it selects fies the viewer shows.
Is there a way to get standalone viewer behave just like the viewer pane?
Or make the viewer pane able to detach to another place?

You could modify the script to check a variable which stops it changing the selection when set, and add a toolbar button to toggle the variable.

Or, without having to modify the script at all, you could add a toolbar button to the viewer which toggles the whole script between installed and uninstalled:

@ifexists:/scripts\Viewer_Select.js.txt
Rename /scripts\Viewer_Select.js.txt PATTERN * TO *_NOT
@ifexists:else
Rename /scripts\Viewer_Select.js.txt_NOT PATTERN *_NOT TO *

(That assumes it's saved as Viewer_Select.js.txt. It might be Viewer_Select.js, depending on how it was installed.)

Hello again, I tried this and standalone viewer still does not follow lister's selected images.