You’re welcome, @TheWart. I’m glad it worked for you.
Where did you got this script? Apparently, it asks for a template file in the resources folder of the script bundle.
You’re welcome, @TheWart. I’m glad it worked for you.
Where did you got this script? Apparently, it asks for a template file in the resources folder of the script bundle.
I got it through my link in the 5th post of this thread above. That makes sense since the script has a .scptd extension, and I can “View package contents” and locate the original .oo3 file the script is calling for.
Fantastic. I forked Rob’s repository and made a modification to my branch.
Now, it creates .ooutline files and adds a link back to the Omnioutliner file in the OF2 project notes.
I hope this solves the problem.
That definitely creates a link back and forth with the OO file, mirroring my OF nested project structure.
However, since it isn’t my default template I tried to copy mine into the .scptd file using "Show package package contents and get the following error:
I think you’re copying a .otemplate file into the package contents. Can you try with a .ooutline file?
That was it! OO file is now created and linked properly between both DTPO and OF.
For a final step, I may try to hack a way to have the DTPO link for the notes file appended to the respective OF project’s note field. After running the script, I would like to see in the OF project notes field:
[DEVONthink group for this project] x-devonthink-item://xxxxxxxx
[blank line]
[OmniOutliner notes for this project] x-devonthink-item://xxxxxxxx
Or, even better:
[DEVONthink group for this project] <-------- as a hyperlink to x-devonthink-item://xxxxxxxx
[blank line]
[OmniOutliner notes for this project] <-------- as a hyperlink to x-devonthink-item://xxxxxxxx
I tried to follow Rob’s original parsing of the hyperlink (which worked brilliantly in OF1) but couldn’t figure out how to paste rich text into the notes field of OF2.
I’m glad it worked.
I made the improvement. Committed changes into my branch. Now it creates rich text links in OF Project Notes.
Is this what you had in mind?
I am so grateful for your work, @unlocked2412. With the help of Keyboard Maestro, I am back to the functionality I enjoyed with Rob’s original scripts using OmniFocus 1.
For posterity and future development, here’s the final script I use, the Keyboard Maestro macros that connect it all, and a (very homespun) video that shows how I use them all together.
You’re welcome, @TheWart!
You explain really well, so it’s easy to understand what you are trying to do.
One suggestion to your excellent workflow: would you like to open both links with separate shortcuts via Applescript? If you move the window, the KM macro cannot locate the links, I think.
P.S.: I’m intrigued: what the purpose of Script: interactive Inbox?
You’re kind, but things were easy to understand because you made the program do exactly what was needed!
I’d like to learn how to get OF to open either link with AppleScript, and the script would reach a wider audience than a Keyboard Maestro macro. Would it be possible to activate an AppleScript that, when activated from within the tasks of a project, throws a pop-up that allows me to choose between hyperlinks in the host project’s note field?
I’ve tested the KM macro in different window locations because the first mouse click is not dependent upon position of the OF window, but actually looks for the image of hyperlinked text on a white background. This is KM’s secret sauce for me: “Click at found image” does what no other shortcut program can.
You’re right. It’s a clever solution but it is little faster and more reliable with Applescript.
I used “Click at found image” many times. In some cases, it’s the only option.
Yes, it’s possible. This is a starting point. To open DT link:
Code:
--unlocked2412
tell application "OmniFocus"
tell front document
tell front document window
set lst_values to (value of selected trees of content) whose (class of value = task) or (class of value = project)
if (count of lst_values) = 0 then
set lst_values to (value of selected trees of sidebar) whose (class of value = task) or (class of value = project)
if (count of lst_values) = 0 then
display notification "Select a project or task"
return
end if
end if
set the_value to item 1 of lst_values
if class of the_value = task then
set the_project to containing project of the_value
else
set the_project to the_value
end if
end tell
set note_ref to a reference to (note of the_project)
tell note_ref
set dt_link to value of attribute "link" of style of paragraph 1
end tell
end tell
end tell
tell application "System Events"
open location dt_link
end tell
If you need to open OmniOutliner link, you must get de value of attribute “link” of style of paragraph 3.
I leave the code for reference:
tell application "OmniFocus"
tell front document
tell front document window
set lst_values to (value of selected trees of content) whose (class of value = task) or (class of value = project)
if (count of lst_values) = 0 then
set lst_values to (value of selected trees of sidebar) whose (class of value = task) or (class of value = project)
if (count of lst_values) = 0 then
display notification "Select a project or task"
return
end if
end if
set the_value to item 1 of lst_values
if class of the_value = task then
set the_project to containing project of the_value
else
set the_project to the_value
end if
end tell
set note_ref to a reference to (note of the_project)
tell note_ref
set oo_link to value of attribute "link" of style of paragraph 3
end tell
end tell
end tell
tell application "System Events"
open location oo_link
end tell
We can do that with a Standard Additions command (Applescript): choose from list.
Or, trigger a Keyboard Maestro palette. What do you prefer?
Tell me if you need some help, @TheWart.
That is very helpful. I see how changing paragraph link to 1 allows the script to open the associated DTPO group. I’ve made two copies of the AppleScript and placed them in my OF toolbar. I’ll load both scripts into my existing Keyboard Maestro palette instead of my Rube Goldberg macros.
Thank you very much!
P.S. You asked earlier about the “Interactive Inbox” script in my toolbar. It reads my OF inbox and prompts for a project and a context to assign each inbox task. It was taken from the work of someone else in the forum. I’ll look for it and link it back here.
use AppleScript version "2.4" -- Yosemite (10.10) or later
use scripting additions
use O : script "omnifocus"
property assign_method : 3
if assign_method is 1 then
assign_project()
else if assign_method is 2 then
assign_context()
else if assign_method is 3 then
assign_project()
assign_context()
end if
on assign_project()
tell application "OmniFocus"
tell default document
repeat with _task in ((every inbox task) whose (completed) is false)
try
set nofolder_Projects to (name of (flattened projects where its folder is missing value and its status is active))
set folder_Projects to (name of (flattened projects where hidden of its folder is false and its status is active))
set projectNames to nofolder_Projects & folder_Projects
set _project to O's findProject(choose from list projectNames with title "Interactive Inbox" with prompt "Assign project to: " & name of _task without empty selection allowed)
set assigned container of _task to _project
on error
display notification "No project selected for " & name of _task & "."
end try
end repeat
compact
if (count of (inbox tasks whose (completed) is false)) > 1 then
display notification (((count of (inbox tasks whose (completed) is false)) as text) & " tasks remain in the inbox.")
else if (count of inbox tasks) > 0 then
display notification (((count of (inbox tasks whose (completed) is false)) as text) & " task remains in the inbox.")
end if
end tell
end tell
end assign_project
on assign_context()
tell application "OmniFocus"
tell default document
repeat with _task in ((every inbox task) whose (completed) is false)
try
set contextNames to (name of every flattened context whose hidden is false)
set _context to O's findContext(choose from list contextNames with title "Interactive Inbox" with prompt "Assign context to: " & name of _task without empty selection allowed)
set context of _task to _context
on error
display notification "No context selected for " & name of _task & "."
end try
end repeat
compact
if (count of (inbox tasks whose (completed) is false)) > 1 then
display notification (((count of (inbox tasks whose (completed) is false)) as text) & " tasks remain in the inbox.")
else if (count of inbox tasks) > 0 then
display notification (((count of (inbox tasks whose (completed) is false)) as text) & " task remains in the inbox.")
end if
end tell
end tell
end assign_context
This is very promising and it would be great if I can make this working on my machine, however I get the following error message:
error “OmniFocus kreeg een fout: Error: near “Support”: syntax error” number 1
It is on this command line probably:
set strNoteXML to do shell script "sqlite3 " & pstrDBPath & space & quoted form of strQuery
I use this DBPath:
property pstrDBPath : "~/Library/Containers/com.omnigroup.OmniFocus2.MacAppStore/Data/Library/Application Support/Omnifocus/OmniFocus.ofocus"
Could you give me a hint where to look for a solution!
I’ll try to give you a hint. Did you bought OmniFocus in the Mac App Store?
If so, try with this line:
property pstrDBPath : "~/Library/Containers/com.omnigroup.OmniFocus2.MacAppStore/Data/Library/Caches/com.omnigroup.OmniFocus2.MacAppStore/OmniFocusDatabase2"
If not:
property pstrDBPath : "$HOME/Library/Containers/com.omnigroup.OmniFocus2/Data/Library/Caches/com.omnigroup.OmniFocus2/OmniFocusDatabase2"
I hope that helps. Let me know if it works.
Thank you very much for your quick reply and answer. It is great to have such supportive people, willing to help!
Your suggestions helped and everything is working now!
That’s fantastic! You’re welcome. I’m glad I could help.
I’m working through adding this to my system, but I’m having trouble trying to get KM to recognise the area of the OF note to activate a switch to either DevonThink or OmniOutliner.
It seems that KM just can’t ‘see’ the text image to be able to activate the click action.
I’ve tried taking my own screenshot and replacing the built-in as well as mucking around with fuzziness, but it’s not working.
Any ideas?
To respond to my own thread to help others; I discovered that I had to recreate the screenshots of the text in KM - I think my font must have been different.
I also went into System Preferences and toggled the reduce transparency setting to prevent colour bleed - although not sure this has any impact, to be honest.
Now, though, with my own screenshot, the text is recognised consistently and the script works.
I used the Rob Trew versions back in OF1 days, and it’s nice to have them back again!
If you like, I am leaving here two scripts I wrote in JXA to open DT link and OO link
Usage:
P.S.: In one of the above posts, there is an AppleScript version.
(() => {
// Data List JS ----------------------------------------------------------
// bindMay (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
const bindMay = (mb, mf) =>
mb.nothing ? mb : mf(mb.just);
// just :: a -> Just a
const just = x => ({
nothing: false,
just: x
});
// nothing :: () -> Nothing
const nothing = (optionalMsg) => ({
nothing: true,
msg: optionalMsg
});
// OF Functions -----------------------------------
// projectMay :: Window -> Maybe Project
const projectMay = win => {
const seln = win.content.selectedTrees.value();
return seln.length > 0 ?
(Object.keys(seln[0].properties()).includes('reviewInterval')) ?
just(seln[0]) : nothing('No projects selected') :
nothing('No selection')
}
// linkMay :: OF Project -> URL String
const linkMay = x => {
try {
return {
nothing: false,
just: x.note.paragraphs[0].style.attributes['link'].value()
};
} catch (e) {
return {
nothing: true,
msg: 'No link in note'
};
}
};
// groupMay :: URL String -> maybe DT record
const groupMay = x => {
const strUUID = x.split('//')[1]
return dt.getRecordWithUuid(strUUID) == null ?
nothing('') :
just(x)
};
// MAIN
const
ca = Application.currentApplication(),
sa = (ca.includeStandardAdditions = true, ca),
dt = Application('DEVONthink Pro'),
of = Application('OmniFocus'),
oDoc = of.defaultDocument,
oWin = oDoc.documentWindows[0];
const mb = bindMay(bindMay(projectMay(oWin), linkMay), groupMay)
return (mb.nothing) ? mb.msg : ca.openLocation(mb.just)
})();
(() => {
// Data List JS ----------------------------------------------------------
// bindMay (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
const bindMay = (mb, mf) =>
mb.nothing ? mb : mf(mb.just);
// Data List JS ----------------------------------------------------------
// just :: a -> Just a
const just = x => ({
nothing: false,
just: x
});
// nothing :: () -> Nothing
const nothing = (optionalMsg) => ({
nothing: true,
msg: optionalMsg
});
// OF Functions -----------------------------------
// projectMay :: Window -> Maybe Project
const projectMay = win => {
const seln = win.content.selectedTrees.value();
return seln.length > 0 ?
(Object.keys(seln[0].properties()).includes('reviewInterval')) ?
just(seln[0]) : nothing('No projects selected') :
nothing('No selection')
}
// linkMay :: OF Project -> URL String
const linkMay = x => {
try {
return {
nothing: false,
just: x.note.paragraphs[2].style.attributes['link'].value()
};
} catch (e) {
return {
nothing: true,
msg: 'No link in note'
};
}
};
// groupMay :: URL String -> maybe DT record
const groupMay = x => {
const strUUID = x.split('//')[1]
return dt.getRecordWithUuid(strUUID) == null ?
nothing('') :
just(x)
};
// MAIN
const
ca = Application.currentApplication(),
sa = (ca.includeStandardAdditions = true, ca),
dt = Application('DEVONthink Pro'),
of = Application('OmniFocus'),
oDoc = of.defaultDocument,
oWin = oDoc.documentWindows[0];
const mb = bindMay(bindMay(projectMay(oWin), linkMay), groupMay)
return (mb.nothing) ? mb.msg : ca.openLocation(mb.just)
})();