[34] | 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"
|
---|
[53] | 10 | #import "PSAlert.h"
|
---|
| 11 | #import "PSAlerts.h"
|
---|
[34] | 12 |
|
---|
| 13 | NSString * 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 |
|
---|
[53] | 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];
|
---|
[105] | 43 | NSLog(@"removed: %@; still pending: %@", alert, [pendingAlerts description]);
|
---|
| 44 | NSLog(@"alarm: %@ retainCount %d", [notification object], [[notification object] retainCount]);
|
---|
[53] | 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 |
|
---|
[113] | 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 |
|
---|
[34] | 75 | - (id)initWithAlarm:(PSAlarm *)alarm;
|
---|
| 76 | {
|
---|
| 77 | if ( (self = [super init]) != nil) {
|
---|
[113] | 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];
|
---|
[34] | 80 | }
|
---|
| 81 | return self;
|
---|
| 82 | }
|
---|
| 83 |
|
---|
[53] | 84 | - (void)dealloc;
|
---|
| 85 | {
|
---|
| 86 | NSLog(@"%@ dealloc", self);
|
---|
| 87 | [pendingAlerts release];
|
---|
| 88 | [super dealloc];
|
---|
| 89 | }
|
---|
| 90 |
|
---|
[34] | 91 | @end
|
---|