Because of my bad eyesight, I can’t use the build-in “Move to…” or “Open…” dialogs. The interface is simply to small. So I tried to recreate them using Keyboard Maestros “Prompt with List” action. It has a bigger, more Spotlight/Alfred like interface:
For this reason, I use two AppleScripts (per macro). The first one compiles a list of paths into a multiline string. To support multiple Databases, the Database name becomes the first Path element, followed by the groups and sub groups. To simplify things, I use posix format:
database/group/subgroup/
Here comes the script:
tell application id "DNtp"
set grpList to {}
repeat with db in databases
set end of grpList to (name of db) & "/" & return
repeat with par in every parent of db
set thePath to name of db & location of par & name of par & return
if thePath does not contain "/Papierkorb" and thePath does not contain "/Tags" then
set end of grpList to thePath
end if
end repeat
end repeat
grpList as text
end tell
The “grpList” result will be feed into Keyboard Maestros “Prompt with List” dialog, which will return the user selected line to a KM variable “selectedGroupPath”:
The following scipt decomposes the string to its 2 components (database and location) and will finally open the selected group in DEVONthink:
property grp : ""
tell application "Keyboard Maestro Engine"
set grp to getvariable "selectedGroupPath"
end tell
tell application id "DNtp"
activate
set pos to offset of "/" in grp
set db to characters 1 thru (pos - 1) of grp as string
set grp to characters pos thru end of grp as string
if grp is "/" then
root of database db
else
get record at grp in database db
end if
set root of viewer window 1 to result
end tell
I felt “get record at grp in database db” should easily get the job done. But because “/” isn’t returning a reference to “root”, I had to workaround this case by returning “root” explicitly in the IF construct above. Not a great deal, but not pretty either.
If I understand you correctly, you first compose a list of strings from which to chose. After you have chosen, you partially decompose the selection again to get the database and the path (location) to the group in it.
I don’t know KM well enough, but if it’s possible to attach data to the strings in the list, this might ease the process a bit. That is, if something like the name/value pair in HTML’s selection element exits in KM, you could use the string to show the user what to select (name) and the value to store the database and group (if it exists), perhaps in an AS record. Or maybe that would be over-engineered.
This is exactly what one will usually do in “normal” languages. Unfortunately, KM doesn’t support “payloads” when using the Spotlight-like interface (there is some way to have one string for display, and another one as an return code, but in any case only a single string will be returned). For this reason I had to “encode” the database in some form into the string.
Another way I tried was to keep two separate lists (couldn’t figure out how user defined lists of records work in AppleScript). One list of Strings for display in KM, and second one with the actual Record objects from DEVONthink. This way I was able to dereference the right group simply by index. But that code reads awkward, too (but it also has upsides: it will correctly work if you have two groups with exactly the same pathname).
This was the first version using recursion and two lists:
use scripting additions
property listOfGroups : {}
property listOfGroupPaths : {}
property tempPath : {}
tell application "DEVONthink 3"
repeat with db in databases
my getGroups(root of db)
end repeat
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to ASCII character 10
set output to listOfGroupPaths as text
set AppleScript's text item delimiters to tid
end tell
tell application "Keyboard Maestro Engine"
setvariable "listOfGroupPaths" to output
do script "BC5FEB81-210F-488D-AD05-3B0BCEB58640"
set selectedGroupPath to getvariable "selectedGroupPath"
end tell
tell application "DEVONthink 3"
set pos to my list_position(selectedGroupPath, listOfGroupPaths)
set test to location of item pos of listOfGroups & name of item pos of listOfGroups
return test
end tell
on list_position(this_item, this_list)
repeat with i from 1 to the count of this_list
if item i of this_list is this_item then return i
end repeat
return 0
end list_position
on getGroups(aGroup)
tell application "DEVONthink 3"
if name of aGroup is "Tags" then return
if name of aGroup is "Papierkorb" then return
set end of tempPath to name of aGroup
set tid to AppleScript's text item delimiters
set AppleScript's text item delimiters to " ➤ "
set end of listOfGroupPaths to tempPath as text
set AppleScript's text item delimiters to tid
set end of listOfGroups to aGroup
set subGroups to every child of aGroup whose type is group
repeat with theGroup in subGroups
my getGroups(theGroup)
end repeat
set tempPath to reverse of (rest of (reverse of tempPath))
end tell
end getGroups