Is OO4 Applescript broken?

The scripts and example outline may be downloaded from here : https://dl.dropboxusercontent.com/u/41900569/OO%20Applescript%20problem.zip

Hi,

I have used Applescript off an on for a number of years with OO3 and am attempting to migrate my scripts to OO4. Errors in a script normally cause a useful error message to be posted but with OO4 I am seeing a general applescript error “OmniOutliner got an error : AppleEvent handler failed” associated with the script line :

set LatestDate to make new child at end of rows of ClosedActions with properties {topic:dateString}

Now I have written the script as I entered it (and run using OO3), but when the error occurs the complete script is rewritten in an intermediate language rewriting the line I entered to :

set LatestDate to make new «class OOsu» at end of every «class OOrw» of ClosedActions with properties {«class OOtp»:dateString}

I have put the two versions of my script at the end of this post.

I have contacted support and received a most unhelpful reply : "The amount of AppleScript writing support we’re able to offer is pretty limited. " she goes on to point me to the limited information on their web site and then attempts to get me to look at omni-focus.

I use Omnioutliner as a general purpose task/project management tool much as others use Curio, Circus Ponies Notebook or Tinderbox. Now both Curio and CP Notebook have better GUI and Tinderbox has better note manipulation but AppleScript and OminOutliner three allowed flexible data manipulation and the creation of custom applications. Furthermore Omnigroup were willing to support the use of Applescript and offer help and support which includes a user guide and a number of example scripts. So I used OmniOutliner three with Applescript.

Now I find myself in the situation where I have “upgraded” to OO4 and my scripts no longer work and Omni and unable to offer useful support.

The old forums use to have several users that could do wonders with Applescript and Omnioutliner and Omnigraffle but they do not seem to be posting to the new forum but I post in hope while blowing the dust off my copies of Tinderbox and Curio…

First the working OO3 script (N.B. the script expects the outline to have certain named styles defined)

(*

20131002-0930
This script is used to aid the management of a list of actions. It is designed to operate with an
OmniOutliner pro file that has multiple columns and some predefined styles.

The user may edit these styles in the document.

The first Column may be named anything but it makes sence to cal it Action or ToDo
The order of the following columns is NOT important but does affect any sorts that may be applied
Task - Type popUp groups actions to tasks in sorts
Start - Type Date - user enters a start date e.g. next Thursday
Priority - Type PopUp List: Normal; High
Completed - Type Date - This routine enters a date stamp if the row is ticked

The priority column may be set to either normal or high. The high priority only has an effect once the start date is reached.

The user may edit the styles inthe oo3 document to change how the text looks

)
– version 1.0 19th April 2013 © Simon Knight
– version 2.0 30 September 2013
– version 3.0 2nd October 2013
– Changed the column order and added date stamping of completed items
– Use at your own risk
– set up some variables
–set today to the present date
– set the time to near midnight
(
otherwise, you get both date and time down to second, which screws up your comparison later on *)
set today to (current date)
set time of today to 23 * hours + 59 * minutes + 59 – 1 second to midnight
log today

set dateString to month of today & " - " & year of today as string – e.g. “May - 2013”
– set var to refer to this document
set original to front document of application “OmniOutliner”
–beep
tell front document of application “OmniOutliner”

-- Trap for script being run in a brand new blank documnt
-- Later perhaps
-- check that script is applicable to the OO file  should contain 3 columns
if title of every column does not contain {"Action", "Priority", "Task", "Start", "Completed"} then
	
	display dialog "You need a minimum of five columns 'Action, Priority, Task, Start, Completed' to use this script " buttons "Cancel" default button 1
end if

-- A brand new document may not have any rows so trap for this condition
-- create a blank row if the document has no rows (i.e brand new document) - unlikely
if not (exists (last child of original)) then
	tell original
		make new row at end of rows
	end tell
end if




-- set up some counter variables
set OpenCount to 0
set CompleteCounter to 0
set rowCounter to 0

--set the style variables

set StyleHigh to named style ("HighPriority")
set StyleNormal to named style ("NormalPriority")
set StyleWaiting to named style ("LowPriority")
set StyleCompleted to named style ("Completed")
set StyleArchive to named style ("Archived")



--repeat with oneRow in (every row of original whose level = 2)
repeat with oneRow in (every row of first child of original whose has subtopics of it is false)
	remove every named style from named styles of style of oneRow
	--add StyleTaskTitle to named styles of style of oneRow
end repeat

--set OpenActions to first child of original -- e.g Open Actions
--set ClosedActions to second child of original -- e.g Closed Actions

