Index: /trunk/Cocoa/Pester/Source/PSAlarm.h
===================================================================
--- /trunk/Cocoa/Pester/Source/PSAlarm.h	(revision 24)
+++ /trunk/Cocoa/Pester/Source/PSAlarm.h	(revision 24)
@@ -0,0 +1,35 @@
+//
+//  PSAlarm.h
+//  Pester
+//
+//  Created by Nicholas Riley on Wed Oct 09 2002.
+//  Copyright (c) 2002 Nicholas Riley. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+
+typedef enum {
+    PSAlarmInvalid, PSAlarmInterval, PSAlarmDate
+} PSAlarmType;
+
+@interface PSAlarm : NSObject {
+    PSAlarmType alarmType;
+    NSCalendarDate *alarmDate;
+    NSTimeInterval alarmInterval;
+    NSString *alarmMessage;
+    NSString *invalidMessage;
+}
+
+- (void)setInterval:(NSTimeInterval)anInterval;
+- (void)setForDateAtTime:(NSDate *)dateTime;
+- (void)setForDate:(NSDate *)date atTime:(NSDate *)time;
+- (void)setMessage:(NSString *)aMessage;
+
+- (NSDate *)date;
+- (NSTimeInterval)interval;
+
+- (BOOL)isValid;
+- (NSString *)message;
+- (NSString *)invalidMessage;
+
+@end
Index: /trunk/Cocoa/Pester/Source/PSAlarm.m
===================================================================
--- /trunk/Cocoa/Pester/Source/PSAlarm.m	(revision 24)
+++ /trunk/Cocoa/Pester/Source/PSAlarm.m	(revision 24)
@@ -0,0 +1,144 @@
+//
+//  PSAlarm.m
+//  Pester
+//
+//  Created by Nicholas Riley on Wed Oct 09 2002.
+//  Copyright (c) 2002 Nicholas Riley. All rights reserved.
+//
+
+#import "PSAlarm.h"
+
+
+@implementation PSAlarm
+
+- (void)_setAlarmDate:(NSCalendarDate *)aDate;
+{
+    if (alarmDate != aDate) {
+        [alarmDate release];
+        alarmDate = nil;
+        alarmDate = [aDate retain];
+    }
+}
+
+- (void)_invalidate:(NSString *)aMessage;
+{
+    alarmType = PSAlarmInvalid;
+    if (aMessage != invalidMessage) {
+        [invalidMessage release];
+        invalidMessage = nil;
+        [self _setAlarmDate: nil];
+        alarmInterval = 0;
+        invalidMessage = [aMessage retain];
+    }
+}
+
+- (void)_validateForType:(PSAlarmType)type;
+{
+    [invalidMessage release];
+    invalidMessage = nil;
+    alarmType = type;
+}
+
+- (void)_setDateFromInterval;
+{
+    [alarmDate release]; alarmDate = nil;
+    alarmDate = [NSCalendarDate dateWithTimeIntervalSinceNow: alarmInterval];
+    [alarmDate retain];
+    [self _validateForType: PSAlarmInterval];
+}
+
+- (void)setInterval:(NSTimeInterval)anInterval;
+{
+    alarmInterval = anInterval;
+    if (alarmInterval <= 0) {
+        [self _invalidate: @"Please specify an alarm interval."]; return;
+    }
+}
+
+- (void)_setIntervalFromDate;
+{
+    alarmInterval = [alarmDate timeIntervalSinceNow];
+    if (alarmInterval <= 0) {
+        [self _invalidate: @"Please specify an alarm time in the future."];
+        return;
+    }
+    [self _validateForType: PSAlarmDate];
+}
+
+- (void)setForDateAtTime:(NSDate *)dateTime;
+{
+    if (dateTime != alarmDate) {
+        [alarmDate release];
+        alarmDate = nil;
+        alarmDate = [dateTime retain];
+    }
+    [self _setIntervalFromDate];
+}
+
+- (void)setForDate:(NSDate *)date atTime:(NSDate *)time;
+{
+    NSCalendarDate *calTime, *calDate;
+    if (time == nil && date == nil) {
+        [self _invalidate: @"Please specify an alarm date and time."]; return;
+    }
+    if (time == nil) {
+        [self _invalidate: @"Please specify an alarm time."]; return;
+    }
+    if (date == nil) {
+        [self _invalidate: @"Please specify an alarm date."]; return;
+    }
+    // XXX if calTime's date is different from the default date, complain
+    calTime = [NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [time timeIntervalSinceReferenceDate]];
+    calDate = [NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [date timeIntervalSinceReferenceDate]];
+    if (calTime == nil || calDate == nil) {
+        [self _invalidate: @"Please specify a reasonable date and time."];
+    }
+    [self setForDateAtTime:
+        [[[NSCalendarDate alloc] initWithYear: [calDate yearOfCommonEra]
+                                        month: [calDate monthOfYear]
+                                          day: [calDate dayOfMonth]
+                                         hour: [calTime hourOfDay]
+                                       minute: [calTime minuteOfHour]
+                                       second: [calTime secondOfMinute]
+                                     timeZone: nil] autorelease]];
+}
+
+- (BOOL)isValid;
+{
+    return (alarmType == PSAlarmInvalid);
+}
+
+- (void)setMessage:(NSString *)aMessage;
+{
+    if (aMessage != alarmMessage) {
+        [alarmMessage release];
+        alarmMessage = nil;
+        alarmMessage = [aMessage retain];
+    }
+}
+
+- (NSString *)message;
+{
+    if (alarmMessage == nil || [alarmMessage isEqualToString: @""])
+        return @"Alarm!";
+    return alarmMessage;    
+}
+
+- (NSString *)invalidMessage;
+{
+    return invalidMessage;
+}
+
+- (NSDate *)date;
+{
+    if (alarmType == PSAlarmInterval) [self _setDateFromInterval];
+    return alarmDate;
+}
+
+- (NSTimeInterval)interval;
+{
+    if (alarmType == PSAlarmDate) [self _setIntervalFromDate];
+    return alarmInterval;
+}
+
+@end
Index: /trunk/Cocoa/Pester/Source/PSAlarmNotifierController.m
===================================================================
--- /trunk/Cocoa/Pester/Source/PSAlarmNotifierController.m	(revision 23)
+++ /trunk/Cocoa/Pester/Source/PSAlarmNotifierController.m	(revision 24)
@@ -8,5 +8,5 @@
 
 #import "PSAlarmNotifierController.h"
