Ignore:
Timestamp:
10/20/02 06:35:16 (22 years ago)
Author:
Nicholas Riley
Message:

Pester 1.0b1

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Cocoa/Pester/Source/PSAlarmSetController.m

    r24 r26  
    2828// XXX please expose the iCal controls!
    2929
     30@interface PSAlarmSetController (Private)
     31
     32- (void)_stopUpdateTimer;
     33
     34@end
    3035
    3136@implementation PSAlarmSetController
     
    3338- (void)awakeFromNib;
    3439{
    35     // NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
     40    // XXX bugs prevent this code from working properly on Jaguar
     41    /* NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
     42    [timeOfDay setFormatter: [[NJRDateFormatter alloc] initWithDateFormat: [defaults objectForKey: NSTimeFormatString] allowNaturalLanguage: YES]];
     43    [timeDate setFormatter: [[NJRDateFormatter alloc] initWithDateFormat: [defaults objectForKey: NSShortDateFormatString] allowNaturalLanguage: YES]]; */
     44    alarm = [[PSAlarm alloc] init];
    3645    [[self window] center];
    37     // XXX bugs prevent these from working (sigh...)
    38     // [timeOfDay setFormatter: [[NJRDateFormatter alloc] initWithDateFormat: [defaults objectForKey: NSTimeFormatString] allowNaturalLanguage: YES]];
    39     // [timeDate setFormatter: [[NJRDateFormatter alloc] initWithDateFormat: [defaults objectForKey: NSShortDateFormatString] allowNaturalLanguage: YES]];
    4046    [self inAtChanged: nil];
    41     alarm = [[PSAlarm alloc] init];
    4247    [[self window] makeKeyAndOrderFront: nil];
    4348}
    4449
    45 - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag;
    46 {
    47     if (!flag) [self showWindow: self];
    48     return YES;
    49 }
    50 
    5150- (void)setStatus:(NSString *)aString;
    5251{
     52    // NSLog(@"%@", alarm);
    5353    if (aString != status) {
    5454        [status release]; status = nil;
     
    7474- (void)setAlarmDateAndInterval:(id)sender;
    7575{
    76     if (isIn) {
     76    if (isInterval) {
    7777        [alarm setInterval:
    7878            [[self objectValueForTextField: timeInterval whileEditing: sender] intValue] *
     
    8484}
    8585
    86 // XXX should set timer to update status every second while configuration is valid, application is in front, and isIn
     86- (void)_stopUpdateTimer;
     87{
     88    if ([updateTimer isValid]) [updateTimer invalidate];
     89    [updateTimer release]; updateTimer = nil;
     90}
    8791
    8892// XXX use OACalendar?
    8993
    90 // 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.
    91 
    9294- (IBAction)updateDateDisplay:(id)sender;
    9395{
     96    // NSLog(@"updateDateDisplay: %@", sender);
    9497    if ([alarm isValid]) {
    9598        [self setStatus: [[alarm date] descriptionWithCalendarFormat: @"Alarm will be set for %X on %x" timeZone: nil locale: nil]];
    9699        [setButton setEnabled: YES];
     100        if (updateTimer == nil || ![updateTimer isValid]) {
     101            // XXX this logic (and the timer) should really go into PSAlarm, to send notifications for status updates instead.  Timer starts when people are watching, stops when people aren't.
     102            // NSLog(@"setting timer");
     103            if (isInterval) {
     104                updateTimer = [NSTimer scheduledTimerWithTimeInterval: 1 target: self selector: @selector(updateDateDisplay:) userInfo: nil repeats: YES];
     105            } else {
     106                updateTimer = [NSTimer scheduledTimerWithTimeInterval: [alarm interval] target: self selector: @selector(updateDateDisplay:) userInfo: nil repeats: NO];
     107            }
     108            [updateTimer retain];
     109        }
    97110    } else {
    98111        [setButton setEnabled: NO];
    99     }
    100 }
     112        [self setStatus: [alarm invalidMessage]];
     113        [self _stopUpdateTimer];
     114    }
     115}
     116
     117// 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.
    101118
    102119- (IBAction)update:(id)sender;
     
    109126- (IBAction)inAtChanged:(id)sender;
    110127{
    111     isIn = ([inAtMatrix selectedTag] == 0);
    112     [timeInterval setEnabled: isIn];
    113     [timeIntervalUnits setEnabled: isIn];
    114     [timeOfDay setEnabled: !isIn];
    115     [timeDate setEnabled: !isIn];
    116     [timeDateCompletions setEnabled: !isIn];
     128    isInterval = ([inAtMatrix selectedTag] == 0);
     129    [timeInterval setEnabled: isInterval];
     130    [timeIntervalUnits setEnabled: isInterval];
     131    [timeOfDay setEnabled: !isInterval];
     132    [timeDate setEnabled: !isInterval];
     133    [timeDateCompletions setEnabled: !isInterval];
    117134    if (sender != nil)
    118         [[self window] makeFirstResponder: isIn ? timeInterval : timeOfDay];
     135        [[self window] makeFirstResponder: isInterval ? timeInterval : timeOfDay];
    119136    // NSLog(@"UPDATING FROM inAtChanged");
    120137    [self update: nil];
    121138}
     139
     140- (IBAction)dateCompleted:(NSPopUpButton *)sender;
     141{
     142    [timeDate setStringValue: [sender titleOfSelectedItem]];
     143    [self update: sender];
     144}
     145
     146// to ensure proper updating of interval, this should be the only method by which the window is shown (e.g. from the Alarm menu)
     147- (IBAction)showWindow:(id)sender;
     148{
     149    if (![[self window] isVisible]) {
     150        // NSLog(@"UPDATING FROM showWindow");
     151        [self update: self];
     152    }
     153    [super showWindow: sender];
     154}
     155
     156- (IBAction)setAlarm:(NSButton *)sender;
     157{
     158    PSAlarmNotifierController *notifier = [PSAlarmNotifierController alloc];
     159    if (notifier == nil) {
     160        [self setStatus: @"Unable to set alarm."];
     161        return;
     162    }
     163    [self setAlarmDateAndInterval: sender];
     164    [alarm setMessage: [messageField stringValue]];
     165    if (![alarm setTimer]) {
     166        [self setStatus: [@"Unable to set alarm.  " stringByAppendingString: [alarm invalidMessage]]];
     167        return;
     168    }
     169    [self setStatus: [[alarm date] descriptionWithCalendarFormat: @"Alarm set for %x at %X" timeZone: nil locale: nil]];
     170    [[self window] close];
     171    [alarm release];
     172    alarm = [[PSAlarm alloc] init];
     173}
     174
     175@end
     176
     177@implementation PSAlarmSetController (NSControlSubclassDelegate)
    122178
    123179- (void)control:(NSControl *)control didFailToValidatePartialString:(NSString *)string errorDescription:(NSString *)error;
     
    140196}
    141197
    142 - (IBAction)dateCompleted:(NSPopUpButton *)sender;
    143 {
    144     [timeDate setStringValue: [sender titleOfSelectedItem]];
    145 }
    146 
    147 // to ensure proper updating of interval, this should be the only method by which the window is shown (e.g. from the Alarm menu)
    148 - (IBAction)showWindow:(id)sender;
    149 {
    150     if (![[self window] isVisible]) {
    151         // NSLog(@"UPDATING FROM showWindow");
    152         [self update: self];
    153     }
    154     [super showWindow: sender];
    155    
    156 }
    157 
    158 - (IBAction)setAlarm:(NSButton *)sender;
    159 {
    160     PSAlarmNotifierController *notifier = [PSAlarmNotifierController alloc];
    161     NSTimer *timer;
    162     NSTimeInterval interval;
    163     [self setAlarmDateAndInterval: sender];
    164     if (notifier == nil || ( (interval = [alarm interval]) == 0)) {
    165         [self setStatus: @"Unable to set alarm (time just passed?)"];
    166         return;
    167     }
    168     [alarm setMessage: [messageField stringValue]];
    169     // XXX should use alarm object instead for userInfo
    170     timer = [NSTimer scheduledTimerWithTimeInterval: interval
    171                                              target: notifier
    172                                            selector: @selector(initWithTimer:)
    173                                            userInfo: alarm
    174                                             repeats: NO];
    175     [self setStatus: [[alarm date] descriptionWithCalendarFormat: @"Alarm set for %x at %X" timeZone: nil locale: nil]];
    176     [[self window] close];
    177 }
     198@end
     199
     200@implementation PSAlarmSetController (NSWindowNotifications)
     201
     202- (void)windowWillClose:(NSNotification *)notification;
     203{
     204    // NSLog(@"stopping update timer");
     205    [self _stopUpdateTimer];
     206}
     207
     208@end
     209
     210@implementation PSAlarmSetController (NSControlSubclassNotifications)
    178211
    179212// called because we're the delegate
     
    186219
    187220@end
     221
     222@implementation PSAlarmSetController (NSApplicationDelegate)
     223
     224- (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag;
     225{
     226    if (!flag) [self showWindow: self];
     227    return YES;
     228}
     229
     230@end
Note: See TracChangeset for help on using the changeset viewer.