Fixed use of a method which doesn't exist in adium-0.8
[adiumx.git] / Source / ESContactInfoListController.m
blobd705e8dbddd94164305630f6e33d3bfaf59be996
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 "AIContactInfoWindowController.h"
19 #import "ESContactInfoListController.h"
20 #import <Adium/AIListGroup.h>
21 #import <Adium/AIListObject.h>
22 #import <Adium/AIListOutlineView.h>
23 #import <Adium/AIMetaContact.h>
25 @implementation ESContactInfoListController
27 //The superclass's implementation does not expand metaContacts
28 - (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item
30     if(item == nil){
31                 if (hideRoot){
32                         if([contactList isKindOfClass:[AIMetaContact class]]){
33                                 return((index >= 0 && index < [(AIMetaContact *)contactList uniqueContainedObjectsCount]) ?
34                                            [(AIMetaContact *)contactList uniqueObjectAtIndex:index] : 
35                                            nil);
36                         }else{
37                                 return((index >= 0 && index < [(AIListGroup *)contactList containedObjectsCount]) ? [contactList objectAtIndex:index] : nil);
38                         }
39                 }else{
40                         return contactList;
41                 }
42     }else{
43                 if ([item isKindOfClass:[AIMetaContact class]]){
44                         return((index >= 0 && index < [(AIMetaContact *)item uniqueContainedObjectsCount]) ? 
45                                    [(AIMetaContact *)item uniqueObjectAtIndex:index] : 
46                                    nil);
47                 }else{
48                         return((index >= 0 && index < [(AIListGroup *)item containedObjectsCount]) ? [item objectAtIndex:index] : nil);
49                 }
50     }
53 //The superclass's implementation does not expand metaContacts
54 - (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
56     if(item == nil){
57                 if(hideRoot){
58                         if ([contactList isKindOfClass:[AIMetaContact class]]){
59                                 return([(AIMetaContact *)contactList uniqueContainedObjectsCount]);
60                         }else{
61                                 return([(AIListGroup *)contactList containedObjectsCount]);
62                         }
63                 }else{
64                         return(1);
65                 }
66     }else{
67                 if([item isKindOfClass:[AIMetaContact class]]){
68                         return([(AIMetaContact *)item uniqueContainedObjectsCount]);
69                 }else{
70                         return([(AIListGroup *)item containedObjectsCount]);
71                 }
72     }
75 //The superclass's implementation does not expand metaContacts
76 - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
78     if([item isKindOfClass:[AIMetaContact class]] || [item isKindOfClass:[AIListGroup class]]){
79         return(YES);
80     }else{
81         return(NO);
82     }
85 /*!
86  * @brief Change the info window as the selection changes
87  *
88  * We want to configure for contact-specific information when a contact is selected in the drawer
89  * If no row is selected, we configure for the contactList root (the metaContact itself)
90  */
91 - (void)outlineViewSelectionDidChange:(NSNotification *)aNotification
93         if (!aNotification || [aNotification object] == contactListView){
94                 int selectedRow = [contactListView selectedRow];
95                 [(AIContactInfoWindowController *)delegate configureForListObject:((selectedRow != -1) ?
96                                                                                                                                                    [contactListView itemAtRow:selectedRow] :
97                                                                                                                                                    contactList)];
98         }
102  * @brief Remove the selected rows from the metaContact
103  */
104 - (void)outlineViewDeleteSelectedRows:(NSOutlineView *)outlineView
106         [(AIContactInfoWindowController *)delegate removeContact:outlineView];
110  * @brief Validate a drag and drop operation
111  */
112 - (NSDragOperation)outlineView:(NSOutlineView*)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)index
114         NSPasteboard    *draggingPasteboard = [info draggingPasteboard];
115     NSString            *avaliableType = [draggingPasteboard availableTypeFromArray:[NSArray arrayWithObject:@"AIListObject"]];
116         
117         //No dropping into contacts
118     if([avaliableType isEqualToString:@"AIListObject"]){
119                 
120                 id      primaryDragItem = nil;
121                 
122                 //If we don't have drag items, we are dragging from another instance; build our own dragItems array
123                 //using the supplied internalObjectIDs
124                 if (!dragItems){
125                         if ([[draggingPasteboard availableTypeFromArray:[NSArray arrayWithObject:@"AIListObjectUniqueIDs"]] isEqualToString:@"AIListObjectUniqueIDs"]){
126                                 NSArray                 *dragItemsUniqueIDs;
127                                 NSMutableArray  *arrayOfDragItems;
128                                 NSString                *uniqueID;
129                                 NSEnumerator    *enumerator;
130                                         
131                                 dragItemsUniqueIDs = [draggingPasteboard propertyListForType:@"AIListObjectUniqueIDs"];
132                                 arrayOfDragItems = [NSMutableArray array];
133                                 
134                                 enumerator = [dragItemsUniqueIDs objectEnumerator];
135                                 while (uniqueID = [enumerator nextObject]){
136                                         [arrayOfDragItems addObject:[[adium contactController] existingListObjectWithUniqueID:uniqueID]];
137                                 }
139                                 //We will release this when the drag is completed
140                                 dragItems = [arrayOfDragItems retain];
141                         }
142                 }
144                 primaryDragItem = [dragItems objectAtIndex:0];                  
146                 if([primaryDragItem isKindOfClass:[AIListGroup class]]){
147                         //Disallow dragging groups into the contact info window
148                         return(NSDragOperationNone);
149                         
150                 }else{
151                         //Disallow dragging contacts into anything besides the contact list
152                         if(index == NSOutlineViewDropOnItemIndex){
154                                 //The contactList is 'nil' to the outlineView
155                                 [outlineView setDropItem:nil dropChildIndex:[outlineView rowForItem:item]];
156                         }
157                 }
158         }
159         
160         return(NSDragOperationPrivate);
164 - (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(int)index
166         NSPasteboard    *draggingPasteboard = [info draggingPasteboard];
167     NSString    *availableType = [draggingPasteboard availableTypeFromArray:[NSArray arrayWithObject:@"AIListObject"]];
169         //No longer in a drag, so allow tooltips again
170     if([availableType isEqualToString:@"AIListObject"]){
171                 
172                 //If we don't have drag items, we are dragging from another instance; build our own dragItems array
173                 //using the supplied internalObjectIDs
174                 if (!dragItems){
175                         if ([[draggingPasteboard availableTypeFromArray:[NSArray arrayWithObject:@"AIListObjectUniqueIDs"]] isEqualToString:@"AIListObjectUniqueIDs"]){
176                                 NSArray                 *dragItemsUniqueIDs;
177                                 NSMutableArray  *arrayOfDragItems;
178                                 NSString                *uniqueID;
179                                 NSEnumerator    *enumerator;
180                                 
181                                 dragItemsUniqueIDs = [draggingPasteboard propertyListForType:@"AIListObjectUniqueIDs"];
182                                 arrayOfDragItems = [NSMutableArray array];
183                                 
184                                 enumerator = [dragItemsUniqueIDs objectEnumerator];
185                                 while (uniqueID = [enumerator nextObject]){
186                                         [arrayOfDragItems addObject:[[adium contactController] existingListObjectWithUniqueID:uniqueID]];
187                                 }
188                                 
189                                 //We will release this when the drag is completed
190                                 dragItems = [arrayOfDragItems retain];
191                         }
192                 }
194                 //The tree root is not associated with our root contact list group, so we need to make that association here
195                 if(item == nil) item = contactList;
196                 
197                 //Move the list object to its new location
198                 if([item isKindOfClass:[AIMetaContact class]]){
199                         
200                         NSMutableArray  *realDragItems = [NSMutableArray array];
201                         NSEnumerator    *enumerator;
202                         AIListObject    *aDragItem;
203                         
204                         if (index == [outlineView numberOfRows]){
205                                 index = [item containedObjectsCount];
206                         }else{
207                                 //The outline view has one unique contact for each service/UID combination, while the metacontact
208                                 //has a containedObjectsArray with multiple contacts for each.  We want to find which item is at
209                                 //our drop row, then determine the index in the metacontact of that item.  That's the index we move to.
210                                 index = [(AIMetaContact *)item indexOfObject:[outlineView itemAtRow:index]];
211                         }
212                         
213                         enumerator = [dragItems objectEnumerator];
214                         while (aDragItem = [enumerator nextObject]){
215                                 if ([aDragItem isMemberOfClass:[AIListContact class]]){
216                                         //For listContacts, add all contacts with the same service and UID (on all accounts)
217                                         [realDragItems addObjectsFromArray:[[adium contactController] allContactsWithService:[aDragItem service] 
218                                                                                                                                                                                                          UID:[aDragItem UID]]];
219                                 }else{
220                                         [realDragItems addObject:aDragItem];
221                                 }
222                         }
223                         
224                         [[adium contactController] moveListObjects:realDragItems toGroup:item index:index];
225                         [outlineView reloadData];
226                 }
227         }
229         //Call super and return its value
230     return([super outlineView:outlineView acceptDrop:info item:item childIndex:index]);
233 //Due to a bug in NSDrawer, convertPoint:fromView reports a point too low by the trailingOffset 
234 //when our contact list is in a drawer.
235 - (AIListObject *)contactListItemAtScreenPoint:(NSPoint)screenPoint
237         NSPoint                 viewPoint = [contactListView convertPoint:[[contactListView window] convertScreenToBase:screenPoint] fromView:[[contactListView window] contentView]];
238         
239         viewPoint.y += [(AIContactInfoWindowController *)delegate drawerTrailingOffset];
240         
241         AIListObject    *hoveredObject = [contactListView itemAtRow:[contactListView rowAtPoint:viewPoint]];
242         
243         return(hoveredObject);
246 //We want to just show UIDs whereever possible
247 - (BOOL)useAliasesInContactListAsRequested
249         return NO;
252 //We don't want to change text colors based on the user's status or state
253 - (BOOL)shouldUseContactTextColors{
254         return NO;
256         
257 @end