2 * Adium is the legal property of its developers, whose names are listed in the copyright file included
3 * with this source distribution.
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.
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.
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.
17 #import "ESFileTransferProgressRow.h"
18 #import "ESFileTransferProgressView.h"
19 #import <AIUtilities/AIParagraphStyleAdditions.h>
20 #import <AIUtilities/AIRolloverButton.h>
21 #import <AIUtilities/AIImageAdditions.h>
22 #import <AIUtilities/AIStringAdditions.h>
24 #define NORMAL_TEXT_COLOR [NSColor controlTextColor]
25 #define SELECTED_TEXT_COLOR [NSColor whiteColor]
26 #define TRANSFER_STATUS_COLOR [NSColor disabledControlTextColor]
28 @interface ESFileTransferProgressView (PRIVATE)
29 - (void)updateHeaderLine;
30 - (void)updateButtonReveal;
31 - (void)updateButtonStopResume;
34 @implementation ESFileTransferProgressView
38 if ([[self superclass] instancesRespondToSelector:@selector(awakeFromNib)]) {
42 [progressIndicator setUsesThreadedAnimation:YES];
43 [progressIndicator setIndeterminate:YES];
44 progressVisible = YES;
47 [view_details retain];
49 [button_stopResume setDelegate:self];
50 [button_reveal setDelegate:self];
52 buttonStopResumeIsHovered = NO;
53 buttonRevealIsHovered = NO;
58 [view_details release];
63 #pragma mark Source and destination
64 - (void)setSourceName:(NSString *)inSourceName
66 [textField_source setStringValue:(inSourceName ? inSourceName : @"")];
68 - (void)setSourceIcon:(NSImage *)inSourceIcon
70 [imageView_source setImage:inSourceIcon];
72 - (void)setDestinationName:(NSString *)inDestinationName
74 [textField_destination setStringValue:(inDestinationName ? inDestinationName : @"")];
76 - (void)setDestinationIcon:(NSImage *)inDestinationIcon
78 [imageView_destination setImage:inDestinationIcon];
81 #pragma mark File and its icon
82 - (void)setFileName:(NSString *)inFileName
84 [textField_fileName setStringValue:(inFileName ?
86 [AILocalizedString(@"Initializing transfer",nil) stringByAppendingEllipsis])];
88 - (void)setIconImage:(NSImage *)inIconImage
90 [button_icon setImage:inIconImage];
94 - (void)setProgressDoubleValue:(double)inPercent
96 [progressIndicator setDoubleValue:inPercent];
98 - (void)setProgressIndeterminate:(BOOL)flag
100 [progressIndicator setIndeterminate:flag];
102 - (void)setProgressAnimation:(BOOL)flag
105 [progressIndicator startAnimation:self];
107 [progressIndicator stopAnimation:self];
110 - (void)setProgressVisible:(BOOL)flag
112 if (flag != progressVisible) {
113 progressVisible = flag;
114 if (progressVisible) {
115 //Redisplay the progress bar. We never do this at present, so unimplemented for now.
117 NSRect progressRect = [progressIndicator frame];
119 float distanceToMove = progressRect.size.height / 2;
121 [progressIndicator setDisplayedWhenStopped:NO];
122 [progressIndicator setIndeterminate:YES];
123 [progressIndicator stopAnimation:self];
125 //I don't trust setDisplayedWhenStopped... call me crazy.
126 [progressIndicator setFrame:NSZeroRect];
127 [progressIndicator setNeedsDisplay:YES];
129 //Top objects moving down
131 frame = [textField_fileName frame];
132 frame.origin.y -= distanceToMove;
133 //Don't let it be any further right than the progress bar used to be to avoid our buttons
134 frame.size.width = (progressRect.origin.x + progressRect.size.width) - frame.origin.x;
135 [textField_fileName setFrame:frame];
138 //Bottom objects moving up
140 frame = [twiddle_details frame];
141 frame.origin.y += distanceToMove;
142 [twiddle_details setFrame:frame];
144 frame = [textField_detailsLabel frame];
145 frame.origin.y += distanceToMove;
146 [textField_detailsLabel setFrame:frame];
148 frame = [box_transferStatusFrame frame];
149 frame.origin.y += distanceToMove;
150 //Don't let it be any further right than the progress bar used to be to avoid our buttons
151 frame.size.width = (progressRect.origin.x + progressRect.size.width) - frame.origin.x;
152 [box_transferStatusFrame setFrame:frame];
156 //Display immediately
157 [[self window] display];
161 - (void)setTransferBytesStatus:(NSString *)inTransferBytesStatus
162 remainingStatus:(NSString *)inTransferRemainingStatus
163 speedStatus:(NSString *)inTransferSpeedStatus
165 [transferStatus release];
167 if (inTransferBytesStatus && inTransferRemainingStatus) {
168 transferStatus = [NSString stringWithFormat:@"%@ - %@",
169 inTransferBytesStatus,
170 inTransferRemainingStatus];
171 } else if (inTransferBytesStatus) {
172 transferStatus = inTransferBytesStatus;
173 } else if (inTransferRemainingStatus) {
174 transferStatus = inTransferRemainingStatus;
176 transferStatus = @"";
179 [transferStatus retain];
181 // [textField_transferStatus setStringValue:transferStatus];
182 [self setNeedsDisplayInRect:[box_transferStatusFrame frame]];
183 [textField_rate setStringValue:(inTransferSpeedStatus ? inTransferSpeedStatus : @"")];
187 //Sent when the details twiddle is clicked
188 - (IBAction)toggleDetails:(id)sender
190 NSRect detailsFrame = [view_details frame];
191 NSRect primaryControlsFrame = [box_primaryControls frame];
192 NSRect oldFrame = [self frame];
193 NSRect newFrame = oldFrame;
195 showingDetails = !showingDetails;
197 if (showingDetails) {
198 //Increase our height to make space
199 newFrame.size.height += detailsFrame.size.height;
200 newFrame.origin.y -= detailsFrame.size.height;
201 [self setFrame:newFrame];
203 //Move the box with our primary controls up
204 primaryControlsFrame.origin.y += detailsFrame.size.height;
205 [box_primaryControls setFrame:primaryControlsFrame];
207 //Add the details subview
208 [self addSubview:view_details];
210 //Line up the details frame with the twiddle which revealed it
211 detailsFrame.origin.x = [twiddle_details frame].origin.x;
212 detailsFrame.origin.y = 0;
214 [view_details setFrame:detailsFrame];
217 [twiddle_details setState:NSOnState];
219 newFrame.size.height -= detailsFrame.size.height;
220 newFrame.origin.y += detailsFrame.size.height;
222 [self setFrame:newFrame];
224 //Move the box with our primary controls back down
225 primaryControlsFrame.origin.y -= detailsFrame.size.height;
226 [box_primaryControls setFrame:primaryControlsFrame];
228 [view_details removeFromSuperview];
231 [twiddle_details setState:NSOffState];
234 //Let the owner know our height changed so other rows can be adjusted accordingly
235 [owner fileTransferProgressView:self
236 heightChangedFrom:oldFrame.size.height
237 to:newFrame.size.height];
240 - (void)setShowsDetails:(BOOL)flag
242 if (showingDetails != flag) {
243 [self toggleDetails:nil];
247 - (void)setAllowsCancel:(BOOL)flag
249 [button_stopResume setEnabled:flag];
252 #pragma mark Selection
253 - (void)setIsHighlighted:(BOOL)flag
255 if (isSelected != flag) {
259 NSColor *transferStatusColor;
262 newColor = SELECTED_TEXT_COLOR;
263 transferStatusColor = newColor;
265 newColor = NORMAL_TEXT_COLOR;
266 transferStatusColor = TRANSFER_STATUS_COLOR;
269 [textField_rate setTextColor:newColor];
270 [textField_source setTextColor:newColor];
271 [textField_destination setTextColor:newColor];
272 [textField_fileName setTextColor:newColor];
274 [self updateButtonStopResume];
275 [self updateButtonReveal];
279 - (void)updateButtonStopResume
282 [button_stopResume setImage:[NSImage imageNamed:(buttonStopResumeIsHovered ? @"FTProgressStopRollover_Selected" : @"FTProgressStop_Selected")
283 forClass:[self class]]];
285 [button_stopResume setAlternateImage:[NSImage imageNamed:@"FTProgressStopPressed_Selected" forClass:[self class]]];
288 [button_stopResume setImage:[NSImage imageNamed:(buttonStopResumeIsHovered ? @"FTProgressStopRollover" : @"FTProgressStop")
289 forClass:[self class]]];
291 [button_stopResume setAlternateImage:[NSImage imageNamed:@"FTProgressStopPressed" forClass:[self class]]];
295 - (void)updateButtonReveal
298 [button_reveal setImage:[NSImage imageNamed:(buttonRevealIsHovered ? @"FTProgressRevealRollover_Selected" : @"FTProgressReveal_Selected")
299 forClass:[self class]]];
301 [button_reveal setAlternateImage:[NSImage imageNamed:@"FTProgressRevealPressed_Selected" forClass:[self class]]];
304 [button_reveal setImage:[NSImage imageNamed:(buttonRevealIsHovered ? @"FTProgressRevealRollover" : @"FTProgressReveal")
305 forClass:[self class]]];
307 [button_reveal setAlternateImage:[NSImage imageNamed:@"FTProgressRevealPressed" forClass:[self class]]];
311 - (void)rolloverButton:(AIRolloverButton *)inButton mouseChangedToInsideButton:(BOOL)isInside
313 if (inButton == button_stopResume) {
314 buttonStopResumeIsHovered = isInside;
315 [self updateButtonStopResume];
317 } else if (inButton == button_reveal) {
318 buttonRevealIsHovered = isInside;
319 [self updateButtonReveal];
324 static NSDictionary *transferStatusAttributes = nil;
325 static NSDictionary *transferStatusSelectedAttributes = nil;
327 //Draw the transfer status after other views draw. This lets us use custom drawing behavior including the
328 //NSLineBreakByTruncatingTail paragraph style. We draw into a frame reserved for us by box_transferStatusFrame;
329 //this lets us not worry about autosizing and positioning since the view takes care of that for us.
330 - (void)drawRect:(NSRect)rect
333 [super drawRect:rect];
335 NSDictionary *attributes;
336 NSRect primaryControlsRect = [box_primaryControls frame];
337 NSRect targetRect = [box_transferStatusFrame frame];
339 targetRect.origin.x += primaryControlsRect.origin.x;
340 targetRect.origin.y += primaryControlsRect.origin.y;
343 if (!transferStatusSelectedAttributes) {
344 NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle styleWithAlignment:NSLeftTextAlignment
345 lineBreakMode:NSLineBreakByTruncatingTail];
346 [paragraphStyle setMaximumLineHeight:[box_transferStatusFrame frame].size.height];
348 transferStatusSelectedAttributes = [[NSDictionary dictionaryWithObjectsAndKeys:
349 paragraphStyle, NSParagraphStyleAttributeName,
350 [NSFont systemFontOfSize:9], NSFontAttributeName,
351 SELECTED_TEXT_COLOR, NSForegroundColorAttributeName, nil] retain];
354 attributes = transferStatusSelectedAttributes;
356 if (!transferStatusAttributes) {
357 NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle styleWithAlignment:NSLeftTextAlignment
358 lineBreakMode:NSLineBreakByTruncatingTail];
359 [paragraphStyle setMaximumLineHeight:[box_transferStatusFrame frame].size.height];
361 transferStatusAttributes = [[NSDictionary dictionaryWithObjectsAndKeys:
362 paragraphStyle, NSParagraphStyleAttributeName,
363 [NSFont systemFontOfSize:9], NSFontAttributeName,
364 TRANSFER_STATUS_COLOR, NSForegroundColorAttributeName, nil] retain];
367 attributes = transferStatusAttributes;
370 [transferStatus drawInRect:targetRect
371 withAttributes:attributes];
375 - (NSMenu *)menuForEvent:(NSEvent *)inEvent
377 return [owner menuForEvent:inEvent];