-
+#import "PSAlarm.h"
 
 @implementation PSAlarmNotifierController
@@ -15,10 +15,8 @@
 {
     if ([self initWithWindowNibName: @"Notifier"]) {
-        NSString *message = [timer userInfo];
+        PSAlarm *alarm = [timer userInfo];
 
         [[self window] center];
-        if (message == nil || [message isEqualToString: @""])
-            message = @"Alarm!";
-        [messageField setStringValue: message];
+        [messageField setStringValue: [alarm message]];
         [dateField setObjectValue: [timer fireDate]];
         [NSApp activateIgnoringOtherApps: YES];
Index: /trunk/Cocoa/Pester/Source/PSAlarmSetController.h
===================================================================
--- /trunk/Cocoa/Pester/Source/PSAlarmSetController.h	(revision 23)
+++ /trunk/Cocoa/Pester/Source/PSAlarmSetController.h	(revision 24)
@@ -8,5 +8,5 @@
 
 #import <AppKit/AppKit.h>
-
+#import "PSAlarm.h"
 
 @interface PSAlarmSetController : NSWindowController {
@@ -20,8 +20,7 @@
     IBOutlet NSTextField *timeSummary;
     IBOutlet NSButton *setButton;
+    PSAlarm *alarm;
     NSString *status;
     BOOL isIn;
-    NSCalendarDate *alarmDate;
-    NSTimeInterval alarmInterval;
 }
 
Index: /trunk/Cocoa/Pester/Source/PSAlarmSetController.m
===================================================================
--- /trunk/Cocoa/Pester/Source/PSAlarmSetController.m	(revision 23)
+++ /trunk/Cocoa/Pester/Source/PSAlarmSetController.m	(revision 24)
@@ -39,4 +39,12 @@
     // [timeDate setFormatter: [[NJRDateFormatter alloc] initWithDateFormat: [defaults objectForKey: NSShortDateFormatString] allowNaturalLanguage: YES]];
     [self inAtChanged: nil];
+    alarm = [[PSAlarm alloc] init];
+    [[self window] makeKeyAndOrderFront: nil];
+}
+
+- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag;
+{
+    if (!flag) [self showWindow: self];
+    return YES;
 }
 
@@ -66,47 +74,11 @@
 - (void)setAlarmDateAndInterval:(id)sender;
 {
-    [alarmDate release];
-    alarmDate = nil;
-    alarmInterval = 0;
     if (isIn) {
-        alarmInterval = [[self objectValueForTextField: timeInterval whileEditing: sender] intValue] * [timeIntervalUnits selectedTag];
-        if (alarmInterval == 0) {
-            [self setStatus: @"Please specify an alarm interval."]; return;
-        }
-        alarmDate = [NSCalendarDate dateWithTimeIntervalSinceNow: alarmInterval];
-        [alarmDate retain];
+        [alarm setInterval:
+            [[self objectValueForTextField: timeInterval whileEditing: sender] intValue] *
+                [timeIntervalUnits selectedTag]];
     } else {
-        NSDate *time = [self objectValueForTextField: timeOfDay whileEditing: sender];
-        NSDate *date = [self objectValueForTextField: timeDate whileEditing: sender];
-        NSCalendarDate *calTime, *calDate;
-        if (time == nil && date == nil) {
-            [self setStatus: @"Please specify an alarm date and time."]; return;
-        }
-        if (time == nil) {
-            [self setStatus: @"Please specify an alarm time."]; return;
-        }
-        if (date == nil) {
-            [self setStatus: @"Please specify an alarm date."]; return;
-        }
-        // XXX if calTime's date is different from the default date, complain
-        calTime = [NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [time timeIntervalSinceReferenceDate]];
-        calDate = [NSCalendarDate dateWithTimeIntervalSinceReferenceDate: [date timeIntervalSinceReferenceDate]];
-        if (time == nil || date == nil) {
-            [self setStatus: @"Please specify a reasonable date and time."];
-        }
-        alarmDate = [[NSCalendarDate alloc] initWithYear: [calDate yearOfCommonEra]
-                                                   month: [calDate monthOfYear]
-                                                     day: [calDate dayOfMonth]
-                                                    hour: [calTime hourOfDay]
-                                                  minute: [calTime minuteOfHour]
-                                                  second: [calTime secondOfMinute]
-                                                timeZone: nil];
-        alarmInterval = [alarmDate timeIntervalSinceNow];
-        if (alarmInterval <= 0) {
-            [self setStatus: @"Please specify an alarm time in the future."];
-            [alarmDate release];
-            alarmDate = nil;
-            return;
-        }
+        [alarm setForDate: [self objectValueForTextField: timeDate whileEditing: sender]
+                   atTime: [self objectValueForTextField: timeOfDay whileEditing: sender]];
     }
 }
@@ -118,14 +90,19 @@
 // Be careful not to hook up any of the text fields' actions to update: because we handle them in controlTextDidChange: instead.  If we could get the active text field somehow via public API (guess we could use controlTextDidBegin/controlTextDidEndEditing) then we'd not need to overload the update sender for this purpose.  Or, I guess, we could use another method other than update.  It should not be this hard to implement what is essentially standard behavior.  Sigh.
 
+- (IBAction)updateDateDisplay:(id)sender;
+{
+    if ([alarm isValid]) {
+        [self setStatus: [[alarm date] descriptionWithCalendarFormat: @"Alarm will be set for %X on %x" timeZone: nil locale: nil]];
+        [setButton setEnabled: YES];
+    } else {
+        [setButton setEnabled: NO];
+    }
+}
+
 - (IBAction)update:(id)sender;
 {
     // NSLog(@"update: %@", sender);
     [self setAlarmDateAndInterval: sender];
-    if (alarmDate != nil) {
-        [self setStatus: [alarmDate descriptionWithCalendarFormat: @"Alarm will be set for %X on %x" timeZone: nil locale: nil]];
-        [setButton setEnabled: YES];
-    } else {
-        [setButton setEnabled: NO];
-    }
+    [self updateDateDisplay: sender];
 }
 
@@ -183,16 +160,18 @@
     PSAlarmNotifierController *notifier = [PSAlarmNotifierController alloc];
     NSTimer *timer;
+    NSTimeInterval interval;
     [self setAlarmDateAndInterval: sender];
-    if (notifier == nil || alarmDate == nil) {
+    if (notifier == nil || ( (interval = [alarm interval]) == 0)) {
         [self setStatus: @"Unable to set alarm (time just passed?)"];
         return;
     }
+    [alarm setMessage: [messageField stringValue]];
     // XXX should use alarm object instead for userInfo
-    timer = [NSTimer scheduledTimerWithTimeInterval: alarmInterval
+    timer = [NSTimer scheduledTimerWithTimeInterval: interval
                                              target: notifier
                                            selector: @selector(initWithTimer:)
-                                           userInfo: [messageField stringValue]
+                                           userInfo: alarm
                                             repeats: NO];
-    [self setStatus: [alarmDate descriptionWithCalendarFormat: @"Alarm set for %x at %X" timeZone: nil locale: nil]];
+    [self setStatus: [[alarm date] descriptionWithCalendarFormat: @"Alarm set for %x at %X" timeZone: nil locale: nil]];
     [[self window] close];
 }
Index: /trunk/Cocoa/Pester/Source/Pester.pbproj/nicholas.pbxuser
===================================================================
--- /trunk/Cocoa/Pester/Source/Pester.pbproj/nicholas.pbxuser	(revision 23)
+++ /trunk/Cocoa/Pester/Source/Pester.pbproj/nicholas.pbxuser	(revision 24)
@@ -14,259 +14,15 @@
 		);
 		perUserDictionary = {
-			PBXPerProjectTemplateStateSaveDate = 55845278;
-			"PBXTemplateGeometry-F5314676015831810DCA290F" = {
-				ContentSize = "{618, 257}";
+			PBXPerProjectTemplateStateSaveDate = 55895130;
+			"PBXTemplateGeometry-F5CA7ECB015C094F0DCA290F" = {
+				ContentSize = "{668, 621}";
 				LeftSlideOut = {
 					Collapsed = NO;
-					Frame = "{{0, 23}, {618, 234}}";
-					Split0 = {
-						ActiveTab = 2;
-						Collapsed = YES;
-						Frame = "{{0, 0}, {618, 234}}";
-						Split0 = {
-							Frame = "{{1e+06, 1e+06}, {618, 0}}";
-						};
-						SplitCount = 1;
-						Tab0 = {
-							Debugger = {
-								Collapsed = NO;
-								Frame = "{{0, 0}, {952, 321}}";
-								Split0 = {
-									Frame = "{{0, 24}, {952, 297}}";
-									Split0 = {
-										Frame = "{{0, 0}, {468, 297}}";
-									};
-									Split1 = {
-										DebugVariablesTableConfiguration = (
-											Name,
-											126.803,
-											Value,
-											150.074,
-											Summary,
-											172.123,
-										);
-										Frame = "{{477, 0}, {475, 297}}";
-									};
-									SplitCount = 2;
-								};
-								SplitCount = 1;
-								Tab0 = {
-									Frame = "{{0, 0}, {100, 50}}";
-								};
-								Tab1 = {
-									Frame = "{{0, 0}, {100, 50}}";
-								};
-								TabCount = 2;
-								TabsVisible = YES;
-							};
-							Frame = "{{0, 0}, {952, 321}}";
-							LauncherConfigVersion = 7;
-						};
-						Tab1 = {
-							Frame = "{{0, 0}, {781, 452}}";
-							LauncherConfigVersion = 3;
-							Runner = {
-								Frame = "{{0, 0}, {781, 452}}";
-							};
-						};
-						Tab2 = {
-							BuildMessageFrame = "{{0, 0}, {620, 123}}";
-							BuildTranscriptFrame = "{{0, 132}, {620, 98}}";
-							Frame = "{{0, 0}, {618, 228}}";
-						};
-						Tab3 = {
-							Frame = "{{0, 0}, {612, 295}}";
-						};
-						TabCount = 4;
-						TabsVisible = NO;
-					};
-					SplitCount = 1;
-					Tab0 = {
-						Frame = "{{0, 0}, {300, 533}}";
-						GroupTreeTableConfiguration = (
-							TargetStatusColumn,
-							18,
-							MainColumn,
-							267,
-						);
-					};
-					Tab1 = {
-						ClassesFrame = "{{0, 0}, {280, 398}}";
-						ClassesTreeTableConfiguration = (
-							PBXBookColumnIdentifier,
-							20,
-							PBXClassColumnIdentifier,
-							237,
-						);
-						Frame = "{{0, 0}, {278, 659}}";
-						MembersFrame = "{{0, 407}, {280, 252}}";
-						MembersTreeTableConfiguration = (
-							PBXBookColumnIdentifier,
-							20,
-							PBXMethodColumnIdentifier,
-							236,
-						);
-					};
-					Tab2 = {
-						Frame = "{{0, 0}, {200, 100}}";
-					};
-					Tab3 = {
-						Frame = "{{0, 0}, {200, 100}}";
-						TargetTableConfiguration = (
-							ActiveObject,
-							16,
-							ObjectNames,
-							202.296,
-						);
-					};
-					Tab4 = {
-						BreakpointsTreeTableConfiguration = (
-							breakpointColumn,
-							197,
-							enabledColumn,
-							31,
-						);
-						Frame = "{{0, 0}, {250, 100}}";
-					};
-					TabCount = 5;
-					TabsVisible = NO;
-				};
-				StatusViewVisible = YES;
-				Template = F5314676015831810DCA290F;
-				ToolbarVisible = YES;
-				WindowLocation = "{601, 113}";
-			};
-			"PBXTemplateGeometry-F5534CB2020F3F8A0DCA290F" = {
-				ContentSize = "{594, 303}";
-				LeftSlideOut = {
-					Collapsed = NO;
-					Frame = "{{0, 23}, {594, 280}}";
-					Split0 = {
-						ActiveTab = 1;
-						Collapsed = YES;
-						Frame = "{{0, 0}, {594, 280}}";
-						Split0 = {
-							Frame = "{{1e+06, 1e+06}, {594, 0}}";
-						};
-						SplitCount = 1;
-						Tab0 = {
-							Debugger = {
-								Collapsed = NO;
-								Frame = "{{0, 0}, {804, 321}}";
-								Split0 = {
-									Frame = "{{0, 24}, {804, 297}}";
-									Split0 = {
-										Frame = "{{0, 0}, {394, 297}}";
-									};
-									Split1 = {
-										DebugVariablesTableConfiguration = (
-											Name,
-											123,
-											Value,
-											85,
-											Summary,
-											167.123,
-										);
-										Frame = "{{403, 0}, {401, 297}}";
-									};
-									SplitCount = 2;
-								};
-								SplitCount = 1;
-								Tab0 = {
-									Frame = "{{0, 0}, {100, 50}}";
-								};
-								Tab1 = {
-									Frame = "{{0, 0}, {100, 50}}";
-								};
-								TabCount = 2;
-								TabsVisible = YES;
-							};
-							Frame = "{{0, 0}, {804, 321}}";
-							LauncherConfigVersion = 7;
-						};
-						Tab1 = {
-							Frame = "{{0, 0}, {594, 274}}";
-							LauncherConfigVersion = 3;
-							Runner = {
-								Frame = "{{0, 0}, {594, 274}}";
-							};
-						};
-						Tab2 = {
-							BuildMessageFrame = "{{0, 0}, {806, 237}}";
-							BuildTranscriptFrame = "{{0, 246}, {806, 3}}";
-							Frame = "{{0, 0}, {804, 247}}";
-						};
-						Tab3 = {
-							Frame = "{{0, 0}, {612, 295}}";
-						};
-						TabCount = 4;
-						TabsVisible = NO;
-					};
-					SplitCount = 1;
-					Tab0 = {
-						Frame = "{{0, 0}, {300, 533}}";
-						GroupTreeTableConfiguration = (
-							TargetStatusColumn,
-							18,
-							MainColumn,
-							267,
-						);
-					};
-					Tab1 = {
-						ClassesFrame = "{{0, 0}, {280, 398}}";
-						ClassesTreeTableConfiguration = (
-							PBXBookColumnIdentifier,
-							20,
-							PBXClassColumnIdentifier,
-							237,
-						);
-						Frame = "{{0, 0}, {278, 659}}";
-						MembersFrame = "{{0, 407}, {280, 252}}";
-						MembersTreeTableConfiguration = (
-							PBXBookColumnIdentifier,
-							20,
-							PBXMethodColumnIdentifier,
-							236,
-						);
-					};
-					Tab2 = {
-						Frame = "{{0, 0}, {200, 100}}";
-					};
-					Tab3 = {
-						Frame = "{{0, 0}, {200, 386}}";
-						TargetTableConfiguration = (
-							ActiveObject,
-							16,
-							ObjectNames,
-							202.296,
-						);
-					};
-					Tab4 = {
-						BreakpointsTreeTableConfiguration = (
-							breakpointColumn,
-							197,
-							enabledColumn,
-							31,
-						);
-						Frame = "{{0, 0}, {250, 386}}";
-					};
-					TabCount = 5;
-					TabsVisible = NO;
-				};
-				StatusViewVisible = YES;
-				Template = F5534CB2020F3F8A0DCA290F;
-				ToolbarVisible = YES;
-				WindowLocation = "{188, 218}";
-			};
-			"PBXTemplateGeometry-F5CA7EC8015C06940DCA290F" = {
-				ContentSize = "{705, 569}";
-				LeftSlideOut = {
-					Collapsed = NO;
-					Frame = "{{0, 0}, {705, 569}}";
+					Frame = "{{0, 0}, {668, 621}}";
 					Split0 = {
 						Collapsed = NO;
-						Frame = "{{0, 0}, {705, 569}}";
+						Frame = "{{0, 0}, {668, 621}}";
 						Split0 = {
-							Frame = "{{0, 0}, {705, 569}}";
+							Frame = "{{0, 0}, {668, 621}}";
 						};
 						SplitCount = 1;
@@ -307,126 +63,4 @@
 						};
 						Tab1 = {
-							Frame = "{{0, 0}, {522, 208}}";
-							LauncherConfigVersion = 3;
-							Runner = {
-								Frame = "{{0, 0}, {522, 208}}";
-							};
-						};
-						Tab2 = {
-							BuildMessageFrame = "{{0, 0}, {809, 410}}";
-							BuildTranscriptFrame = "{{0, 419}, {809, 119}}";
-							Frame = "{{0, 0}, {807, 536}}";
-						};
-						Tab3 = {
-							Frame = "{{0, 0}, {612, 295}}";
-						};
-						TabCount = 4;
-						TabsVisible = NO;
-					};
-					SplitCount = 1;
-					Tab0 = {
-						Frame = "{{0, 0}, {300, 533}}";
-						GroupTreeTableConfiguration = (
-							TargetStatusColumn,
-							18,
-							MainColumn,
-							267,
-						);
-					};
-					Tab1 = {
-						ClassesFrame = "{{0, 0}, {280, 398}}";
-						ClassesTreeTableConfiguration = (
-							PBXBookColumnIdentifier,
-							20,
-							PBXClassColumnIdentifier,
-							237,
-						);
-						Frame = "{{0, 0}, {278, 659}}";
-						MembersFrame = "{{0, 407}, {280, 252}}";
-						MembersTreeTableConfiguration = (
-							PBXBookColumnIdentifier,
-							20,
-							PBXMethodColumnIdentifier,
-							236,
-						);
-					};
-					Tab2 = {
-						Frame = "{{0, 0}, {200, 100}}";
-					};
-					Tab3 = {
-						Frame = "{{0, 0}, {222, 536}}";
-						TargetTableConfiguration = (
-							ActiveObject,
-							16,
-							ObjectNames,
-							202.296,
-						);
-					};
-					Tab4 = {
-						BreakpointsTreeTableConfiguration = (
-							breakpointColumn,
-							197,
-							enabledColumn,
-							31,
-						);
-						Frame = "{{0, 0}, {250, 528}}";
-					};
-					TabCount = 5;
-					TabsVisible = NO;
-				};
-				StatusViewVisible = NO;
-				Template = F5CA7EC8015C06940DCA290F;
-				ToolbarVisible = YES;
-				WindowLocation = "{34, 330}";
-			};
-			"PBXTemplateGeometry-F5CA7EC9015C08ED0DCA290F" = {
-				ContentSize = "{665, 594}";
-				LeftSlideOut = {
-					Collapsed = NO;
-					Frame = "{{0, 0}, {665, 594}}";
-					Split0 = {
-						ActiveTab = 3;
-						Collapsed = NO;
-						Frame = "{{0, 0}, {665, 594}}";
-						Split0 = {
-							Frame = "{{0, 304}, {665, 290}}";
-						};
-						SplitCount = 1;
-						Tab0 = {
-							Debugger = {
-								Collapsed = NO;
-								Frame = "{{0, 0}, {484, 208}}";
-								Split0 = {
-									Frame = "{{0, 24}, {484, 184}}";
-									Split0 = {
-										Frame = "{{0, 0}, {236, 184}}";
-									};
-									Split1 = {
-										DebugVariablesTableConfiguration = (
-											Name,
-											123,
-											Value,
-											85,
-											Summary,
-											62.123,
-										);
-										Frame = "{{245, 0}, {239, 184}}";
-									};
-									SplitCount = 2;
-								};
-								SplitCount = 1;
-								Tab0 = {
-									Frame = "{{0, 0}, {100, 50}}";
-								};
-								Tab1 = {
-									Frame = "{{0, 0}, {100, 50}}";
-								};
-								TabCount = 2;
-								TabsVisible = YES;
-							};
-							Frame = "{{0, 0}, {484, 208}}";
-							LauncherConfigVersion = 7;
-						};
-						Tab1 = {
 							Frame = "{{0, 0}, {664, 208}}";
 							LauncherConfigVersion = 3;
@@ -441,5 +75,5 @@
 						};
 						Tab3 = {
-							Frame = "{{0, 0}, {665, 298}}";
+							Frame = "{{0, 0}, {612, 295}}";
 						};
 						TabCount = 4;
@@ -498,249 +132,7 @@
 				};
 				StatusViewVisible = NO;
-				Template = F5CA7EC9015C08ED0DCA290F;
-				ToolbarVisible = NO;
-				WindowLocation = "{69, 372}";
-			};
-			"PBXTemplateGeometry-F5CA7ECA015C09360DCA290F" = {
-				ContentSize = "{773, 818}";
-				LeftSlideOut = {
-					Collapsed = NO;
-					Frame = "{{0, 0}, {773, 818}}";
-					Split0 = {
-						Collapsed = NO;
-						Frame = "{{0, 0}, {773, 818}}";
-						Split0 = {
-							Frame = "{{0, 0}, {773, 818}}";
-						};
-						SplitCount = 1;
-						Tab0 = {
-							Debugger = {
-								Collapsed = NO;
-								Frame = "{{0, 0}, {484, 208}}";
-								Split0 = {
-									Frame = "{{0, 24}, {484, 184}}";
-									Split0 = {
-										Frame = "{{0, 0}, {236, 184}}";
-									};
-									Split1 = {
-										DebugVariablesTableConfiguration = (
-											Name,
-											123,
-											Value,
-											85,
-											Summary,
-											62.123,
-										);
-										Frame = "{{245, 0}, {239, 184}}";
-									};
-									SplitCount = 2;
-								};
-								SplitCount = 1;
-								Tab0 = {
-									Frame = "{{0, 0}, {100, 50}}";
-								};
-								Tab1 = {
-									Frame = "{{0, 0}, {100, 50}}";
-								};
-								TabCount = 2;
-								TabsVisible = YES;
-							};
-							Frame = "{{0, 0}, {484, 208}}";
-							LauncherConfigVersion = 7;
-						};
-						Tab1 = {
-							Frame = "{{0, 0}, {664, 208}}";
-							LauncherConfigVersion = 3;
-							Runner = {
-								Frame = "{{0, 0}, {664, 208}}";
-							};
-						};
-						Tab2 = {
-							BuildMessageFrame = "{{0, 0}, {666, 43}}";
-							BuildTranscriptFrame = "{{0, 52}, {666, 0}}";
-							Frame = "{{0, 0}, {664, 50}}";
-						};
-						Tab3 = {
-							Frame = "{{0, 0}, {612, 295}}";
-						};
-						TabCount = 4;
-						TabsVisible = NO;
-					};
-					SplitCount = 1;
-					Tab0 = {
-						Frame = "{{0, 0}, {313, 531}}";
-						GroupTreeTableConfiguration = (
-							TargetStatusColumn,
-							18,
-							MainColumn,
-							280,
-						);
-					};
-					Tab1 = {
-						ClassesFrame = "{{0, 0}, {280, 398}}";
-						ClassesTreeTableConfiguration = (
-							PBXBookColumnIdentifier,
-							20,
-							PBXClassColumnIdentifier,
-							237,
-						);
-						Frame = "{{0, 0}, {278, 659}}";
-						MembersFrame = "{{0, 407}, {280, 252}}";
-						MembersTreeTableConfiguration = (
-							PBXBookColumnIdentifier,
-							20,
-							PBXMethodColumnIdentifier,
-							236,
-						);
-					};
-					Tab2 = {
-						Frame = "{{0, 0}, {200, 100}}";
-					};
-					Tab3 = {
-						Frame = "{{0, 0}, {200, 557}}";
-						TargetTableConfiguration = (
-							ActiveObject,
-							16,
-							ObjectNames,
-							202.296,
-						);
-					};
-					Tab4 = {
-						BreakpointsTreeTableConfiguration = (
-							breakpointColumn,
-							197,
-							enabledColumn,
-							31,
-						);
-						Frame = "{{0, 0}, {250, 100}}";
-					};
-					TabCount = 5;
-					TabsVisible = NO;
-				};
-				StatusViewVisible = NO;
-				Template = F5CA7ECA015C09360DCA290F;
-				ToolbarVisible = NO;
-				WindowLocation = "{724, 200}";
-			};
-			"PBXTemplateGeometry-F5CA7ECB015C094F0DCA290F" = {
-				ContentSize = "{668, 621}";
-				LeftSlideOut = {
-					Collapsed = NO;
-					Frame = "{{0, 0}, {668, 621}}";
-					Split0 = {
-						Collapsed = NO;
-						Frame = "{{0, 0}, {668, 621}}";
-						Split0 = {
-							Frame = "{{0, 0}, {668, 621}}";
-						};
-						SplitCount = 1;
-						Tab0 = {
-							Debugger = {
-								Collapsed = NO;
-								Frame = "{{0, 0}, {484, 208}}";
-								Split0 = {
-									Frame = "{{0, 24}, {484, 184}}";
-									Split0 = {
-										Frame = "{{0, 0}, {236, 184}}";
-									};
-									Split1 = {
-										DebugVariablesTableConfiguration = (
-											Name,
-											123,
-											Value,
-											85,
-											Summary,
-											62.123,
-										);
-										Frame = "{{245, 0}, {239, 184}}";
-									};
-									SplitCount = 2;
-								};
-								SplitCount = 1;
-								Tab0 = {
-									Frame = "{{0, 0}, {100, 50}}";
-								};
-								Tab1 = {
-									Frame = "{{0, 0}, {100, 50}}";
-								};
-								TabCount = 2;
-								TabsVisible = YES;
-							};
-							Frame = "{{0, 0}, {484, 208}}";
-							LauncherConfigVersion = 7;
-						};
-						Tab1 = {
-							Frame = "{{0, 0}, {664, 208}}";
-							LauncherConfigVersion = 3;
-							Runner = {
-								Frame = "{{0, 0}, {664, 208}}";
-							};
-						};
-						Tab2 = {
-							BuildMessageFrame = "{{0, 0}, {666, 43}}";
-							BuildTranscriptFrame = "{{0, 52}, {666, 0}}";
-							Frame = "{{0, 0}, {664, 50}}";
-						};
-						Tab3 = {
-							Frame = "{{0, 0}, {612, 295}}";
-						};
-						TabCount = 4;
-						TabsVisible = NO;
-					};
-					SplitCount = 1;
-					Tab0 = {
-						Frame = "{{0, 0}, {313, 531}}";
-						GroupTreeTableConfiguration = (
-							TargetStatusColumn,
-							18,
-							MainColumn,
-							280,
-						);
-					};
-					Tab1 = {
-						ClassesFrame = "{{0, 0}, {280, 398}}";
-						ClassesTreeTableConfiguration = (
-							PBXBookColumnIdentifier,
-							20,
-							PBXClassColumnIdentifier,
-							237,
-						);
-						Frame = "{{0, 0}, {278, 659}}";
-						MembersFrame = "{{0, 407}, {280, 252}}";
-						MembersTreeTableConfiguration = (
-							PBXBookColumnIdentifier,
-							20,
-							PBXMethodColumnIdentifier,
-							236,
-						);
-					};
-					Tab2 = {
-						Frame = "{{0, 0}, {200, 100}}";
-					};
-					Tab3 = {
-						Frame = "{{0, 0}, {200, 557}}";
-						TargetTableConfiguration = (
-							ActiveObject,
-							16,
-							ObjectNames,
-							202.296,
-						);
-					};
-					Tab4 = {
-						BreakpointsTreeTableConfiguration = (
-							breakpointColumn,
-							197,
-							enabledColumn,
-							31,
-						);
-						Frame = "{{0, 0}, {250, 100}}";
-					};
-					TabCount = 5;
-					TabsVisible = NO;
-				};
-				StatusViewVisible = NO;
 				Template = F5CA7ECB015C094F0DCA290F;
 				ToolbarVisible = NO;
-				WindowLocation = "{382, 526}";
+				WindowLocation = "{48, 349}";
 			};
 			PBXWorkspaceContents = (
@@ -752,74 +144,4 @@
 								NavGeometry0 = {
 									Frame = "{{0, 0}, {150, 530}}";
-									NavBarVisible = YES;
-								};
-							};
-							SplitCount = 1;
-							Tab0 = {
-								Debugger = {
-									Split0 = {
-										SplitCount = 2;
-									};
-									SplitCount = 1;
-									TabCount = 2;
-								};
-								LauncherConfigVersion = 7;
-							};
-							Tab1 = {
-								LauncherConfigVersion = 3;
-								Runner = {
-								};
-							};
-							TabCount = 4;
-						};
-						SplitCount = 1;
-						Tab1 = {
-							OptionsSetName = "Hierarchy, all classes";
-						};
-						TabCount = 5;
-					};
-				},
-				{
-					LeftSlideOut = {
-						Split0 = {
-							Split0 = {
-								NavCount = 1;
-								NavGeometry0 = {
-									Frame = "{{0, 0}, {594, 150}}";
-									NavBarVisible = YES;
-								};
-							};
-							SplitCount = 1;
-							Tab0 = {
-								Debugger = {
-									Split0 = {
-										SplitCount = 2;
-									};
-									SplitCount = 1;
-									TabCount = 2;
-								};
-								LauncherConfigVersion = 7;
-							};
-							Tab1 = {
-								LauncherConfigVersion = 3;
-								Runner = {
-								};
-							};
-							TabCount = 4;
-						};
-						SplitCount = 1;
-						Tab1 = {
-							OptionsSetName = "Hierarchy, all classes";
-						};
-						TabCount = 5;
-					};
-				},
-				{
-					LeftSlideOut = {
-						Split0 = {
-							Split0 = {
-								NavCount = 1;
-								NavGeometry0 = {
-									Frame = "{{0, 0}, {618, 150}}";
 									NavBarVisible = YES;
 								};
@@ -974,250 +296,6 @@
 					WindowLocation = "{20, 553}";
 				},
-				{
-					ContentSize = "{594, 303}";
-					LeftSlideOut = {
-						Collapsed = NO;
-						Frame = "{{0, 23}, {594, 280}}";
-						Split0 = {
-							ActiveTab = 1;
-							Collapsed = YES;
-							Frame = "{{0, 0}, {594, 280}}";
-							Split0 = {
-								Frame = "{{1e+06, 1e+06}, {594, 0}}";
-							};
-							SplitCount = 1;
-							Tab0 = {
-								Debugger = {
-									Collapsed = NO;
-									Frame = "{{0, 0}, {804, 321}}";
-									Split0 = {
-										Frame = "{{0, 24}, {804, 297}}";
-										Split0 = {
-											Frame = "{{0, 0}, {394, 297}}";
-										};
-										Split1 = {
-											DebugVariablesTableConfiguration = (
-												Name,
-												123,
-												Value,
-												85,
-												Summary,
-												167.123,
-											);
-											Frame = "{{403, 0}, {401, 297}}";
-										};
-										SplitCount = 2;
-									};
-									SplitCount = 1;
-									Tab0 = {
-										Frame = "{{0, 0}, {100, 50}}";
-									};
-									Tab1 = {
-										Frame = "{{0, 0}, {100, 50}}";
-									};
-									TabCount = 2;
-									TabsVisible = YES;
-								};
-								Frame = "{{0, 0}, {804, 321}}";
-								LauncherConfigVersion = 7;
-							};
-							Tab1 = {
-								Frame = "{{0, 0}, {594, 274}}";
-								LauncherConfigVersion = 3;
-								Runner = {
-									Frame = "{{0, 0}, {594, 274}}";
-								};
-							};
-							Tab2 = {
-								BuildMessageFrame = "{{0, 0}, {806, 237}}";
-								BuildTranscriptFrame = "{{0, 246}, {806, 3}}";
-								Frame = "{{0, 0}, {804, 247}}";
-							};
-							Tab3 = {
-								Frame = "{{0, 0}, {612, 295}}";
-							};
-							TabCount = 4;
-							TabsVisible = NO;
-						};
-						SplitCount = 1;
-						Tab0 = {
-							Frame = "{{0, 0}, {300, 533}}";
-							GroupTreeTableConfiguration = (
-								TargetStatusColumn,
-								18,
-								MainColumn,
-								267,
-							);
-						};
-						Tab1 = {
-							ClassesFrame = "{{0, 0}, {280, 398}}";
-							ClassesTreeTableConfiguration = (
-								PBXBookColumnIdentifier,
-								20,
-								PBXClassColumnIdentifier,
-								237,
-							);
-							Frame = "{{0, 0}, {278, 659}}";
-							MembersFrame = "{{0, 407}, {280, 252}}";
-							MembersTreeTableConfiguration = (
-								PBXBookColumnIdentifier,
-								20,
-								PBXMethodColumnIdentifier,
-								236,
-							);
-						};
-						Tab2 = {
-							Frame = "{{0, 0}, {200, 100}}";
-						};
-						Tab3 = {
-							Frame = "{{0, 0}, {200, 386}}";
-							TargetTableConfiguration = (
-								ActiveObject,
-								16,
-								ObjectNames,
-								202.296,
-							);
-						};
-						Tab4 = {
-							BreakpointsTreeTableConfiguration = (
-								breakpointColumn,
-								197,
-								enabledColumn,
-								31,
-							);
-							Frame = "{{0, 0}, {250, 386}}";
-						};
-						TabCount = 5;
-						TabsVisible = NO;
-					};
-					StatusViewVisible = YES;
-					Template = F5534CB2020F3F8A0DCA290F;
-					ToolbarVisible = YES;
-					WindowLocation = "{188, 218}";
-				},
-				{
-					ContentSize = "{618, 257}";
-					LeftSlideOut = {
-						Collapsed = NO;
-						Frame = "{{0, 23}, {618, 234}}";
-						Split0 = {
-							ActiveTab = 2;
-							Collapsed = YES;
-							Frame = "{{0, 0}, {618, 234}}";
-							Split0 = {
-								Frame = "{{1e+06, 1e+06}, {618, 0}}";
-							};
-							SplitCount = 1;
-							Tab0 = {
-								Debugger = {
-									Collapsed = NO;
-									Frame = "{{0, 0}, {952, 321}}";
-									Split0 = {
-										Frame = "{{0, 24}, {952, 297}}";
-										Split0 = {
-											Frame = "{{0, 0}, {468, 297}}";
-										};
-										Split1 = {
-											DebugVariablesTableConfiguration = (
-												Name,
-												126.803,
-												Value,
-												150.074,
-												Summary,
-												172.123,
-											);
-											Frame = "{{477, 0}, {475, 297}}";
-										};
-										SplitCount = 2;
-									};
-									SplitCount = 1;
-									Tab0 = {
-										Frame = "{{0, 0}, {100, 50}}";
-									};
-									Tab1 = {
-										Frame = "{{0, 0}, {100, 50}}";
-									};
-									TabCount = 2;
-									TabsVisible = YES;
-								};
-								Frame = "{{0, 0}, {952, 321}}";
-								LauncherConfigVersion = 7;
-							};
-							Tab1 = {
-								Frame = "{{0, 0}, {781, 452}}";
-								LauncherConfigVersion = 3;
-								Runner = {
-									Frame = "{{0, 0}, {781, 452}}";
-								};
-							};
-							Tab2 = {
-								BuildMessageFrame = "{{0, 0}, {620, 123}}";
-								BuildTranscriptFrame = "{{0, 132}, {620, 98}}";
-								Frame = "{{0, 0}, {618, 228}}";
-							};
-							Tab3 = {
-								Frame = "{{0, 0}, {612, 295}}";
-							};
-							TabCount = 4;
-							TabsVisible = NO;
-						};
-						SplitCount = 1;
-						Tab0 = {
-							Frame = "{{0, 0}, {300, 533}}";
-							GroupTreeTableConfiguration = (
-								TargetStatusColumn,
-								18,
-								MainColumn,
-								267,
-							);
-						};
-						Tab1 = {
-							ClassesFrame = "{{0, 0}, {280, 398}}";
-							ClassesTreeTableConfiguration = (
-								PBXBookColumnIdentifier,
-								20,
-								PBXClassColumnIdentifier,
-								237,
-							);
-							Frame = "{{0, 0}, {278, 659}}";
-							MembersFrame = "{{0, 407}, {280, 252}}";
-							MembersTreeTableConfiguration = (
-								PBXBookColumnIdentifier,
-								20,
-								PBXMethodColumnIdentifier,
-								236,
-							);
-						};
-						Tab2 = {
-							Frame = "{{0, 0}, {200, 100}}";
-						};
-						Tab3 = {
-							Frame = "{{0, 0}, {200, 100}}";
-							TargetTableConfiguration = (
-								ActiveObject,
-								16,
-								ObjectNames,
-								202.296,
-							);
-						};
-						Tab4 = {
-							BreakpointsTreeTableConfiguration = (
-								breakpointColumn,
-								197,
-								enabledColumn,
-								31,
-							);
-							Frame = "{{0, 0}, {250, 100}}";
-						};
-						TabCount = 5;
-						TabsVisible = NO;
-					};
-					StatusViewVisible = YES;
-					Template = F5314676015831810DCA290F;
-					ToolbarVisible = YES;
-					WindowLocation = "{601, 113}";
-				},
 			);
-			PBXWorkspaceStateSaveDate = 55845278;
+			PBXWorkspaceStateSaveDate = 55895130;
 		};
 		projectwideBuildSettings = {
@@ -1269,5 +347,5 @@
 		name = "PSAlarmSetController.m: 16";
 		rLen = 0;
-		rLoc = 2511;
+		rLoc = 2594;
 		rType = 0;
 		vrLen = 291;
@@ -1279,5 +357,5 @@
 		name = "PSAlarmSetController.m: inAtChanged:";
 		rLen = 36;
-		rLoc = 6528;
+		rLoc = 4953;
 		rType = 0;
 		vrLen = 478;
@@ -1289,5 +367,5 @@
 		name = "PSAlarmSetController.h: 25";
 		rLen = 0;
-		rLoc = 799;
+		rLoc = 773;
 		rType = 0;
 		vrLen = 758;
@@ -1299,5 +377,5 @@
 		name = "PSAlarmSetController.h: 31";
 		rLen = 0;
-		rLoc = 959;
+		rLoc = 933;
 		rType = 0;
 		vrLen = 826;
Index: /trunk/Cocoa/Pester/Source/Pester.pbproj/project.pbxproj
===================================================================
--- /trunk/Cocoa/Pester/Source/Pester.pbproj/project.pbxproj	(revision 23)
+++ /trunk/Cocoa/Pester/Source/Pester.pbproj/project.pbxproj	(revision 24)
@@ -22,4 +22,6 @@
 				F59DC6FC0354188F01AEEDB1,
 				F59DC6FD0354188F01AEEDB1,
+				F59F6CB40354E7DA01AEEDB1,
+				F59F6CB50354E7DA01AEEDB1,
 			);
 			isa = PBXGroup;
@@ -231,7 +233,7 @@
 				LIBRARY_SEARCH_PATHS = "";
 				OTHER_CFLAGS = "";
-				OTHER_LDFLAGS = "";
 				PRODUCT_NAME = Pester;
 				SECTORDER_FLAGS = "";
+				USE_GCC3_PFE_SUPPORT = YES;
 				WARNING_CFLAGS = "-Wmost -Wno-four-char-constants -Wno-unknown-pragmas";
 				WRAPPER_EXTENSION = app;
@@ -253,5 +255,5 @@
 	<string>Pester</string>
 	<key>CFBundleGetInfoString</key>
-	<string>Pester 1.0d1, © 2002 Nicholas Riley</string>
+	<string>Pester 1.0d2, © 2002 Nicholas Riley</string>
 	<key>CFBundleIconFile</key>
 	<string>Application icon</string>
@@ -269,5 +271,5 @@
 	<string>Pstr</string>
 	<key>CFBundleVersion</key>
-	<string>1.0d1</string>
+	<string>1.0d2</string>
 	<key>NSMainNibFile</key>
 	<string>MainMenu</string>
@@ -286,4 +288,5 @@
 				F59DC6EB0353F58B01AEEDB1,
 				F59DC6FE0354188F01AEEDB1,
+				F59F6CB60354E7DA01AEEDB1,
 			);
 			isa = PBXHeadersBuildPhase;
@@ -309,4 +312,5 @@
 				F59DC6EA0353F58B01AEEDB1,
 				F59DC6FF0354188F01AEEDB1,
+				F59F6CB70354E7DA01AEEDB1,
 			);
 			isa = PBXSourcesBuildPhase;
@@ -488,4 +492,26 @@
 			};
 		};
+		F59F6CB40354E7DA01AEEDB1 = {
+			isa = PBXFileReference;
+			path = PSAlarm.h;
+			refType = 4;
+		};
+		F59F6CB50354E7DA01AEEDB1 = {
+			isa = PBXFileReference;
+			path = PSAlarm.m;
+			refType = 4;
+		};
+		F59F6CB60354E7DA01AEEDB1 = {
+			fileRef = F59F6CB40354E7DA01AEEDB1;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		F59F6CB70354E7DA01AEEDB1 = {
+			fileRef = F59F6CB50354E7DA01AEEDB1;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
 	};
 	rootObject = 29B97313FDCFA39411CA2CEA;
