source: trunk/macosx/InfoWindowController.m @ 377

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

Might as well make size more precise.

  • Property svn:keywords set to Date Rev Author Id
File size: 14.8 KB
Line 
1/******************************************************************************
2 * $Id: InfoWindowController.m 377 2006-06-16 00:35:11Z 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 TAB_INFO_IDENT @"Info"
33#define TAB_STATUS_IDENT @"Status"
34#define TAB_OPTIONS_IDENT @"Options"
35#define TAB_FILES_IDENT @"Files"
36
37//15 spacing at the bottom of each tab
38#define TAB_INFO_HEIGHT 196.0
39#define TAB_STATUS_HEIGHT 262.0
40#define TAB_OPTIONS_HEIGHT 82.0
41#define TAB_FILES_HEIGHT 250.0
42
43@implementation InfoWindowController
44
45- (void) awakeFromNib
46{
47    fAppIcon = [[NSApp applicationIconImage] copy];
48   
49    fFiles = [[NSMutableArray alloc] initWithCapacity: 6];
50    [fFileTable setDoubleAction: @selector(revealFile:)];
51   
52    //window location and size
53    NSPanel * window = (NSPanel *)[self window];
54   
55    [window setBecomesKeyOnlyIfNeeded: YES];
56   
57    [window setFrameAutosaveName: @"InspectorWindowFrame"];
58    [window setFrameUsingName: @"InspectorWindowFrame" force: YES];
59   
60    NSRect frame = [window frame];
61    float difference = TAB_INFO_HEIGHT - [[[fTabView selectedTabViewItem]
62                                                    view] frame].size.height;
63    frame.origin.y -= difference;
64    frame.size.height += difference;
65    [window setFrame: frame display: YES];
66}
67
68- (void) dealloc
69{
70    if (fTorrents)
71        [fTorrents release];
72    [fFiles release];
73
74    [fAppIcon release];
75    [super dealloc];
76}
77
78- (void) updateInfoForTorrents: (NSArray *) torrents
79{
80    if (fTorrents)
81        [fTorrents release];
82    fTorrents = [torrents retain];
83
84    int numberSelected = [fTorrents count];
85    if (numberSelected != 1)
86    {
87        if (numberSelected > 0)
88        {
89            [fNameField setStringValue: [NSString stringWithFormat:
90                            @"%d Torrents Selected", numberSelected]];
91       
92            uint64_t size = 0;
93            NSEnumerator * enumerator = [torrents objectEnumerator];
94            Torrent * torrent;
95            while ((torrent = [enumerator nextObject]))
96                size += [torrent size];
97           
98            [fSizeField setStringValue: [[NSString stringForFileSize: size]
99                                stringByAppendingString: @" Total"]];
100        }
101        else
102        {
103            [fNameField setStringValue: @"No Torrents Selected"];
104            [fSizeField setStringValue: @""];
105           
106            [fDownloadRateField setStringValue: @""];
107            [fUploadRateField setStringValue: @""];
108           
109            [fDownloadedValidField setStringValue: @""];
110            [fDownloadedTotalField setStringValue: @""];
111            [fUploadedTotalField setStringValue: @""];
112        }
113       
114        [fImageView setImage: fAppIcon];
115       
116        [fNameField setToolTip: nil];
117
118        [fTrackerField setStringValue: @""];
119        [fTrackerField setToolTip: nil];
120        [fAnnounceField setStringValue: @""];
121        [fAnnounceField setToolTip: nil];
122        [fPieceSizeField setStringValue: @""];
123        [fPiecesField setStringValue: @""];
124        [fHashField setStringValue: @""];
125       
126        [fTorrentLocationField setStringValue: @""];
127        [fTorrentLocationField setToolTip: nil];
128        [fDataLocationField setStringValue: @""];
129        [fDataLocationField setToolTip: nil];
130        [fDateStartedField setStringValue: @""];
131       
132        [fStateField setStringValue: @""];
133        [fPercentField setStringValue: @""];
134        [fRatioField setStringValue: @""];
135       
136        [fSeedersField setStringValue: @""];
137        [fLeechersField setStringValue: @""];
138        [fConnectedPeersField setStringValue: @""];
139        [fDownloadingFromField setStringValue: @""];
140        [fUploadingToField setStringValue: @""];
141    }
142    else
143    {   
144        Torrent * torrent = [fTorrents objectAtIndex: 0];
145       
146        [fImageView setImage: [torrent icon]];
147       
148        NSString * name = [torrent name];
149        [fNameField setStringValue: name];
150        [fNameField setToolTip: name];
151        [fSizeField setStringValue: [NSString stringForFileSize: [torrent size]]];
152       
153        NSString * tracker = [torrent tracker], * announce = [torrent announce];
154        [fTrackerField setStringValue: tracker];
155        [fTrackerField setToolTip: tracker];
156        [fAnnounceField setStringValue: announce];
157        [fAnnounceField setToolTip: announce];
158        [fPieceSizeField setStringValue: [NSString stringForFileSize: [torrent pieceSize]]];
159        [fPiecesField setIntValue: [torrent pieceCount]];
160        [fHashField setStringValue: [torrent hashString]];
161       
162        [fTorrentLocationField setStringValue: [[torrent torrentLocation]
163                                        stringByAbbreviatingWithTildeInPath]];
164        [fTorrentLocationField setToolTip: [torrent torrentLocation]];
165        [fDataLocationField setStringValue: [[torrent dataLocation]
166                                        stringByAbbreviatingWithTildeInPath]];
167        [fDataLocationField setToolTip: [torrent dataLocation]];
168        [fDateStartedField setObjectValue: [torrent date]];
169    }
170    [self updateInfoStats];
171
172    //set file table
173    [fFiles removeAllObjects];
174   
175    Torrent * torrent;
176    NSEnumerator * enumerator = [fTorrents objectEnumerator];
177    while ((torrent = [enumerator nextObject]))
178        [fFiles addObjectsFromArray: [torrent fileList]];
179   
180    [fFileTable deselectAll: nil];
181    [fFileTable reloadData];
182   
183    //set ratio settings
184    if (numberSelected > 0)
185    {
186        NSEnumerator * enumerator = [fTorrents objectEnumerator];
187        Torrent * torrent = [enumerator nextObject]; //first torrent
188        const int INVALID = -99;
189        int ratioSetting = [torrent stopRatioSetting];
190        float ratioLimit = [torrent ratioLimit];
191       
192        while ((ratioSetting != INVALID || ratioLimit != INVALID)
193                && (torrent = [enumerator nextObject]))
194        {
195            if (ratioSetting != INVALID && ratioSetting != [torrent stopRatioSetting])
196                ratioSetting = INVALID;
197           
198            if (ratioLimit != INVALID && ratioLimit != [torrent ratioLimit])
199                ratioLimit = INVALID;
200        }
201       
202        [fRatioMatrix setEnabled: YES];
203       
204        if (ratioSetting == RATIO_CHECK)
205        {
206            [fRatioMatrix selectCellWithTag: RATIO_CHECK_TAG];
207            [fRatioLimitField setEnabled: YES];
208        }
209        else
210        {
211            if (ratioSetting == RATIO_NO_CHECK)
212                [fRatioMatrix selectCellWithTag: RATIO_NO_CHECK_TAG];
213            else if (ratioSetting == RATIO_GLOBAL)
214                [fRatioMatrix selectCellWithTag: RATIO_GLOBAL_TAG];
215            else
216                [fRatioMatrix deselectAllCells];
217           
218            [fRatioLimitField setEnabled: NO];
219        }
220       
221        if (ratioLimit != INVALID)
222            [fRatioLimitField setFloatValue: ratioLimit];
223        else
224            [fRatioLimitField setStringValue: @""];
225    }
226    else
227    {
228        [fRatioMatrix deselectAllCells];
229        [fRatioMatrix setEnabled: NO];
230       
231        [fRatioLimitField setEnabled: NO];
232        [fRatioLimitField setStringValue: @""];
233    }
234}
235
236- (void) updateInfoStats
237{
238    int numberSelected = [fTorrents count];
239    if (numberSelected > 0)
240    {
241        float downloadRate = 0, uploadRate = 0, downloadedValid;
242        uint64_t downloadedTotal = 0, uploadedTotal = 0;
243        Torrent * torrent;
244        NSEnumerator * enumerator = [fTorrents objectEnumerator];
245        while ((torrent = [enumerator nextObject]))
246        {
247            downloadRate += [torrent downloadRate];
248            uploadRate += [torrent uploadRate];
249           
250            downloadedValid += [torrent downloadedValid];
251            downloadedTotal += [torrent downloadedTotal];
252            uploadedTotal += [torrent uploadedTotal];
253        }
254       
255        [fDownloadRateField setStringValue: [NSString stringForSpeed: downloadRate]];
256        [fUploadRateField setStringValue: [NSString stringForSpeed: uploadRate]];
257       
258        [fDownloadedValidField setStringValue: [NSString stringForFileSize: downloadedValid]];
259        [fDownloadedTotalField setStringValue: [NSString stringForFileSize: downloadedTotal]];
260        [fUploadedTotalField setStringValue: [NSString stringForFileSize: uploadedTotal]];
261   
262        if (numberSelected == 1)
263        {
264            torrent = [fTorrents objectAtIndex: 0];
265           
266            [fStateField setStringValue: [torrent state]];
267            [fPercentField setStringValue: [NSString stringWithFormat:
268                                            @"%.2f%%", 100.0 * [torrent progress]]];
269
270            int seeders = [torrent seeders], leechers = [torrent leechers];
271            [fSeedersField setStringValue: seeders < 0 ?
272                @"N/A" : [NSString stringWithInt: seeders]];
273            [fLeechersField setStringValue: leechers < 0 ?
274                @"N/A" : [NSString stringWithInt: leechers]];
275           
276            BOOL active = [torrent isActive];
277           
278            [fConnectedPeersField setStringValue: active ? [NSString
279                    stringWithInt: [torrent totalPeers]] : @"N/A"];
280            [fDownloadingFromField setStringValue: active ? [NSString
281                    stringWithInt: [torrent peersUploading]] : @"N/A"];
282            [fUploadingToField setStringValue: active ? [NSString
283                    stringWithInt: [torrent peersDownloading]] : @"N/A"];
284           
285            [fRatioField setStringValue: [NSString stringForRatioWithDownload:
286                                        downloadedTotal upload: uploadedTotal]];
287        }
288    }
289}
290
291- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
292{
293    SEL action = [menuItem action];
294   
295    if (action == @selector(revealFile:))
296        return [fFileTable numberOfSelectedRows] > 0 &&
297            [[[fTabView selectedTabViewItem] identifier] isEqualToString: TAB_FILES_IDENT];
298       
299    return YES;
300}
301
302- (void) tabView: (NSTabView *) tabView didSelectTabViewItem: (NSTabViewItem *) tabViewItem
303{
304    NSWindow * window = [self window];
305    NSRect frame = [window frame];
306
307    float height;
308    NSString * identifier = [tabViewItem identifier];
309    if ([identifier isEqualToString: TAB_INFO_IDENT])
310        height = TAB_INFO_HEIGHT;
311    else if ([identifier isEqualToString: TAB_STATUS_IDENT])
312        height = TAB_STATUS_HEIGHT;
313    else if ([identifier isEqualToString: TAB_OPTIONS_IDENT])
314        height = TAB_OPTIONS_HEIGHT;
315    else
316        height = TAB_FILES_HEIGHT;
317   
318    NSView * view = [tabViewItem view];
319    float difference = height - [view frame].size.height;
320    frame.origin.y -= difference;
321    frame.size.height += difference;
322   
323    [view setHidden: YES];
324    [window setFrame: frame display: YES animate: YES];
325    [view setHidden: NO];
326}
327
328- (void) setNextTab
329{
330    if ([fTabView indexOfTabViewItem: [fTabView selectedTabViewItem]]
331                                    == [fTabView numberOfTabViewItems] - 1)
332        [fTabView selectFirstTabViewItem: nil];
333    else
334        [fTabView selectNextTabViewItem: nil];
335}
336
337- (void) setPreviousTab
338{
339    if ([fTabView indexOfTabViewItem: [fTabView selectedTabViewItem]] == 0)
340        [fTabView selectLastTabViewItem: nil];
341    else
342        [fTabView selectPreviousTabViewItem: nil];
343}
344
345- (int) numberOfRowsInTableView: (NSTableView *) tableView
346{
347    return [fFiles count];
348}
349
350- (id) tableView: (NSTableView *) tableView objectValueForTableColumn:
351                    (NSTableColumn *) column row: (int) row
352{
353    NSString * file = [fFiles objectAtIndex: row];
354    if ([[column identifier] isEqualToString: @"Icon"])
355        return [[NSWorkspace sharedWorkspace] iconForFileType: [file pathExtension]];
356    else
357        return [file lastPathComponent];
358}
359
360//only called on >= 10.4
361- (NSString *) tableView: (NSTableView *) tableView toolTipForCell: (NSCell *) cell
362        rect: (NSRectPointer) rect tableColumn: (NSTableColumn *) column
363        row: (int) row mouseLocation: (NSPoint) mouseLocation
364{
365    return [fFiles objectAtIndex: row];
366}
367
368- (void) revealFile: (id) sender
369{
370    NSIndexSet * indexSet = [fFileTable selectedRowIndexes];
371    unsigned int i;
372    for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
373        [[NSWorkspace sharedWorkspace] selectFile: [fFiles objectAtIndex: i]
374            inFileViewerRootedAtPath: nil];
375}
376
377- (void) setRatioCheck: (id) sender
378{
379    NSButtonCell * selected = [fRatioMatrix selectedCell];
380    int ratioSetting;
381    if (selected == [fRatioMatrix cellWithTag: RATIO_CHECK_TAG])
382        ratioSetting = RATIO_CHECK;
383    else if (selected == [fRatioMatrix cellWithTag: RATIO_NO_CHECK_TAG])
384        ratioSetting = RATIO_NO_CHECK;
385    else
386        ratioSetting = RATIO_GLOBAL;
387
388    Torrent * torrent;
389    NSEnumerator * enumerator = [fTorrents objectEnumerator];
390    while ((torrent = [enumerator nextObject]))
391        [torrent setStopRatioSetting: ratioSetting];
392   
393    [self setRatioLimit: fRatioLimitField];
394    [fRatioLimitField setEnabled: selected == [fRatioMatrix cellWithTag: RATIO_CHECK_TAG]];
395}
396
397- (void) setRatioLimit: (id) sender
398{
399    Torrent * torrent;
400    NSEnumerator * enumerator = [fTorrents objectEnumerator];
401
402    float ratioLimit = [sender floatValue];
403    if (![[sender stringValue] isEqualToString:
404            [NSString stringWithFormat: @"%.2f", ratioLimit]]
405            || ratioLimit < 0)
406    {
407        NSBeep();
408        float ratioLimit = [[enumerator nextObject] ratioLimit]; //use first torrent
409        while ((torrent = [enumerator nextObject]))
410            if (ratioLimit != [torrent ratioLimit])
411            {
412                [sender setStringValue: @""];
413                return;
414            }
415       
416        [sender setFloatValue: ratioLimit];
417    }
418    else
419    {
420        while ((torrent = [enumerator nextObject]))
421            [torrent setRatioLimit: ratioLimit];
422    }
423}
424
425@end
Note: See TracBrowser for help on using the repository browser.