~ubuntu-branches/ubuntu/maverick/transmission/maverick

« back to all changes in this revision

Viewing changes to macosx/InfoWindowController.m

  • Committer: Bazaar Package Importer
  • Author(s): Philipp Benner
  • Date: 2006-08-29 20:50:41 UTC
  • Revision ID: james.westby@ubuntu.com-20060829205041-mzhpiqksdf7pbk17
Tags: upstream-0.6.1.dfsg
ImportĀ upstreamĀ versionĀ 0.6.1.dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 * $Id: InfoWindowController.m 431 2006-06-22 02:51:59Z 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_ACTIVITY_IDENT @"Activity"
 
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_ACTIVITY_HEIGHT 199.0
 
43
#define TAB_OPTIONS_HEIGHT 82.0
 
44
#define TAB_FILES_HEIGHT 250.0
 
45
 
 
46
@interface InfoWindowController (Private)
 
47
 
 
48
- (void) setWindowForTab: (NSString *) identifier animate: (BOOL) animate;
 
49
 
 
50
@end
 
51
 
 
52
@implementation InfoWindowController
 
53
 
 
54
- (void) awakeFromNib
 
55
{
 
56
    fAppIcon = [[NSApp applicationIconImage] copy];
 
57
    
 
58
    fTorrents = [[NSArray alloc] init];
 
59
    fFiles = [[NSMutableArray alloc] initWithCapacity: 6];
 
60
    [fFileTable setDoubleAction: @selector(revealFile:)];
 
61
    
 
62
    //window location and size
 
63
    NSPanel * window = (NSPanel *)[self window];
 
64
    
 
65
    [window setBecomesKeyOnlyIfNeeded: YES];
 
66
    
 
67
    [window setFrameAutosaveName: @"InspectorWindowFrame"];
 
68
    [window setFrameUsingName: @"InspectorWindowFrame"];
 
69
    
 
70
    NSString * identifier = [[NSUserDefaults standardUserDefaults] stringForKey: @"InfoTab"];
 
71
    [fTabView selectTabViewItemWithIdentifier: identifier];
 
72
    [self setWindowForTab: identifier animate: NO];
 
73
}
 
74
 
 
75
- (void) dealloc
 
76
{
 
77
    [fTorrents release];
 
78
    [fFiles release];
 
79
 
 
80
    [fAppIcon release];
 
81
    [super dealloc];
 
82
}
 
83
 
 
84
- (void) updateInfoForTorrents: (NSArray *) torrents
 
