Issue 72* June 4 2009

Creating Tcal: Part Two, Alarms
Aprogrammers job is never done, users always want more features!

by Roberto Trevisan

Creating Tcal: part 2, Alarms

In the last edition of revUp, we published the first in a series looking at the creation of a full featured Calendar application in Revolution. You can read part one here.

As soon as I published Tcal, after having provided some kind of copy protection, which for obvious reasons I will not talk about here, I received an email asking if Tcal had Alarms - some kind of reminder for deadline or events.

What a drag! You think the job is done...and it is not.

Since alarms are a little different from regular applications, for example they are not supposed to be visible if not in use, I knew that the request was not so easy to accomplish.

Looking at how other calendars function, I came up with the following requirements for the alarm application, called, you may guess...TcalAlarms:

  • always on (even if the calendar is not launched)
  • invisible if there is not an alarm sounding
  • sharing alarm data with the calendar (if I modify an alarmed event in the calendar, TcalAlarms must know. And the reverse is true too)
  • able to launch Tcal (easy...)

After several searches on the RunRev forum, I realized that I could not make a true “service” application (I think this is the name of applications hidden from the user by the OS), so I went the simple way.

On Mac OS X:
A hidden compiled application shows only the “quit” menu in the Finder. If the user wanted to quit TcalAlarms, that was ok as long as I could provide a way to start it from Tcal.

I managed to get the alias of TcalAlarms on the start-Up element list of Log-in using an applescript:

tell application "System Events"
  get exists login item "TcalAlarms.app"
  if result is false then
        make new login item at end of login items with properties \
          {path:"ThePathToTcalAlarms",hidden:true}
  end if
return the result
end tell 

On Windows:
For some reason (remember, I am not a programmer so I had to learn everything from scratch and, while I am used to Mac OS X, I find Windows very difficult to cope with) a hidden compiled application, without a menu, on Windows is just that: hidden. Like the service application I was trying to create, it shows up only when needed (at the sounding of an alarm). I still have not found a way to put it in the start-up list at login.

-----------------

Alarm data would be written on the Tcal preferences, a simple text file, so that they could be polled from both applications; alarm timing was provided by “send TheCommand in xx seconds” which was very easy, and communication between the two application was going to happen using sockets. The TcalAlarms came up like this (using shaped stacks is very nice and easy: you just import a .gif and write its ID in the stack inspector):

Tcal Alarm

 

Version 1.1 of Tcal was out, but the socket communication, mixed up with the socket protocols between Tcal and Tcalserver, became even more complex and buggy. 

Then I discovered the Shell commands.

Since Tcal and TcalAlarms must be on the same computer, this has become for me the solution for application communication: AppleScript on OSX and Shell commands on Windows.

I must say that while AppleScript is easier for me to manage than Shell scripting, both of these are much less intuitive than RunRev scripting. You must take into account the different formatting for text, dates, list, items and the fact that you end up fighting with “quotes”  all the time. For example, when I made Tcalserver able to write and read to Microsoft Access, for every message I had to take into account the RunRev script, that would run the VBscript, that would run the SQL script! All of them passing parameters...formatted differently on each "language". SQL even uses single quotes so you end up using "': quote and single quote... Probably I could have used the database functions of Revolution and saved myself a lot of work. But the idea was to give the User an application that could set-up by itself the ODBC connection, driver, etc. without having the user messing about with the control panel ODBC setup of Window XP.

Anyway, this is how I made it.

On Mac OS X:
I keep this AppleScript in the Tcal stack custom properties

--this one, named “AlarmScript”, ask TcalAlarms to do
-- something, but you could use it the other way arund too
try
   tell application "TcalAlarms"
   activate
   do script "MyLog" & quote & "TheData" & quote
end tell
on error errText
   return errText --if there is an error the result on RunRev gets \
          this
end try 

On TcalAlarms there is a script like this:

on mylog WhatToDo 
            do WhatToDo --WhatToDo is "Beep"
end mylog 

To make it work, you just need to get the script from the Tcal stack custom properties and replace the required text:

put the AlarmScript of stack “Tcal” into TheScript --get the \
       custom property and put it into a variable
replace “TheData” with “Beep” in TheScript --beep is the \
       command i want to send
do TheScript as Applescript  

So, at the end, this is the same as scripting in Tcal:

send “beep” to stack “TcalAlarms” 

(but it does not work between compiled applications... so save your time)

Just more complex...but believe me, socket communication is much more difficult, since AppleScript takes care of everything (timing and errors).

Note: when you are testing Applescript communication between uncompiled stacks, you have to use slightly different scripts, since Applescript will be talking to Revolution, not to the application “TcalAlarms”:

--TcalAlarm is a stack
try
   tell application "Revolution"
   set TheScript to "send MyLog & quote & \"TheData\" & quote \
          to stack \"TcalAlarms\""
   do script TheScript
end tell
on error errText
   return errText
end try 

The \” thing is how Applescript knows that you mean quotes. Don’t ask me...

On Windows:
There were probably other ways to do it - at the time there was no easy VBScript in Revolution but, since it is working, I left it this way.

On TcalAlarms I wrote this script:

On relaunch pParam
      if pParam is not empty then
            MyLog pParam
      end if
end relaunch 

On Tcal (the calling application in this case):

put the effective filename of this stack into tAlarmPath      \
       --get the path to TcalAlarms
set the itemDelimiter to "/"
put "TcalAlarms.exe" into the last item of tAlarmPath      \
       --TcalAlarms is in the same folder as Tcal
replace "/" with "\" in tAlarmPath --Windows way
put "start" && quote & quote && quote & tAlarmPath & quote  && \
       quote & TheData & quote into theShell
-- the extra quotes after "start" are a "blank" window title
-- for the (hidden) console window
set the hideConsoleWindows to true
put shell (theShell) into risultato 

For more details on this, see this thread in the RunRev forum.

From what I’ve understood, the Tcal script “launches” TcalAlarms. Since this is already open, on Windows (not on Mac OS X) the “relaunch” command gets called. The parameter is passed through the $1 system variable on the OS.

If TcalAlarms is closed I can launch it from Tcal with the above script and have TcalAlarms do the task, putting this on TcalAlarms:

on startUp 
      if $1 is not empty then
            put $1 into AlarmDataPostStart
      end if
end startUp 

and this at the end of the PreOpenStack script:

if AlarmDataPostStart is not empty then
   put AlarmDataPostStart into TheData
   MyLog TheData
end if 

So, one way or the other, I managed to make the alarms work on Mac OS X and Windows. On Mac OS X I put the TcalAlarms application inside the “resource” folder of the Tcal package (a la iCal). It works and it is out of the way.

From all this I learned that while application communication between different computers must be done through sockets, on the same PC or Mac there are other ways. They are not that easy, but you may get the handle of it.

In the next article I will explain how I fixed the socket handshake between the Client (Tcal) and the Server (Tcalserver, the one talking to the database) and how thanks to Revolution V3 (now 3.5) and VBscript I was able to make TcalServer talk to Microsoft Access.

About the Author

Roberto Trevisan is an architect working as an Exposition and MultiMedia event Designer in Torino, Italy. He has managed projects for architectural firms working with Fiat, Alfa Romeo, Zegna, Philip Morris, Tim Telephone, Sai and several chainstores. Visit the Tcal website here.

 

 

Main Menu

What's New

RunRevLive Edinburgh