The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniFocus Extras (http://forums.omnigroup.com/forumdisplay.php?f=44)
-   -   Newbie try to get recursive Context (http://forums.omnigroup.com/showthread.php?t=17824)

PaulMeier 2010-09-07 06:25 AM

Newbie try to get recursive Context
 
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
[/CODE]

RobTrew 2010-09-07 06:59 AM

To get a task by id

[CODE]set oTask to task id "gai3KfHDdg2" of front document[/CODE]

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[/CODE]

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[/CODE]

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

PaulMeier 2010-09-07 08:01 AM

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

RobTrew 2010-09-07 11:38 AM

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.

whpalmer4 2010-09-07 01:38 PM

[QUOTE=PaulMeier;85100]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....
[/QUOTE]
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
[/code]

RobTrew 2010-09-07 10:32 PM

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[/CODE]

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

PaulMeier 2010-09-13 12:04 PM

Perfect - Thank you very much


All times are GMT -8. The time now is 12:52 AM.

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