Merged [13645] and [13646]: Fixed one of the longest-standing Adium bugs: The Color...
[adiumx.git] / Source / AIContactListEditorPlugin.m
blob19603f1666431fac700561d7fb2087e892a2320a
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  */
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;
54 @end
56 /*!
57  * @class AIContactListEditorPlugin
58  * @brief Component for managing adding and deleting contacts and groups
59  */
60 @implementation AIContactListEditorPlugin
62 /*!
63  * @brief Install
64  */
65 - (void)installPlugin
67     NSMenuItem          *menuItem;
68         NSToolbarItem   *toolbarItem;
69         
70         //Add contact menu item
71     menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_CONTACT_ELLIPSIS
72                                                                                                                                          target:self
73                                                                                                                                          action:@selector(addContact:)
74                                                                                                                           keyEquivalent:@"+"] autorelease];
75     [[adium menuController] addMenuItem:menuItem toLocation:LOC_Contact_Manage];
76         
77         //Add contact context menu item
78         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_CONTACT_TO_GROUP_ELLIPSIS
79                                                                                                                                          target:self
80                                                                                                                                          action:@selector(addContact:)
81                                                                                                                           keyEquivalent:@""] autorelease];
82         [[adium menuController] addContextualMenuItem:menuItem toLocation:Context_Group_Manage];
83         
84         //Add contact context menu item for tabs
85         menuItem_tabAddContact = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_CONTACT_ELLIPSIS
86                                                                                                                                                                    target:self 
87                                                                                                                                                                    action:@selector(addContactFromTab:)
88                                                                                                                                                         keyEquivalent:@""] autorelease];
89     [[adium menuController] addContextualMenuItem:menuItem_tabAddContact toLocation:Context_Contact_Stranger_TabAction];
90         
91         //Add group menu item
92     menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_GROUP_ELLIPSIS
93                                                                                                                                          target:self
94                                                                                                                                          action:@selector(addGroup:) 
95                                                                                                                           keyEquivalent:@"+"] autorelease];
96         [menuItem setKeyEquivalentModifierMask:(NSCommandKeyMask | NSAlternateKeyMask)];
97     [[adium menuController] addMenuItem:menuItem toLocation:LOC_Contact_Manage];
98         
99         //Delete selection menu item
100     menuItem_delete = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:DELETE_CONTACT
101                                                                                                                                                    target:self
102                                                                                                                                                    action:@selector(deleteSelection:) 
103                                                                                                                                         keyEquivalent:@"\b"];
104     [[adium menuController] addMenuItem:menuItem_delete toLocation:LOC_Contact_Manage];
105         
106         //Rename group context menu item
107         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:RENAME_GROUP_ELLIPSIS
108                                                                                                                                          target:self
109                                                                                                                                          action:@selector(renameGroup:) 
110                                                                                                                           keyEquivalent:@""] autorelease];
111     //[[adium menuController] addContextualMenuItem:menuItem toLocation:Context_Group_Manage];
112         
113         //Delete selection context menu item
114         menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:DELETE_CONTACT_CONTEXT
115                                                                                                                                          target:self
116                                                                                                                                          action:@selector(deleteSelectionFromTab:) 
117                                                                                                                           keyEquivalent:@""] autorelease];
118         [[adium menuController] addContextualMenuItem:menuItem toLocation:Context_Contact_NegativeAction];
119         
120         //Add Contact toolbar item
121     toolbarItem = [AIToolbarUtilities toolbarItemWithIdentifier:ADD_CONTACT_IDENTIFIER
122                                                                                                                   label:ADD_CONTACT
123                                                                                                    paletteLabel:ADD_CONTACT
124                                                                                                                 toolTip:AILocalizedString(@"Add a new contact",nil)
125                                                                                                                  target:self
126                                                                                                 settingSelector:@selector(setImage:)
127                                                                                                         itemContent:[NSImage imageNamed:@"AddContact" forClass:[self class]]
128                                                                                                                  action:@selector(addContact:)
129                                                                                                                    menu:nil];
130     [[adium toolbarController] registerToolbarItem:toolbarItem forToolbarType:@"ListObject"];   
131         
132         //Add Contact toolbar item
133     toolbarItem = [AIToolbarUtilities toolbarItemWithIdentifier:ADD_GROUP_IDENTIFIER
134                                                                                                                   label:ADD_GROUP
135                                                                                                    paletteLabel:ADD_GROUP
136                                                                                                                 toolTip:AILocalizedString(@"Add a new group",nil)
137                                                                                                                  target:self
138                                                                                                 settingSelector:@selector(setImage:)
139                                                                                                         itemContent:[NSImage imageNamed:@"addGroup" forClass:[self class]]
140                                                                                                                  action:@selector(addGroup:)
141                                                                                                                    menu:nil];
142     [[adium toolbarController] registerToolbarItem:toolbarItem forToolbarType:@"ContactList"];  
143         
144         [[adium notificationCenter] addObserver:self 
145                                                                    selector:@selector(addContactRequest:) 
146                                                                            name:Contact_AddNewContact 
147                                                                          object:nil];
148         
152  * @brief Uninstall
153  */
154 - (void)uninstallPlugin
156     [[adium notificationCenter] removeObserver:self];
160  * @brief Validate our menu items
161  */
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]]];
172             }else{
173                 [menuItem_delete setTitle:DELETE_CONTACT];
174                 return NO;
175             }
176         }else if(menuItem == menuItem_tabAddContact){
177                 return([[adium menuController] currentContextMenuObject] != nil);
178         }
179         
180         return(YES);
184  * @brief Prompt for a new contact
185  */
186 - (IBAction)addContact:(id)sender
188         //Get the "selected" list object (contact list or message window)
189         AIListContact   *stranger = nil;
190         AIListObject    *selectedObject;
191         
192         selectedObject = [[adium contactController] selectedListObject];        
193         
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;
198         }
199         
200         [self promptForNewContactOnWindow:nil
201                                   strangerListContact:stranger];
205  * @brief Prompt for a new contact with the current tab's name
206  */
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];
213         }
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
221  */
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
234  */
235 - (void)addContactRequest:(NSNotification *)notification
237         NSDictionary *userInfo = [notification userInfo];
238         if (userInfo){
239                 [AINewContactWindowController promptForNewContactOnWindow:nil
240                                                                                                                          name:[userInfo objectForKey:@"UID"]
241                                                                                                                   service:[userInfo objectForKey:@"service"]];
242         }
246  * @brief Prompt for a new group
247  */
248 - (IBAction)addGroup:(id)sender
250         [AINewGroupWindowController promptForNewGroupOnWindow:nil];
254  * @brief Delete the list objects selected in the contact list
255  */
256 - (IBAction)deleteSelection:(id)sender
257 {       
258         NSArray                 *array = [[adium contactController] arrayOfSelectedListObjectsInContactList];
259         [self deleteFromArray:array];
263  * @brief Delete the list object associated with the current context menu
264  */
265 - (IBAction)deleteSelectionFromTab:(id)sender
267         AIListObject   *currentContextMenuObject;
268         if (currentContextMenuObject = [[adium menuController] currentContextMenuObject]){
269                 [NSApp activateIgnoringOtherApps:YES];
270                 [self deleteFromArray:[NSArray arrayWithObject:currentContextMenuObject]];
271         }
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.
280  */
281 - (void)deleteFromArray:(NSArray *)array
283         if(array){
284                 int count = [array count];
285                 
286                 NSString        *name = ((count == 1) ?
287                                                          [[array objectAtIndex:0] displayName] : 
288                                                          [NSString stringWithFormat:AILocalizedString(@"%i contacts",nil),count]);
289                 
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),
295                                                                          nil);
297                 if(result == NSAlertDefaultReturn){
298                         [[adium contactController] removeListObjects:array];
299                 }
300         }       
304 //Called by a context menu
305 - (IBAction)renameGroup:(id)sender
307 //      AIListObject    *object = [[adium menuController] currentContextMenuObject];
308         
311 @end