--Loop through each row of the first section of the document -  this is where data should have been entered
-- this section first removes the styles and then resets them acording to status and priority
repeat with oneRow in (every row of first child of original whose has subtopics of it is false)
	--remove every named style from named styles of style of oneRow
	set myparent to the parent of oneRow
	set MyParentAction to value of cell "Action" of myparent
	set tTask to value of cell "Task" of oneRow
	--display dialog "My Parent action is :" & MyParentAction & " tTask is " & tTask
	
	
	if tTask is missing value or tTask is "" then
		set value of cell "Task" of oneRow to MyParentAction
		--display dialog "Inside the if statement " & MyParentAction
	end if
	
	set RowLevel to (get the level of oneRow) --Task elements will be 3 and lower
	
	if RowLevel > 1 then
		remove every named style from named styles of style of oneRow
		
		if (state of oneRow is equal to checked) then
			--The Action is "checked" so set its style to the completed style and add a date stamp if required
			add StyleCompleted to named styles of style of oneRow
			--Add a date stamp
			set value of cell "Completed" of oneRow to today
			
			-- the completed action record has now been given a date stamp
			
		else
			--  Action is not checked  so add required syle i.e. set its colour
			-- reset the completed date to null, the user may reactivate the task element
			set value of cell "Completed" of oneRow to missing value
			
			--read in the startdate
			set TheStartDate to value of cell "Start" of oneRow -- cell is of type date
			if TheStartDate is missing value then
				set value of cell "Start" of oneRow to today
			end if
			set ElementPriority to value of cell "Priority" of oneRow
			if ElementPriority is missing value then
				set ElementPriority to "Normal"
				set value of cell "Priority" of oneRow to ElementPriority
			end if
			-- set the style depending on the date and priority
			if TheStartDate > today then
				--If startdate is in the future then set the task not started style waiting
				add StyleWaiting to named styles of style of oneRow
				-- set value of cell "Priority" of oneRow to "High"
			else
				-- the task element is live i.e. not set to start in the future
				-- Read in its priority
				if ElementPriority = "High" then
					add StyleHigh to named styles of style of oneRow
				else
					--Set normal active style
					add StyleNormal to named styles of style of oneRow
				end if -- Priority setting
			end if -- Startdate check
		end if -- checking if the row has been ticked / checked
	end if -- Check that row has no children and is at a level > 2
	
end repeat
-- End of loop that processes each row setting its display style

--*** The next section does the moving of the completed actions

(* Check for a date stamped subsection for today - used to store completed items*)
-- Variable datestring is created above and is in the form of "April - 2013"	
set OpenActions to first child of original -- e.g Open Actions
set ClosedActions to second child of original -- e.g Closed Actions
try
	-- latestdate is a container at level 2 in the last section
	set LatestDate to last row of ClosedActions whose level = 2
on error
	--add a new row as error is thrown when there are no rows in section
	-- note datestring is a string in the form month - year e.g. "May - 2013"
	set LatestDate to make new child at end of rows of ClosedActions with properties {topic:dateString}
end try

-- This section checks that the current month container exists, if not it is created
if dateString is equal to (topic of LatestDate) then -- if date from record month - year is equal to last container
	set LastRowClosedActions to LatestDate -- very last row of document could be date container or item
else
	-- add new datestamped subsection
	set LastRowClosedActions to make new child at end of rows of ClosedActions with properties {topic:dateString}
	--add StyleArchive to named styles of style of LatestDate
end if

-- Some of rob trew's code

--set {rowList, rowDone} to {child 1, child 2}

--set refDone to a reference to (children of rowList where state is checked)
--move refDone to end of children of rowDone

-- end of rob's code



-- move the checked items of the first section to the last section
move (every row of first child of original whose state is checked and has subtopics of it is false) to end of children of LastRowClosedActions


repeat with oneRow in (every row of last child of second child of original whose state is checked and has subtopics of it is false)
	-- Now modify the text of the action to include a date stamp
	set tDate to short date string of today
	set tActionText to the value of cell "Action" of oneRow
	set tActionText to tDate & " - " & tActionText
	set the value of cell "Action" of oneRow to tActionText
end repeat

-- uncheck the rows in the last section
set the state of every row of ClosedActions to unchecked
--hoist LastSection
--set expanded of newRow to true

try
	save original
on error number errNum from badObj -- time out error handling
end try

end tell


******** NOW the same script converted for OO4 and run once note how the commands have been changed when the error occured :

