source: trunk/macosx/InfoWindowController.m @ 10376

Last change on this file since 10376 was 10376, checked in by livings124, 12 years ago

simplify how the icons are set for the inspector tabs

  • Property svn:keywords set to Date Rev Author Id
File size: 17.7 KB
Line 
1/******************************************************************************
2 * $Id: InfoWindowController.m 10376 2010-03-14 15:03:14Z livings124 $
3 *
4 * Copyright (c) 2006-2010 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 "InfoViewController.h"
27#import "InfoGeneralViewController.h"
28#import "InfoActivityViewController.h"
29#import "InfoTrackersViewController.h"
30#import "InfoPeersViewController.h"
31#import "InfoFileViewController.h"
32#import "InfoOptionsViewController.h"
33#import "InfoTabButtonCell.h"
34#import "NSApplicationAdditions.h"
35#import "NSStringAdditions.h"
36#import "Torrent.h"
37
38#define TAB_INFO_IDENT @"Info"
39#define TAB_ACTIVITY_IDENT @"Activity"
40#define TAB_TRACKER_IDENT @"Tracker"
41#define TAB_PEERS_IDENT @"Peers"
42#define TAB_FILES_IDENT @"Files"
43#define TAB_OPTIONS_IDENT @"Options"
44
45#define TAB_MIN_HEIGHT 250
46
47#define INVALID -99
48
49typedef enum
50{
51    TAB_GENERAL_TAG = 0,
52    TAB_ACTIVITY_TAG = 1,
53    TAB_TRACKERS_TAG = 2,
54    TAB_PEERS_TAG = 3,
55    TAB_FILE_TAG = 4,
56    TAB_OPTIONS_TAG = 5
57} tabTag;
58
59@interface InfoWindowController (Private)
60
61- (void) resetInfo;
62- (void) resetInfoForTorrent: (NSNotification *) notification;
63
64@end
65
66@implementation InfoWindowController
67
68- (id) init
69{
70    self = [super initWithWindowNibName: @"InfoWindow"];
71    return self;
72}
73
74- (void) awakeFromNib
75{
76    //window location and size
77    NSPanel * window = (NSPanel *)[self window];
78   
79    const CGFloat windowHeight = NSHeight([window frame]);
80   
81    [window setFrameAutosaveName: @"InspectorWindow"];
82    [window setFrameUsingName: @"InspectorWindow"];
83   
84    NSRect windowRect = [window frame];
85    windowRect.origin.y -= windowHeight - NSHeight(windowRect);
86    windowRect.size.height = windowHeight;
87    [window setFrame: windowRect display: NO];
88   
89    [window setBecomesKeyOnlyIfNeeded: YES];
90   
91    //set tab tooltips
92    [fTabMatrix setToolTip: NSLocalizedString(@"General Info", "Inspector -> tab") forCell: [fTabMatrix cellWithTag: TAB_GENERAL_TAG]];
93    [fTabMatrix setToolTip: NSLocalizedString(@"Activity", "Inspector -> tab") forCell: [fTabMatrix cellWithTag: TAB_ACTIVITY_TAG]];
94    [fTabMatrix setToolTip: NSLocalizedString(@"Trackers", "Inspector -> tab") forCell: [fTabMatrix cellWithTag: TAB_TRACKERS_TAG]];
95    [fTabMatrix setToolTip: NSLocalizedString(@"Peers", "Inspector -> tab") forCell: [fTabMatrix cellWithTag: TAB_PEERS_TAG]];
96    [fTabMatrix setToolTip: NSLocalizedString(@"Files", "Inspector -> tab") forCell: [fTabMatrix cellWithTag: TAB_FILE_TAG]];
97    [fTabMatrix setToolTip: NSLocalizedString(@"Options", "Inspector -> tab") forCell: [fTabMatrix cellWithTag: TAB_OPTIONS_TAG]];
98   
99    //set selected tab
100    fCurrentTabTag = INVALID;
101    NSString * identifier = [[NSUserDefaults standardUserDefaults] stringForKey: @"InspectorSelected"];
102    NSInteger tag;
103    if ([identifier isEqualToString: TAB_INFO_IDENT])
104        tag = TAB_GENERAL_TAG;
105    else if ([identifier isEqualToString: TAB_ACTIVITY_IDENT])
106        tag = TAB_ACTIVITY_TAG;
107    else if ([identifier isEqualToString: TAB_TRACKER_IDENT])
108        tag = TAB_TRACKERS_TAG;
109    else if ([identifier isEqualToString: TAB_PEERS_IDENT])
110        tag = TAB_PEERS_TAG;
111    else if ([identifier isEqualToString: TAB_FILES_IDENT])
112        tag = TAB_FILE_TAG;
113    else if ([identifier isEqualToString: TAB_OPTIONS_IDENT])
114        tag = TAB_OPTIONS_TAG;
115    else //safety
116    {
117        [[NSUserDefaults standardUserDefaults] setObject: TAB_INFO_IDENT forKey: @"InspectorSelected"];
118        tag = TAB_GENERAL_TAG;
119    }
120    [fTabMatrix selectCellWithTag: tag];
121    [self setTab: nil];
122   
123    //set blank inspector
124    [self setInfoForTorrents: [NSArray array]];
125   
126    //allow for update notifications
127    NSNotificationCenter * nc = [NSNotificationCenter defaultCenter];
128    [nc addObserver: self selector: @selector(resetInfoForTorrent:) name: @"ResetInspector" object: nil];
129    [nc addObserver: self selector: @selector(updateInfoStats) name: @"UpdateStats" object: nil];
130    [nc addObserver: self selector: @selector(updateOptions) name: @"UpdateOptions" object: nil];
131}
132
133- (void) dealloc
134{
135    [[NSNotificationCenter defaultCenter] removeObserver: self];
136   
137    if ([fViewController respondsToSelector: @selector(saveViewSize)])
138        [fViewController saveViewSize];
139   
140    [fGeneralViewController dealloc];
141    [fActivityViewController dealloc];
142    [fTrackersViewController dealloc];
143    [fPeersViewController dealloc];
144    [fFileViewController dealloc];
145    [fOptionsViewController dealloc];
146   
147    [fTorrents release];
148   
149    [super dealloc];
150}
151
152- (void) setInfoForTorrents: (NSArray *) torrents
153{
154    if (fTorrents && [fTorrents isEqualToArray: torrents])
155        return;
156   
157    [fTorrents release];
158    fTorrents = [torrents retain];
159   
160    [self resetInfo];
161}
162
163- (NSRect) windowWillUseStandardFrame: (NSWindow *) window defaultFrame: (NSRect) defaultFrame
164{
165    NSRect windowRect = [window frame];
166    windowRect.size.width = [window minSize].width;
167    return windowRect;
168}
169
170- (NSSize) windowWillResize: (NSWindow *) window toSize: (NSSize) proposedFrameSize
171{
172    //this is an edge-case - just stop the animation
173    [fPeersViewController stopWebSeedAnimation];
174   
175    return proposedFrameSize;
176}
177
178- (void) windowWillClose: (NSNotification *) notification
179{
180    if ([NSApp isOnSnowLeopardOrBetter] && fCurrentTabTag == TAB_FILE_TAG
181        && ([QLPreviewPanelSL sharedPreviewPanelExists] && [[QLPreviewPanelSL sharedPreviewPanel] isVisible]))
182        [[QLPreviewPanelSL sharedPreviewPanel] reloadData];
183}
184
185- (void) setTab: (id) sender
186{
187    const NSInteger oldTabTag = fCurrentTabTag;
188    fCurrentTabTag = [fTabMatrix selectedTag];
189    if (fCurrentTabTag == oldTabTag)
190        return;
191   
192    //take care of old view
193    CGFloat oldHeight = 0;
194    if (oldTabTag != INVALID)
195    {
196        //deselect old tab item
197        [(InfoTabButtonCell *)[fTabMatrix cellWithTag: oldTabTag] setSelectedTab: NO];
198       
199        if ([fViewController respondsToSelector: @selector(saveViewSize)])
200            [fViewController saveViewSize];
201       
202        if ([fViewController respondsToSelector: @selector(clearView)])
203            [fViewController clearView];
204       
205        NSView * oldView = [fViewController view];
206        oldHeight = NSHeight([oldView frame]);
207       
208        //remove old view
209        [oldView removeFromSuperview];
210    }
211   
212    //set new tab item
213    NSString * identifier;
214    switch (fCurrentTabTag)
215    {
216        case TAB_GENERAL_TAG:
217            if (!fGeneralViewController)
218            {
219                fGeneralViewController = [[InfoGeneralViewController alloc] init];
220                [fGeneralViewController setInfoForTorrents: fTorrents];
221            }
222           
223            fViewController = fGeneralViewController;
224            identifier = TAB_INFO_IDENT;
225            break;
226        case TAB_ACTIVITY_TAG:
227            if (!fActivityViewController)
228            {
229                fActivityViewController = [[InfoActivityViewController alloc] init];
230                [fActivityViewController setInfoForTorrents: fTorrents];
231            }
232           
233            fViewController = fActivityViewController;
234            identifier = TAB_ACTIVITY_IDENT;
235            break;
236        case TAB_TRACKERS_TAG:
237            if (!fTrackersViewController)
238            {
239                fTrackersViewController = [[InfoTrackersViewController alloc] init];
240                [fTrackersViewController setInfoForTorrents: fTorrents];
241            }
242           
243            fViewController = fTrackersViewController;
244            identifier = TAB_TRACKER_IDENT;
245            break;
246        case TAB_PEERS_TAG:
247            if (!fPeersViewController)
248            {
249                fPeersViewController = [[InfoPeersViewController alloc] init];
250                [fPeersViewController setInfoForTorrents: fTorrents];
251            }
252           
253            fViewController = fPeersViewController;
254            identifier = TAB_PEERS_IDENT;
255            break;
256        case TAB_FILE_TAG:
257            if (!fFileViewController)
258            {
259                fFileViewController = [[InfoFileViewController alloc] init];
260                [fFileViewController setInfoForTorrents: fTorrents];
261            }
262           
263            fViewController = fFileViewController;
264            identifier = TAB_FILES_IDENT;
265            break;
266        case TAB_OPTIONS_TAG:
267            if (!fOptionsViewController)
268            {
269                fOptionsViewController = [[InfoOptionsViewController alloc] init];
270                [fOptionsViewController setInfoForTorrents: fTorrents];
271            }
272           
273            fViewController = fOptionsViewController;
274            identifier = TAB_OPTIONS_IDENT;
275            break;
276        default:
277            NSAssert1(NO, @"Unknown info tab selected: %d", fCurrentTabTag);
278            return;
279    }
280   
281    [[NSUserDefaults standardUserDefaults] setObject: identifier forKey: @"InspectorSelected"];
282   
283    NSWindow * window = [self window];
284   
285    [window setTitle: [NSString stringWithFormat: @"%@ - %@", [fViewController title],
286                        NSLocalizedString(@"Torrent Inspector", "Inspector -> title")]];
287   
288    //selected tab item
289    [(InfoTabButtonCell *)[fTabMatrix selectedCell] setSelectedTab: YES];
290   
291    NSView * view = [fViewController view];
292   
293    [fViewController updateInfo];
294   
295    NSRect windowRect = [window frame], viewRect = [view frame];
296   
297    CGFloat difference = (NSHeight(viewRect) - oldHeight) * [window userSpaceScaleFactor];
298    windowRect.origin.y -= difference;
299    windowRect.size.height += difference;
300   
301    if ([fViewController respondsToSelector: @selector(saveViewSize)]) //a little bit hacky, but avoids requiring an extra method
302    {
303        [window setMinSize: NSMakeSize([window minSize].width, NSHeight(windowRect) - NSHeight(viewRect) + TAB_MIN_HEIGHT)];
304        [window setMaxSize: NSMakeSize(FLT_MAX, FLT_MAX)];
305    }
306    else
307    {
308        [window setMinSize: NSMakeSize([window minSize].width, NSHeight(windowRect))];
309        [window setMaxSize: NSMakeSize(FLT_MAX, NSHeight(windowRect))];
310    }
311   
312    viewRect.size.width = NSWidth(windowRect);
313    [view setFrame: viewRect];
314   
315    [window setFrame: windowRect display: YES animate: oldTabTag != INVALID];
316    [[window contentView] addSubview: view];
317   
318    if ([NSApp isOnSnowLeopardOrBetter] && (fCurrentTabTag == TAB_FILE_TAG || oldTabTag == TAB_FILE_TAG)
319        && ([QLPreviewPanelSL sharedPreviewPanelExists] && [[QLPreviewPanelSL sharedPreviewPanel] isVisible]))
320        [[QLPreviewPanelSL sharedPreviewPanel] reloadData];
321}
322
323- (void) setNextTab
324{
325    NSInteger tag = [fTabMatrix selectedTag]+1;
326    if (tag >= [fTabMatrix numberOfColumns])
327        tag = 0;
328   
329    [fTabMatrix selectCellWithTag: tag];
330    [self setTab: nil];
331}
332
333- (void) setPreviousTab
334{
335    NSInteger tag = [fTabMatrix selectedTag]-1;
336    if (tag < 0)
337        tag = [fTabMatrix numberOfColumns]-1;
338   
339    [fTabMatrix selectCellWithTag: tag];
340    [self setTab: nil];
341}
342
343- (void) updateInfoStats
344{
345    [fViewController updateInfo];
346}
347
348- (void) updateOptions
349{
350    [fOptionsViewController updateOptions];
351}
352
353- (NSArray *) quickLookURLs
354{
355    return [fFileViewController quickLookURLs];
356}
357
358- (BOOL) canQuickLook
359{
360    if (fCurrentTabTag != TAB_FILE_TAG || ![[self window] isVisible] || ![NSApp isOnSnowLeopardOrBetter])
361        return NO;
362   
363    return [fFileViewController canQuickLook];
364}
365
366#warning uncomment (in header too)
367- (NSRect) quickLookSourceFrameForPreviewItem: (id /*<QLPreviewItem>*/) item
368{
369    return [fFileViewController quickLookSourceFrameForPreviewItem: item];
370}
371
372@end
373
374@implementation InfoWindowController (Private)
375
376- (void) resetInfo
377{
378    const NSUInteger numberSelected = [fTorrents count];
379    if (numberSelected != 1)
380    {
381        if (numberSelected > 0)
382        {
383            [fImageView setImage: [NSImage imageNamed: NSImageNameMultipleDocuments]];
384           
385            [fNameField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%d Torrents Selected",
386                                            "Inspector -> selected torrents"), numberSelected]];
387       
388            uint64_t size = 0;
389            NSUInteger fileCount = 0, magnetCount = 0;
390            for (Torrent * torrent in fTorrents)
391            {
392                size += [torrent size];
393                fileCount += [torrent fileCount];
394                if ([torrent isMagnet])
395                    ++magnetCount;
396            }
397           
398            NSMutableArray * fileStrings = [NSMutableArray arrayWithCapacity: 2];
399            if (fileCount > 0)
400            {
401                NSString * fileString;
402                if (fileCount == 1)
403                    fileString = NSLocalizedString(@"1 file", "Inspector -> selected torrents");
404                else
405                    fileString = [NSString stringWithFormat: NSLocalizedString(@"%d files", "Inspector -> selected torrents"), fileCount];
406                [fileStrings addObject: fileString];
407            }
408            if (magnetCount > 0)
409            {
410                NSString * magnetString;
411                if (magnetCount == 1)
412                    magnetString = NSLocalizedString(@"1 magnetized transfer", "Inspector -> selected torrents");
413                else
414                    magnetString = [NSString stringWithFormat: NSLocalizedString(@"%d magnetized transfers",
415                                    "Inspector -> selected torrents"), magnetCount];
416                [fileStrings addObject: magnetString];
417            }
418           
419            NSString * fileString = [fileStrings componentsJoinedByString: @" + "];
420           
421            if (magnetCount < numberSelected)
422            {
423                [fBasicInfoField setStringValue: [NSString stringWithFormat: @"%@, %@", fileString,
424                    [NSString stringWithFormat: NSLocalizedString(@"%@ total", "Inspector -> selected torrents"),
425                        [NSString stringForFileSize: size]]]];
426                [fBasicInfoField setToolTip: [NSString stringWithFormat: NSLocalizedString(@"%llu bytes",
427                                                "Inspector -> selected torrents"), size]];
428            }
429            else
430            {
431                [fBasicInfoField setStringValue: fileString];
432                [fBasicInfoField setToolTip: nil];
433            }
434        }
435        else
436        {
437            [fImageView setImage: [NSImage imageNamed: @"NSApplicationIcon"]];
438           
439            [fNameField setStringValue: NSLocalizedString(@"No Torrents Selected", "Inspector -> selected torrents")];
440            [fBasicInfoField setStringValue: @""];
441            [fBasicInfoField setToolTip: @""];
442        }
443       
444        [fNameField setToolTip: nil];
445    }
446    else
447    {
448        Torrent * torrent = [fTorrents objectAtIndex: 0];
449       
450        if ([NSApp isOnSnowLeopardOrBetter])
451            [fImageView setImage: [torrent icon]];
452        else
453        {
454            NSImage * icon = [[torrent icon] copy];
455            [icon setFlipped: NO];
456            [fImageView setImage: icon];
457            [icon release];
458        }
459       
460        NSString * name = [torrent name];
461        [fNameField setStringValue: name];
462        [fNameField setToolTip: name];
463       
464        if (![torrent isMagnet])
465        {
466            NSString * basicString = [NSString stringForFileSize: [torrent size]];
467            if ([torrent isFolder])
468            {
469                NSString * fileString;
470                const NSInteger fileCount = [torrent fileCount];
471                if (fileCount == 1)
472                    fileString = NSLocalizedString(@"1 file", "Inspector -> selected torrents");
473                else
474                    fileString= [NSString stringWithFormat: NSLocalizedString(@"%d files", "Inspector -> selected torrents"), fileCount];
475                basicString = [NSString stringWithFormat: @"%@, %@", fileString, basicString];
476            }
477            [fBasicInfoField setStringValue: basicString];
478            [fBasicInfoField setToolTip: [NSString stringWithFormat: NSLocalizedString(@"%llu bytes", "Inspector -> selected torrents"),
479                                            [torrent size]]];
480        }
481        else
482        {
483            [fBasicInfoField setStringValue: NSLocalizedString(@"Magnetized transfer", "Inspector -> selected torrents")];
484            [fBasicInfoField setToolTip: nil];
485        }
486    }
487   
488    [fGeneralViewController setInfoForTorrents: fTorrents];
489    [fActivityViewController setInfoForTorrents: fTorrents];
490    [fTrackersViewController setInfoForTorrents: fTorrents];
491    [fPeersViewController setInfoForTorrents: fTorrents];
492    [fFileViewController setInfoForTorrents: fTorrents];
493    [fOptionsViewController setInfoForTorrents: fTorrents];
494   
495    [fViewController updateInfo];
496}
497
498- (void) resetInfoForTorrent: (NSNotification *) notification
499{
500    if (fTorrents && [fTorrents containsObject: [notification object]])
501        [self resetInfo];
502}
503
504@end
Note: See TracBrowser for help on using the repository browser.