Make GrowlMail's main suicide-pill method into a public function. The core method lives on, and the function calls it through the shiny new singleton-instance static variable that I added in the previous commit.
authorPeter Hosey <hg@boredzo.org>
Sat Jun 06 21:30:17 2009 -0700 (2009-06-06)
changeset 4210c36ddc8e6b22
parent 4209 f8a902d33769
child 4211 3be8b67aac72
Make GrowlMail's main suicide-pill method into a public function. The core method lives on, and the function calls it through the shiny new singleton-instance static variable that I added in the previous commit.
Extras/GrowlMail/GrowlMailNotifier.h
Extras/GrowlMail/GrowlMailNotifier.m
     1.1 --- a/Extras/GrowlMail/GrowlMailNotifier.h	Sat Jun 06 21:30:17 2009 -0700
     1.2 +++ b/Extras/GrowlMail/GrowlMailNotifier.h	Sat Jun 06 21:30:17 2009 -0700
     1.3 @@ -94,4 +94,12 @@
     1.4  
     1.5  - (void)didFinishNotificationForMessage:(Message *)message;
     1.6  
     1.7 +
     1.8 +/*!	@brief	Disable GrowlMail and print a warning message
     1.9 + *
    1.10 + *	GrowlMail is paranoid about changes in Mail's behavior. Whenever it detects such a change, it calls this function, which removes GrowlMail's notification-observer registrations and stops it from posting Growl notifications. We call it the “suicide pill”.
    1.11 + *
    1.12 + *	@param	specificWarning	Additional information to add to the warning message. Can be \c nil.
    1.13 + */
    1.14 +void GMShutDownGrowlMailAndWarn(NSString *specificWarning);
    1.15  @end
     2.1 --- a/Extras/GrowlMail/GrowlMailNotifier.m	Sat Jun 06 21:30:17 2009 -0700
     2.2 +++ b/Extras/GrowlMail/GrowlMailNotifier.m	Sat Jun 06 21:30:17 2009 -0700
     2.3 @@ -33,18 +33,6 @@
     2.4  - (void) shutDownGrowlMail {
     2.5  	[[NSNotificationCenter defaultCenter] removeObserver:self];
     2.6  	[GrowlApplicationBridge setGrowlDelegate:nil];
     2.7 -
     2.8 -	//Prevent ourselves from re-enabling later.
     2.9 -	notifierEnabled = NO;
    2.10 -}
    2.11 -
    2.12 -//This is a suicide pill. GrowlMail sends itself this message any time it detects a change in Mail's implementation, such as a missing method or an object of the wrong class.
    2.13 -- (void) shutDownGrowlMailAndWarn:(NSString *)specificWarning {
    2.14 -	NSLog(NSLocalizedString(@"WARNING: Mail is not behaving in the way that GrowlMail expects. This is probably because GrowlMail is incompatible with the version of Mail you're using. GrowlMail will now turn itself off. Please check the Growl website for a new version. If you're a programmer and want to debug this error, run gdb, load Mail, set a breakpoint on %s, and run.", /*comment*/ nil), __PRETTY_FUNCTION__);
    2.15 -	if (specificWarning)
    2.16 -		NSLog(@"Furthermore, the caller provided a more specific message: %@", specificWarning);
    2.17 -
    2.18 -	[self shutDownGrowlMail];
    2.19  }
    2.20  
    2.21  #pragma mark The circle of life
    2.22 @@ -129,11 +117,11 @@
    2.23  	if ([clickContext length]) {
    2.24  		//Make sure we have all the methods we need.
    2.25  		if (!class_getClassMethod([Library class], @selector(messageWithMessageID:)))
    2.26 -			[self shutDownGrowlMailAndWarn:@"Library does not respond to +messageWithMessageID:"];
    2.27 +			GMShutDownGrowlMailAndWarn(@"Library does not respond to +messageWithMessageID:");
    2.28  		if (!class_getInstanceMethod([SingleMessageViewer class], @selector(initForViewingMessage:showAllHeaders:viewingState:fromDefaults:)))
    2.29 -			[self shutDownGrowlMailAndWarn:@"SingleMessageViewer does not respond to -initForViewingMessage:showAllHeaders:viewingState:fromDefaults:"];
    2.30 +			GMShutDownGrowlMailAndWarn(@"SingleMessageViewer does not respond to -initForViewingMessage:showAllHeaders:viewingState:fromDefaults:");
    2.31  		if (!class_getInstanceMethod([SingleMessageViewer class], @selector(showAndMakeKey:)))
    2.32 -			[self shutDownGrowlMailAndWarn:@"SingleMessageViewer does not respond to -showAndMakeKey:"];
    2.33 +			GMShutDownGrowlMailAndWarn(@"SingleMessageViewer does not respond to -showAndMakeKey:");
    2.34  
    2.35  		Message *message = [Library messageWithMessageID:clickContext];
    2.36  		MessageViewingState *viewingState = [[MessageViewingState alloc] init];
    2.37 @@ -224,7 +212,7 @@
    2.38  
    2.39  	Library *store = [notification object];
    2.40  	if (!store) {
    2.41 -		[self shutDownGrowlMailAndWarn:[NSString stringWithFormat:@"'%@' notification has no object", [notification name]]];
    2.42 +		GMShutDownGrowlMailAndWarn([NSString stringWithFormat:@"'%@' notification has no object", [notification name]]);
    2.43  	}
    2.44  	if ([store isKindOfClass:[LibraryStore class]]) {
    2.45  		//As of Tiger, this is normal; this notification is posted a couple times (perhaps once per inbox) with a LibraryStore object.
    2.46 @@ -235,7 +223,7 @@
    2.47  	//The rest of the handler should be able to work just fine without proving anything else about the store, since it doesn't use the store.
    2.48  
    2.49  	NSDictionary *userInfo = [notification userInfo];
    2.50 -	if (!userInfo) [self shutDownGrowlMailAndWarn:@"Notification had no userInfo"];
    2.51 +	if (!userInfo) GMShutDownGrowlMailAndWarn(@"Notification had no userInfo");
    2.52  
    2.53  	NSArray *mailboxes = [userInfo objectForKey:@"mailboxes"];
    2.54  #ifdef GROWL_MAIL_DEBUG
    2.55 @@ -248,16 +236,16 @@
    2.56  	//Ignore a notification if we're ignoring all of the mailboxes involved.
    2.57  	Class MailAccount_class = [MailAccount class];
    2.58  	if (!class_getClassMethod(MailAccount_class, @selector(draftMailboxUids)))
    2.59 -		[self shutDownGrowlMailAndWarn:@"MailAccount does not respond to +draftMailboxUids"];
    2.60 +		GMShutDownGrowlMailAndWarn(@"MailAccount does not respond to +draftMailboxUids");
    2.61  	if (!class_getClassMethod(MailAccount_class, @selector(outboxMailboxUids)))
    2.62 -		[self shutDownGrowlMailAndWarn:@"MailAccount does not respond to +outboxMailboxUids"];
    2.63 +		GMShutDownGrowlMailAndWarn(@"MailAccount does not respond to +outboxMailboxUids");
    2.64  	if (!class_getClassMethod(MailAccount_class, @selector(sentMessagesMailboxUids)))
    2.65 -		[self shutDownGrowlMailAndWarn:@"MailAccount does not respond to +sentMessagesMailboxUids"];
    2.66 +		GMShutDownGrowlMailAndWarn(@"MailAccount does not respond to +sentMessagesMailboxUids");
    2.67  	if (!class_getClassMethod(MailAccount_class, @selector(trashMailboxUids)))
    2.68 -		[self shutDownGrowlMailAndWarn:@"MailAccount does not respond to +trashMailboxUids"];
    2.69 +		GMShutDownGrowlMailAndWarn(@"MailAccount does not respond to +trashMailboxUids");
    2.70  	//We need this method to support the Inbox Only preference.
    2.71  	if (!class_getClassMethod(MailAccount_class, @selector(inboxMailboxUids)))
    2.72 -		[self shutDownGrowlMailAndWarn:@"MailAccount does not respond to +inboxMailboxUids"];
    2.73 +		GMShutDownGrowlMailAndWarn(@"MailAccount does not respond to +inboxMailboxUids");
    2.74  
    2.75  	//Ignore messages being written.
    2.76  	NSMutableSet *mailboxesToIgnore = [NSMutableSet setWithArray:[MailAccount draftMailboxUids]];
    2.77 @@ -274,7 +262,7 @@
    2.78  		return;
    2.79  
    2.80  	NSArray *messages = [userInfo objectForKey:@"messages"];
    2.81 -	if (!messages) [self shutDownGrowlMailAndWarn:@"Notification's userInfo has no messages"];
    2.82 +	if (!messages) GMShutDownGrowlMailAndWarn(@"Notification's userInfo has no messages");
    2.83  	
    2.84  #ifdef GROWL_MAIL_DEBUG
    2.85  	NSLog(@"%s: Mail added messages [1] to mailboxes [2].\n[1]: %@\n[2]: %@", __PRETTY_FUNCTION__, messages, mailboxes);
    2.86 @@ -312,7 +300,7 @@
    2.87  					continue;
    2.88  
    2.89  				if (![message isKindOfClass:Message_class])
    2.90 -					[self shutDownGrowlMailAndWarn:[NSString stringWithFormat:@"Message in notification was not a Message; it is %@", message]];
    2.91 +					GMShutDownGrowlMailAndWarn([NSString stringWithFormat:@"Message in notification was not a Message; it is %@", message]);
    2.92  
    2.93  				if (![message respondsToSelector:@selector(isRead)] || ![message isRead]) {
    2.94  					/* Don't display read messages */
    2.95 @@ -323,9 +311,9 @@
    2.96  		}
    2.97  		case GrowlMailSummaryModeAlways: {
    2.98  			if (!class_getClassMethod([MailAccount class], @selector(mailAccounts)))
    2.99 -				[self shutDownGrowlMailAndWarn:@"MailAccount does not respond to +mailAccounts"];
   2.100 +				GMShutDownGrowlMailAndWarn(@"MailAccount does not respond to +mailAccounts");
   2.101  			if (!class_getInstanceMethod(Message_class, @selector(mailbox)))
   2.102 -				[self shutDownGrowlMailAndWarn:@"Message does not respond to -mailbox"];
   2.103 +				GMShutDownGrowlMailAndWarn(@"Message does not respond to -mailbox");
   2.104  
   2.105  			NSArray *accounts = [MailAccount mailAccounts];
   2.106  			unsigned accountsCount = [accounts count];
   2.107 @@ -420,7 +408,7 @@
   2.108  		NSLog(@"Copying a message: messageCopies is now %i", messageCopies);
   2.109  #endif
   2.110  		if (messageCopies <= 0)
   2.111 -			[self shutDownGrowlMailAndWarn:@"Number of message-copying operations overflowed. How on earth did you accomplish starting more than 2 billion copying operations at a time?!"];
   2.112 +			GMShutDownGrowlMailAndWarn(@"Number of message-copying operations overflowed. How on earth did you accomplish starting more than 2 billion copying operations at a time?!");
   2.113  	}
   2.114  }
   2.115  
   2.116 @@ -428,7 +416,7 @@
   2.117  {
   2.118  	if ([[[notification object] description] isEqualToString:@"Copying messages"]) {
   2.119  		if (messageCopies <= 0)
   2.120 -			[self shutDownGrowlMailAndWarn:@"Number of message-copying operations went below 0. It is not possible to have a negative number of copying operations!"];
   2.121 +			GMShutDownGrowlMailAndWarn(@"Number of message-copying operations went below 0. It is not possible to have a negative number of copying operations!");
   2.122  		messageCopies--;
   2.123  #ifdef GROWL_MAIL_DEBUG
   2.124  		NSLog(@"Finished copying a message: messageCopies is now %i", messageCopies);
   2.125 @@ -482,4 +470,18 @@
   2.126  	return descriptionFormat ? descriptionFormat : @"%subject\n%body";
   2.127  }
   2.128  
   2.129 +#pragma mark Panic buttons
   2.130 +
   2.131 +//This is a suicide pill. GrowlMail calls this function any time it detects a change in Mail's implementation, such as a missing method or an object of the wrong class.
   2.132 +void GMShutDownGrowlMailAndWarn(NSString *specificWarning) {
   2.133 +	NSLog(NSLocalizedString(@"WARNING: Mail is not behaving in the way that GrowlMail expects. This is probably because GrowlMail is incompatible with the version of Mail you're using. GrowlMail will now turn itself off. Please check the Growl website for a new version. If you're a programmer and want to debug this error, run gdb, load Mail, set a breakpoint on %s, and run.", /*comment*/ nil), __PRETTY_FUNCTION__);
   2.134 +	if (specificWarning)
   2.135 +		NSLog(@"Furthermore, the caller provided a more specific message: %@", specificWarning);
   2.136 +
   2.137 +	[sharedNotifier shutDownGrowlMail];
   2.138 +
   2.139 +	//Prevent ourselves from re-enabling later.
   2.140 +	notifierEnabled = NO;
   2.141 +}
   2.142 +
   2.143  @end