Navigate through different open windows

Hi there,
I am trying to execute an action in a different window than the one I am. The set up and actions are the following:
A - Normally work with multiple DNtp windows. Two of them never change and display two groups from the same database (zettelkasten): window A displays a group with research notes (zettels), and window B displays an indexed group (zotfile) with articles in pdf.
B - I use this script to add a new Zettle, using the selected text (if any) as follows:

property zettels_group : "/zettels"

tell application id "DNtp"
	
	-- Step 1. Set the_selection even if nothing is selected
	try
		set the_selection to selected text of think window 1
		if the_selection is null then set the selection to ""
	on error
		set the_selection to ""
	end try
	
	-- Step 2. Compose a new Zettel
	try
		set zettel_id to do shell script "date '+%y%m%d%H%M'"
		display dialog "Enter a Title and Aliases for a new Zettel:" & return & "  (Separated by commas)" default answer the_selection
		set user_input to text returned of the result
		try
			set astid to AppleScript's text item delimiters
			set AppleScript's text item delimiters to ","
			--			set the_aliases to user_input
			set zettel_title to first text item in user_input
			set AppleScript's text item delimiters to astid
		on error
			display dialog "Couldn't process input"
		end try
		set zettel_content to "# " & zettel_title & return & "  [[" & zettel_id & "]]" & return & return & "## See also" & return & "- " & return & return & "## Notes" & return
		
		-- Step 3. Add new Zettel
		try
			set zettels to get record at zettels_group
			set new_zettel to create record with {name:zettel_id, type:text, content:zettel_content, aliases:user_input} in zettels
		end try
		
		--	Step 4. Set selection of window containing "Zettels" to new_zettel
		
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell

As it is, I can launch this script from any window and it will always create the record in the right group (zettels), which is great (i.e. I can create a Zettel from a keyword in a pdf in window B but also from a keyword in another zettel in window A).
So… my trouble and question comes here.
What I would like to do now in “Step 4”, is to somehow change the selected item in the window that displays my research notes (zettels), to show me the one I just created. I am not trying to open it in a new window but select it in one of the already existing ones.

The main reason for this is that since I have many zettels, every time I create a new one I have to search it before continuing writing. I know I could arrange the list by name, however my convenience arrangement is by aliases.
Aditionally, if I were always in the same window, I could achieve it with a

set selection of think window 1 to {the_zettel}

however it is not always the case.

Apologies in advance, as denoted by my messy example I am newbie in applescript and this forum.

This is what I am currently using. It will open the new markdown files after it is created.
Perhaps it can be useful to you. Let me know if there is something you don’t understand.

property WikiTop : "Corp. | Arc. | Plat. | Arist. | Hist. | Gloss. | Zk.  "
property OptionToAddClipboard : false
property OptionToAddReturnLink : false
property CreateInSameGroup : false
property OpenInSameWindow : true

tell application id "DNtp"
	try
		if not (exists think window 1) then error "No window opened."
		
		set theRecord to (content record of think window 1) -- 
		set theSource to name of theRecord
		set theGroup to parent 1 of theRecord
		
		-- Get note name
		
		try
			set invalidName to false
			set theName to selected text of think window 1
			if theName is "" then set invalidName to true
		on error
			set invalidName to true
		end try
		
		if invalidName is true then set theName to display name editor info "Insert name of new markdown file"
		
		
		
		-- Add clipboard to body
		
		if OptionToAddClipboard then
			set theClipOption to {"true", "false"}
			set theClip to choose from list theClipOption with prompt "Insert clipboard body of note?" default items {"true"}
			set theClipAns to item 1 of theClip
			if theClipAns is "true" then set theMDbody to "# " & theName & return & return & (the clipboard)
			if theClipAns is not "true" then set theMDbody to "# " & theName & return & return
			
		else
			set theMDbody to "# " & theName & return & return
			
		end if
		
		-- Add return link
		
		if OptionToAddReturnLink then
			set theBLC to {"true", "false"}
			set theBL to choose from list theBLC with prompt "Insert link back to source?" default items {"true"}
			set theBLR to item 1 of theBL -- Resultado da escolha
			if theBLR is "true" then set theMD to WikiTop & return & return & "Backlink: " & theSource & "  " & return & return & theMDbody
			if theBLR is not "true" then set theMD to WikiTop & return & return & theMDbody
		else
			set theMD to WikiTop & return & return & theMDbody
		end if
		
		-- Create new markdown file
		if CreateInSameGroup then
			set theResult to create record with {name:theName, type:markdown, content:theMD} in theGroup
		else
			set theResult to create record with {name:theName, type:markdown, content:theMD}
		end if
		
		-- Open in same window
		if OpenInSameWindow then
			open tab for record theResult in think window 1
		else
			open tab for record theResult
		end if
		
		-- Error
	on error error_message number error_number
		if the error_number is not -128 then display alert "DEVONthink" message error_message as warning
	end try