85
{
 
86
    [fTorrents release];
 
87
    fTorrents = [torrents retain];
 
88
 
 
89
    int numberSelected = [fTorrents count];
 
90
    if (numberSelected != 1)
 
91
    {
 
92
        if (numberSelected > 0)
 
93
        {
 
94
            [fNameField setStringValue: [NSString stringWithFormat:
 
95
                            @"%d Torrents Selected", numberSelected]];
 
96
        
 
97
            uint64_t size = 0;
 
98
            NSEnumerator * enumerator = [torrents objectEnumerator];
 
99
            Torrent * torrent;
 
100
            while ((torrent = [enumerator nextObject]))
 
101
                size += [torrent size];
 
102
            
 
103
            [fSizeField setStringValue: [[NSString stringForFileSize: size]
 
104
                                stringByAppendingString: @" Total"]];
 
105
        }
 
106
        else
 
107
        {
 
108
            [fNameField setStringValue: @"No Torrents Selected"];
 
109
            [fSizeField setStringValue: @""];
 
110
            
 
111
/*
 
112
            [fDownloadRateField setStringValue: @""];
 
113
            [fUploadRateField setStringValue: @""];
 
114
*/
 
115
            [fDownloadedValidField setStringValue: @""];
 
116
            [fDownloadedTotalField setStringValue: @""];
 
117
            [fUploadedTotalField setStringValue: @""];
 
118
        }
 
119
        
 
120
        [fImageView setImage: fAppIcon];
 
121
        
 
122
        [fNameField setToolTip: nil];
 
123
 
 
124
        [fTrackerField setStringValue: @""];
 
125
        [fTrackerField setToolTip: nil];
 
126
        [fAnnounceField setStringValue: @""];
 
127
        [fAnnounceField setToolTip: nil];
 
128
        [fPieceSizeField setStringValue: @""];
 
129
        [fPiecesField setStringValue: @""];
 
130
        [fHashField setStringValue: @""];
 
131
        [fHashField setToolTip: nil];
 
132
        
 
133
        [fTorrentLocationField setStringValue: @""];
 
134
        [fTorrentLocationField setToolTip: nil];
 
135
        [fDataLocationField setStringValue: @""];
 
136
        [fDataLocationField setToolTip: nil];
 
137
        [fDateStartedField setStringValue: @""];
 
138
        
 
139
/*
 
140
        [fStateField setStringValue: @""];
 
141
        [fPercentField setStringValue: @""];
 
142
*/
 
143
        [fRatioField setStringValue: @""];
 
144
        
 
145
        [fSeedersField setStringValue: @""];
 
146
        [fLeechersField setStringValue: @""];
 
147
        [fConnectedPeersField setStringValue: @""];
 
148
        [fDownloadingFromField setStringValue: @""];
 
149
        [fUploadingToField setStringValue: @""];
 
150
    }
 
151
    else
 
152
    {    
 
153
        Torrent * torrent = [fTorrents objectAtIndex: 0];
 
154
        
 
155
        [fImageView setImage: [torrent icon]];
 
156
        
 
157
        NSString * name = [torrent name];
 
158
        [fNameField setStringValue: name];
 
159
        [fNameField setToolTip: name];
 
160
        [fSizeField setStringValue: [NSString stringForFileSize: [torrent size]]];
 
161
        
 
162
        NSString * tracker = [torrent tracker],
 
163
                * announce = [torrent announce],
 
164
                * hashString = [torrent hashString];
 
165
        [fTrackerField setStringValue: tracker];
 
166
        [fTrackerField setToolTip: tracker];
 
167
        [fAnnounceField setStringValue: announce];
 
168
        [fAnnounceField setToolTip: announce];
 
169
        [fPieceSizeField setStringValue: [NSString stringForFileSize: [torrent pieceSize]]];
 
170
        [fPiecesField setIntValue: [torrent pieceCount]];
 
171
        [fHashField setStringValue: hashString];
 
172
        [fHashField setToolTip: hashString];
 
173
        
 
174
        [fTorrentLocationField setStringValue: [torrent torrentLocationString]];
 
175
        [fTorrentLocationField setToolTip: [torrent torrentLocation]];
 
176
        [fDataLocationField setStringValue: [[torrent dataLocation] 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;
 
252
        float downloadedValid = 0;
 
253
        uint64_t downloadedTotal = 0, uploadedTotal = 0;
 
254
        Torrent * torrent;
 
255
        NSEnumerator * enumerator = [fTorrents objectEnumerator];
 
256
        while ((torrent = [enumerator nextObject]))
 
257
        {
 
258
            /*downloadRate += [torrent downloadRate];
 
259
            uploadRate += [torrent uploadRate];
 
260
            */
 
261
            downloadedValid += [torrent downloadedValid];
 
262
            downloadedTotal += [torrent downloadedTotal];
 
263
            uploadedTotal += [torrent uploadedTotal];
 
264
        }
 
265
/*
 
266
        [fDownloadRateField setStringValue: [NSString stringForSpeed: downloadRate]];
 
267
        [fUploadRateField setStringValue: [NSString stringForSpeed: uploadRate]];
 
268
*/
 
269
        [fDownloadedValidField setStringValue: [NSString stringForFileSize: downloadedValid]];
 
270
        [fDownloadedTotalField setStringValue: [NSString stringForFileSize: downloadedTotal]];
 
271
        [fUploadedTotalField setStringValue: [NSString stringForFileSize: uploadedTotal]];
 
272
    
 
273
        if (numberSelected == 1)
 
274
        {
 
275
            torrent = [fTorrents objectAtIndex: 0];
 
276
/*
 
277
            [fStateField setStringValue: [torrent state]];
 
278
            [fPercentField setStringValue: [NSString stringWithFormat:
 
279
                                            @"%.2f%%", 100.0 * [torrent progress]]];
 
280
*/
 
281
            int seeders = [torrent seeders], leechers = [torrent leechers];
 
282
            [fSeedersField setStringValue: seeders < 0 ?
 
283
                @"N/A" : [NSString stringWithInt: seeders]];
 
284
            [fLeechersField setStringValue: leechers < 0 ?
 
285
                @"N/A" : [NSString stringWithInt: leechers]];
 
286
            
 
287
            BOOL active = [torrent isActive];
 
288
            
 
289
            [fConnectedPeersField setStringValue: active ? [NSString
 
290
                    stringWithInt: [torrent totalPeers]] : @"N/A"];
 
291
            [fDownloadingFromField setStringValue: active ? [NSString
 
292
                    stringWithInt: [torrent peersUploading]] : @"N/A"];
 
293
            [fUploadingToField setStringValue: active ? [NSString
 
294
                    stringWithInt: [torrent peersDownloading]] : @"N/A"];
 
295
            
 
296
            [fRatioField setStringValue: [NSString stringForRatioWithDownload:
 
297
                                        downloadedTotal upload: uploadedTotal]];
 
298
        }
 
299
    }
 
300
}
 
301
 
 
302
- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
 
303
{
 
304
    SEL action = [menuItem action];
 
305
    
 
306
    if (action == @selector(revealFile:))
 
307
        return [fFileTable numberOfSelectedRows] > 0 &&
 
308
            [[[fTabView selectedTabViewItem] identifier] isEqualToString: TAB_FILES_IDENT];
 
309
        
 
310
    return YES;
 
311
}
 
312
 
 
313
- (NSRect) windowWillUseStandardFrame: (NSWindow *) window defaultFrame: (NSRect) defaultFrame
 
314
{
 
315
    NSRect windowRect = [window frame];
 
316
    windowRect.size.width = [window minSize].width;    
 
317
    return windowRect;
 
318
}
 
319
 
 
320
- (void) tabView: (NSTabView *) tabView didSelectTabViewItem: (NSTabViewItem *) tabViewItem
 
321
{
 
322
    NSString * identifier = [tabViewItem identifier];
 
323
    [self setWindowForTab: identifier animate: YES];
 
324
    [[NSUserDefaults standardUserDefaults] setObject: identifier forKey: @"InfoTab"];
 
325
}
 
326
 
 
327
- (void) setWindowForTab: (NSString *) identifier animate: (BOOL) animate
 
328
{
 
329
    float height;
 
330
    if ([identifier isEqualToString: TAB_ACTIVITY_IDENT])
 
331
        height = TAB_ACTIVITY_HEIGHT;
 
332
    else if ([identifier isEqualToString: TAB_OPTIONS_IDENT])
 
333
        height = TAB_OPTIONS_HEIGHT;
 
334
    else if ([identifier isEqualToString: TAB_FILES_IDENT])
 
335
        height = TAB_FILES_HEIGHT;
 
336
    else
 
337
        height = TAB_INFO_HEIGHT;
 
338
    
 
339
    NSWindow * window = [self window];
 
340
    NSRect frame = [window frame];
 
341
    NSView * view = [[fTabView selectedTabViewItem] view];
 
342
    
 
343
    float difference = height - [view frame].size.height;
 
344
    frame.origin.y -= difference;
 
345
    frame.size.height += difference;
 
346
    
 
347
    if (animate)
 
348
    {
 
349
        [view setHidden: YES];
 
350
        [window setFrame: frame display: YES animate: YES];
 
351
        [view setHidden: NO];
 
352
    }
 
353
    else
 
354
        [window setFrame: frame display: YES];
 
355
    
 
356
    [window setMinSize: NSMakeSize(MIN_WINDOW_WIDTH, frame.size.height)];
 
357
    [window setMaxSize: NSMakeSize(MAX_WINDOW_WIDTH, frame.size.height)];
 
358
}
 
359
 
 
360
- (void) setNextTab
 
361
{
 
362
    if ([fTabView indexOfTabViewItem: [fTabView selectedTabViewItem]]
 
363
                                    == [fTabView numberOfTabViewItems] - 1)
 
364
        [fTabView selectFirstTabViewItem: nil];
 
365
    else
 
366
        [fTabView selectNextTabViewItem: nil];
 
367
}
 
368
 
 
369
- (void) setPreviousTab
 
370
{
 
371
    if ([fTabView indexOfTabViewItem: [fTabView selectedTabViewItem]] == 0)
 
372
        [fTabView selectLastTabViewItem: nil];
 
373
    else
 
374
        [fTabView selectPreviousTabViewItem: nil];
 
375
}
 
376
 
 
377
- (int) numberOfRowsInTableView: (NSTableView *) tableView
 
378
{
 
379
    return [fFiles count];
 
380
}
 
381
 
 
382
- (id) tableView: (NSTableView *) tableView objectValueForTableColumn:
 
383
                    (NSTableColumn *) column row: (int) row
 
384
{
 
385
    NSString * file = [fFiles objectAtIndex: row];
 
386
    if ([[column identifier] isEqualToString: @"Icon"])
 
387
        return [[NSWorkspace sharedWorkspace] iconForFileType: [file pathExtension]];
 
388
    else
 
389
        return [file lastPathComponent];
 
390
}
 
391
 
 
392
//only called on >= 10.4
 
393
- (NSString *) tableView: (NSTableView *) tableView toolTipForCell: (NSCell *) cell
 
394
        rect: (NSRectPointer) rect tableColumn: (NSTableColumn *) column
 
395
        row: (int) row mouseLocation: (NSPoint) mouseLocation
 
396
{
 
397
    return [fFiles objectAtIndex: row];
 
398
}
 
399
 
 
400
- (void) revealFile: (id) sender
 
401
{
 
402
    NSIndexSet * indexSet = [fFileTable selectedRowIndexes];
 
403
    unsigned int i;
 
404
    for (i = [indexSet firstIndex]; i != NSNotFound; i = [indexSet indexGreaterThanIndex: i])
 
405
        [[NSWorkspace sharedWorkspace] selectFile: [fFiles objectAtIndex: i]
 
406
            inFileViewerRootedAtPath: nil];
 
407
}
 
408
 
 
409
- (void) setRatioCheck: (id) sender
 
410
{
 
411
    NSButtonCell * selected = [fRatioMatrix selectedCell];
 
412
    int ratioSetting;
 
413
    if (selected == [fRatioMatrix cellWithTag: RATIO_CHECK_TAG])
 
414
        ratioSetting = RATIO_CHECK;
 
415
    else if (selected == [fRatioMatrix cellWithTag: RATIO_NO_CHECK_TAG])
 
416
        ratioSetting = RATIO_NO_CHECK;
 
417
    else
 
418
        ratioSetting = RATIO_GLOBAL;
 
419
 
 
420
    Torrent * torrent;
 
421
    NSEnumerator * enumerator = [fTorrents objectEnumerator];
 
422
    while ((torrent = [enumerator nextObject]))
 
423
        [torrent setStopRatioSetting: ratioSetting];
 
424
    
 
425
    [self setRatioLimit: fRatioLimitField];
 
426
    [fRatioLimitField setEnabled: selected == [fRatioMatrix cellWithTag: RATIO_CHECK_TAG]];
 
427
}
 
428
 
 
429
- (void) setRatioLimit: (id) sender
 
430
{
 
431
    Torrent * torrent;
 
432
    NSEnumerator * enumerator = [fTorrents objectEnumerator];
 
433
 
 
434
    float ratioLimit = [sender floatValue];
 
435
    if (![[sender stringValue] isEqualToString: [NSString stringWithFormat: @"%.2f", ratioLimit]]
 
436
            || ratioLimit < 0)
 
437
    {
 
438
        NSBeep();
 
439
        float ratioLimit = [[enumerator nextObject] ratioLimit]; //use first torrent
 
440
        while ((torrent = [enumerator nextObject]))
 
441
            if (ratioLimit != [torrent ratioLimit])
 
442
            {
 
443
                [sender setStringValue: @""];
 
444
                return;
 
445
            }
 
446
        
 
447
        [sender setFloatValue: ratioLimit];
 
448
    }
 
449
    else
 
450
    {
 
451
        while ((torrent = [enumerator nextObject]))
 
452
            [torrent setRatioLimit: ratioLimit];
 
453
    }
 
454
}
 
455
 
 
456
@end