source: trunk/macosx/InfoWindowController.m @ 10371

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

move the code for remembering resize information for the info views into the individual views

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