The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniFocus Extras (http://forums.omnigroup.com/forumdisplay.php?f=44)
-   -   Toggle State of Context via AppleScript? (http://forums.omnigroup.com/showthread.php?t=21977)

DrJJWMac 2011-08-25 08:22 AM

Toggle State of Context via AppleScript?
 
Does a simple way exist via AppleScript to toggle the state of an entire context Active, On Hold, and Dropped? It seems this is not a property of contexts that can be altered via AppleScript. I wonder if that means the only way to accomplish it is via a loop through actions to toggle their state?

The application is to set up a background app to toggle on/off such contexts as Errands at particular times.

--
JJW

whpalmer4 2011-08-25 08:58 AM

Yes, here's a sample script that will toggle the availability of the Errands context each time it is run:

[code]
tell application "OmniFocus"
tell front document
set idHome to id of first item of (complete "Errands" as context)
set homeContext to first item of (every context where id is idHome)
tell homeContext
set allows next action to not allows next action
end tell
end tell
end tell
[/code]

Looking at the variable names, you might well deduce that I originally was toggling the state of a different context :-)

RobTrew 2011-08-25 09:26 AM

And to cycle a whole clump of selected contexts between three states:

[CODE]-- Toggle selected contexts
tell application id "OFOC"
tell front document window of front document
-- GET A REFERENCE TO THE SELECTED CONTEXTS
repeat with oPanel in {sidebar, content}
set refContexts to (a reference to (selected trees of oPanel where class of its value is context))
set lngContexts to count of refContexts
if lngContexts > 0 then exit repeat
end repeat
if lngContexts < 1 then return

-- GET THE STATE OF THE FIRST SELECTED CONTEXT
tell (value of first item of refContexts) to
set {blnNotOnHold, blnHidden} to {allows next action, effectively hidden}

-- CYCLE THE STATE AROUND A TRIANGLE
-- Active --> on hold --> dropped --> active
if blnNotOnHold then
set {blnNotOnHold, blnHidden} to {false, false}
else if blnHidden then
set {blnNotOnHold, blnHidden} to {true, false}
else -- on hold
set {blnNotOnHold, blnHidden} to {false, true}
end if
tell value of refContexts to
set {allows next action, hidden} to {blnNotOnHold, blnHidden}
end tell
end tell
[/CODE]

[COLOR="White"]--[/COLOR]

DrJJWMac 2011-08-25 09:41 AM

Thanks. Unfortunately, the context I am trying to reach is a sub-context. Substituting "@ : Errands" is not working. How do I get to a sub-context level?

--
JJW

RobTrew 2011-08-25 09:54 AM

If you are working with nested contexts, one word should do it:

[I]every context [/I]--> [I]every flattened context[/I]

whpalmer4 2011-08-25 09:57 AM

In truly churlish fashion, I'll point out that you won't get the results you want if you are toggling a group of contexts which are not all in the same availability state :-)

If you had two sets of contexts which were mutually exclusive (set A is available when set B is unavailable, and vice versa), Rob's improved version would set them all to be available or unavailable. Here's an improvement on the improvement:

[code]
-- Toggle selected contexts
tell application id "OFOC"
tell front document window of front document
-- GET A REFERENCE TO THE SELECTED CONTEXTS
repeat with oPanel in {sidebar, content}
set refContexts to (a reference to (selected trees of oPanel where class of its value is context))
set lngContexts to count of refContexts
if lngContexts > 0 then exit repeat
end repeat
if lngContexts < 1 then return

repeat with curContext in refContexts
set blnOnHold to not allows next action of value of curContext
set allows next action of value of curContext to blnOnHold
end repeat
end tell
end tell
[/code]

whpalmer4 2011-08-25 10:01 AM

Ah, the endless fun opportunities that OmniFocus offers for tinkering rather than working :-)

DrJJWMac 2011-08-25 10:02 AM

[QUOTE=RobTrew;100965]If you are working with nested contexts, one word should do it:

[I]every context [/I]--> [I]every flattened context[/I][/QUOTE]

Oh happy day! Thank you.

--
JJW

RobTrew 2011-08-25 10:03 AM

Well, a difference in management style perhaps :-)

I like to dragoon my children into some kind of unison ...

(but I'm demonstrably just as willing to be distracted :-)

whpalmer4 2011-08-31 10:06 AM

Here's yet another variation! This one prompts for a context name substring to match, in response to another thread where this sort of is being discussed. The new state for each context is independently determined, though to make full use of that, you might want to change the logic to have it just go between two states (active/dropped or active/on hold being the likely candidates) instead of active/on hold/dropped as is done here. Left as an exercise for the reader :-)

[code]

tell application "OmniFocus"
-- prompt user for context substring to match
set Matchstr to text returned of (display dialog
"Context substring to match" default answer
"" buttons {"OK", "Cancel"}
default button 1)

tell front document
set refContexts to (every flattened context where name contains Matchstr)
set lngContexts to count of refContexts
if lngContexts < 1 then -- oops, didn't find any matches!
display alert "No matching contexts found for " & Matchstr
return
end if

repeat with curContext in refContexts
tell curContext to
set {blnNotOnHold, blnHidden} to {allows next action, effectively hidden} of curContext

-- CYCLE THE STATE AROUND A TRIANGLE
-- Active --> on hold --> dropped --> active
if blnNotOnHold then
set {blnNotOnHold, blnHidden} to {false, false}
else if blnHidden then
set {blnNotOnHold, blnHidden} to {true, false}
else -- on hold
set {blnNotOnHold, blnHidden} to {false, true}
end if

tell curContext to
set {allows next action, hidden} to {blnNotOnHold, blnHidden}
end repeat

end tell
end tell

[/code]

bashosfrog 2011-08-31 04:24 PM

Seeing as you're having so much fun, can the same principle be applied to the Availability filter? I'm forever toggling it between "Remaining" and "Any Status" to look up information in tasks that are completed, and therefore hidden.

Or is there an easier way to achieve this that might have escaped me? A lot escapes me these days.

whpalmer4 2011-08-31 05:37 PM

My database takes so long to switch between views that I try to avoid doing this sort of thing, and so don't take note of what others may have contributed to do it. It does seem to me that someone had posted something similar, but I didn't find it in the first few pages of results in the OmniFocus Extras forum, so I rolled my own. Perhaps someone else remembers what I do not.
[code]
tell application "OmniFocus"
tell front document window of default document
set curTaskState to selected task state filter identifier of content
if (curTaskState is "all") then
set curTaskState to "available"
else
set curTaskState to "all"
end if
set selected task state filter identifier of content to curTaskState
end tell
end tell
[/code]

This script will flip the task status filter for the front document window between Any Status and Available each time it is invoked. If you have some other status displayed, it will switch to Any Status. You could put the script in the toolbar via View→Customize Toolbar... and have one-click access (seems like anything more would be less convenient than just twiddling the view bar setting by hand).

Searching around a bit, perhaps this is what I saw: [url]http://www.sandro.org/omnifocus/index.php#cyclestates[/url]

bashosfrog 2011-08-31 09:36 PM

Your script is just bloody perfect. The toggle is pretty much instant in my DB, which suggests I probably need to do some mindsweeping and fill it up more.

Thanks!


All times are GMT -8. The time now is 11:28 AM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2022, vBulletin Solutions, Inc.