The code is quite long, so I recommend just downloading here:
http://tr.im/DwuW
Description:
It allows you to create a To Do in iCal using text entered in QS text
entry mode. And yes, the iCal plugin does this too. But this action
lets you specify which Calendar you want to add your To Dos to (the
plugin version uses iCal's default calendar).
Even more importantly, this action lets you specify Dates, Priorities,
and Notes to go along with your To Do using a simple syntax.
Where to Save:
~/Library/Application Support/Quicksilver/Actions
Usage:
Activate Quicksilver into text entry mode using a trigger, or by
activating QS and typing a period. Enter your To Do, hit tab, find the
action and hit enter. you can specify Dates, Priorities, and Notes to
go along with your To Do using a simple syntax.
The syntax is as follows:
You can signify priority of 1-4 using "!" (so !4 is highest
priority).
The default priority, if you don't enter one, is Low (or 2).
You can specify dates following the @ symbol:
ie "Don't forget the milk @11/01/09".
Date entry is relatively flexible. you can enter numerical
dates using the format mm/dd/yy.
You can also use mm/dd or dd, which will create a todo at the
next time your mm/dd or dd happens.
(so if you enter a todo on october 30th, 2009 and just use @11
it will assume you're talking about Nov.11, 2009.
If use had used 10/29, it would assume Oct 29th, 2010).
You can also enter dates using natural language. The action
understands the following:
Tomorrow, Names of Days of the week refer to the next time
that day arises.
and "Next " + day of the week refers to the second time that
day arises.
Examples: "Don't forget the milk @Next Wednesday !1" and
"Don't forget the milk @Tomorrow !1"
You can add additional notes to your Todo following "#" :
Examples "here's a todo @12/09/09 !4 #don't forget the milk"
You can specify any combination of the parameters.
Examples "Don't forget the milk"
"Don't forget the butter !4"
"Don't forget the cereal #and the milk"
"Don't not forget the margerine @Tomorrow !1" all work
Two last things:
Don't use a space between your symbol and entry.
So don't use "@ Next Wednesday" or "! 2". Use "@Next
Wednesday", and "!2".
And keep the To Do event name first and the note last.
Specifying Which Calendar to use works as follows:
The first time this is run, the action will ask for the name
of the calendar you want to associate future To Dos with.
The calendar name will be stored in a file named
ToDoMoreCalendarName.txt, which will be saved in ~/Library/
Preferences.
If you change your mind in the future, or enter it
incorrectly just type: "!reset" and run the action, the action will
then ask you for a new Calendar name.
Or, you can delete the preferences file, and the next time
you run the action it will ask for a new calendar name.
Code:
property myPath : ""
property myPrefsFile : ""
property useCal : ""
property Grlyes : ""
using terms from application "Quicksilver"
on process text qtxt
set todoist to my klWS(qtxt)
if todoist is not -1 then
set dothis to my mnprgm(todoist)
set AppleScript's text item delimiters to ""
return dothis
else
return ""
end if
end process text
end using terms from
on mnprgm(ToDoThis)
set chCt to count characters of ToDoThis
if chCt > 0 then
try
set tdccmd to ToDoThis as string
if tdccmd is "!reset" then
set useCal to my getCal(1)
triggerGrowl("Reset To Do Calendar
Name To:", useCal)
return useCal
else
try
set {todocmd, tdPri, tdNote,
tdDue} to my parseToDo(tdccmd)
on error
set todocmd to ToDoThis as
string
set tdPri to ""
set tdNote to ""
set tdDue to ""
end try
if todocmd is not -2 then
set nwgTd to my newTodo
(todocmd, tdPri, tdNote, tdDue)
return todocmd
else
return ""
end if
end if
on error
return ""
end try
else
return ""
end if
end mnprgm
on klWS(intxt) -- will return txt without leading or trailing
whitespace OR (if blank) -1
if (count of intxt) is 0 then
return -1
else
set outxt to ""
set outid to 0
set k to 1
repeat
set thschr to character k of intxt
if thschr is " " then
set outid to 0
else if thschr is "" then
set outid to 0
else
set outid to k
exit repeat
end if
if k < (count of intxt) then
set k to k + 1
else
set k to -1
exit repeat
end if
end repeat
if k > 0 then
set midtxt to characters k thru (count of
intxt) of intxt as string
else
return -1
end if
set j to count of midtxt
repeat
set thschr to character j of midtxt
if thschr is " " then
set outid to 0
else if thschr is "" then
set outid to 0
else
set outid to j
exit repeat
end if
if j > 1 then
set j to j - 1
else
set j to -1
exit repeat
end if
end repeat
if j > 0 then
set outxt to characters 1 thru j of midtxt as
string
else
return -1
end if
return (outxt as string)
end if
end klWS
on parseToDo(dttxt)
set todocmd to dttxt as string
if todocmd contains "!" then
try
set pOff to offset of "!" in todocmd
set tdPri to character (pOff + 1) of todocmd
as string
if pOff is not 1 then
set todo1 to characters 1 thru (pOff -
1) of todocmd as string
set todo1 to my klWS(todo1)
else
set todo1 to ""
end if
if pOff is not ((count of todocmd) - 1) then
set todo2 to characters (pOff + 2)
thru (count of todocmd) of
todocmd as string
set todo2 to my klWS(todo2)
else
set todo2 to ""
end if
set todocmd to todo1 & " " & todo2 as string
on error
set tdPri to "1"
end try
else
set tdPri to "2"
end if
if todocmd contains "#" then
try
set pOff to offset of "#" in todocmd
set tdNote to characters (pOff + 1) thru
(count of todocmd) of
todocmd as string
set todocmd to characters 1 thru (pOff - 1) of
todocmd as string
set tdNote to my klWS(tdNote)
set todocmd to my klWS(todocmd)
if tdNote is not -1 then
if tdNote contains "@" then
set atOff to offset of "@" in
tdNote
set tddate to characters atOff
thru (count of characters of
tdNote) of tdNote as string
set tdNote to characters 1
thru (atOff - 1) of tdNote as string
set todocmd to todocmd & " " &
tddate as string
end if
else
set tdNote to ""
end if
on error
set tdNote to ""
end try
else
set tdNote to ""
end if
if todocmd contains "@" then
try
if todocmd contains "/" then
set pOff to offset of "@" in todocmd
set tdtxt to characters 1 thru (pOff -
1) of todocmd as string
set tdat to characters (pOff + 1) thru
(count of todocmd) of
todocmd as string
set tdat to my klWS(tdat)
set todocmd to my klWS(tdtxt)
if tdat is -1 then
set tdDue to ""
else
set tdDue to my figureDate
(tdat, 1)
end if
else
set pOff to offset of "@" in todocmd
set tdtxt to characters 1 thru (pOff -
1) of todocmd as string
set teeDo to characters (pOff + 1)
thru (count of todocmd) of
todocmd as string
if (count of teeDo) > 0 then
set todocmd to my klWS(tdtxt)
set teeDo to my klWS(teeDo)
if todocmd is -1 then
set todocmd to ""
end if
if teeDo is not -1 then
try
set tstnums to
teeDo as integer
set tdDue to
my figureDate(teeDo, 1)
on error
set tdDue to
my figureDate(teeDo, 0)
end try
else
set tdDue to ""
end if
else
set tdDue to ""
end if
end if
on error
set tdDue to ""
end try
else
set tdDue to ""
end if
try
return {todocmd, tdPri, tdNote, tdDue}
return ""
on error
return {-2, "", "", ""}
end try
end parseToDo
on figureDate(inDate, swtch) -- if swtch is 1 then it will look for
dates formatted like 12/01/08, otherwise it will attempt a limited
natural language
set thisDay to current date
set thisDay's day to 32
set thisDay's day to 1
set endmo to thisDay - (1 * days)
set lastdy to endmo's day as integer
set {year:y, month:m, weekday:wd, day:d} to current date
set d to d as integer
set m to m as integer
set y to y as integer
if swtch is 1 then
try
set AppleScript's text item delimiters to "/"
set duect to count of text items of inDate
if (count of text items of inDate) is 1 then
set dy to text item 1 of inDate as
integer
set AppleScript's text item delimiters
to ""
set mnth to m as integer
set yr to y as integer
if dy > lastdy then
set dy to dy - lastdy
end if
if dy > d then
set mnth to m
else
set mnth to m + 1
if mnth is 13 then
set mnth to 1
set yr to y + 1
end if
end if
set yr to yr as string
else if (count of text items of inDate) is 2
then
set mnth to text item 1 of inDate as
integer
set dy to text item 2 of inDate as
integer
set AppleScript's text item delimiters
to ""
set yr to y as integer
if dy > lastdy then
set dy to dy - lastdy as
integer
set mnth to mnth + 1
end if
if mnth < m then
set yr to y + 1 as integer
else if mnth is equal to m then
if dy < d then
set yr to y + 1 as
integer
else
set yr to y as
integer
end if
else if m < mnth then
set yr to y as integer
end if
set yr to yr as string
else if (count of text items of inDate) is 3
then
set mnth to text item 1 of inDate as
integer
set dy to text item 2 of inDate as
integer
set yr to text item 3 of inDate as
string
set AppleScript's text item delimiters
to ""
end if
if (count of characters of yr) is 1 then
set yr to "200" & yr as string
else if (count of characters of yr) is 2 then
set yr to "20" & yr as string
end if
set yr to yr as integer
set thisdate to mnth & "/" & dy & "/" & yr as
string
set usedt to date thisdate
return usedt
on error
return ""
end try
else
try
set mint to m as integer
try
set nwday to inDate as integer
if nwday > lastdy then
set nwday to nwday - lastdy
end if
if nwday < d then
if mint < 12 then
set mint to mint + 1
else
set mint to 1
set y to y + 1 as
integer
end if
end if
on error
set wdint to wd as integer
set inDateInt to 0 as integer
if inDate contains "Sunday" then
set inDateInt to inDateInt +
1
else if inDate contains "Monday" then
set inDateInt to inDateInt +
2
else if inDate contains "Tuesday"
then
set inDateInt to inDateInt +
3
else if inDate contains "Wednesday"
then
set inDateInt to inDateInt +
4
else if inDate contains "Thursday"
then
set inDateInt to inDateInt +
5
else if inDate contains "Friday" then
set inDateInt to inDateInt +
6
else if inDate contains "Saturday"
then
set inDateInt to inDateInt +
7
else if inDate is "Tomorrow" then
set inDateInt to wdint + 1
end if
if inDateInt > wdint then
set diff to inDateInt - wdint
else
set diff to (inDateInt -
wdint) + 7
end if
if inDate contains "Next" then
set diff to diff + 7
end if
set nwday to d + diff as integer
if nwday > lastdy then
set nwday to nwday - lastdy
if mint < 12 then
set mint to mint + 1
else
set mint to 1
set y to y + 1 as
integer
end if
end if
end try
set newdate to mint & "/" & nwday & "/" & y as
string
set usedt to date newdate
return usedt
on error
return ""
end try
end if
end figureDate
on newTodo(icalSum, icalPri, icalNote, icalDue)
if useCal is "" then
set useCal to my getCal(0)
end if
try
set emT to (missing value)
set td to icalSum as string
try
set tdPri to icalPri
on error
set tdPri to "1"
end try
try
set tdNote to icalNote
if (emT is in tdNote) then
set tdNote to " "
end if
on error
set tdNote to " "
end try
if icalDue is not "" then
try
set tdDue to icalDue
on error
set tdDue to ""
end try
else
set tdDue to ""
end if
if ((emT is in tdDue) or (tdDue is "")) then
tell application "iCal"
if tdPri is "1" then
make todo at end of events of
(calendar useCal) with properties
{summary:td, description:tdNote, priority:no priority}
else if tdPri is "2" then
make todo at end of events of
(calendar useCal) with properties
{summary:td, description:tdNote, priority:low priority}
else if tdPri is "3" then
make todo at end of events of
(calendar useCal) with properties
{summary:td, description:tdNote, priority:medium priority}
else if tdPri is "4" then
make todo at end of events of
(calendar useCal) with properties
{summary:td, description:tdNote, priority:high priority}
end if
end tell
triggerGrowl("New To Do:", td)
else
tell application "iCal"
if tdPri is "1" then
make todo at end of events of
(calendar useCal) with properties
{summary:td, description:tdNote, priority:no priority, due
date:tdDue}
else if tdPri is "2" then
make todo at end of events of
(calendar useCal) with properties
{summary:td, description:tdNote, priority:low priority, due
date:tdDue}
else if tdPri is "3" then
make todo at end of events of
(calendar useCal) with properties
{summary:td, description:tdNote, priority:medium priority, due
date:tdDue}
else if tdPri is "4" then
make todo at end of events of
(calendar useCal) with properties
{summary:td, description:tdNote, priority:high priority, due
date:tdDue}
end if
end tell
triggerGrowl("New To Do:", td)
end if
return ""
on error
triggerGrowl("Failed to create a Todo", td)
return ""
end try
end newTodo
on getCal(swtch)
if ("ToDoMoreCalendarName.txt" is not in myPrefsFile) then
set myPath to (POSIX path of (path to home folder))
set myFilePath to (POSIX path of (path to preferences
folder from
user domain))
set myFileName to "ToDoMoreCalendarName.txt"
set myPrefsFile to myFilePath & myFileName
end if
tell application "System Events"
if not (exists file myPrefsFile) then
do shell script "touch " & myPrefsFile
end if
end tell
if swtch < 1 then
set bC to get eof myPrefsFile
if bC is equal to 0 then
set swtch to 1
else
set prefsContents to read myPrefsFile until
bC
set useCal to prefsContents
end if
end if
if (swtch is 1) then
set useCal to ""
set eof of myPrefsFile to 0
set userCanceled to false
try
activate
set usercal to text returned of (display
dialog "Please enter the
name of the iCal Calendar you want thermoCLine to use: " default
answer "" default button 2)
on error number -128
set usercal to ""
set userCanceled to true
end try
if userCanceled is false then
set eof of myPrefsFile to 0
write usercal to myPrefsFile
end if
set useCal to usercal as string
end if
return useCal
end getCal
on triggerGrowl(currentTitle, currentStatus)
set grlApp to "Quicksilver"
if Grlyes is not in {"yes", "no"} then
tell application "System Events"
--set MyApp to name of the first process whose
frontmost is true
set processnames to name of every process
if "GrowlHelperApp" is in processnames then
set Grlyes to "yes"
else
set Grlyes to "no"
end if
end tell
end if
if Grlyes is "yes" then
tell application "GrowlHelperApp"
set the allNotificationsList to
{"Notification"}
set the enabledNotificationsList to
{"Notification"}
register as application ¬
grlApp all notifications
allNotificationsList ¬
default notifications
enabledNotificationsList ¬
icon of application "Quicksilver"
notify with name "Notification" title
currentTitle description
currentStatus application name grlApp
end tell
else
activate
display dialog currentTitle
end if
end triggerGrowl