I have built a JXA script that opens a database root.
The script currently opens the database in a new DEVONthink window.
How can I force the database to open in an existing DEVONthink window, if the app is already open?
I’m sure I’m overlooking something obvious, and am grateful for any advice. After searching around, I think I probably need to do something with ViewerWindow and selection, but I’m having trouble working out the JXA syntax.
My script looks like this:
// init methods for DEVONthink
const dT = Application('DEVONthink 3')
dT.includeStandardAdditions = true
// focus DEVONthink
dT.activate()
// get the database
const dTdb = dT.getDatabaseWithUuid("uuid-of-the-db")
// open the db root in a new window
dT.openWindowFor({record: dTdb.root() })
I’m not sure if that is what you want though: After executing the command, the DB is simply open when it was closed before.
But while fooling around with DT and JXA, I stumbled about this phenomenon:
When I try to list all databases (app.databases()...), DT only returns those that are open. Same for AppleScript. If that is intended behaviour, it should be mentioned in the documentation I think (@cgrunenberg ?).
How would one programmatically open all closed databases, for example?
TX @pete31
That’s a bit of a catch 22: to open the database I have to know its path which I can’t get from the database unless it’s open. I can smell the logic behind it, but the documentation should state this behavior explicitly, I think.
Kind of: viewerWindow() - note the lowercase v!
Do you run the code in script editor? Then you can pepper it with console.log() statements. I suppose that vw is undefined.
I didn’t really try it before. What you describes matches my experiences now, though. viewerWindow() throws an error, whereas ViewerWindow() returns an object. But setting this object’s root property to the root of a database does not do anything here. According to the code posted by @pete31, ViewerWindow should be a list (aka array). However, there’s no length property available on the object returned by app.ViewerWindow().
I think @cgrunenberg would have to comment on this. Although I did some JXA scripting with DT, I never tried to do what you do (which is to get where, exactly?). DT and JXA are not always happy with one another, and some parts of DT are not really working with JXA at all (or not as one would expect).
But maybe you don’t need all this viewer window stuff to achieve what you want to?
I had wondered whether this was a failing on my part, or something more fundamental in the interaction between Applescript and JXA. From what I can tell, this seems to be relatively straightforward with Applescript, but as I’m adding this into a workflow automation that is entirely based in JXA, I was hoping there would be an easy way to translate. Hopefully @cgrunenberg can shed some light on whether or not this would be expected to work.
But maybe you don’t need all this viewer window stuff to achieve what you want to?
Do you have an alternative approach in mind? As mentioned in my original post, I have this working with the openWindowFor method but it opens a new window each time it is run. I’d be very interested if you can suggest alternatives to viewer window that might enable me to change the selection in the active DT window.
Given that I don’t know any context of this - no, I don’t. The automation I did with DT always centred on (selected) records, there was never the need to open a window. The only other thing I’m doing with JXA in this context is adding files to different databases/groups with Hazel. Also straigh tforward.
In my AppleScript example I used viewer window 1 as there’s no need to first get all viewer windows and afterwards item 1 of, at least not in AppleScript - don’t know about JavaScript.
This works.
// init methods for DEVONthink
const dT = Application('DEVONthink 3')
dT.includeStandardAdditions = true
// focus DEVONthink window
dT.activate()
// get the DEVONthink database for the selected project
let dTdb = dT.getDatabaseWithUuid("C06D2AA9-7453-4A6E-9A86-EDCF3B242A6F")
// get the first viewer window - no error checking included …
let vw1 = dT.viewerWindows()[0];
// set viewer window root
vw1.root = dTdb.root();