source: trunk/macosx/InfoWindowController.m @ 402

Last change on this file since 402 was 402, checked in by livings124, 16 years ago

Better resizing behavior.

  • Property svn:keywords set to Date Rev Author Id
File size: 15.5 KB
Line 
1/******************************************************************************
2 * $Id: InfoWindowController.m 402 2006-06-20 00:36:51Z livings124 $
3 *
4 * Copyright (c) 2006 Transmission authors and contributors
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *****************************************************************************/
24
25#import "InfoWindowController.h"
26#import "StringAdditions.h"
27
28#define RATIO_NO_CHECK_TAG 0
29#define RATIO_GLOBAL_TAG 1
30#define RATIO_CHECK_TAG 2
31
32#define MIN_WINDOW_WIDTH 270
33#define MAX_WINDOW_WIDTH 2000
34
35#define TAB_INFO_IDENT @"Info"
36#define TAB_STATUS_IDENT @"Status"
37#define TAB_OPTIONS_IDENT @"Options"
38#define TAB_FILES_IDENT @"Files"
39
40//15 spacing at the bottom of each tab
41#define TAB_INFO_HEIGHT 185.0
42#define TAB_STATUS_HEIGHT 199.0
43#define TAB_OPTIONS_HEIGHT 82.0
44#define TAB_FILES_HEIGHT 250.0
45
46@implementation InfoWindowController
47
48- (void) awakeFromNib
49{
50    fAppIcon = [[NSApp applicationIconImage] copy];
51   
52    fFiles = [[NSMutableArray alloc] initWithCapacity: 6];
53    [fFileTable setDoubleAction: @selector(revealFile:)];
54   
55    //window location and size
56    NSPanel * window = (NSPanel *)[self window];
57   
58    [window setBecomesKeyOnlyIfNeeded: YES];
59   
60    [window setFrameAutosaveName: @"InspectorWindowFrame"];
61    [window setFrameUsingName: @"InspectorWindowFrame" force: YES];
62   
63    NSRect frame = [window frame];
64    float difference = TAB_INFO_HEIGHT - [[[fTabView selectedTabViewItem]
65                                                    view] frame].size.height;
66    frame.origin.y -= difference;
67    frame.size.height += difference;
68    [window setFrame: frame display: YES];
69   
70    [window setMinSize: NSMakeSize(MIN_WINDOW_WIDTH, frame.size.height)];
71    [window setMaxSize: NSMakeSize(MAX_WINDOW_WIDTH, frame.size.height)];
72}
73
74- (void) dealloc
75{
76    if (fTorrents)
77        [fTorrents release];
78    [fFiles release];
79
80    [fAppIcon release];
81    [super dealloc];
82}
83
84- (void) updateInfoForTorrents: (NSArray *) torrents
85{
86    if (fTorrents)
87        [fTorrents release];
88    fTorrents = [torrents retain];
89
90    int numberSelected = [fTorrents count];
91    if (numberSelected != 1)
92    {
93        if (numberSelected > 0)
94        {
95            [fNameField setStringValue: [NSString stringWithFormat:
96                            @"%d Torrents Selected", numberSelected]];
97       
98            uint64_t size = 0;
99            NSEnumerator * enumerator = [torrents objectEnumerator];
100            Torrent * torrent;
101            while ((torrent = [enumerator nextObject]))
102                size += [torrent size];
103           
104            [fSizeField setStringValue: [[NSString stringForFileSize: size]
105                                stringByAppendingString: @" Total"]];
106        }
107        else
108        {
109            [fNameField setStringValue: @"No Torrents Selected"];
110            [fSizeField setStringValue: @""];
111           
112#if 0
113            [fDownloadRateField setStringValue: @""];
114            [fUploadRateField setStringValue: @""];
115#endif
116           
117            [fDownloadedValidField setStringValue: @""];
118            [fDownloadedTotalField setStringValue: @""];
119            [fUploadedTotalField setStringValue: @""];
120        }
121       
122        [fImageView setImage: fAppIcon];
123       
124        [fNameField setToolTip: nil];
125
126        [fTrackerField setStringValue: @""];
127        [fTrackerField setToolTip: nil];
128        [fAnnounceField setStringValue: @""];
129        [fAnnounceField setToolTip: nil];
130        [fPieceSizeField setStringValue: @""];
131        [fPiecesField setStringValue: @""];
132        [fHashField setStringValue: @""];
133       
134        [fTorrentLocationField setStringValue: @""];
135        [fTorrentLocationField setToolTip: nil];
136        [fDataLocationField setStringValue: @""];
137        [fDataLocationField setToolTip: nil];
138        [fDateStartedField setStringValue: @""];
139       
140#if 0
141        [fStateField setStringValue: @""];
142        [fPercentField setStringValue: @""];
143#endif
144        [fRatioField setStringValue: @""];
145       
146        [fSeedersField setStringValue: @""];
147        [fLeechersField setStringValue: @""];
148        [fConnectedPeersField setStringValue: @""];
149        [fDownloadingFromField setStringValue: @""];
150        [fUploadingToField setStringValue: @""];
151    }
152    else
153    {   
154        Torrent * torrent = [fTorrents objectAtIndex: 0];
155       
156        [fImageView setImage: [torrent icon]];
157       
158        NSString * name = [torrent name];
159        [fNameField setStringValue: name];
160        [fNameField setToolTip: name];
161        [fSizeField setStringValue: [NSString stringForFileSize: [torrent size]]];
162       
163        NSString * tracker = [torrent tracker], * announce = [torrent announce];
164        [fTrackerField setStringValue: tracker];
165        [fTrackerField setToolTip: tracker];
166        [fAnnounceField setStringValue: announce];
167        [fAnnounceField setToolTip: announce];
168        [fPieceSizeField setStringValue: [NSString stringForFileSize: [torrent pieceSize]]];
169        [fPiecesField setIntValue: [torrent pieceCount]];
170        [fHashField setStringValue: [torrent hashString]];
171       
172        [fTorrentLocationField setStringValue: [[torrent torrentLocationString]
173                                        stringByAbbreviatingWithTildeInPath]];
174        [fTorrentLocationField setToolTip: [torrent torrentLocation]];
175        [fDataLocationField setStringValue: [[torrent dataLocation]
176                                        stringByAbbreviatingWithTildeInPath]];
177        [fDataLocationField setToolTip: [torrent dataLocation]];
178        [fDateStartedField setObjectValue: [torrent date]];
179    }
180    [self updateInfoStats];
181
182    //set file table
183    [fFiles removeAllObjects];
184   
185    Torrent * torrent;
186    NSEnumerator * enumerator = [fTorrents objectEnumerator];
187    while ((torrent = [enumerator nextObject]))
188        [fFiles addObjectsFromArray: [torrent fileList]];
189   
190    [fFileTable deselectAll: nil];
191    [fFileTable reloadData];
192   
193    //set ratio settings
194    if (numberSelected > 0)
195    {
196        NSEnumerator * enumerator = [fTorrents objectEnumerator];
197        Torrent * torrent = [enumerator nextObject]; //first torrent
198        const int INVALID = -99;
199        int ratioSetting = [torrent stopRatioSetting];
200        float ratioLimit = [torrent ratioLimit];
201       
202        while ((ratioSetting != INVALID || ratioLimit != INVALID)
203                && (torrent = [enumerator nextObject]))
204        {
205            if (ratioSetting != INVALID && ratioSetting != [torrent stopRatioSetting])
206                ratioSetting = INVALID;
207           
208            if (ratioLimit != INVALID && ratioLimit != [torrent ratioLimit])
209                ratioLimit = INVALID;
210        }
211       
212        [fRatioMatrix setEnabled: YES];
213       
214        if (ratioSetting == RATIO_CHECK)
215        {
216            [fRatioMatrix selectCellWithTag: RATIO_CHECK_TAG];
217            [fRatioLimitField setEnabled: YES];
218        }
219        else
220        {
221            if (ratioSetting == RATIO_NO_CHECK)
222                [fRatioMatrix selectCellWithTag: RATIO_NO_CHECK_TAG];
223            else if (ratioSetting == RATIO_GLOBAL)
224                [fRatioMatrix selectCellWithTag: RATIO_GLOBAL_TAG];
225            else
226                [fRatioMatrix deselectAllCells];
227           
228            [fRatioLimitField setEnabled: NO];
229        }
230       
231        if (ratioLimit != INVALID)
232            [fRatioLimitField setFloatValue: ratioLimit];
233        else
234            [fRatioLimitField setStringValue: @""];
235    }
236    else
237    {
238        [fRatioMatrix deselectAllCells];
239        [fRatioMatrix setEnabled: NO];
240       
241        [fRatioLimitField setEnabled: NO];
242        [fRatioLimitField setStringValue: @""];
243    }
244}
245
246- (void) updateInfoStats
247{
248    int numberSelected = [fTorrents count];
249    if (numberSelected > 0)
250    {
251        float downloadRate = 0, uploadRate = 0, downloadedValid;
252        uint64_t downloadedTotal = 0, uploadedTotal = 0;
253        Torrent * torrent;
254        NSEnumerator * enumerator = [fTorrents objectEnumerator];
255        while ((torrent = [enumerator nextObject]))
256        {
257            downloadRate += [torrent downloadRate];
258            uploadRate += [torrent uploadRate];
259           
260            downloadedValid += [torrent downloadedValid];
261            downloadedTotal += [torrent downloadedTotal];
262            uploadedTotal += [torrent uploadedTotal];
263        }
264       
265#if 0
266        [fDownloadRateField setStringValue: [NSString stringForSpeed: downloadRate]];
267        [fUploadRateField setStringValue: [NSString stringForSpeed: uploadRate]];
268#endif
269       
270        [fDownloadedValidField setStringValue: [NSString stringForFileSize: downloadedValid]];
271        [fDownloadedTotalField setStringValue: [NSString stringForFileSize: downloadedTotal]];
272        [fUploadedTotalField setStringValue: [NSString stringForFileSize: uploadedTotal]];
273   
274        if (numberSelected == 1)
275        {
276            torrent = [fTorrents objectAtIndex: 0];
277           
278#if 0
279            [fStateField setStringValue: [torrent state]];
280            [fPercentField setStringValue: [NSString stringWithFormat:
281                                            @"%.2f%%", 100.0 * [torrent progress]]];
282#endif
283
284            int seeders = [torrent seeders], leechers = [torrent leechers];
285            [fSeedersField setStringValue: seeders < 0 ?
286                @"N/A" : [NSString stringWithInt: seeders]];
287            [fLeechersField setStringValue: leechers < 0 ?
288                @"N/A" : [NSString stringWithInt: leechers]];
289           
290            BOOL active = [torrent isActive];
291           
292            [fConnectedPeersField setStringValue: active ? [NSString
293                    stringWithInt: [torrent totalPeers]] : @"N/A"];
294            [fDownloadingFromField setStringValue: active ? [NSString
295                    stringWithInt: [torrent peersUploading]] : @"N/A"];
296            [fUploadingToField setStringValue: active ? [NSString
297                    stringWithInt: [torrent peersDownloading]] : @"N/A"];
298           
299            [fRatioField setStringValue: [NSString stringForRatioWithDownload:
300                                        downloadedTotal upload: uploadedTotal]];
301        }
302    }
303}
304
305- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
306{
307    SEL action = [menuItem action];
308   
309    if (action == @selector(revealFile:))
310        return [fFileTable numberOfSelectedRows] > 0 &&
311            [[[fTabView selectedTabViewItem] identifier] isEqualToString: TAB_FILES_IDENT];
312       
313    return YES;
314}
315
316- (NSRect) windowWillUseStandardFrame: (NSWindow *) window defaultFrame: (NSRect) defaultFrame
317{
318    NSPoint windowOrigin = [window frame].origin;
319    NSSize minSize = [window minSize];
320   
321    return NSMakeRect(windowOrigin.x, windowOrigin.y, minSize.width, minSize.height);
322}
323
324- (void) tabView: (NSTabView *) tabView didSelectTabViewItem: (NSTabViewItem *) tabViewItem
325{
326    NSWindow * window = [self window];
327    NSRect frame = [window frame];
328
329    float height;
330    NSString * identifier = [tabViewItem identifier];
331    if ([identifier isEqualToString: TAB_INFO_IDENT])
332        height = TAB_INFO_HEIGHT;
333    else if ([identifier isEqualToString: TAB_STATUS_IDENT])
334        height = TAB_STATUS_HEIGHT;
335    else if ([identifier isEqualToString: TAB_OPTIONS_IDENT])
336        height = TAB_OPTIONS_HEIGHT;
337    else
338        height = TAB_FILES_HEIGHT;
339   
340    NSView * view = [tabViewItem view];
341    float difference = height - [view frame].size.height;
342    frame.origin.y -= difference;
343    frame.size.height += difference;
344   
345    [view setHidden: YES];
346    [window setFrame: frame display: YES animate: YES];
347    [view setHidden: NO];
348   
349    [window setMinSize: NSMakeSize(MIN_WINDOW_WIDTH, frame.size.height)];
350    [window setMaxSize: NSMakeSize(MAX_WINDOW_WIDTH, frame.size.height)];
351}
352
353- (void) setNextTab
354{
355    if ([fTabView indexOfTabViewItem: [fTabView selectedTabViewItem]]
356                                    == [fTabView numberOfTabViewItems] - 1)
357        [fTabView selectFirstTabViewItem: nil];
358    else
359        [fTabView selectNextTabViewItem: nil];
360}
361
362- (void) setPreviousTab
363{
364    if ([fTabView indexOfTabViewItem: [fTabView selectedTabViewItem]] == 0)
365        [fTabView selectLastTabViewItem: nil];
366    else
367        [fTabView selectPreviousTabViewItem: nil];
368}
369
370- (int) numberOfRowsInTableView: (NSTableView *) tableView
371{
372    return [fFiles count];
373}
374
375- (id) tableView: (NSTableView *) tableView objectValueForTableColumn:
376                    (NSTableColumn *) column row: (int) row
377{
378    NSString * file = [fFiles objectAtIndex: row];
379    if ([[column identifier] isEqualToString: @"Icon"])
380        return [[NSWorkspace sharedWorkspace] iconForFileType: [file pathExtension]];
381    else
382        return [file lastPathComponent];
383}
384
385//only called on >= 10.4
386- (NSString *) tableView: (NSTableView *) tableView toolTipForCell: (NSCell *) cell
387        rect: (NSRectPointer) rect tableColumn: (NSTableColumn *) column
388        row: (int) row mouseLocation: (NSPoint) mouseLocation
389{
390    return [fFiles objectAtIndex: row];
391}
392
393- (void) revealFile: (id) sender
394{
395    NSIndexSet * indexSet = [fFileTable selectedRowIndexes];
396    unsigned int i;
397    for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
398        [[NSWorkspace sharedWorkspace] selectFile: [fFiles objectAtIndex: i]
399            inFileViewerRootedAtPath: nil];
400}
401
402- (void) setRatioCheck: (id) sender
403{
404    NSButtonCell * selected = [fRatioMatrix selectedCell];
405    int ratioSetting;
406    if (selected == [fRatioMatrix cellWithTag: RATIO_CHECK_TAG])
407        ratioSetting = RATIO_CHECK;
408    else if (selected == [fRatioMatrix cellWithTag: RATIO_NO_CHECK_TAG])
409        ratioSetting = RATIO_NO_CHECK;
410    else
411        ratioSetting = RATIO_GLOBAL;
412
413    Torrent * torrent;
414    NSEnumerator * enumerator = [fTorrents objectEnumerator];
415    while ((torrent = [enumerator nextObject]))
416        [torrent setStopRatioSetting: ratioSetting];
417   
418    [self setRatioLimit: fRatioLimitField];
419    [fRatioLimitField setEnabled: selected == [fRatioMatrix cellWithTag: RATIO_CHECK_TAG]];
420}
421
422- (void) setRatioLimit: (id) sender
423{
424    Torrent * torrent;
425    NSEnumerator * enumerator = [fTorrents objectEnumerator];
426
427    float ratioLimit = [sender floatValue];
428    if (![[sender stringValue] isEqualToString:
429            [NSString stringWithFormat: @"%.2f", ratioLimit]]
430            || ratioLimit < 0)
431    {
432        NSBeep();
433        float ratioLimit = [[enumerator nextObject] ratioLimit]; //use first torrent
434        while ((torrent = [enumerator nextObject]))
435            if (ratioLimit != [torrent ratioLimit])
436            {
437                [sender setStringValue: @""];
438                return;
439            }
440       
441        [sender setFloatValue: ratioLimit];
442    }
443    else
444    {
445        while ((torrent = [enumerator nextObject]))
446            [torrent setRatioLimit: ratioLimit];
447    }
448}
449
450@end
Note: See TracBrowser for help on using the repository browser.