The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniFocus Extras (http://forums.omnigroup.com/forumdisplay.php?f=44)
-   -   Looking for script to toggle parallel/sequential (http://forums.omnigroup.com/showthread.php?t=16570)

vinyl_warrior 2010-06-23 06:31 PM

Looking for script to toggle parallel/sequential
 
I seem to need parallel and sequential projects about 50/50, so the ability to set a preference for one or the other is just a tease.

Does anyone happen to have a script that will toggle a project from parallel to sequential or vice versa? It would be ideal if all I had to do is have a task currently selected and have the script change the project.

It would be great if there were just a keyboard shortcut for this, but alas, I couldn't find a menu option for it. Maybe I'm just mistaken, though :)

RobTrew 2010-06-23 11:09 PM

[QUOTE=vinyl_warrior;79107]Does anyone happen to have a script that will toggle a project from parallel to sequential or vice versa? It would be ideal if all I had to do is have a task currently selected and have the script change the project.[/QUOTE]

As parent tasks within the same project can have different parallel/sequential settings, I am guessing that you want to[LIST=1][*]Toggle the project's status[*]Reset the status of all the contained parent tasks to match that of the project[/LIST]
If so, then then you should edit the value of the property [COLOR="SeaGreen"]pblnTasksChangeWithProject[/COLOR] near the top of the script to [B]true[/B]
If, however, you just want to toggle the status of the project, and leave unchanged the state of any parent tasks within the project, then you should leave the value of the property [COLOR="SeaGreen"]pblnTasksChangeWithProject[/COLOR] as [B]false[/B]

[CODE]-- Toggles the selected project(s)
-- (or the project(s) of the selected task(s))
-- between sequential and parallel

-- If this property is set to TRUE,
-- the status of ALL PARENT TASKS is changed to match the
-- new status of the project itself.
-- if it is set to false, ONLY THE PROJECT ITSELF is toggled,
-- and the status of any contained parent tasks is left unchanged.
property pblnTasksChangeWithProject : true

tell application "OmniFocus"
tell front document window of default document
set refSeln to a reference to (selected trees of content)
if (count of refSeln) < 1 then
set refSeln to a reference to (selected trees of sidebar)
if (count of refSeln) < 1 then return

-- gather a list of selected projects to be toggled
set lstObjects to value of refSeln
set lstProjects to {}
repeat with oObj in lstObjects
set cClass to class of oObj
if cClass is project then
if not my IsMember(oObj, lstProjects) then
set end of lstProjects to oObj
else if cClass is task then
set oProj to containing project of oObj
if not my IsMember(oProj, lstProjects) then
set end of lstProjects to oProj
end if
end repeat

-- toggle each project
repeat with oProj in lstProjects
set blnNewState to not sequential of oProj
my SetState(oProj, blnNewState)
end repeat
end tell
end tell

-- Either toggles just the project itself
-- or, if pblnTasksChangeWithProject is TRUE,
---- (see top of script)
---- recursively sets all tasks to match the
---- new status of the project
on SetState(oObject, blnNewState)
using terms from application "OmniFocus"
tell oObject
set sequential to blnNewState
if pblnTasksChangeWithProject then
set lstTasks to tasks
repeat with oTask in lstTasks
my SetState(oTask, blnNewState)
end repeat
end if
end tell
end using terms from
end SetState

-- Simple test for list membership
-- used to ensure that we don't toggle the same project twice
on IsMember(oElement, lstList)
using terms from application "OmniFocus"
repeat with oItem in lstList
if id of oItem is id of oElement then return true
end repeat
false
end using terms from
end IsMember[/CODE]

vinyl_warrior 2010-06-24 02:22 AM

Awesome, Rob!

Is there a way to make it so that if the currently selected task were a child task (ie. a task within a subproject) then the script would change the parent task and not the project. Basically, to get the script to toggle the status of the project/subproject that is one up from what it is currently selected.

Or maybe it's easier to have a separate script that just changes the subproject...

Thanks so much for your help!

RobTrew 2010-06-24 04:15 AM

[QUOTE=vinyl_warrior;79121]Is there a way to make it so that if the currently selected task were a child task (ie. a task within a subproject) then the script would change the parent task and not the project. Basically, to get the script to toggle the status of the project/subproject that is one up from what it is currently selected.[/QUOTE]

Here is a redraft which can be fine-tuned by setting two properties at the top of the script:[LIST=1][*][COLOR="Green"]pblnImmediateParentOnly[/COLOR][*][COLOR="green"]pblnAllDescendantsInherit[/COLOR][/LIST]
If [COLOR="Green"]pblnImmediateParentOnly[/COLOR] is set to TRUE, only the immediately selected object (or its immediate parent (task or project) if it is a childless leaf task) is the root of the toggle.
If [COLOR="Green"]pblnImmediateParentOnly[/COLOR] is set to FALSE, the root of the toggle is the selected project, or the project containing the selection.

If [COLOR="green"]pblnAllDescendantsInherit[/COLOR] is set to TRUE, the specified root node (a project or a parent task) is toggled, and all of its descendants, unto the last generation, inherit its new parallel/sequential setting.
If [COLOR="green"]pblnAllDescendantsInherit[/COLOR] is set to FALSE, then only the immediate node is toggled, and any contained parent tasks retain their settings.

(A rough draft, I recommend a little testing and experimentation on dummy data before you start to use it)

[CODE]-- Toggles selected project(s) / or parent task(s) between parallel and sequential
-- The root of the toggle may be the project or the immediate parent task
-- The result of the toggle may optionally be inherited by all descendants

-- See the settings of the following two boolean properties:

-- If TRUE the root of the toggling is the selected project
-- or selected parent task
-- or the immediate parent of the selected leaf task
-- if FALSE the root of the toggling is the selected PROJECT
-- or the PROJECT containing the selected task
property pblnImmediateParentOnly : true

-- If TRUE the root node is toggled, and ALL its descendants inherit the
-- the new status, down to the last generation
property pblnAllDescendantsInherit : false


tell application "OmniFocus"
set oWin to front document window of default document
set lstSeldObjects to my SelectedObjects(oWin)

set lstParents to {}
repeat with oObject in lstSeldObjects
set cClass to class of oObject
if cClass is project or cClass is task then
if cClass is project then
set oParent to oObject
else -- cClass is Task
if pblnImmediateParentOnly then
if (count of tasks of oObject) > 0 then
set oParent to oObject
else
set oParent to container of oObject
end if
else -- Toggle the project of this task
set oParent to containing project of oObject
end if
end if
if not my IsMember(oParent, lstParents) then set end of lstParents to oParent
end if
end repeat

-- toggle each specified parent of tasks
repeat with oParent in lstParents
set blnNewState to not sequential of oParent
my SetState(oParent, blnNewState)
end repeat
end tell


-- Toggles the status of the project or parent task,
-- and optionally (depending on the value of pblnAllDescendantsInherit)
-- propagates the new state down to the last generation of descendants
on SetState(oObject, blnNewState)
using terms from application "OmniFocus"
tell oObject
set sequential to blnNewState
if pblnAllDescendantsInherit then
set lstTasks to tasks
repeat with oTask in lstTasks
my SetState(oTask, blnNewState)
end repeat
end if
end tell
end using terms from
end SetState

-- List of objects selected in the window
on SelectedObjects(oWin)
using terms from application "OmniFocus"
tell oWin
set refSeln to a reference to (selected trees of content)
if (count of refSeln) < 1 then
set refSeln to a reference to (selected trees of sidebar)
if (count of refSeln) < 1 then return {}
value of refSeln
end tell
end using terms from
end SelectedObjects


-- Simple test for list membership
-- used to ensure that we don't toggle the same project twice
on IsMember(oElement, lstList)
using terms from application "OmniFocus"
repeat with oItem in lstList
if id of oItem is id of oElement then return true
end repeat
false
end using terms from
end IsMember[/CODE]

vinyl_warrior 2010-06-24 08:38 AM

Awesome! I'm looking forward to testing this out :)

RobTrew 2011-04-07 06:19 AM

FWIW updating this because I find I am using a much simpler script these days.

This toggles the selected subtree between sequential and parallel.

If the selection is a twig (rather than an action group or project), the immediate parent and all its descendants are all toggled to the same state.

If the selection is a parent (i.e. a project or a action group), then it and all its descendants are toggled to a uniform state.

[CODE]tell application id "OFOC"
tell front document window of front document
set refTrees to a reference to (selected trees of content where class of its value is task or class of its value is project)
if (count of refTrees) < 1 then set refTrees to a reference to (selected trees of sidebar where class of its value is project)
end tell

tell (value of refTrees) as list
if (count) < 1 then return
tell first item
if (class ≠ project) and (count of its tasks) < 1 then
set oParent to container
else
set oParent to it
end if
end tell
end tell

tell oParent
set sequential to not (sequential)
set sequential of flattened tasks to sequential
end tell
end tell
[/CODE]

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


All times are GMT -8. The time now is 03:54 AM.

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