The Omni Group Forums

The Omni Group Forums (http://forums.omnigroup.com/index.php)
-   OmniFocus Extras (http://forums.omnigroup.com/forumdisplay.php?f=44)
-   -   Reusable approach to exporting from OF (http://forums.omnigroup.com/showthread.php?t=15469)

gcrump 2014-01-19 04:13 AM

OF2OO With Project Crashing
 
Rob,

It seems like since the shift to OO4 this script crashes when exporting. I tried to figure out where but with no luck. Any chance you can look at this to see if it is possible to make it work with OO4?

Thanks,

George

[CODE]
-- Copies anything selected in Omnifocus (Project or Context View) into OmniOutliner
-- Including the following fields: DONE, NOTE, CONTEXT or PROJECT, START, DUE, COMPLETED, DURATION, FLAGGED}
-- Note that the whole sub-tree is copied, so only 'parent' elements need to be selected.
-- The destination is the currently open OmniOutliner document.
-- (A fresh OmniOutliner document is created if none is open)

property pPROJECT : "project"
property pTASK : "task"
property pINBX_TASK : "inbox task"
property pITEM : "item"

property pColProjContext : 3 as integer
property pSTART : 4 as integer
property pDUE : 5 as integer
property pCOMPLETED : 6 as integer
property pDURATION : 7 as integer
property pFLAGGED : 8 as integer

on run
PlaceInOO(SelectedInOF())
end run

-- READ SELECTED OmniFocus CONTENT TREE(S) TO NESTED APPLESCRIPT LISTS - Ver.04

on SelectedInOF()
tell application "OmniFocus"
tell front window
set blnContext to ((selected view mode identifier) is not equal to pPROJECT)

repeat with oPanel in {content, sidebar}
set lstNodes to value of (selected trees of oPanel where class of its value ≠ item)
set lngNodes to count of lstNodes
if lngNodes > 0 then exit repeat
end repeat
set blnAll to (lngNodes < 1)
if blnAll then set lstNodes to value of (trees of content where class of its value ≠ item)
end tell

repeat with i from 1 to length of lstNodes
tell item i of lstNodes
if blnContext then
set oParent to its containing project
else
set oParent to its context
end if
if oParent is not missing value then
set strParent to my ReadNodePath(oParent)
else
set strParent to ""
end if
if (its class) is not folder then
set item i of lstNodes to {name, completed, my ListSubNodes(its tasks, blnContext, blnAll), note, strParent, start date, due date, completion date, estimated minutes, flagged}
else
set item i of lstNodes to {name, false, my ListSubNodes(its projects, blnContext, blnAll), note, strParent, missing value, missing value, missing value, missing value, false}
end if
end tell
end repeat

return {lstNodes, blnContext}
end tell
end SelectedInOF

on ListSubNodes(lstNodes, blnContext, blnAll)
if lstNodes ≠ {} then
using terms from application "OmniFocus"
repeat with i from 1 to length of lstNodes
tell item i of lstNodes
if blnContext then
set oParent to its containing project
else
set oParent to its context
end if
if oParent is not missing value then
set strParent to ReadNodePath(oParent)
else
set strParent to ""
end if

set item i of lstNodes to {name, completed, my ListSubNodes(its tasks, blnContext, blnAll), note, strParent, start date, due date, completion date, estimated minutes, flagged}
end tell
end repeat
return lstNodes
end using terms from
else
{}
end if
end ListSubNodes


-- PLACING IN OMNIOUTLINER

on PlaceInOO({lstTasks, blnContext})
if (length of lstTasks > 0) then
tell application id "OOut"
activate
set docTarget to make new document at before documents
set bounds of (front window) to {0, 0, 1000, 500}

-- Create required columns
tell docTarget
if blnContext then
make new column with properties {column type:styled text, name:"Project"}
else
make new column with properties {column type:styled text, name:"Context"}
end if
repeat with recProps in {{column type:datetime, name:"Start"}, {column type:datetime, name:"Due"}, {column type:datetime, name:"Completed"}, ¬
{column type:duration, name:"Duration"}, {column type:checkbox, name:"Flagged", width:64}}
make new column with properties recProps
end repeat
end tell

my Tasks2OO(lstTasks, docTarget)
tell docTarget to set expanded of every row to true
return docTarget
end tell
end if
end PlaceInOO

on Tasks2OO(lstTasks, oParent)
tell application id "OOut"
tell oParent
repeat with oTask in lstTasks
set {strName, blnDone, lstChiln, strNote, strProjContext, dteStart, dteDue, dteDone, lngMins, blnFlagged} to oTask

if length of strNote > 0 then
set recRow to {topic:strName, note:strNote, expanded:true}
else
set recRow to {topic:strName, expanded:true}
end if
if blnDone then set recRow to recRow & {state:checked}

tell (make new row at end of children with properties recRow)
if strProjContext is not missing value then set value of cell pColProjContext to strProjContext
if dteStart is not missing value then set value of cell pSTART to dteStart
if dteDue is not missing value then set value of cell pDUE to dteDue
if blnDone then if (dteDone is not missing value) then set value of cell pCOMPLETED to dteDone
if lngMins > 0 then set value of cell pDURATION to lngMins / 60
if blnFlagged then set state of cell pFLAGGED to checked

if (length of lstChiln > 0) then my Tasks2OO(lstChiln, it)
end tell
end repeat
end tell
end tell
end Tasks2OO


on ReadNodePath(oNode)
set lst to GetNodePath(oNode, "")
set {dlm, my text item delimiters} to {my text item delimiters, ":"}
set str to lst as string
set my text item delimiters to dlm
return str
end ReadNodePath

on GetNodePath(oNode, strProjMarker)
tell application id "OFOC"
set {cClass, oParent, strName} to {class, container, name} of oNode
set cParentClass to class of oParent
if cParentClass is document or cParentClass is folder then
if cClass is task or cClass is project then
tell oNode
if (cClass is project) or (it is root task of its containing project) then
if strProjMarker ≠ "" then
set strName to strName & strProjMarker
end if

set oFolder to folder of containing project of oNode
if oFolder is not missing value then
set cParentClass to folder
set oParent to oFolder
end if
end if
end tell
end if
end if
if cParentClass is not document then
return my GetNodePath(oParent, strProjMarker) & {strName}
else
return {strName}
end if
end tell
end GetNodePath

[/CODE]

Ken Case 2014-01-21 06:09 AM

[QUOTE=gcrump;129099]It seems like since the shift to OO4 this script crashes when exporting. I tried to figure out where but with no luck. Any chance you can look at this to see if it is possible to make it work with OO4?[/QUOTE]

It looks like OmniOutliner 4 is returning an error when it's asked to make a new row with the expanded property already set, which is triggered by these lines in that script:

[CODE] if length of strNote > 0 then
set recRow to {topic:strName, note:strNote, expanded:true}
else
set recRow to {topic:strName, expanded:true}
end if[/CODE]

We'll fix that, it shouldn't return an error.

In the meantime, the workaround is to set the expansion state after the row has already been created—and it turns out the script was already doing just that:

[CODE] tell docTarget to set expanded of every row to true[/CODE]

So all we need to do is to modify the script to stop trying to set the initial expansion state of a row:

[CODE] if length of strNote > 0 then
set recRow to {topic:strName, note:strNote}
else
set recRow to {topic:strName}
end if[/CODE]

Here is the full, working script:

[CODE]-- Copies anything selected in Omnifocus (Project or Context View) into OmniOutliner
-- Including the following fields: DONE, NOTE, CONTEXT or PROJECT, START, DUE, COMPLETED, DURATION, FLAGGED}
-- Note that the whole sub-tree is copied, so only 'parent' elements need to be selected.
-- The destination is the currently open OmniOutliner document.
-- (A fresh OmniOutliner document is created if none is open)

property pPROJECT : "project"
property pTASK : "task"
property pINBX_TASK : "inbox task"
property pITEM : "item"

property pColProjContext : 3 as integer
property pSTART : 4 as integer
property pDUE : 5 as integer
property pCOMPLETED : 6 as integer
property pDURATION : 7 as integer
property pFLAGGED : 8 as integer

on run
PlaceInOO(SelectedInOF())
end run

-- READ SELECTED OmniFocus CONTENT TREE(S) TO NESTED APPLESCRIPT LISTS - Ver.04

on SelectedInOF()
tell application "OmniFocus"
tell front window
set blnContext to ((selected view mode identifier) is not equal to pPROJECT)

repeat with oPanel in {content, sidebar}
set lstNodes to value of (selected trees of oPanel where class of its value ≠ item)
set lngNodes to count of lstNodes
if lngNodes > 0 then exit repeat
end repeat
set blnAll to (lngNodes < 1)
if blnAll then set lstNodes to value of (trees of content where class of its value ≠ item)
end tell

repeat with i from 1 to length of lstNodes
tell item i of lstNodes
if blnContext then
set oParent to its containing project
else
set oParent to its context
end if
if oParent is not missing value then
set strParent to my ReadNodePath(oParent)
else
set strParent to ""
end if
if (its class) is not folder then
set item i of lstNodes to {name, completed, my ListSubNodes(its tasks, blnContext, blnAll), note, strParent, start date, due date, completion date, estimated minutes, flagged}
else
set item i of lstNodes to {name, false, my ListSubNodes(its projects, blnContext, blnAll), note, strParent, missing value, missing value, missing value, missing value, false}
end if
end tell
end repeat

return {lstNodes, blnContext}
end tell
end SelectedInOF

on ListSubNodes(lstNodes, blnContext, blnAll)
if lstNodes ≠ {} then
using terms from application "OmniFocus"
repeat with i from 1 to length of lstNodes
tell item i of lstNodes
if blnContext then
set oParent to its containing project
else
set oParent to its context
end if
if oParent is not missing value then
set strParent to ReadNodePath(oParent)
else
set strParent to ""
end if

set item i of lstNodes to {name, completed, my ListSubNodes(its tasks, blnContext, blnAll), note, strParent, start date, due date, completion date, estimated minutes, flagged}
end tell
end repeat
return lstNodes
end using terms from
else
{}
end if
end ListSubNodes


-- PLACING IN OMNIOUTLINER

on PlaceInOO({lstTasks, blnContext})
if (length of lstTasks > 0) then
tell application id "OOut"
activate
set docTarget to make new document at before documents
set bounds of (front window) to {0, 0, 1000, 500}

-- Create required columns
tell docTarget
if blnContext then
make new column with properties {column type:styled text, name:"Project"}
else
make new column with properties {column type:styled text, name:"Context"}
end if
repeat with recProps in {{column type:datetime, name:"Start"}, {column type:datetime, name:"Due"}, {column type:datetime, name:"Completed"}, ¬
{column type:duration, name:"Duration"}, {column type:checkbox, name:"Flagged", width:64}}
make new column with properties recProps
end repeat
end tell

my Tasks2OO(lstTasks, docTarget)
tell docTarget to set expanded of every row to true
return docTarget
end tell
end if
end PlaceInOO

on Tasks2OO(lstTasks, oParent)
tell application id "OOut"
tell oParent
repeat with oTask in lstTasks
set {strName, blnDone, lstChiln, strNote, strProjContext, dteStart, dteDue, dteDone, lngMins, blnFlagged} to oTask

if length of strNote > 0 then
set recRow to {topic:strName, note:strNote}
else
set recRow to {topic:strName}
end if
if blnDone then set recRow to recRow & {state:checked}

tell (make new row at end of children with properties recRow)
if strProjContext is not missing value then set value of cell pColProjContext to strProjContext
if dteStart is not missing value then set value of cell pSTART to dteStart
if dteDue is not missing value then set value of cell pDUE to dteDue
if blnDone then if (dteDone is not missing value) then set value of cell pCOMPLETED to dteDone
if lngMins > 0 then set value of cell pDURATION to lngMins / 60
if blnFlagged then set state of cell pFLAGGED to checked

if (length of lstChiln > 0) then my Tasks2OO(lstChiln, it)
end tell
end repeat
end tell
end tell
end Tasks2OO


on ReadNodePath(oNode)
set lst to GetNodePath(oNode, "")
set {dlm, my text item delimiters} to {my text item delimiters, ":"}
set str to lst as string
set my text item delimiters to dlm
return str
end ReadNodePath

on GetNodePath(oNode, strProjMarker)
tell application id "OFOC"
set {cClass, oParent, strName} to {class, container, name} of oNode
set cParentClass to class of oParent
if cParentClass is document or cParentClass is folder then
if cClass is task or cClass is project then
tell oNode
if (cClass is project) or (it is root task of its containing project) then
if strProjMarker ≠ "" then
set strName to strName & strProjMarker
end if

set oFolder to folder of containing project of oNode
if oFolder is not missing value then
set cParentClass to folder
set oParent to oFolder
end if
end if
end tell
end if
end if
if cParentClass is not document then
return my GetNodePath(oParent, strProjMarker) & {strName}
else
return {strName}
end if
end tell
end GetNodePath[/CODE]

Hope this helps!

gcrump 2014-01-22 02:57 AM

Ken, It works perfectly thank you very much. I'm impressed! I was on the fence about upgrading to 4.0, You just cinched the deal! Plus I'll by OO for my iPad.

I do have one request that maybe you or someone else could help with. When I run this script in a context view the contexts don't export. When I run it from the project view they do. Is there anyway to have the context with full hierarchy also exported?

Not critical would be nice though.

joshfree 2014-03-13 10:01 AM

When I copy the script and paste it into either TextWrangler or AppleScript Editor, I lose all the line breaks. (They seem to come through as multiple tabs, but the code is kind of a mess.).. is that normal? Am I doing something wrong? I'm not a programmer, just a user of most of the Omni apps, so sorry for my ignorance.

Ken Case 2014-03-16 11:19 AM

[QUOTE=joshfree;129856]When I copy the script and paste it into either TextWrangler or AppleScript Editor, I lose all the line breaks. (They seem to come through as multiple tabs, but the code is kind of a mess.).. is that normal?[/QUOTE]

No, that's not normal; sounds like it might be a browser-specific issue? (It sounds like "Copy" in your web browser is encoding those lines in an unusual way.) In OmniWeb (and presumably Safari and hopefully most other OS X web browsers), if I copy that text from this page to AppleScript Editor each line comes across with proper line breaks.

cbeaudj 2014-03-23 09:19 PM

Script no longer working?
 
Hi all, I was able to get Ken's script working last week when I was using the trial version of OO4, but now that I bought a licence for OO4 (standard) the script no longer works.

Upon running the script I now get the following error:

[I]error "OmniOutliner got an error: Can’t make class «class OOcl»." number -2710 from «class OOcl» to class[/I]

Which comes from this line of code:
[I]make new «class OOcl» with properties {«class OOct»:«constant OOCtOct0», name:"Context"}[/I]

I tried copying Ken's code into the AppleScript Editor once again and re-compiling, and I get the following error in the editor:

[I]Syntax Error: Expected “,” or “}” but found class name.[/I]

which is for the following line of code:
[I]if blnContext then
make new column with properties {column type:styled text, name:"Project"}[/I]

Any ideas as to why this might be happening? Do I require OO4 pro to be able to do this?

Thanks for your help,

C

Lizard 2014-03-24 10:05 AM

Yes, AppleScript support is a Pro feature in OmniOutliner 4. See the bottom of this page for more details: [url]http://www.omnigroup.com/omnioutliner/[/url]

cbeaudj 2014-03-24 11:25 AM

Thanks Lizard, I somehow missed that. Cheers


All times are GMT -8. The time now is 11:38 PM.

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