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 Today's Posts

 
Newbie try to get recursive Context Thread Tools Search this Thread Display Modes
Hi,

im trying with applescript since 1 week, somthing is working fine, somthing not.

1) Is there an easy way to get a task by id? Can't find anything.


2) So please have look to my coding, I try to get all contexts from omnifocus.
Example:
node1
node11
node111
node12
node2

In the main part of my script i try to get all contexts with child contexts (node1). With this node, I will call my subroutine to get the child nodes. This sub routine should be called in a recursive way to receive all contexts. But i have developed a endless loop. In my coding mycontext2 is every time node1.

Any ideas? Thanks in advance Paul


Code:
tell application "OmniFocus"
	tell first document
		repeat with mycontext in contexts
			set myCounter to count of contexts in mycontext
			if myCounter > 0 then
				my getContextChilds(mycontext)
			end if
		end repeat
	end tell	
end tell

on getContextChilds(mycontext2)
	tell application "OmniFocus"
			repeat with myChildcontext in mycontext2
				set myChildContextName to name of myChildcontext
				my getContextChilds(myChildcontext)
			end repeat
		end tell
end getContextChilds

Last edited by PaulMeier; 2010-09-07 at 06:29 AM..
 
To get a task by id

Code:
set oTask to task id "gai3KfHDdg2" of front document
The simplest route to a context list is to download the OF 1.8 sneaky peak, in which you can write:

Code:
-- OF 1.8 only
tell application id "com.omnigroup.omnifocus"
	tell front document
		set lstContexts to flattened contexts
	end tell
end tell
If you want something which will also work with earlier versions of OF:

Code:
tell application id "com.omnigroup.omnifocus"
	set oDoc to front document
	set lstContexts to my GetContexts(oDoc)
end tell

on GetContexts(oParent)
	tell application id "com.omnigroup.omnifocus"
		tell oParent
			set lstContexts to contexts
			-- contexts under this parent which themselves have sub-contexts
			set lstParents to contexts where (contexts of contexts) is not contexts
			repeat with oParent in lstParents
				set lstContexts to lstContexts & my GetContexts(oParent)
			end repeat
			return lstContexts
		end tell
	end tell
end GetContexts
--
 
Thank you it works, perfect. But, if you have a little bit time, can you explain what is wrong on my idea with recursion? I don't understand the error....

Many Thanks
 
Perhaps the best news of OF 1.8 is that users no longer need to write recursive scripts :-)

In addition to the flattened contexts collection, the enhanced Applescript library now also offers flattened folders, flattened projects, and and flattened tasks.
 
Quote:
Originally Posted by PaulMeier View Post
Thank you it works, perfect. But, if you have a little bit time, can you explain what is wrong on my idea with recursion? I don't understand the error....
The problem is that your recursion isn't simplifying the work to be done, probably because the names are so confusing. Here's a version of your script that will log the context names, indented, to your event log:

Code:
tell application "OmniFocus"
	set prefixStr to ""
	
	tell first document
		repeat with mycontext in contexts
			my printContext(mycontext, prefixStr)
		end repeat
	end tell
end tell

on printContext(mycontext, prefixStr)
	
	tell application "OmniFocus"
		-- print name of context
		log prefixStr & name of mycontext
		if (count of contexts of mycontext) > 0 then
			-- context has nested items
			set oldprefixStr to prefixStr
			set prefixStr to prefixStr & "--"
			
			repeat with myChildcontext in contexts of mycontext
				if (count of contexts of myChildcontext) > 0 then
					-- further structure, recurse on it
					my printContext(myChildcontext, prefixStr)
				else
					-- nothing beneath this child, just print its name
					log prefixStr & name of myChildcontext
				end if
			end repeat
			
			set prefixStr to oldprefixStr
		end if
	end tell
end printContext
 
whpalmer4's code is an excellent and salutary reminder that even in OF 1.8 recursion can still be an efficient and natural way of doing something - flattening a nested structure does, after all, discard information.

If recursion feels counter-intuitive, however, we can still write simple non-recursive code which retrieves information about depth of nesting, and allows us, for example, to indent.

Here is an example with two simple loops, one to walk straight through the flattened list of contexts, and another to check how deeply nested each context is.

(If this costs a few hundredths of a second in run-time, but saves 10mins of scripting time, it may not be a bad deal :-)

Code:
property pMyPrefix : "-->"

set strLog to ""
tell application "OmniFocus"
	repeat with oContext in flattened contexts of front document
		set strLog to strLog & my Indented(oContext) & return
	end repeat
end tell


display dialog strLog buttons {"OK"} with title "Indented Contexts"


on Indented(oContext)
	set {strTabs, strName} to {"", name of oContext}
	repeat while class of (container of oContext) is not document
		set oContext to container of oContext
		set strTabs to strTabs & tab
	end repeat
	strTabs & pMyPrefix & strName
end Indented
--

Last edited by RobTrew; 2010-09-08 at 03:34 AM..
 
Perfect - Thank you very much
 
 




Similar Threads
Thread Thread Starter Forum Replies Last Post
A newbie is confused lorew OmniPlan General 0 2012-08-14 11:10 PM
Newbie question re editing context list kshell OmniFocus 1 for Mac 2 2008-07-20 07:05 AM


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


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