The Omni Group
These forums are now read-only. Please visit our new forums to participate in discussion. A new account will be required to post in the new forums. For more info on the switch, see this post. Thank you!

Go Back   The Omni Group Forums > OmniFocus > OmniFocus Extras
FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
Applescript for dependent projects Thread Tools Search this Thread Display Modes
I threw together something that enables me to select two or more projects, then select one from among them to remain active. The rest are put On Hold, and tasks are added to all the selected projects with links between the projects. Here's the result after running the script:



This is what I've been doing by hand until now.

The "this project on hold pending"... tasks are easilly visible during my reviews and helps me remember why I put the project on hold.

And of course the last tasks in the Active Project is now to active the blocked ones.

Applescript still mystifies (and baffles) me sometimes, so I'm certain there are several ways I could have done this better - and aside from that this could probably benefit from some refactoring. Any feedback on the script and the approach would be welcome.

The script is attached to this post
Attached Thumbnails
Click image for larger version

Name:	OmniFocus.jpg
Views:	1478
Size:	37.5 KB
ID:	1008  
Attached Files
File Type: applescript Set project dependency.applescript (9.0 KB, 746 views)

Last edited by fudster; 2009-07-23 at 08:39 AM.. Reason: forgot to say where the script can be found
 
One more thing - I noticed in the Dictionary that projects have a "blocked" property:

blocked (boolean, r/o) : True if the project has a project that must be completed prior to it being actionable.

I haven't seen this implemented in the UI of OmniFocus - I've never seen a way to ascribe dependencies between projects in OmniFocus - only between tasks. Am I missing something?
 
The script appears to be corrupted when I download it. Could you upload it as a zip file, or use the forum's CODE tags to post the script in a post?
 
Sorry about that Greg, not sure why. Here's the script:

Code:
on run
    tell application "OmniFocus"
        tell front document
            tell document window 1
                set selectedTrees to selected trees of content
                
                set selectedTrees to selected trees of content
                if (count of selectedTrees) is less than 2 then
                    set selectedTrees to selected trees of sidebar
                end if
                
                set treeCount to count of selectedTrees
                
                if not treeCount ≥ 2 then
                    display dialog "more than two projects must be selected in order to set a dependency"
                    --should also check to make sure they're projects and not tasks 
                else
                    
                    -- obtain the project which is the "active" project, the one on which the others are waiting
                    --   build the list of names
                    set treeNames to {}
                    repeat with aTree in selectedTrees
                        set end of treeNames to name of aTree
                    end repeat
                    
                    --   obtain selection from user
                    set nameOfActiveTree to {choose from list treeNames with prompt "Choose the project that should remain active (all others will be placed on hold):"}
                    
                    --   now loop through the selected projects and grab the one the user specified, by name
                    set activeTree to missing value
                    repeat with aTree in selectedTrees
                        if (name of aTree as string) is equal to (nameOfActiveTree as string) then
                            set activeTree to aTree
                        end if
                    end repeat
                    set activeProject to the value of activeTree
                    
                    -- now do the stuff
                    repeat with aTree in selectedTrees
                        set aProject to the value of aTree
                        if aProject = activeProject then
                            
                        else
                            -- add task with link to the active project, and set the status to on hold
                            tell activeProject
                                set newTask to make new task with properties {name:"activate project: " & name of aProject, note:"omnifocus:///task/" & id of aProject & linefeed}
                            end tell
                            set status of aProject to on hold
                            
                            -- add task with link to the blocked project
                            tell aProject
                                set newTask to make new task at beginning with properties {name:"this project on hold pending completion of: " & name of activeProject, note:"omnifocus:///task/" & id of activeProject & linefeed}
                            end tell
                        end if
                    end repeat
                end if
            end tell
        end tell
    end tell
end run

-- TODO:
-- could create an accompanying script that locates the linked project in a task's notes, activates it, and then toggles the status of the task

Watch out for an annoyance with the selection - if there are non-projects (i.e. tasks) selected in the right pane, the script won't work. I haven't tested what it does in this scenario, but I should probably update the script to handle it.
 
Thanks for posting the code. That's a pretty nice script-I like it.
 