(*

Updated 08 Aug 2014 to run on Outliner version 4
This script is used to aid the management of a list of actions. It is designed to operate with an
OmniOutliner pro file that has multiple columns and some predefined styles.

The user may edit these styles in the document.

The first Column may be named anything but it makes sence to cal it Action or ToDo
The order of the following columns is NOT important but does affect any sorts that may be applied
Task - Type popUp groups actions to tasks in sorts
Start - Type Date - user enters a start date e.g. next Thursday
Priority - Type PopUp List: Normal; High
Completed - Type Date - This routine enters a date stamp if the row is ticked

The priority column may be set to either normal or high. The high priority only has an effect once the start date is reached.

The user may edit the styles inthe oo3 document to change how the text looks

)
– version 1.0 19th April 2013 © Simon Knight
– version 2.0 30 September 2013
– version 3.0 2nd October 2013
– version 4.0 08 Aug 2014 – converted to run on OO version 4
– Changed the column order and added date stamping of completed items
– Use at your own risk
– set up some variables
–set today to the present date
– set the time to near midnight
(
otherwise, you get both date and time down to second, which screws up your comparison later on *)
set today to (current date)
set time of today to 23 * hours + 59 * minutes + 59 – 1 second to midnight
log today

set dateString to month of today & " - " & year of today as string – e.g. “May - 2013”
– set var to refer to this document
set original to front document of application id “com.omnigroup.OmniOutliner4”
–beep
–tell front document of application “OmniOutliner3 Professional”
tell front document of application id “com.omnigroup.OmniOutliner4”

--! TBD Trap for script being run in a brand new blank documnt

-- check that script is applicable to the OO file  should contain the required columns
if «class OOtt» of every «class OOcl» does not contain {"Action", "Priority", "Task", "Start", "Completed"} then
	
	display dialog "You need a minimum of five columns 'Action, Priority, Task, Start, Completed' to use this script " buttons "Cancel" default button 1
end if

-- A brand new document may not have any rows so trap for this condition
-- create a blank row if the document has no rows (i.e brand new document) - unlikely
if not (exists (last «class OOsu» of original)) then
	tell original
		make new «class OOrw» at end of every «class OOrw»
	end tell
end if




-- set up some counter variables
set OpenCount to 0
set CompleteCounter to 0
set rowCounter to 0

--set the style variables

set StyleHigh to «class OSns» ("HighPriority")
set StyleNormal to «class OSns» ("NormalPriority")
set StyleLow to «class OSns» ("LowPriority")
set StyleCompleted to «class OSns» ("Completed")
set StyleArchive to «class OSns» ("Archived")



--repeat with oneRow in (every row of original whose level = 2)
repeat with oneRow in (every «class OOrw» of first «class OOsu» of original whose «class OOhc» of it is false)
	«event OFssremv» every «class OSns» given «class from»:every «class OSns» of «class OSst» of oneRow
	--add StyleTaskTitle to named styles of style of oneRow
end repeat

--set OpenActions to first child of original -- e.g Open Actions
--set ClosedActions to second child of original -- e.g Closed Actions

--Loop through each row of the first section of the document -  this is where data should have been entered
-- this section first removes the styles and then resets them acording to status and priority
repeat with oneRow in (every «class OOrw» of first «class OOsu» of original whose «class OOhc» of it is false)
	--remove every named style from named styles of style of oneRow
	set myparent to the «class OOpa» of oneRow
	set MyParentAction to «class valL» of «class OOce» "Action" of myparent
	set tTask to «class valL» of «class OOce» "Task" of oneRow
	--display dialog "My Parent action is :" & MyParentAction & " tTask is " & tTask
	
	
	if tTask is missing value or tTask is "" then
		set «class valL» of «class OOce» "Task" of oneRow to MyParentAction
		--display dialog "Inside the if statement " & MyParentAction
	end if
	
	set RowLevel to (get the «class OOlv» of oneRow) --Task elements will be 3 and lower
	
	if RowLevel > 1 then
		«event OFssremv» every «class OSns» given «class from»:every «class OSns» of «class OSst» of oneRow
		
		if («class OOst» of oneRow is equal to «constant OOStOOS2») then
			--The Action is "checked" so set its style to the completed style and add a date stamp if required
			«event OFssiadd» StyleCompleted given «class to  »:every «class OSns» of «class OSst» of oneRow
			--Add a date stamp
			set «class valL» of «class OOce» "Completed" of oneRow to today
			
			-- the completed action record has now been given a date stamp
			
		else
			--  Action is not checked  so add required syle i.e. set its colour
			-- reset the completed date to null, the user may reactivate the task element
			set «class valL» of «class OOce» "Completed" of oneRow to missing value
			
			--read in the startdate
			set TheStartDate to «class valL» of «class OOce» "Start" of oneRow -- cell is of type date
			if TheStartDate is missing value then
				set «class valL» of «class OOce» "Start" of oneRow to today
			end if
			set ElementPriority to «class valL» of «class OOce» "Priority" of oneRow
			if ElementPriority is missing value then
				set ElementPriority to "Normal"
				set «class valL» of «class OOce» "Priority" of oneRow to ElementPriority
			end if
			-- set the style depending on the date and priority
			if TheStartDate > today then
				--If startdate is in the future then set the task style to low
				«event OFssiadd» StyleLow given «class to  »:every «class OSns» of «class OSst» of oneRow
				-- set value of cell "Priority" of oneRow to "High"
			else
				-- the task element is live i.e. not set to start in the future
				-- Read in its priority
				if ElementPriority = "High" then
					«event OFssiadd» StyleHigh given «class to  »:every «class OSns» of «class OSst» of oneRow
				else
					--Set normal active style
					«event OFssiadd» StyleNormal given «class to  »:every «class OSns» of «class OSst» of oneRow
				end if -- Priority setting
			end if -- Startdate check
		end if -- checking if the row has been ticked / checked
	end if -- Check that row has no children and is at a level > 2
	
end repeat
-- End of loop that processes each row in the first section i.e. OPEN, setting its display style

--*** The next section does the moving of the completed actions

(* Check for a date stamped subsection for today - used to store completed items*)
-- Variable datestring is created above and is in the form of "April - 2013"	
set OpenActions to first «class OOsu» of original -- e.g Open Actions
set ClosedActions to second «class OOsu» of original -- e.g Closed Actions
try
	-- latestdate is a container at level 2 in the last section
	set LatestDate to last «class OOrw» of ClosedActions whose «class OOlv» = 2
on error
	--add a new row as error is thrown when there are no rows in section
	-- note datestring is a string in the form month - year e.g. "May - 2013"
	set LatestDate to make new «class OOsu» at end of every «class OOrw» of ClosedActions with properties {«class OOtp»:dateString}
end try

-- This section checks that the current month container exists, if not it is created
-- Comment Out if you wish the closed items in one list 
if dateString is equal to («class OOtp» of LatestDate) then -- if date from record month - year is equal to last container
	set LastRowClosedActions to LatestDate -- very last row of document could be date container or item
else
	-- add new datestamped subsection
	set LastRowClosedActions to make new «class OOsu» at end of every «class OOrw» of ClosedActions with properties {«class OOtp»:dateString}
	--add StyleArchive to named styles of style of LatestDate
end if

-- End of the bit to be commented out

-- Some of rob trew's code

--set {rowList, rowDone} to {child 1, child 2}

--set refDone to a reference to (children of rowList where state is checked)
--move refDone to end of children of rowDone

-- end of rob's code



-- move the checked items of the first section to the last section
move (every «class OOrw» of first «class OOsu» of original whose «class OOst» is «constant OOStOOS2» and «class OOhc» of it is false) to end of every «class OOsu» of LastRowClosedActions


repeat with oneRow in (every «class OOrw» of last «class OOsu» of second «class OOsu» of original whose «class OOst» is «constant OOStOOS2» and «class OOhc» of it is false)
	-- Now modify the text of the action to include a date stamp
	set tDate to short date string of today
	set tActionText to the «class valL» of «class OOce» "Action" of oneRow
	set tActionText to tDate & " - " & tActionText
	set the «class valL» of «class OOce» "Action" of oneRow to tActionText
end repeat

-- uncheck the rows in the last section
set the «class OOst» of every «class OOrw» of ClosedActions to «constant OOStOOS0»
--hoist LastSection
--set expanded of newRow to true

try
	save original
on error number errNum from badObj -- time out error handling
end try

end tell

It looks like this forum is truncating some of the script code so please download the archive from the link at the top. Seems odd that this forum does not allow outlines and scripts to be attached.

Thanks for reading

Simon

I apologise for the poor use of the code tags in my post above. I can’t say I am all that happy with this new forum software.

Simon

In answer to my own question : no it is not broken. However, there is a but. When things go wrong Omni-Outliner 4 displays very general error messages e.g. "AppleEvent handler failed" whereas the same error in Omni-Outliner 3 is reported as "'READ ME!' is not a valid enumeration value for the specified column." (My code was attempting to write READ ME! to a column that was defined as a pop-up list and READ ME! was not a member of the list.)

The general error message makes it very difficult to rectify errors and led me to believe that there was something wrong with either the implementation of applescript or my installation of applescript. I now write and debug scripts in version 3 and then when working move them to version 4.

best wishes

Simon K.