Request info to get user icons when a Jabber contact signs on. Fixes #4205
[adiumx.git] / Source / AIContactListRecentImagesWindowController.m
blob596232d4942d372f5a10fcf98b507b056d232336
1 //
2 //  AIContactListRecentImagesWindowController.m
3 //  Adium
4 //
5 //  Created by Evan Schoenberg on 12/19/05.
6 //
8 #import "AIContactListRecentImagesWindowController.h"
9 #import <Adium/AIAccountControllerProtocol.h>
10 #import <Adium/AIContactControllerProtocol.h>
11 #import <Adium/AIPreferenceControllerProtocol.h>
12 #import "AIStandardListWindowController.h"
13 #import "AIContactListImagePicker.h"
14 #import "AIMenuItemView.h"
15 #import <Adium/AIAccount.h>
16 #import <AIUtilities/AIImageGridView.h>
17 #import <AIUtilities/AIBorderlessWindow.h>
18 #import <AIUtilities/AIMenuAdditions.h>
19 #import <AIUtilities/AIStringAdditions.h>
20 #import <AIUtilities/AIColoredBoxView.h>
22 #import "NSIPRecentPicture.h"
24 #define FADE_INCREMENT  0.3
25 #define FADE_TIME               .3
27 @interface AIContactListRecentImagesWindowController (PRIVATE)
28 - (id)initWithWindowNibName:(NSString *)inWindowNibName
29                                 imagePicker:(AIContactListImagePicker *)inPicker
30           recentPictureSelector:(SEL)inRecentPictureSelector;
31 - (void)fadeOutAndClose;
32 @end
34 @implementation AIContactListRecentImagesWindowController
35 /*!
36  * @brief Show the widow
37  *
38  * @param inPoint The bottom-right corner of our parent view
39  */
40 + (void)showWindowFromPoint:(NSPoint)inPoint
41                                 imagePicker:(AIContactListImagePicker *)inPicker
42           recentPictureSelector:(SEL)inRecentPictureSelector
44         AIContactListRecentImagesWindowController       *controller = [[self alloc] initWithWindowNibName:@"ContactListRecentImages"
45                                                                                                                                                                           imagePicker:inPicker
46                                                                                                                                                         recentPictureSelector:inRecentPictureSelector];
48         NSWindow                        *window = [controller window];
50         [controller positionFromPoint:inPoint];
51         [(AIBorderlessWindow *)window setMoveable:NO];
52         
53         [controller showWindow:nil];
54         [window makeKeyAndOrderFront:nil];
57 - (id)initWithWindowNibName:(NSString *)inWindowNibName
58                                 imagePicker:(AIContactListImagePicker *)inPicker
59           recentPictureSelector:(SEL)inRecentPictureSelector
61         if ((self = [super initWithWindowNibName:inWindowNibName])) {
62                 picker = [inPicker retain];
63                 recentPictureSelector = inRecentPictureSelector;
64                 
65                 [[NSNotificationCenter defaultCenter] addObserver:self
66                                                                                                  selector:@selector(parentWindowWillClose:)
67                                                                                                          name:NSWindowWillCloseNotification
68                                                                                                    object:[picker window]];
69         }
70         
71         return self;
74 - (void)dealloc
76         [[NSNotificationCenter defaultCenter] removeObserver:self];
77         [picker release];
78         
79         [super dealloc];
82 - (void)windowDidLoad
84         [imageGridView setImageSize:NSMakeSize(30, 30)];        
85         [coloredBox setColor:[NSColor windowBackgroundColor]];
86         currentHoveredIndex = -1;
89 - (void)positionFromPoint:(NSPoint)inPoint
91         NSWindow *window = [self window];
92         NSRect   frame = [window frame];
93         NSRect   screenFrame = [[window screen] visibleFrame];
94         
95         frame.origin.x = inPoint.x - frame.size.width;
96         if (frame.origin.x < screenFrame.origin.x) {
97                 frame.origin.x = screenFrame.origin.x;
98         } else if (frame.origin.x + frame.size.width > screenFrame.origin.x + screenFrame.size.width) {
99                 frame.origin.x = screenFrame.origin.x + screenFrame.size.width - frame.size.width;
100         }
101         
102         frame.origin.y = inPoint.y - frame.size.height;
103         if (frame.origin.y < screenFrame.origin.y) {
104                 frame.origin.y = screenFrame.origin.y;
105         }
106         
107         //Ensure our window is visible above the window of the imagePicker that created us
108         if ([window level] < [[picker window] level]) {
109                 [window setLevel:[[picker window] level] + 1];
110         }
111         
112         [window setFrame:frame display:NO animate:NO];  
115 - (int)numberOfImagesInImageGridView:(AIImageGridView *)imageGridView
117         return 10;
120 - (NSImage *)imageGridView:(AIImageGridView *)imageGridView imageAtIndex:(int)index
122         NSImage          *displayImage;
124         if (index < [[NSIPRecentPicture recentSmallIcons] count]) {
125                 NSImage          *image = [[NSIPRecentPicture recentSmallIcons] objectAtIndex:index];
126                 NSSize          size = [image size];
127                 NSBezierPath *fullPath = [NSBezierPath bezierPathWithRect:NSMakeRect(0, 0, size.width, size.height)];
128                 displayImage = [image copy];
129                 
130                 [displayImage setFlipped:YES];
131                 [displayImage lockFocus];
132                 
133                 if (index == currentHoveredIndex) {
134                         [[[NSColor blueColor] colorWithAlphaComponent:0.30] set];
135                         [fullPath fill];
136                         
137                         [[NSColor blueColor] set];
138                         [fullPath stroke];
139                         
140                 } else {
141                         [[NSColor whiteColor] set];
142                         [fullPath stroke];
143                 }
144                 
145                 [displayImage unlockFocus];
146         } else {
147                 NSSize           size = NSMakeSize(32, 32);
148                 NSBezierPath *fullPath = [NSBezierPath bezierPathWithRect:NSMakeRect(0, 0, size.width, size.height)];
150                 displayImage = [[NSImage alloc] initWithSize:size];
151                 [displayImage lockFocus];
152                 
153                 [[NSColor lightGrayColor] set];
154                 [fullPath fill];
155                 
156                 [displayImage unlockFocus];
157         }
158         
159         return [displayImage autorelease];
162 - (void)imageGridView:(AIImageGridView *)inImageGridView cursorIsHoveringImageAtIndex:(int)index
164         //Update our hovered index and redisplay the image
165         currentHoveredIndex = index;
166         [imageGridView setNeedsDisplayOfImageAtIndex:index];
169 - (void)imageGridViewSelectionDidChange:(NSNotification *)notification
171         int selectedIndex = [imageGridView selectedIndex];
172         NSArray *recentPictures = [NSIPRecentPicture recentPictures];
173         if (selectedIndex < [recentPictures count]) {
174                 //Notify as if the image had been selected in the picker
175                 [[picker delegate] imageViewWithImagePicker:picker
176                                                            didChangeToImageData:[NSData dataWithContentsOfFile:[[recentPictures objectAtIndex:selectedIndex] originalImagePath]]];
177         }
179         [self fadeOutAndClose];
182 - (void)selectedAccount:(id)sender
184         AIAccount       *activeAccount = [sender representedObject];
186         //Change the active account
187         [[adium preferenceController] setPreference:(activeAccount ? [activeAccount internalObjectID] : nil)
188                                                                                  forKey:@"Active Icon Selection Account"
189                                                                                   group:GROUP_ACCOUNT_STATUS];
191         [menuItemView setMenu:[self menuForMenuItemView:menuItemView]];
194 - (void)chooseIcon:(id)sender
196         [picker showImagePicker:nil];
197         
198         [self fadeOutAndClose];
201 - (void)clearRecentPictures:(id)sender
203         [NSIPRecentPicture removeAllButCurrent];
204         [imageGridView reloadData];
207 - (void)windowDidResignMain:(NSNotification *)aNotification
209         [self fadeOutAndClose];
212 - (void)windowDidResignKey:(NSNotification *)aNotification
214         [self fadeOutAndClose];         
217 - (void)parentWindowWillClose:(NSNotification *)aNotification
219         //Close, no fade, when our parent window closes
220         [self close];
223 #pragma mark Fading
224 - (void)fadeOut:(NSTimer *)inTimer
226         float                           currentAlpha = [[self window] alphaValue];
227         currentAlpha -= 0.15;
228         
229         if (currentAlpha <= 0) {
230                 [self close];
231                 [inTimer invalidate];
233         } else {
234                 [[self window] setAlphaValue:currentAlpha];
235         }
238 - (void)fadeOutAndClose
240         [NSTimer scheduledTimerWithTimeInterval:.01
241                                                                          target:self 
242                                                                    selector:@selector(fadeOut:)
243                                                                    userInfo:nil
244                                                                         repeats:YES];
247 #pragma mark AIMenuItemView delegate
249 - (NSMenu *)menuForMenuItemView:(AIMenuItemView *)inMenuItemView
251         NSMenu           *menu = [[NSMenu alloc] init];
252         NSMutableSet *onlineAccounts = [NSMutableSet set];
253         NSMutableSet *ownIconAccounts = [NSMutableSet set];
254         AIAccount        *activeAccount = nil;
255         NSMenuItem       *menuItem;
257         activeAccount = [AIStandardListWindowController activeAccountForIconsGettingOnlineAccounts:onlineAccounts
258                                                                                                                                                            ownIconAccounts:ownIconAccounts];
259         
260         int ownIconAccountsCount = [ownIconAccounts count];
261         int onlineAccountsCount = [onlineAccounts count];
262         if (ownIconAccountsCount && ((ownIconAccountsCount > 1) || (onlineAccountsCount > 1))) {
263                 //There are at least some accounts using the global preference if the counts differ
264                 BOOL             includeGlobal = (onlineAccountsCount != ownIconAccountsCount);
265                 AIAccount        *account;
266                 NSEnumerator *enumerator;
268                 menuItem = [[NSMenuItem alloc] initWithTitle:AILocalizedString(@"Change Icon For:", nil)
269                                                                                           target:nil
270                                                                                           action:nil
271                                                                            keyEquivalent:@""];
272                 [menuItem setEnabled:NO];
273                 [menu addItem:menuItem];
274                 [menuItem release];
275                 
276                 enumerator = [ownIconAccounts objectEnumerator];
277                 while ((account = [enumerator nextObject])) {
278                         //Put a check before the account if it is the active account
279                         menuItem = [[NSMenuItem alloc] initWithTitle:[account formattedUID]
280                                                                                                   target:self
281                                                                                                   action:@selector(selectedAccount:)
282                                                                                    keyEquivalent:@""];
283                         [menuItem setRepresentedObject:account];
285                         if (activeAccount == account) {
286                                 [menuItem setState:NSOnState];
287                         }
288                         [menuItem setIndentationLevel:1];
289                         [menu addItem:menuItem];
290                         
291                         [menuItem release];
292                 }
293                 
294                 if (includeGlobal) {
295                         menuItem = [[NSMenuItem alloc] initWithTitle:ALL_OTHER_ACCOUNTS
296                                                                                                   target:self
297                                                                                                   action:@selector(selectedAccount:)
298                                                                                    keyEquivalent:@""];
299                         if (!activeAccount) {
300                                 [menuItem setState:NSOnState];
301                         }
302                         [menuItem setIndentationLevel:1];
304                         [menu addItem:menuItem];
305                         [menuItem release];
306                 }
307                 
308                 [menu addItem:[NSMenuItem separatorItem]];
310         } else {
311                 //All accounts are using the global preference
312         }
314         menuItem = [[NSMenuItem alloc] initWithTitle:[AILocalizedString(@"Choose Icon", nil) stringByAppendingEllipsis]
315                                                                                   target:self
316                                                                                   action:@selector(chooseIcon:)
317                                                                    keyEquivalent:@""];
318         [menu addItem:menuItem];
319         [menuItem release];
321         menuItem = [[NSMenuItem alloc] initWithTitle:AILocalizedString(@"Clear Recent Pictures", nil)
322                                                                                   target:self
323                                                                                   action:@selector(clearRecentPictures:)
324                                                                    keyEquivalent:@""];
325         [menu addItem:menuItem];
326         [menuItem release];
328         return [menu autorelease];
331 - (void)menuItemViewDidChangeMenu:(AIMenuItemView *)inMenuItemView
333         NSRect  oldFrame = [inMenuItemView frame];
334         [inMenuItemView sizeToFit];
335         NSRect  newFrame = [inMenuItemView frame];
337         float   heightDifference = newFrame.size.height - oldFrame.size.height;
339         if (heightDifference != 0) {
340                 NSRect  myFrame = [[self window] frame];
341                 
342                 myFrame.size.height += heightDifference;
343                 myFrame.origin.y -= heightDifference;
344                 
345                 [[self window] setFrame:myFrame display:YES animate:NO];
346         }
350 @end