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 "AIContactController.h"
18 #import "AIContactListEditorPlugin.h"
19 #import "AIMenuController.h"
20 #import "AINewContactWindowController.h"
21 #import "AINewGroupWindowController.h"
22 #import "AIToolbarController.h"
23 #import <AIUtilities/AIMenuAdditions.h>
24 #import <AIUtilities/AIToolbarUtilities.h>
25 #import <AIUtilities/ESImageAdditions.h>
26 #import <AIUtilities/AIStringAdditions.h>
27 #import <Adium/AIListContact.h>
28 #import <Adium/AIListObject.h>
30 #define ADD_CONTACT AILocalizedString(@"Add Contact",nil)
31 #define ADD_CONTACT_ELLIPSIS [ADD_CONTACT stringByAppendingEllipsis]
33 #define ADD_CONTACT_TO_GROUP AILocalizedString(@"Add Contact To Group",nil)
34 #define ADD_CONTACT_TO_GROUP_ELLIPSIS [ADD_CONTACT_TO_GROUP stringByAppendingEllipsis]
36 #define ADD_GROUP AILocalizedString(@"Add Group",nil)
37 #define ADD_GROUP_ELLIPSIS [ADD_GROUP stringByAppendingEllipsis]
39 #define DELETE_CONTACT AILocalizedString(@"Remove Contact",nil)
40 #define DELETE_CONTACT_CONTEXT AILocalizedString(@"Delete",nil)
41 #define DELETE_CONTACT_CONTEXT_ELLIPSIS [DELETE_CONTACT_CONTEXT stringByAppendingEllipsis]
43 #define RENAME_GROUP AILocalizedString(@"Rename Group",nil)
44 #define RENAME_GROUP_ELLIPSIS [RENAME_GROUP stringByAppendingEllipsis]
46 #define INVITE_CONTACT [AILocalizedString(@"Invite to This Chat",nil) stringByAppendingEllipsis]
48 #define ADD_CONTACT_IDENTIFIER @"AddContact"
49 #define ADD_GROUP_IDENTIFIER @"AddGroup"
51 @interface AIContactListEditorPlugin (PRIVATE)
52 - (void)deleteFromArray:(NSArray *)array;
53 - (void)promptForNewContactOnWindow:(NSWindow *)inWindow strangerListContact:(AIListContact *)inListContact;
57 * @class AIContactListEditorPlugin
58 * @brief Component for managing adding and deleting contacts and groups
60 @implementation AIContactListEditorPlugin
68 NSToolbarItem *toolbarItem;
70 //Add contact menu item
71 menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_CONTACT_ELLIPSIS
73 action:@selector(addContact:)
74 keyEquivalent:@"+"] autorelease];
75 [[adium menuController] addMenuItem:menuItem toLocation:LOC_Contact_Manage];
77 //Add contact context menu item
78 menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_CONTACT_TO_GROUP_ELLIPSIS
80 action:@selector(addContact:)
81 keyEquivalent:@""] autorelease];
82 [[adium menuController] addContextualMenuItem:menuItem toLocation:Context_Group_Manage];
84 //Add contact context menu item for tabs
85 menuItem_tabAddContact = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_CONTACT_ELLIPSIS
87 action:@selector(addContactFromTab:)
88 keyEquivalent:@""] autorelease];
89 [[adium menuController] addContextualMenuItem:menuItem_tabAddContact toLocation:Context_Contact_Stranger_TabAction];
92 menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_GROUP_ELLIPSIS
94 action:@selector(addGroup:)
95 keyEquivalent:@"+"] autorelease];
96 [menuItem setKeyEquivalentModifierMask:(NSCommandKeyMask | NSAlternateKeyMask)];
97 [[adium menuController] addMenuItem:menuItem toLocation:LOC_Contact_Manage];
99 //Delete selection menu item
100 menuItem_delete = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:DELETE_CONTACT
102 action:@selector(deleteSelection:)
103 keyEquivalent:@"\b"];
104 [[adium menuController] addMenuItem:menuItem_delete toLocation:LOC_Contact_Manage];
106 //Rename group context menu item
107 menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:RENAME_GROUP_ELLIPSIS
109 action:@selector(renameGroup:)
110 keyEquivalent:@""] autorelease];
111 //[[adium menuController] addContextualMenuItem:menuItem toLocation:Context_Group_Manage];
113 //Delete selection context menu item
114 menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:DELETE_CONTACT_CONTEXT
116 action:@selector(deleteSelectionFromTab:)
117 keyEquivalent:@""] autorelease];
118 [[adium menuController] addContextualMenuItem:menuItem toLocation:Context_Contact_NegativeAction];
120 //Add Contact toolbar item
121 toolbarItem = [AIToolbarUtilities toolbarItemWithIdentifier:ADD_CONTACT_IDENTIFIER
123 paletteLabel:ADD_CONTACT
124 toolTip:AILocalizedString(@"Add a new contact",nil)
126 settingSelector:@selector(setImage:)
127 itemContent:[NSImage imageNamed:@"AddContact" forClass:[self class]]
128 action:@selector(addContact:)
130 [[adium toolbarController] registerToolbarItem:toolbarItem forToolbarType:@"ListObject"];
132 //Add Contact toolbar item
133 toolbarItem = [AIToolbarUtilities toolbarItemWithIdentifier:ADD_GROUP_IDENTIFIER
135 paletteLabel:ADD_GROUP
136 toolTip:AILocalizedString(@"Add a new group",nil)
138 settingSelector:@selector(setImage:)
139 itemContent:[NSImage imageNamed:@"addGroup" forClass:[self class]]
140 action:@selector(addGroup:)
142 [[adium toolbarController] registerToolbarItem:toolbarItem forToolbarType:@"ContactList"];
144 [[adium notificationCenter] addObserver:self
145 selector:@selector(addContactRequest:)
146 name:Contact_AddNewContact
154 - (void)uninstallPlugin
156 [[adium notificationCenter] removeObserver:self];
160 * @brief Validate our menu items
162 - (BOOL)validateMenuItem:(id <NSMenuItem>)menuItem
164 //Disable 'delete selection' if nothing is selected or the contact list isn't in front
165 if(menuItem == menuItem_delete){
166 //return([[adium contactController] selectedListObjectInContactList] != nil);
167 //Update the menu titles to reflect the selected contact
168 if([[adium contactController] selectedListObjectInContactList] != nil){
169 [menuItem_delete setTitle:[NSString stringWithFormat:
170 AILocalizedString(@"Remove %@","%@ will be a contact's name"),
171 [[[adium contactController] selectedListObjectInContactList] displayName]]];
173 [menuItem_delete setTitle:DELETE_CONTACT];
176 }else if(menuItem == menuItem_tabAddContact){
177 return([[adium menuController] currentContextMenuObject] != nil);
184 * @brief Prompt for a new contact
186 - (IBAction)addContact:(id)sender
188 //Get the "selected" list object (contact list or message window)
189 AIListContact *stranger = nil;
190 AIListObject *selectedObject;
192 selectedObject = [[adium contactController] selectedListObject];
194 //Pass this selectedObject only if it's a listContact and a stranger
195 if ([selectedObject isKindOfClass:[AIListContact class]] &&
196 [(AIListContact *)selectedObject isStranger]){
197 stranger = (AIListContact *)selectedObject;
200 [self promptForNewContactOnWindow:nil
201 strangerListContact:stranger];
205 * @brief Prompt for a new contact with the current tab's name
207 - (IBAction)addContactFromTab:(id)sender
209 AIListObject *object = [[adium menuController] currentContextMenuObject];
210 if([object isKindOfClass:[AIListContact class]]){
211 [self promptForNewContactOnWindow:nil
212 strangerListContact:(AIListContact *)object];
217 * @brief Prompt for a new contact
219 * @param inWindow If non-nil, display the new contact prompt as a sheet on inWindow
220 * @param inListContact If non-nil, autofill the new contact prompt with information from inListContact
222 - (void)promptForNewContactOnWindow:(NSWindow *)inWindow strangerListContact:(AIListContact *)inListContact
224 [AINewContactWindowController promptForNewContactOnWindow:inWindow
225 name:(inListContact ? [inListContact UID] : nil)
226 service:(inListContact ? [inListContact service] : nil)];
230 * @brief Add contact request notification
232 * Display the add contact window. Triggered by an incoming Contact_AddNewContact notification
233 * @param notification Notification with a userInfo containing @"UID" and @"Service" keys
235 - (void)addContactRequest:(NSNotification *)notification
237 NSDictionary *userInfo = [notification userInfo];
239 [AINewContactWindowController promptForNewContactOnWindow:nil
240 name:[userInfo objectForKey:@"UID"]
241 service:[userInfo objectForKey:@"service"]];
246 * @brief Prompt for a new group
248 - (IBAction)addGroup:(id)sender
250 [AINewGroupWindowController promptForNewGroupOnWindow:nil];
254 * @brief Delete the list objects selected in the contact list
256 - (IBAction)deleteSelection:(id)sender
258 NSArray *array = [[adium contactController] arrayOfSelectedListObjectsInContactList];
259 [self deleteFromArray:array];
263 * @brief Delete the list object associated with the current context menu
265 - (IBAction)deleteSelectionFromTab:(id)sender
267 AIListObject *currentContextMenuObject;
268 if (currentContextMenuObject = [[adium menuController] currentContextMenuObject]){
269 [NSApp activateIgnoringOtherApps:YES];
270 [self deleteFromArray:[NSArray arrayWithObject:currentContextMenuObject]];
275 * @brief Delete an array of <tt>AIListObject</tt>s
277 * After a modal confirmation prompt, the objects in the array are deleted.
279 * @param array An <tt>NSArray</tt> of <tt>AIListObject</tt>s.
281 - (void)deleteFromArray:(NSArray *)array
284 int count = [array count];
286 NSString *name = ((count == 1) ?
287 [[array objectAtIndex:0] displayName] :
288 [NSString stringWithFormat:AILocalizedString(@"%i contacts",nil),count]);
290 //Guard deletion with a warning prompt
291 int result = NSRunAlertPanel([NSString stringWithFormat:AILocalizedString(@"Remove %@ from your list?",nil),name],
292 AILocalizedString(@"Be careful. You cannot undo this action.",nil),
293 AILocalizedString(@"Remove",nil),
294 AILocalizedString(@"Cancel",nil),
297 if(result == NSAlertDefaultReturn){
298 [[adium contactController] removeListObjects:array];
304 //Called by a context menu
305 - (IBAction)renameGroup:(id)sender
307 // AIListObject *object = [[adium menuController] currentContextMenuObject];