Merged [15040]: Trying some magic: 5 seconds after the last unreachable host is repor...
[adiumx.git] / Source / ESFileTransferProgressView.m
blob81c1b4e5296390d19521abc280f5f5208508810d
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 "ESFileTransferProgressRow.h"
18 #import "ESFileTransferProgressView.h"
19 #import <AIUtilities/AIParagraphStyleAdditions.h>
20 #import <AIUtilities/AIRolloverButton.h>
21 #import <AIUtilities/ESImageAdditions.h>
23 #define NORMAL_TEXT_COLOR               [NSColor controlTextColor]
24 #define SELECTED_TEXT_COLOR             [NSColor whiteColor]
25 #define TRANSFER_STATUS_COLOR   [NSColor disabledControlTextColor]
27 @interface ESFileTransferProgressView (PRIVATE)
28 - (void)updateHeaderLine;
29 - (void)updateButtonReveal;
30 - (void)updateButtonStopResume;
31 @end
33 @implementation ESFileTransferProgressView
35 - (void)awakeFromNib
37         if ([[self superclass] instancesRespondToSelector:@selector(awakeFromNib)]){
38         [super awakeFromNib];
39     }
41         [progressIndicator setUsesThreadedAnimation:YES];
42         [progressIndicator setIndeterminate:YES];
43         progressVisible = YES;
44                 
45         showingDetails = NO;
46         [view_details retain];
48         [button_stopResume setDelegate:self];
49         [button_reveal setDelegate:self];
51         buttonStopResumeIsHovered = NO;
52         buttonRevealIsHovered = NO;
55 - (void)dealloc
57         [view_details release];
58         
59         [super dealloc];
62 #pragma mark Source and destination
63 - (void)setSourceName:(NSString *)inSourceName
65         [textField_source setStringValue:(inSourceName ? inSourceName : @"")];
67 - (void)setSourceIcon:(NSImage *)inSourceIcon
69         [imageView_source setImage:inSourceIcon];
71 - (void)setDestinationName:(NSString *)inDestinationName
73         [textField_destination setStringValue:(inDestinationName ? inDestinationName : @"")];
75 - (void)setDestinationIcon:(NSImage *)inDestinationIcon
77         [imageView_destination setImage:inDestinationIcon];
80 #pragma mark File and its icon
81 - (void)setFileName:(NSString *)inFileName
83         [textField_fileName setStringValue:(inFileName ? 
84                                                                            inFileName : 
85                                                                            AILocalizedString(@"Initializing transfer...",nil))];
87 - (void)setIconImage:(NSImage *)inIconImage
89         [button_icon setImage:inIconImage];
92 #pragma mark Progress
93 - (void)setProgressDoubleValue:(double)inPercent
95         [progressIndicator setDoubleValue:inPercent];
97 - (void)setProgressIndeterminate:(BOOL)flag
99         [progressIndicator setIndeterminate:flag];      
101 - (void)setProgressAnimation:(BOOL)flag
103         if(flag){
104                 [progressIndicator startAnimation:self];
105         }else{
106                 [progressIndicator stopAnimation:self]; 
107         }
109 - (void)setProgressVisible:(BOOL)flag
111         if(flag != progressVisible){
112                 progressVisible = flag;
113                 if(progressVisible){
114                         //Redisplay the progress bar.  We never do this at present, so unimplemented for now.
115                 }else{
116                         NSRect  progressRect = [progressIndicator frame];
117                         NSRect  frame;
118                         float   distanceToMove = progressRect.size.height / 2;
119                         
120                         [progressIndicator setDisplayedWhenStopped:NO];
121                         [progressIndicator setIndeterminate:YES];
122                         [progressIndicator stopAnimation:self];
124                         //I don't trust setDisplayedWhenStopped... call me crazy.
125                         [progressIndicator setFrame:NSZeroRect];
126                         [progressIndicator setNeedsDisplay:YES];
127                         
128                         //Top objects moving down
129                         {
130                                 frame = [textField_fileName frame];
131                                 frame.origin.y -= distanceToMove;
132                                 //Don't let it be any further right than the progress bar used to be to avoid our buttons
133                                 frame.size.width = (progressRect.origin.x + progressRect.size.width) - frame.origin.x;
134                                 [textField_fileName setFrame:frame];
135                         }
136                         
137                         //Bottom objects moving up
138                         {
139                                 frame = [twiddle_details frame];
140                                 frame.origin.y += distanceToMove;
141                                 [twiddle_details setFrame:frame];
143                                 frame = [textField_detailsLabel frame];
144                                 frame.origin.y += distanceToMove;
145                                 [textField_detailsLabel setFrame:frame];
146                                                                 
147                                 frame = [box_transferStatusFrame frame];
148                                 frame.origin.y += distanceToMove;
149                                 //Don't let it be any further right than the progress bar used to be to avoid our buttons
150                                 frame.size.width = (progressRect.origin.x + progressRect.size.width) - frame.origin.x;
151                                 [box_transferStatusFrame setFrame:frame];
152                         }
153                 }
154                 
155                 //Display immediately
156                 [[self window] display];
157         }
160 - (void)setTransferBytesStatus:(NSString *)inTransferBytesStatus
161                            remainingStatus:(NSString *)inTransferRemainingStatus
162                                    speedStatus:(NSString *)inTransferSpeedStatus
164         [transferStatus release];
165         
166         if(inTransferBytesStatus && inTransferRemainingStatus){
167                 transferStatus = [NSString stringWithFormat:@"%@ - %@",
168                         inTransferBytesStatus,
169                         inTransferRemainingStatus];
170         }else if(inTransferBytesStatus){
171                 transferStatus = inTransferBytesStatus;
172         }else if(inTransferRemainingStatus){
173                 transferStatus = inTransferRemainingStatus;             
174         }else{
175                 transferStatus = @"";
176         }
177         
178         [transferStatus retain];
179         
180 //      [textField_transferStatus setStringValue:transferStatus];
181         [self setNeedsDisplayInRect:[box_transferStatusFrame frame]];
182         [textField_rate setStringValue:(inTransferSpeedStatus ? inTransferSpeedStatus : @"")];
185 #pragma mark Details
186 //Sent when the details twiddle is clicked
187 - (IBAction)toggleDetails:(id)sender
189         NSRect  detailsFrame = [view_details frame];
190         NSRect  primaryControlsFrame = [box_primaryControls frame];
191         NSRect  oldFrame = [self frame];
192         NSRect  newFrame = oldFrame;
193         
194         showingDetails = !showingDetails;
196         if(showingDetails){
197                 //Increase our height to make space
198                 newFrame.size.height += detailsFrame.size.height;
199                 newFrame.origin.y -= detailsFrame.size.height;
200                 [self setFrame:newFrame];
201                 
202                 //Move the box with our primary controls up
203                 primaryControlsFrame.origin.y += detailsFrame.size.height;
204                 [box_primaryControls setFrame:primaryControlsFrame];
205                         
206                 //Add the details subview
207                 [self addSubview:view_details];
208                 
209                 //Line up the details frame with the twiddle which revealed it
210                 detailsFrame.origin.x = [twiddle_details frame].origin.x;
211                 detailsFrame.origin.y = 0;
213                 [view_details setFrame:detailsFrame];
214         
215                 //Update the twiddle
216                 [twiddle_details setState:NSOnState];
217         }else{
218                 newFrame.size.height -= detailsFrame.size.height;
219                 newFrame.origin.y += detailsFrame.size.height;
221                 [self setFrame:newFrame];
222                 
223                 //Move the box with our primary controls back down
224                 primaryControlsFrame.origin.y -= detailsFrame.size.height;
225                 [box_primaryControls setFrame:primaryControlsFrame];
226                 
227                 [view_details removeFromSuperview];
228                 
229                 //Update the twiddle
230                 [twiddle_details setState:NSOffState];
231         }
232         
233         //Let the owner know our height changed so other rows can be adjusted accordingly
234         [owner fileTransferProgressView:self
235                                   heightChangedFrom:oldFrame.size.height
236                                                                  to:newFrame.size.height];
239 - (void)setAllowsCancel:(BOOL)flag
241         [button_stopResume setEnabled:flag];
244 #pragma mark Selection
245 - (void)setIsHighlighted:(BOOL)flag
247         if(isSelected != flag){
248                 isSelected = flag;
249                 
250                 NSColor *newColor;
251                 NSColor *transferStatusColor;
252                 
253                 if(isSelected){
254                         newColor = SELECTED_TEXT_COLOR;
255                         transferStatusColor = newColor;
256                 }else{
257                         newColor = NORMAL_TEXT_COLOR;
258                         transferStatusColor = TRANSFER_STATUS_COLOR;
259                 }
260                 
261                 [textField_rate setTextColor:newColor];
262                 [textField_source setTextColor:newColor];
263                 [textField_destination setTextColor:newColor];          
264                 [textField_fileName setTextColor:newColor];
265                 
266                 [self updateButtonStopResume];
267                 [self updateButtonReveal];
268         }
271 - (void)updateButtonStopResume
273         if(isSelected){
274                 [button_stopResume setImage:[NSImage imageNamed:(buttonStopResumeIsHovered ? @"FTProgressStopRollover_Selected" : @"FTProgressStop_Selected")
275                                                                                            forClass:[self class]]];
276                 
277                 [button_stopResume setAlternateImage:[NSImage imageNamed:@"FTProgressStopPressed_Selected" forClass:[self class]]];
278                 
279         }else{
280                 [button_stopResume setImage:[NSImage imageNamed:(buttonStopResumeIsHovered ? @"FTProgressStopRollover" : @"FTProgressStop")
281                                                                                            forClass:[self class]]];
282                 
283                 [button_stopResume setAlternateImage:[NSImage imageNamed:@"FTProgressStopPressed" forClass:[self class]]];
284         }
287 - (void)updateButtonReveal
289         if(isSelected){
290                 [button_reveal setImage:[NSImage imageNamed:(buttonRevealIsHovered ? @"FTProgressRevealRollover_Selected" : @"FTProgressReveal_Selected")
291                                                                                    forClass:[self class]]];
292                 
293                 [button_reveal setAlternateImage:[NSImage imageNamed:@"FTProgressRevealPressed_Selected" forClass:[self class]]];
295         }else{
296                 [button_reveal setImage:[NSImage imageNamed:(buttonRevealIsHovered ? @"FTProgressRevealRollover" : @"FTProgressReveal")
297                                                                                    forClass:[self class]]];
299                 [button_reveal setAlternateImage:[NSImage imageNamed:@"FTProgressRevealPressed" forClass:[self class]]];
301         }
303 - (void)rolloverButton:(AIRolloverButton *)inButton mouseChangedToInsideButton:(BOOL)isInside
305         if(inButton == button_stopResume){
306                 buttonStopResumeIsHovered = isInside;
307                 [self updateButtonStopResume];
308                 
309         }else if(inButton == button_reveal){
310                 buttonRevealIsHovered = isInside;
311                 [self updateButtonReveal];
313         }
316 static NSDictionary     *transferStatusAttributes = nil;
317 static NSDictionary     *transferStatusSelectedAttributes = nil;
319 //Draw the transfer status after other views draw.  This lets us use custom drawing behavior including the
320 //NSLineBreakByTruncatingTail paragraph style.  We draw into a frame reserved for us by box_transferStatusFrame;
321 //this lets us not worry about autosizing and positioning since the view takes care of that for us.
322 - (void)drawRect:(NSRect)rect
325         [super drawRect:rect];
327         NSDictionary    *attributes;
328         NSRect                  primaryControlsRect = [box_primaryControls frame];
329         NSRect                  targetRect = [box_transferStatusFrame frame];
331         targetRect.origin.x += primaryControlsRect.origin.x;
332         targetRect.origin.y += primaryControlsRect.origin.y;
334         if(isSelected){
335                 if(!transferStatusSelectedAttributes){
336                         NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle styleWithAlignment:NSLeftTextAlignment
337                                                                                                                                                                         lineBreakMode:NSLineBreakByTruncatingTail];
338                         [paragraphStyle setMaximumLineHeight:[box_transferStatusFrame frame].size.height];
339                         
340                         transferStatusSelectedAttributes = [[NSDictionary dictionaryWithObjectsAndKeys:
341                                 paragraphStyle, NSParagraphStyleAttributeName,
342                                 [NSFont systemFontOfSize:9], NSFontAttributeName, 
343                                 SELECTED_TEXT_COLOR, NSForegroundColorAttributeName, nil] retain];
344                 }
345                 
346                 attributes = transferStatusSelectedAttributes;
347         }else{
348                 if(!transferStatusAttributes){
349                         NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle styleWithAlignment:NSLeftTextAlignment
350                                                                                                                                                                         lineBreakMode:NSLineBreakByTruncatingTail];
351                         [paragraphStyle setMaximumLineHeight:[box_transferStatusFrame frame].size.height];
352                         
353                         transferStatusAttributes = [[NSDictionary dictionaryWithObjectsAndKeys:
354                                 paragraphStyle, NSParagraphStyleAttributeName,
355                                 [NSFont systemFontOfSize:9], NSFontAttributeName, 
356                                 TRANSFER_STATUS_COLOR, NSForegroundColorAttributeName, nil] retain];
357                 }
358                 
359                 attributes = transferStatusAttributes;
360         }
361         
362         [transferStatus drawInRect:targetRect
363                                 withAttributes:attributes];
366 #pragma mark Menu
367 - (NSMenu *)menuForEvent:(NSEvent *)inEvent
369         return [owner menuForEvent:inEvent];
372 @end