Quote:
Originally Posted by Greg Jones View Post
Thanks for posting the code. That's a pretty nice script-I like it.
No worries, thanks Greg!
 
Quote:
Originally Posted by fudster View Post
--should also check to make sure they're projects and not tasks
The simplest approach is probably to filter the selected trees with a where clause. Something, for example, like:

Code:
tell application "OmniFocus"
	tell front document
		-- GET SELECTED PROJECTS
		tell front document window
			repeat with oPanel in {content, sidebar}
				set refProjects to (a reference to (selected trees of oPanel where class of value is project))
				if (count of refProjects) > 1 then exit repeat
			end repeat
		end tell
		if (count of refProjects) < 2 then ¬
			display dialog "more than two projects must be selected in order to set a dependency" buttons {"OK"} cancel button "OK"
		
		--   CHOOSE ACTIVE PROJECT
		set lstNames to name of refProjects
		set varResponse to {choose from list (lstNames) with prompt "Choose the project that should remain active (all others will be placed on hold):"}
		if varResponse = false then return
		set strActive to varResponse as string
		set oActive to first flattened project where name = (strActive)
		set status of oActive to active
		
		-- SET OTHERS ON HOLD AND MAKE LINKS
		set lstOnHold to value of (selected trees of oPanel where (class of value is project) and (name ≠ strActive))
		repeat with oProj in lstOnHold
			set refClip to (a reference to the clipboard)
			tell oProj
				set strHTML to quoted form of ("<font face=\"helvetica\"><a href=\"" & "omnifocus:///task/" & id & "\">" & name & "</a></font><p>")
				do shell script "echo " & strHTML & "  | textutil -format html -convert rtf -stdin -stdout | pbcopy -Prefer rtf"
				tell oActive to set oTask to (make new task with properties {name:"activate project: " & name of oProj})
				my PasteToNote(oTask)
				
				set status to on hold
				set strHTML to quoted form of ("<font face=\"helvetica\"><a href=\"" & "omnifocus:///task/" & id of oActive & "\">" & name of oActive & "</a></font><p>")
				do shell script "echo " & strHTML & "  | textutil -format html -convert rtf -stdin -stdout | pbcopy -Prefer rtf"
				
				set oTask to (make new task at beginning with properties ¬
					{name:"this project on hold pending completion of: " & name of oActive})
				my PasteToNote(oTask)
			end tell
		end repeat
	end tell
end tell

on PasteToNote(oTask)
	tell application id "com.omnigroup.OmniFocus"
		tell content of front document window of front document to select {oTask}
		activate
	end tell
	tell application id "com.apple.systemevents"
		keystroke "'" using {command down} -- Edit note
		keystroke "v" using {command down} -- Paste
	end tell
end PasteToNote

Last edited by RobTrew; 2011-02-12 at 03:09 AM.. Reason: Amended code to allow for more legible links between projects
 
I notice that illegibility of raw links like omnifocus:///task/gnsId0vG3Jm causes a bit of cognitive friction.

It is possible to amend the code so that it hides these links behind the human-readable names of their target projects.



I have amended the code in the previous posting to illustrate this approach. (Note that System Events pasting seems to be the the only way of inserting the RTF links in the notes, so the code takes a second or two to run).

--
 
Quote:
Originally Posted by RobTrew View Post
hides these links behind the human-readable names of their target projects.
Thanks! I've been wondering how to do that from a script.
 
What I haven't found is a way of getting RTF content from a variable, the clipboard, or a reference thereto, straight into a note without pasting ...

Do tell me if you think of anything.
 
 


Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes


Similar Threads
Thread Thread Starter Forum Replies Last Post
Flexitime -- dependent projects? sgbotsford Applying OmniFocus 2 2013-04-15 10:05 AM
Acting on all projects using Applescript fudster OmniFocus Extras 29 2010-06-24 02:15 AM
Dependent Tasks Haynes OmniFocus 1 for Mac 6 2010-03-13 02:01 AM
Can Omniplan do this? 10,000 projects / AppleScript isv OmniPlan General 3 2007-07-04 03:00 AM
AppleScript Gurus: Projects -> Notes BwanaZulia OmniFocus 1 for Mac 6 2007-06-21 11:02 AM


All times are GMT -8. The time now is 01:06 AM.


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