source: trunk/Cocoa/Pester/Source/PSAlarmAlertController.m @ 113

Last change on this file since 113 was 113, checked in by Nicholas Riley, 17 years ago

PSTimer.m: Fix bug 15, leaking PSTimer from NSInvocation argument retention.

Read Me.rtfd: Updated release notes.

PSAlarm.[hm]: Removed obsolete comment. Changed 1m-59m times to
display without `0h'. Moved code from deserialization to -resetTimer
to be used for alarm deletion undo - fix bug 14.

PSAlarmsController.m: Fix bug 14 - implement _restoreAlarms:,
_removeAlarms and _undoManager. Need to add localized string.

PSAlarmAlertController.m: Fix bug 17, move alert triggering from
constructor to -performAlertsForAlarm: to avoid nested notifications
delivering in wrong order.

PSAlarms.[hm]: Fix bug 14 - implement -restoreAlarms, invokes [PSAlarm
resetTimer]. Clarified a comment. Uncommented some debug logging.

package-Pester.sh: Implemented partition map-less disk image, saves a
few K on distribution. Removed obsolete comments. Added agvtool
bump.

File size: 3.3 KB
Line 
1//
2//  PSAlarmAlertController.m
3//  Pester
4//
5//  Created by Nicholas Riley on Sat Oct 26 2002.
6//  Copyright (c) 2002 Nicholas Riley. All rights reserved.
7//
8
9#import "PSAlarmAlertController.h"
10#import "PSAlert.h"
11#import "PSAlerts.h"
12
13NSString * const PSAlarmAlertStopNotification = @"PSAlarmAlertStopNotification";
14
15@implementation PSAlarmAlertController
16
17+ (PSAlarmAlertController *)controllerWithTimerExpiredNotification:(NSNotification *)notification;
18{
19    return [[[self alloc] initWithAlarm: [notification object]] autorelease];
20}
21
22+ (IBAction)stopAlerts:(id)sender;
23{
24    [[NSNotificationCenter defaultCenter] postNotificationName: PSAlarmAlertStopNotification object: nil];
25}
26
27- (void)_resumeAlarm:(PSAlarm *)alarm;
28{
29    [[NSNotificationCenter defaultCenter] removeObserver: self];
30    [alarm setTimer]; // if snooze not set and not repeating, alarm will die
31    if (frontmostApp.highLongOfPSN != 0 || frontmostApp.lowLongOfPSN != 0) {
32        SetFrontProcess(&frontmostApp);
33        if (appWasHidden)
34            [NSApp hide: self];
35    }
36}
37
38- (void)_alertCompleted:(NSNotification *)notification;
39{
40    PSAlert *alert = [[notification userInfo] objectForKey: @"alert"];
41    unsigned count = [pendingAlerts count];
42    [pendingAlerts removeObject: alert];
43    NSLog(@"removed: %@; still pending: %@", alert, [pendingAlerts description]);
44    NSLog(@"alarm: %@ retainCount %d", [notification object], [[notification object] retainCount]);
45    NSAssert2([pendingAlerts count] == count - 1, @"alert not in set: %@\n%@", alert, notification);
46    if ([pendingAlerts count] == 0) {
47        [self _resumeAlarm: [notification object]];
48        [self release];
49    }
50}
51
52- (void)performAlertsForAlarm:(PSAlarm *)alarm;
53{
54    PSAlerts *alerts = [alarm alerts];
55    NSArray *allAlerts = [alerts allAlerts];
56    if ([allAlerts count] == 0) {
57        [self _resumeAlarm: alarm];
58    } else {
59        pendingAlerts = [[NSMutableSet alloc] init];
60        [pendingAlerts addObjectsFromArray: allAlerts];
61        [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_alertCompleted:)
62                                                     name: PSAlarmAlertCompletedNotification object: alarm];
63        [self retain]; // release in _alertCompleted:
64    }
65    [alerts triggerForAlarm: alarm];
66    if ([alerts requirePesterFrontmost] && ![NSApp isActive]) { // restore frontmost process afterward
67        NSDictionary *activeProcessInfo = [[NSWorkspace sharedWorkspace] activeApplication];
68        frontmostApp.highLongOfPSN = [[activeProcessInfo objectForKey: @"NSApplicationProcessSerialNumberHigh"] longValue];
69        frontmostApp.lowLongOfPSN = [[activeProcessInfo objectForKey: @"NSApplicationProcessSerialNumberLow"] longValue];
70        appWasHidden = [NSApp isHidden];
71        [NSApp activateIgnoringOtherApps: YES];
72    }
73}
74
75- (id)initWithAlarm:(PSAlarm *)alarm;
76{
77    if ( (self = [super init]) != nil) {
78        // because we're called within a notification, and alerts may deliver further notifications, make sure the rest of the notification clients are able to execute first
79        [self performSelector: @selector(performAlertsForAlarm:) withObject: alarm afterDelay: 0];
80    }
81    return self;
82}
83
84- (void)dealloc;
85{
86    NSLog(@"%@ dealloc", self);
87    [pendingAlerts release];
88    [super dealloc];
89}
90
91@end
Note: See TracBrowser for help on using the repository browser.