end tell

1 Like

How about this? Not sure it will be working for ur case.

set the root of think window 1 to the_zettel
set selection of think window 1 to {new_zettel}

1 Like

Your script @Bernardo_V is way better than mine, and achieves a very similar purpose… so I will probably continue adapting your version to my workflow instead. There is however a part in the end that could solve my problem but I don’t completely understand how to adapt it.
Here:

-- Open in same window
if OpenInSameWindow then
open tab for record theResult in think window 1
else
open tab for record theResult
end if 

From my very basic knowledge, I deduce that if OpenInSameWindow = true the script will open the new record in the active window (whichever I am at the moment). However, if the condition is false, it will create a new, different one. Is it right so far?
Then, and returning to the initial question, how could I tell the else statement to open the record theResult in an already existing, but different window?
I guess that, since each window displays a different group, the more logical approach might be to find the window which open group name is "/zettels" or something similar. But this doesn’t work and I am not sure on how to proceed (or if this is possible at all).

@ngan answer might be also useful but we continue having a “window identification” problem to solve.
Let’s suppose we have four open windows at the moment: “inbox”, “research notes”, “research articles”, and “meeting notes”.
In that case…

set selection of think window i to {new_zettel}

…could work, if we somehow know which i corresponds to each of the windows.
Is this possible?

Welcome @rcirer

set zettels to get record at zettels_group

Note, this line is invalid unless there already is a zettels location in the root of a database.

While this isn’t the only way to do this, it’s a good method to be in the habit of using…

set zettels to get record at zettels_group
	
	if zettels = missing value then
		set zettels to create location zettels_group in database "small"
                -- Obviously adjust this name to your situation
	end if
	
	set new_zettel to create record with {name:zettel_id, type:text, content:zettel_content, aliases:user_input} in zettels

PS: I suggest you don’t use try… end try blocks when you’re initially coding, especially when you’re learning. They mask errors that are useful to see.

PPS:

open window for record zettels
	set selection of think window 1 to {new_zettel}

Opens a new main window for the new zettel and selects it.

1 Like

Hi again, and thanks for being so helpful with your suggestions :muscle:
I’ve been investigating and "try-and-error"ing for a while the topic about identifying the open windows and displaying the new record in one of them. I’ve found a solution that seems to work, let me show you my messy version for Step 4:

property target_group : "zettels"

    (...)

	--  Step 4. Find target window containing 
	--    Step 4.1. Recognize windows	
	set count_windows to count think windows
	set list_windows to {}
	repeat with i from 1 to count_windows
		set i_name to filename of the root of think window i
		set end of list_windows to i_name
	end repeat
	
	--   Step 4.2. Compare windows
	set match_i to 0
	repeat with x from 1 to count_windows
		if item x of list_windows = target_group then
			set match_i to x
		end if
	end repeat
	
	--    Step 4.3. Assign target window
	if match_i = 1 then
		set target_window to think window match_i
		-- display dialog "Found target window named: " & item match_i of list_windows
	else
		set target_window to think window 1
		-- display dialog "Target window not found"
	end if
	
	--    Step 5. Set selection of target window to new_zettel
	activate target_window
    set selection of target_window to {new_zettel}

PS: Thanks @BLUEFROG for your help, I’ll save those try blocks for the future!

This is a good way! Thanks for sharing this idea.

1 Like

You’re welcome :slight_smile: