Incomplete tasks - delete or complete?

If I have a task that I don’t want to complete, should I just delete it or mark as complete? I know if I delete it, it won’t be archived.

Thanks.

I use a simple hack to preserve the information while recognizing the task was not completed fully;

  1. change context to: task not fully complete by deadline.
  2. mark as done
2 Likes

Cool idea. I just implemented it in my workflow using a “😲 dropped” context.

Here’s an AppleScript to automate the process to “drop” tasks selected in the main document window.

property pDropContextName : "dropped" -- put the name here
property pAlsoMarkComplete : true -- set to false to change context only

on run {}

tell application "OmniFocus"
	
	-- get the context associated to the context name
	
	tell front document
		set theDropContextID to id of first item of (complete pDropContextName as context)
		set DropContext to (first flattened context whose id is theDropContextID)
	end tell
	
	-- get the tasks selected in the main window
	
	tell content of front document window of default document to ¬
		set theSelectionList to the value of every selected tree
	if the (count of items in theSelectionList) is 0 then abort
	
	-- change the state of every selected task
	
	repeat with theItem in theSelectionList
		set context of theItem to DropContext
		set the completed of theItem to pAlsoMarkComplete
	end repeat
	
end tell

end run


JJW

Here’s an update that fixes the if-then action to return not abort. It can also help avoid that you change the contexts on the wrong tasks because it includes a dialog confirmation with the number of items to be changed.

property pDropContextName : "dropped" -- change this to the name of your dropped context
property pAlsoMarkComplete : true -- set to false to change context only
property pConfirmChange : true -- set to false at your own risk!

on run {}

tell application "OmniFocus"
	
	-- get the context associated to the context name
	
	tell front document
		set theDropContextID to id of first item of (complete pDropContextName as context)
		set DropContext to (first flattened context whose id is theDropContextID)
	end tell
	
	-- get the tasks selected in the main window
	
	tell content of front document window of default document to ¬
		set theSelectionList to the value of every selected tree
	if the (count of items in theSelectionList) is 0 then
		return
	else
		if pConfirmChange then
			set theMessage to "Do you really want to drop "
			if pAlsoMarkComplete then set theMessage to theMessage & "and mark completed "
			set theMessage to theMessage & (count of items in theSelectionList) & " tasks?"
			display dialog theMessage buttons {"Yes", "No"} default button "No" with title "Drop OmniFocus Tasks"
			if (result = {button returned:"No"}) then return
		end if
	end if
	
	-- change the state of every selected task
	
	repeat with theItem in theSelectionList
		set context of theItem to DropContext
		set the completed of theItem to pAlsoMarkComplete
	end repeat
	
end tell

end run


JJW

In case anyone is interested, this modification will append the existing context to the name of the task before it changes the context …

repeat with theItem in theSelectionList
	set theCurrentContext to the name of the context of theItem
	set theNewName to the name of theItem & " > " & theCurrentContext
	set the name of theItem to theNewName
	set context of theItem to DropContext
	set the completed of theItem to pAlsoMarkComplete
end repeat


JJW

This version of the Applescript will also revert tasks that have been dropped back to an active state. I use it now also to reset dropped states for tasks on projects that have a “repeat when completed” setting.

  (*

This script marks all selected items in an OF window as dropped or reverts them all from being dropped
The dropped context must exist
v 3 - checks when pDropContextName or pDropSuffix exists and resets dropped state instead
v 2 - can either change context or append text to title
v 1.1 - appends current context name to end of title before changing context to dropped
*)

 -- properties of this script
 property pScriptTitle : "Drop OmniFocus Tasks"
 property pDropContextName : "dropped"
 property pDropSuffix : " > 🔕 DROPPED"  -- set this to the name of your dropped context
 property pMode : "suffix" -- suffix or context
 property pAlsoMarkComplete : true -- set to false to change context only
 property pConfirmChange : true -- set to false at your own risk!
-- script handler to hold the list of items to change
script theDropList
property theList : missing value
end script
-- run handler
on run

tell application “OmniFocus”

  -- get the context associated to the context name
  if pMode is "context" then
  tell front document
  	try
  		set theDropContextID to id of first item of (complete pDropContextName as context)
  	on error
  		display dialog "Your Drop Context is not defined properly. Script must abort." buttons {"OK"} default button "OK" with title pScriptTitle
  		return
  	end try
  	set DropContext to (first flattened context whose id is theDropContextID)
  end tell
  end if
  -- get the tasks selected in the main window
  tell content of front document window of default document to ¬
  	set theSelectionList to the value of every selected tree
  if the (count of items in theSelectionList) is 0 then return
  if pConfirmChange then
  	set theMessage to "Do you really want to toggle the state of "
  	if pAlsoMarkComplete then set theMessage to theMessage & "and mark not done as completed "
  	set theMessage to theMessage & (count of items in theSelectionList) & " tasks?"
  	display dialog theMessage buttons {"Yes", "No"} default button "No" with title pScriptTitle
  	if (result = {button returned:"No"}) then return
  end if
  set theList of theDropList to theSelectionList
  -- toggle the state of every selected task
  repeat with theItem in theList of theDropList
  	set wasToggled to false
  	-- check whether it has been set to the dropped context or a suffix exists
  	if the context of theItem is DropContext then
  		-- find the previous context
  		set otid to AppleScript's text item delimiters
  		set AppleScript's text item delimiters to " > "
  		set itsName to the name of theItem
  		set theNewName to the first text item of itsName
  		set theOldContextName to the second text item of itsName
  		set AppleScript's text item delimiters to otid
  		-- replace the current context
  		set theOldContextID to id of first item of (complete theOldContextName as context)
  		set theOldContext to (first flattened context whose id is theOldContextID)
  		set the context of theItem to theOldContext
  		-- remove the previous context suffix
  		set the name of theItem to theNewName
  		-- toggle completion to false and set as toggled
  		set the completed of theItem to false
  		set wasToggled to true
  	else
  		if the name of theItem contains pDropSuffix then
  			-- remove the suffix
  			set otid to AppleScript's text item delimiters
  			set AppleScript's text item delimiters to " > "
  			set itsName to the name of theItem
  			set theNewName to the (first text item of itsName)
  			set AppleScript's text item delimiters to otid
  			set the name of theItem to theNewName
  			-- toggle completion to false and set as toggled
  			set the completed of theItem to false
  			set wasToggled to true
  		end if
  	end if
  	if (not wasToggled) then
  		if (pMode is "context") then
  			if the context of theItem is not missing value then
  				set theCurrentContext to the name of the context of theItem
  			else
  				set theCurrentContext to "(no previous context)"
  			end if
  			set theNewName to the name of theItem & " > " & theCurrentContext
  			set context of theItem to DropContext
  		else
  			set theNewName to the name of theItem & pDropSuffix
  		end if
  		set the name of theItem to theNewName
  		set the completed of theItem to pAlsoMarkComplete
  	end if
  end repeat

end tell
end run


JJW

1 Like

I know it’s almost a year old topic. Well, not to me :)

Hi @DrJJWMac, fellow chemist here. I’m testing your context structure, and I’m having a hard time running the v3 of the “toggle drop” script (the v2 works just fine). The error message is:

error “The variable DropContext is not defined.” number -2753 from “DropContext”

I’m not at all versed in AppleScript and therefore unable to debug it. Any thoughts?

Thanks,

Hubert

Yep. I see a problem.

I’ll look at it. I’ve got a few deadlines up front this week, so it may take a few days.


JJW

Here is an update.

(*
This script marks all selected items in an OF window as dropped or reverts them all from being dropped
The dropped context must exist
v 3.1 - fixed a bug and cleaned up code
v 3 - checks when pDropContextName or pDropSuffix exists and resets dropped state instead
v 2 - can either change context or append text to title
v 1.1 - appends current context name to end of title before changing context to dropped
*)

-- properties of this script
-- YOU CAN / SHOULD CHANGE THESE

property pDropContextName : "dropped" -- set this to the name of your "dropped" context (it must exist)
property pMode : "suffix" -- suffix: only add suffix; context: only change context (you cannot do BOTH)
property pDropSuffix : "🔕 DROPPED" -- the suffix to append when adding a suffix
property pAlsoMarkComplete : true -- set to false to keep task active even when dropped
property pConfirmChange : true -- confirm any changes: set to false at your own risk!

-- YOU SHOULD NOT CHANGE THESE

property pScriptTitle : "Drop OmniFocus Tasks" -- script title
property pDropTextContextPrefix : " > " -- the REQUIRED prefix before the suffix (generally    should NOT change this)
property pEmptyContext : "(no previous context)"

-- script handler to hold the list of items to change

script theDropList
	property theList : missing value
end script

-- run handler

on run

tell application "OmniFocus"
	
	-- get the context associated to the context name
	
	tell front document
		try
			set theDropContextID to id of first item of (complete pDropContextName as context)
		on error
			display dialog "Your Drop Context is not defined properly. Script must abort." buttons {"OK"} default button "OK" with title pScriptTitle
			return
		end try
		set DropContext to (first flattened context whose id is theDropContextID)
	end tell
	
	-- get the tasks selected in the main window
	
	tell content of front document window of default document to ¬
		set theSelectionList to the value of every selected tree
	if the (count of items in theSelectionList) is 0 then return
	
	if pConfirmChange then
		set theMessage to "Do you really want to toggle the state of "
		set theMessage to theMessage & (count of items in theSelectionList) & " tasks?"
		if pAlsoMarkComplete then set theMessage to theMessage & " (tasks currently not done will also be marked completed)"
		display dialog theMessage buttons {"Yes", "No"} default button "No" with title pScriptTitle
		if (result = {button returned:"No"}) then return
	end if
	
	set theList of theDropList to theSelectionList
	
	-- toggle the state of every selected task
	
	repeat with theItem in theList of theDropList
		
		set wasToggled to false
		
		-- first check whether it has been set as dropped
		
		if the context of theItem is DropContext then
			
			-- this is in context mode
			-- find the previous context
			
			set otid to AppleScript's text item delimiters
			set AppleScript's text item delimiters to pDropTextContextPrefix
			set itsName to the name of theItem
			set theNewName to the first text item of itsName
			set theOldContextName to the second text item of itsName
			set AppleScript's text item delimiters to otid
			
			-- reset to the previous context
			
			if pEmptyContext contains theOldContextName then
				set the context of theItem to missing value
			else
				tell front document
					set theOldContextID to id of first item of (complete theOldContextName as context)
					set theOldContext to (first flattened context whose id is theOldContextID)
				end tell
				set the context of theItem to theOldContext
				set the name of theItem to theNewName
			end if
			
			-- set the task back to active by default
			
			set the completed of theItem to false
			
			set wasToggled to true
			
		else
			
			-- this is in suffix mode
			
			if the name of theItem contains pDropSuffix then
				
				-- remove the suffix
				
				set otid to AppleScript's text item delimiters
				set AppleScript's text item delimiters to pDropTextContextPrefix
				set itsName to the name of theItem
				set theNewName to the (first text item of itsName)
				set AppleScript's text item delimiters to otid
				
				set the name of theItem to theNewName
				
				-- toggle completion to false and confirm
				
				set the completed of theItem to false
				
				set wasToggled to true
			end if
		end if
		
		-- was not dropped so drop it
		
		if (not wasToggled) then
			-- suffix mode only
			if (pMode is "suffix") then
				set theNewName to the name of theItem & pDropTextContextPrefix & pDropSuffix
			end if
			-- context mode only
			if (pMode is "context") then
				if the context of theItem is not missing value then
					set theCurrentContext to the name of the context of theItem
				else
					set theCurrentContext to pEmptyContext
				end if
				set theNewName to the name of theItem & pDropTextContextPrefix & theCurrentContext
				set context of theItem to DropContext
			end if
			-- toggle name and completion
			set the name of theItem to theNewName
			set the completed of theItem to pAlsoMarkComplete
		end if
	end repeat
	
end tell

end run

Hope this fixes the problem.

JJW

2 Likes

In the above, change this …

… to this …

set the completed of theItem to pAlsoMarkComplete
set the name of theItem to theNewName

IOW, switch the order and set the completion status BEFORE changing the name. This will fix a “bug”. With this change, repeating tasks will no longer carry the suffix and/or dropped context of the drop state. They will be marked completed first, the repeat will kick a new task with the proper name, and the completed task will get a suffix or get moved to the dropped context.


JJW

Thank you @DrJJWMac! The updated script works like a charm.

HM

Hey, thanks for this script, it’s just what I was looking for! I just implemented it along with this change, but the suffix still carries over when task repeats.

If you’re still using it, have you run into this issue lately, or could it just be something unique to me?

Cheers!

The suffix will carry over on repeat. You have to clear it manually.

Otherwise, when you are trying to clear a suffix from a repeated task manually, it may still not clear. This is due to a bug with OmniFocus. What happens when a dropped task is repeated is, the space character AFTER the “>” is dropped. So, you go from this suffix

  • > 🔕 DROPPED

to this suffix

  • >🔕 DROPPED

When the script tries to clear the suffix on a “dropped” task, it does not find one. Fix this problem by changing the code this way …

  • property pDropContextPrefix : " > " – old drop prefix (space after >)
  • property pDropContextPrefix : " >" – new drop prefix (no space after >)

I have not reported the bug to OmniGroup.


JJW

Here is an update of the Drop/Undrop Applescript. This version is for OF3. It no longer uses a suffix method. It relies solely on a “dropped” tag.

Drop / Undrop Applescript

(*
	This script marks all selected items in an OF window as dropped or reverts them all from being dropped
	The dropped tag must exist
	v 4 - for OF3 : only adds/removes dropped tag
*)

-- properties of this script
-- YOU MAY /SHOULD CHANGE THESE

property pDropTagName : "dropped" -- set this to the name of your "dropped" tag (it must exist)
property pAlsoMarkComplete : true -- set to false to keep task active even when dropped
property pConfirmChange : true -- confirm any changes: set to false at your own risk!

-- YOU SHOULD NOT CHANGE THESE

property pScriptTitle : "Drop OmniFocus Tasks" -- script title

-- script handler to hold the list of items to change

script theDropList
	property theList : missing value
end script

-- run handler

on run

	tell application "OmniFocus"
	
		-- get the tasks selected in the main window
	
		tell content of front document window of default document to ¬
			set theSelectionList to the value of every selected tree
		if the (count of items in theSelectionList) is 0 then return
	
		-- get the tag associated to the tag name
	
		tell front document
			try
				set theDropTagID to id of first item of (complete pDropTagName as tag)
			on error
				display dialog "Your Drop Tag is not defined properly. Script must abort." buttons {"OK"} default button "OK" with title pScriptTitle
				return
			end try
			set DropTag to (first flattened tag whose id is theDropTagID)
		end tell
	
		if pConfirmChange then
			set theMessage to "Do you really want to toggle the state of "
			set theMessage to theMessage & (count of items in theSelectionList) & " tasks?"
			if pAlsoMarkComplete then set theMessage to theMessage & " (tasks currently not done will also be marked completed)"
			display dialog theMessage buttons {"Yes", "No"} default button "No" with title pScriptTitle
			if (result = {button returned:"No"}) then return
		end if
	
		set theList of theDropList to theSelectionList
	
		repeat with theItem in theList of theDropList
		
			-- first check whether it has been set as dropped
		
			set theTagList to the id of tags of theItem as list
		
			if the theDropTagID is in theTagList then
				-- remove the dropped tag				
				remove DropTag from tags of theItem
				mark incomplete theItem
			else
				-- add the drop tag
				add DropTag to tags of theItem
				if pAlsoMarkComplete then mark complete theItem
			end if
		
		end repeat
	
	end tell

end run

To install, open the AppleScript editor, copy + paste this code, change the pDropTagName to the name of your drop tag, and save where ever you like. By reference, I have this assigned to a button on the OF3 menubar (the red circle with the line through it).


JJW

1 Like