2 * Adium is the legal property of its developers, whose names are listed in the copyright file included
3 * with this source distribution.
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.
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.
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.
17 #import <Adium/AIAccountControllerProtocol.h>
18 #import <Adium/AIContactControllerProtocol.h>
19 #import <Adium/AIInterfaceControllerProtocol.h>
20 #import "AIContactListEditorPlugin.h"
21 #import <Adium/AIMenuControllerProtocol.h>
22 #import "AINewContactWindowController.h"
23 #import "AINewGroupWindowController.h"
24 #import <Adium/AIToolbarControllerProtocol.h>
25 #import <AIUtilities/AIMenuAdditions.h>
26 #import <AIUtilities/AIToolbarUtilities.h>
27 #import <AIUtilities/AIImageAdditions.h>
28 #import <AIUtilities/AIStringAdditions.h>
29 #import <Adium/AIAccount.h>
30 #import <Adium/AIListContact.h>
31 #import <Adium/AIListObject.h>
32 #import <Adium/AIListGroup.h>
34 #define ADD_CONTACT AILocalizedString(@"Add Contact",nil)
35 #define ADD_CONTACT_ELLIPSIS [ADD_CONTACT stringByAppendingEllipsis]
37 #define ADD_CONTACT_TO_GROUP AILocalizedString(@"Add Contact To Group",nil)
38 #define ADD_CONTACT_TO_GROUP_ELLIPSIS [ADD_CONTACT_TO_GROUP stringByAppendingEllipsis]
40 #define ADD_GROUP AILocalizedString(@"Add Group",nil)
41 #define ADD_GROUP_ELLIPSIS [ADD_GROUP stringByAppendingEllipsis]
43 #define DELETE_CONTACT_ELLIPSIS [AILocalizedString(@"Remove Contact",nil) stringByAppendingEllipsis]
44 #define DELETE_CONTACT_CONTEXT_ELLIPSIS [AILocalizedString(@"Remove",nil) stringByAppendingEllipsis]
46 #define RENAME_GROUP AILocalizedString(@"Rename Group",nil)
47 #define RENAME_GROUP_ELLIPSIS [RENAME_GROUP stringByAppendingEllipsis]
49 #define ADD_CONTACT_IDENTIFIER @"AddContact"
50 #define ADD_GROUP_IDENTIFIER @"AddGroup"
52 @interface AIContactListEditorPlugin (PRIVATE)
53 - (void)deleteFromArray:(NSArray *)array;
54 - (void)promptForNewContactOnWindow:(NSWindow *)inWindow selectedListObject:(AIListObject *)inListObject;
58 * @class AIContactListEditorPlugin
59 * @brief Component for managing adding and deleting contacts and groups
61 @implementation AIContactListEditorPlugin
69 NSToolbarItem *toolbarItem;
72 menuItem_addContact = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_CONTACT_ELLIPSIS
74 action:@selector(addContact:)
76 [[adium menuController] addMenuItem:menuItem_addContact toLocation:LOC_Contact_Manage];
78 menuItem_addContactContext = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_CONTACT_TO_GROUP_ELLIPSIS
80 action:@selector(addContact:)
82 [[adium menuController] addContextualMenuItem:menuItem_addContactContext toLocation:Context_Group_Manage];
84 menuItem_tabAddContact = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_CONTACT_ELLIPSIS
86 action:@selector(addContactFromTab:)
87 keyEquivalent:@""] autorelease];
88 [[adium menuController] addContextualMenuItem:menuItem_tabAddContact toLocation:Context_Contact_Stranger_ChatAction];
90 [[adium notificationCenter] addObserver:self
91 selector:@selector(addContactRequest:)
92 name:Contact_AddNewContact
96 menuItem_addGroup = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_GROUP_ELLIPSIS
98 action:@selector(addGroup:)
100 [[adium menuController] addMenuItem:menuItem_addGroup toLocation:LOC_Contact_Manage];
103 menuItem_delete = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:DELETE_CONTACT_ELLIPSIS
105 action:@selector(deleteSelection:)
106 keyEquivalent:@"\b"];
107 [[adium menuController] addMenuItem:menuItem_delete toLocation:LOC_Contact_Manage];
109 menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:DELETE_CONTACT_CONTEXT_ELLIPSIS
111 action:@selector(deleteSelectionFromTab:)
112 keyEquivalent:@""] autorelease];
113 [[adium menuController] addContextualMenuItem:menuItem toLocation:Context_Contact_NegativeAction];
115 //Add Contact toolbar item
116 toolbarItem = [AIToolbarUtilities toolbarItemWithIdentifier:ADD_CONTACT_IDENTIFIER
118 paletteLabel:ADD_CONTACT
119 toolTip:AILocalizedString(@"Add a new contact",nil)
121 settingSelector:@selector(setImage:)
122 itemContent:[NSImage imageNamed:@"AddContact" forClass:[self class]]
123 action:@selector(addContact:)
125 [[adium toolbarController] registerToolbarItem:toolbarItem forToolbarType:@"ListObject"];
127 //Add Group toolbar item
128 toolbarItem = [AIToolbarUtilities toolbarItemWithIdentifier:ADD_GROUP_IDENTIFIER
130 paletteLabel:ADD_GROUP
131 toolTip:AILocalizedString(@"Add a new group",nil)
133 settingSelector:@selector(setImage:)
134 itemContent:[NSImage imageNamed:@"addGroup" forClass:[self class]]
135 action:@selector(addGroup:)
137 [[adium toolbarController] registerToolbarItem:toolbarItem forToolbarType:@"ContactList"];
140 // menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:RENAME_GROUP_ELLIPSIS
142 // action:@selector(renameGroup:)
143 // keyEquivalent:@""] autorelease];
144 // [[adium menuController] addContextualMenuItem:menuItem toLocation:Context_Group_Manage];
150 - (void)uninstallPlugin
152 [[adium notificationCenter] removeObserver:self];
156 * @brief Validate our menu items
158 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
160 if (menuItem == menuItem_delete) {
161 return [[adium interfaceController] selectedListObjectInContactList] != nil;
163 } else if (menuItem == menuItem_tabAddContact) {
164 return [[adium menuController] currentContextMenuObject] != nil;
166 } else if (menuItem == menuItem_addGroup || menuItem == menuItem_addContact || menuItem == menuItem_addContactContext) {
167 NSEnumerator *enumerator = [[[adium accountController] accounts] objectEnumerator];
170 while ((account = [enumerator nextObject])) {
171 if ([account contactListEditable]) return YES;
180 //Called by a context menu
181 - (IBAction)renameGroup:(id)sender
183 // AIListObject *object = [[adium menuController] currentContextMenuObject];
184 //<renameGroup> : I wish I worked... :(
188 //Add Contact ----------------------------------------------------------------------------------------------------------
189 #pragma mark Add Contact
191 * @brief Prompt for a new contact
193 - (IBAction)addContact:(id)sender
195 [self promptForNewContactOnWindow:nil selectedListObject:[[adium interfaceController] selectedListObject]];
199 * @brief Prompt for a new contact with the current tab's name
201 - (IBAction)addContactFromTab:(id)sender
203 [self promptForNewContactOnWindow:nil selectedListObject:[[adium menuController] currentContextMenuObject]];
207 * @brief Prompt for a new contact
209 * @param inWindow If non-nil, display the new contact prompt as a sheet on inWindow
210 * @param inListObject If a contact and a stranger, will be autofilled into the new contact window
212 - (void)promptForNewContactOnWindow:(NSWindow *)inWindow selectedListObject:(AIListObject *)inListObject
214 //We only autofill if the selected list object is a contact and a stranger
215 if (![inListObject isKindOfClass:[AIListContact class]] || [(AIListContact *)inListObject isIntentionallyNotAStranger] ||
216 [inListObject isKindOfClass:[AIMetaContact class]]) {
220 [AINewContactWindowController promptForNewContactOnWindow:inWindow
221 name:(inListObject ? [inListObject UID] : nil)
222 service:(inListObject ? [(AIListContact *)inListObject service] : nil)
227 * @brief Add contact request notification
229 * Display the add contact window. Triggered by an incoming Contact_AddNewContact notification
230 * @param notification Notification with a userInfo containing @"UID" and @"Service" keys
232 - (void)addContactRequest:(NSNotification *)notification
234 NSDictionary *userInfo = [notification userInfo];
236 [AINewContactWindowController promptForNewContactOnWindow:nil
237 name:[userInfo objectForKey:@"UID"]
238 service:[userInfo objectForKey:@"AIService"]
239 account:[userInfo objectForKey:@"AIAccount"]];
244 //Add Group ------------------------------------------------------------------------------------------------------------
245 #pragma mark Add Group
247 * @brief Prompt for a new group
249 - (IBAction)addGroup:(id)sender
251 [AINewGroupWindowController promptForNewGroupOnWindow:nil];
255 //Delete Selection -----------------------------------------------------------------------------------------------------
256 #pragma mark Delete Selection
258 * @brief Delete the list objects selected in the contact list
260 - (IBAction)deleteSelection:(id)sender
262 [self deleteFromArray:[[adium interfaceController] arrayOfSelectedListObjectsInContactList]];
266 * @brief Delete the list object associated with the current context menu
268 - (IBAction)deleteSelectionFromTab:(id)sender
270 AIListObject *currentContextMenuObject;
271 if ((currentContextMenuObject = [[adium menuController] currentContextMenuObject])) {
272 [self deleteFromArray:[NSArray arrayWithObject:currentContextMenuObject]];
277 * @brief Delete an array of <tt>AIListObject</tt>s
279 * After a modal confirmation prompt, the objects in the array are deleted.
281 * @param array An <tt>NSArray</tt> of <tt>AIListObject</tt>s.
283 - (void)deleteFromArray:(NSArray *)array
287 int count = [array count];
290 AIListObject *listObject = [array objectAtIndex:0];
291 NSString *name = [listObject displayName];
292 if ([listObject isKindOfClass:[AIListGroup class]]) {
293 message = [NSString stringWithFormat:AILocalizedString(@"This will remove the group \"%@\" from the contact lists of your online accounts. The %i contacts within this group will also be removed.\n\nThis action can not be undone.",nil),
295 [(AIListGroup *)listObject containedObjectsCount]];
298 message = [NSString stringWithFormat:AILocalizedString(@"This will remove %@ from the contact lists of your online accounts.",nil), name];
301 BOOL containsGroup = NO;
302 NSEnumerator *enumerator = [array objectEnumerator];
303 AIListObject *listObject;
305 while ((listObject = [enumerator nextObject]) && !containsGroup) {
306 containsGroup = [listObject isKindOfClass:[AIListGroup class]];
310 message = [NSString stringWithFormat:AILocalizedString(@"This will remove %i items from the contact lists of your online accounts. Contacts in any deleted groups will also be removed.\n\nThis action can not be undone.",nil), count];
312 message = [NSString stringWithFormat:AILocalizedString(@"This will remove %i contacts from the contact lists of your online accounts.",nil), count];
316 //Make sure we're in the front so our prompt is visible
317 [NSApp activateIgnoringOtherApps:YES];
319 //Guard deletion with a warning prompt
320 int result = NSRunAlertPanel(AILocalizedString(@"Remove from list?",nil),
322 AILocalizedString(@"Remove",nil),
323 AILocalizedString(@"Cancel",nil),
326 if (result == NSAlertDefaultReturn) {
327 [[adium contactController] removeListObjects:array];