Source/OWSpellingPerContactPlugin.m
author Zachary West <zacw@adium.im>
Thu Oct 29 12:43:40 2009 -0400 (2009-10-29)
changeset 2808 6a41be7632e5
parent 1946 866f1f27b315
child 2902 2911fea407a3
permissions -rw-r--r--
Clean up the per-contact spelling a little. I think this fixes #12359.

This uses new, proper "language-grabbing" methods from the spell checker, as well as properly saves the spelling if the spelling was changed and the window was immediately closed. In this case, it would end up saving the wrong value.
     1 /* 
     2  * Adium is the legal property of its developers, whose names are listed in the copyright file included
     3  * with this source distribution.
     4  * 
     5  * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
     6  * General Public License as published by the Free Software Foundation; either version 2 of the License,
     7  * or (at your option) any later version.
     8  * 
     9  * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
    10  * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    11  * Public License for more details.
    12  * 
    13  * You should have received a copy of the GNU General Public License along with this program; if not,
    14  * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    15  */
    16 
    17 #import "OWSpellingPerContactPlugin.h"
    18 #import <Adium/AIChat.h>
    19 #import <Adium/AIListContact.h>
    20 
    21 #import <AIUtilities/AIApplicationAdditions.h>
    22 #import <AIUtilities/AILeopardCompatibility.h>
    23 
    24 #define GROUP_LAST_USED_SPELLING	@"Last Used Spelling"
    25 #define KEY_LAST_USED_SPELLING		@"Last Used Spelling Languge"
    26 
    27 /*!
    28  * @class OWSpellingPerContactPlugin
    29  * @brief Component to save and restore spelling dictionary language preferences on a per-contact basis for chats
    30  *
    31  * Language settings on a group chat basis are not currently saved.
    32  */
    33 @implementation OWSpellingPerContactPlugin
    34 
    35 /*!
    36  * @brief Install
    37  */
    38 - (void)installPlugin
    39 {
    40 	NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
    41 	
    42 	[notificationCenter addObserver:self
    43 						   selector:@selector(chatBecameActive:)
    44 							   name:Chat_BecameActive
    45 							 object:nil];
    46 	
    47 	[notificationCenter addObserver:self
    48 						   selector:@selector(chatWillClose:)
    49 							   name:Chat_WillClose
    50 							 object:nil];
    51 	
    52 	languageDict = [[NSMutableDictionary alloc] init];
    53 	
    54 	//Find the first language the user prefers which the spellchecker knows about, then keep it around for future reference
    55 	NSArray *preferredLanguages = nil;
    56 	if ([NSApp isOnSnowLeopardOrBetter]) {
    57 		preferredLanguages = [[NSSpellChecker sharedSpellChecker] userPreferredLanguages];
    58 	} else {
    59 		preferredLanguages = [[NSSpellChecker sharedSpellChecker] availableLanguages];
    60 	}
    61 		
    62 	if (preferredLanguages.count) {
    63 		preferredLanguage = [preferredLanguages objectAtIndex:0];
    64 	}
    65 }
    66 
    67 /*!
    68  * @brief Uninstall
    69  */
    70 - (void)uninstallPlugin
    71 {
    72 	[languageDict release]; languageDict = nil;
    73 	[preferredLanguage release]; preferredLanguage = nil;
    74 	
    75 	[[NSNotificationCenter defaultCenter] removeObserver:self];
    76 }
    77 
    78 /*!
    79  * @brief A chat became active; set the spelling language preference appropriately
    80  *
    81  * If a chat was previously active, as indicated by the PreviouslyActiveChat key in the notification's userInfo,
    82  * its language preference is stored before switching.
    83  */
    84 - (void)chatBecameActive:(NSNotification *)notification
    85 {
    86 	@try
    87 	{
    88 		AIChat	 *newChat = [notification object];
    89 		AIChat	 *previousChat = [[notification userInfo] objectForKey:@"PreviouslyActiveChat"];
    90 
    91 		if (previousChat) {
    92 			NSString *language = [[NSSpellChecker sharedSpellChecker] language];
    93 			NSString *chatID = [previousChat uniqueChatID];
    94 
    95 			if (language &&
    96 				![[languageDict objectForKey:chatID] isEqualToString:language]) {
    97 				//If this chat is not known to be in the current language, store its setting in our languageDict
    98 				[languageDict setObject:language
    99 								 forKey:chatID];
   100 			}
   101 		}
   102 		
   103 		if (newChat) {
   104 			NSString *chatID = [newChat uniqueChatID];
   105 			NSString *newChatLanguage = [languageDict objectForKey:chatID];
   106 			
   107 			//If we don't have a previously noted language, try to load one from a preference
   108 			if (!newChatLanguage) {
   109 				AIListObject *listObject = [newChat listObject];
   110 
   111 				if (listObject) {
   112 					//Load the preference if possible
   113 					newChatLanguage = [listObject preferenceForKey:KEY_LAST_USED_SPELLING group:GROUP_LAST_USED_SPELLING];
   114 				}
   115 
   116 				if (!newChatLanguage) {
   117 					//If no preference, use the preferred language
   118 					newChatLanguage = preferredLanguage;
   119 				}
   120 
   121 				[languageDict setObject:newChatLanguage
   122 								 forKey:chatID];
   123 			}
   124 
   125 			[[NSSpellChecker sharedSpellChecker] setLanguage:newChatLanguage];
   126 		}
   127 	}
   128 	@catch(id exc) {}
   129 }
   130 
   131 /*!
   132  * @brief Chat will close; save the language preference for its contact before it closes
   133  */
   134 - (void)chatWillClose:(NSNotification *)notification
   135 {
   136 	AIChat			*chat = [notification object];
   137 	AIListContact	*listObject = chat.listObject;
   138 
   139 	if (listObject) {
   140 		NSString	 *chatID = chat.uniqueChatID;
   141 		NSString	 *chatLanguage = [languageDict objectForKey:chatID];
   142 
   143 		//If we didn't cache a language for this chat, or the chat is currently the active chat, use the spell checker's value.
   144 		if (!chatLanguage || adium.interfaceController.activeChat == chat)
   145 			chatLanguage = [[NSSpellChecker sharedSpellChecker] language];
   146 
   147 		//Now, if we end up at the user's default language, we don't want to store anything
   148 		if ([preferredLanguage isEqualToString:chatLanguage])
   149 			chatLanguage = nil;
   150 		
   151 		NSString *previousLanguage = [listObject preferenceForKey:KEY_LAST_USED_SPELLING group:GROUP_LAST_USED_SPELLING];
   152 		if ((previousLanguage && ![previousLanguage isEqualToString:chatLanguage]) ||
   153 			 (!previousLanguage && chatLanguage)) {
   154 			[listObject setPreference:chatLanguage
   155 							   forKey:KEY_LAST_USED_SPELLING
   156 								group:GROUP_LAST_USED_SPELLING];
   157 		}
   158 		
   159 		[languageDict removeObjectForKey:chatID];
   160 	}
   161 }
   162 
   163 @end