Performed [21405] and [21406], moving the contact list to Source, on adium-1.1
[adiumx.git] / Source / AIContactListEditorPlugin.m
blob57a21bcbb3d9dd4d344ad16de05a9476fe996592
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 <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;
55 @end
57 /*!
58  * @class AIContactListEditorPlugin
59  * @brief Component for managing adding and deleting contacts and groups
60  */
61 @implementation AIContactListEditorPlugin
63 /*!
64  * @brief Install
65  */
66 - (void)installPlugin
68     NSMenuItem          *menuItem;
69         NSToolbarItem   *toolbarItem;
71         //Add Contact
72     menuItem_addContact = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_CONTACT_ELLIPSIS
73                                                                                                                                                                 target:self
74                                                                                                                                                                 action:@selector(addContact:)
75                                                                                                                                                  keyEquivalent:@"d"];
76     [[adium menuController] addMenuItem:menuItem_addContact toLocation:LOC_Contact_Manage];
77         
78         menuItem_addContactContext = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_CONTACT_TO_GROUP_ELLIPSIS
79                                                                                                                                                                           target:self
80                                                                                                                                                                           action:@selector(addContact:)
81                                                                                                                                                            keyEquivalent:@""];
82         [[adium menuController] addContextualMenuItem:menuItem_addContactContext toLocation:Context_Group_Manage];
83         
84         menuItem_tabAddContact = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_CONTACT_ELLIPSIS
85                                                                                                                                                                    target:self 
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 
93                                                                          object:nil];
94         
95         //Add Group
96     menuItem_addGroup = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:ADD_GROUP_ELLIPSIS
97                                                                                                                                                          target:self
98                                                                                                                                                          action:@selector(addGroup:) 
99                                                                                                                                           keyEquivalent:@"D"];
100     [[adium menuController] addMenuItem:menuItem_addGroup toLocation:LOC_Contact_Manage];
102         //Delete Selection
103     menuItem_delete = [[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:DELETE_CONTACT_ELLIPSIS
104                                                                                                                                                    target:self
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
110                                                                                                                                          target:self
111                                                                                                                                          action:@selector(deleteSelectionFromTab:) 
112                                                                                                                           keyEquivalent:@""] autorelease];
113         [[adium menuController] addContextualMenuItem:menuItem toLocation:Context_Contact_NegativeAction];
114         
115         //Add Contact toolbar item
116     toolbarItem = [AIToolbarUtilities toolbarItemWithIdentifier:ADD_CONTACT_IDENTIFIER
117                                                                                                                   label:ADD_CONTACT
118                                                                                                    paletteLabel:ADD_CONTACT
119                                                                                                                 toolTip:AILocalizedString(@"Add a new contact",nil)
120                                                                                                                  target:self
121                                                                                                 settingSelector:@selector(setImage:)
122                                                                                                         itemContent:[NSImage imageNamed:@"AddContact" forClass:[self class]]
123                                                                                                                  action:@selector(addContact:)
124                                                                                                                    menu:nil];
125     [[adium toolbarController] registerToolbarItem:toolbarItem forToolbarType:@"ListObject"];   
126         
127         //Add Group toolbar item
128     toolbarItem = [AIToolbarUtilities toolbarItemWithIdentifier:ADD_GROUP_IDENTIFIER
129                                                                                                                   label:ADD_GROUP
130                                                                                                    paletteLabel:ADD_GROUP
131                                                                                                                 toolTip:AILocalizedString(@"Add a new group",nil)
132                                                                                                                  target:self
133                                                                                                 settingSelector:@selector(setImage:)
134                                                                                                         itemContent:[NSImage imageNamed:@"addGroup" forClass:[self class]]
135                                                                                                                  action:@selector(addGroup:)
136                                                                                                                    menu:nil];
137     [[adium toolbarController] registerToolbarItem:toolbarItem forToolbarType:@"ContactList"];  
138         
139         //Rename Group
140         //      menuItem = [[[NSMenuItem allocWithZone:[NSMenu menuZone]] initWithTitle:RENAME_GROUP_ELLIPSIS
141         //                                                                                                                                       target:self
142         //                                                                                                                                       action:@selector(renameGroup:) 
143         //                                                                                                                        keyEquivalent:@""] autorelease];
144         //  [[adium menuController] addContextualMenuItem:menuItem toLocation:Context_Group_Manage];    
148  * @brief Uninstall
149  */
150 - (void)uninstallPlugin
152     [[adium notificationCenter] removeObserver:self];
156  * @brief Validate our menu items
157  */
158 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
160         if (menuItem == menuItem_delete) {
161                 return [[adium interfaceController] selectedListObjectInContactList] != nil;
162                 
163         } else if (menuItem == menuItem_tabAddContact) {
164                 return [[adium menuController] currentContextMenuObject] != nil;
165         
166         } else if (menuItem == menuItem_addGroup || menuItem == menuItem_addContact || menuItem == menuItem_addContactContext) {
167                 NSEnumerator    *enumerator = [[[adium accountController] accounts] objectEnumerator];
168                 AIAccount               *account;
169                 
170                 while ((account = [enumerator nextObject])) {   
171                         if ([account contactListEditable]) return YES;
172                 }
173                 
174                 return NO;
175         }
176         
177         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
192  */
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
200  */
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
211  */
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]]) {
217                 inListObject = nil;
218         }
219         
220         [AINewContactWindowController promptForNewContactOnWindow:inWindow
221                                                                                                                  name:(inListObject ? [inListObject UID] : nil)
222                                                                                                           service:(inListObject ? [(AIListContact *)inListObject service] : nil)
223                                                                                                           account: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
231  */
232 - (void)addContactRequest:(NSNotification *)notification
234         NSDictionary *userInfo = [notification userInfo];
235         if (userInfo) {
236                 [AINewContactWindowController promptForNewContactOnWindow:nil
237                                                                                                                          name:[userInfo objectForKey:@"UID"]
238                                                                                                                   service:[userInfo objectForKey:@"AIService"]
239                                                                                                                   account:[userInfo objectForKey:@"AIAccount"]];
240         }
244 //Add Group ------------------------------------------------------------------------------------------------------------
245 #pragma mark Add Group
247  * @brief Prompt for a new group
248  */
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
259  */
260 - (IBAction)deleteSelection:(id)sender
261 {       
262         [self deleteFromArray:[[adium interfaceController] arrayOfSelectedListObjectsInContactList]];
266  * @brief Delete the list object associated with the current context menu
267  */
268 - (IBAction)deleteSelectionFromTab:(id)sender
270         AIListObject   *currentContextMenuObject;
271         if ((currentContextMenuObject = [[adium menuController] currentContextMenuObject])) {
272                 [self deleteFromArray:[NSArray arrayWithObject:currentContextMenuObject]];
273         }
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.
282  */
283 - (void)deleteFromArray:(NSArray *)array
285         if (array) {
286                 NSString        *message;
287                 int                     count = [array count];
289                 if (count == 1) {
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),
294                                         name,
295                                         [(AIListGroup *)listObject containedObjectsCount]];
296                                 
297                         } else {
298                                 message = [NSString stringWithFormat:AILocalizedString(@"This will remove %@ from the contact lists of your online accounts.",nil), name];
299                         }
300                 } else {
301                         BOOL            containsGroup = NO;
302                         NSEnumerator *enumerator = [array objectEnumerator];
303                         AIListObject *listObject;
304                         
305                         while ((listObject = [enumerator nextObject]) && !containsGroup) {
306                                 containsGroup = [listObject isKindOfClass:[AIListGroup class]];
307                         }
309                         if (containsGroup) {
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];
311                         } else {
312                                 message = [NSString stringWithFormat:AILocalizedString(@"This will remove %i contacts from the contact lists of your online accounts.",nil), count];
313                         }
314                 }
315                 
316                 //Make sure we're in the front so our prompt is visible
317                 [NSApp activateIgnoringOtherApps:YES];
318                 
319                 //Guard deletion with a warning prompt          
320                 int result = NSRunAlertPanel(AILocalizedString(@"Remove from list?",nil),
321                                                                          message,
322                                                                          AILocalizedString(@"Remove",nil),
323                                                                          AILocalizedString(@"Cancel",nil),
324                                                                          nil);
326                 if (result == NSAlertDefaultReturn) {
327                         [[adium contactController] removeListObjects:array];
328                 }
329         }       
332 @end