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