source: trunk/macosx/StatsWindowController.m

Last change on this file was 14662, checked in by mikedld, 6 years ago

#6042: Remove dead code now that we build for OS X 10.7+ (patch by mattrajca)

In addition to the patch,

  • remove unused global actions menu (popover is used instead)
  • remove *Lion class macros, use NSPopover and NSDataDetector directly
  • Property svn:keywords set to Date Rev Author Id
File size: 10.6 KB
Line 
1/******************************************************************************
2 * $Id: StatsWindowController.m 14662 2016-01-06 11:05:37Z mikedld $
3 *
4 * Copyright (c) 2007-2012 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 "StatsWindowController.h"
26#import "Controller.h"
27#import "NSApplicationAdditions.h"
28#import "NSStringAdditions.h"
29
30#define UPDATE_SECONDS 1.0
31
32@interface StatsWindowController (Private)
33
34- (void) updateStats;
35
36- (void) performResetStats;
37- (void) resetSheetClosed: (NSAlert *) alert returnCode: (NSInteger) code contextInfo: (void *) info;
38
39@end
40
41@implementation StatsWindowController
42
43StatsWindowController * fStatsWindowInstance = nil;
44tr_session * fLib = NULL;
45+ (StatsWindowController *) statsWindow
46{
47    if (!fStatsWindowInstance)
48    {
49        if ((fStatsWindowInstance = [[self alloc] init]))
50        {
51            fLib = [(Controller *)[NSApp delegate] sessionHandle];
52        }
53    }
54    return fStatsWindowInstance;
55}
56
57- (id) init
58{
59    return [super initWithWindowNibName: @"StatsWindow"];
60}
61
62- (void) awakeFromNib
63{
64    [self updateStats];
65   
66    fTimer = [[NSTimer scheduledTimerWithTimeInterval: UPDATE_SECONDS target: self selector: @selector(updateStats) userInfo: nil repeats: YES] retain];
67    [[NSRunLoop currentRunLoop] addTimer: fTimer forMode: NSModalPanelRunLoopMode];
68    [[NSRunLoop currentRunLoop] addTimer: fTimer forMode: NSEventTrackingRunLoopMode];
69
70    [[self window] setRestorationClass: [self class]];
71   
72    [[self window] setTitle: NSLocalizedString(@"Statistics", "Stats window -> title")];
73   
74    //set label text
75    [fUploadedLabelField setStringValue: [NSLocalizedString(@"Uploaded", "Stats window -> label") stringByAppendingString: @":"]];
76    [fDownloadedLabelField setStringValue: [NSLocalizedString(@"Downloaded", "Stats window -> label") stringByAppendingString: @":"]];
77    [fRatioLabelField setStringValue: [NSLocalizedString(@"Ratio", "Stats window -> label") stringByAppendingString: @":"]];
78    [fTimeLabelField setStringValue: [NSLocalizedString(@"Running Time", "Stats window -> label") stringByAppendingString: @":"]];
79    [fNumOpenedLabelField setStringValue: [NSLocalizedString(@"Program Started", "Stats window -> label") stringByAppendingString: @":"]];
80   
81    //size of all labels
82    const CGFloat oldWidth = [fUploadedLabelField frame].size.width;
83   
84    NSArray * labels = @[fUploadedLabelField, fDownloadedLabelField, fRatioLabelField, fTimeLabelField, fNumOpenedLabelField];
85   
86    CGFloat maxWidth = CGFLOAT_MIN;
87    for (NSTextField * label in labels)
88    {
89        [label sizeToFit];
90       
91        const CGFloat width = [label frame].size.width;
92        maxWidth = MAX(maxWidth, width);
93    }
94   
95    for (NSTextField * label in labels)
96    {
97        NSRect frame = [label frame];
98        frame.size.width = maxWidth;
99        [label setFrame: frame];
100    }
101   
102    //resize window for new label width - fields are set in nib to adjust correctly
103    NSRect windowRect = [[self window] frame];
104    windowRect.size.width += maxWidth - oldWidth;
105    [[self window] setFrame: windowRect display: YES];
106   
107    //resize reset button
108    const CGFloat oldButtonWidth = [fResetButton frame].size.width;
109   
110    [fResetButton setTitle: NSLocalizedString(@"Reset", "Stats window -> reset button")];
111    [fResetButton sizeToFit];
112   
113    NSRect buttonFrame = [fResetButton frame];
114    buttonFrame.size.width += 10.0;
115    buttonFrame.origin.x -= buttonFrame.size.width - oldButtonWidth;
116    [fResetButton setFrame: buttonFrame];
117}
118
119- (void) windowWillClose: (id) sender
120{
121    [fTimer invalidate];
122    [fTimer release];
123    fTimer = nil;
124   
125    [fStatsWindowInstance autorelease];
126    fStatsWindowInstance = nil;
127}
128
129+ (void) restoreWindowWithIdentifier: (NSString *) identifier state: (NSCoder *) state completionHandler: (void (^)(NSWindow *, NSError *)) completionHandler
130{
131    NSAssert1([identifier isEqualToString: @"StatsWindow"], @"Trying to restore unexpected identifier %@", identifier);
132   
133    completionHandler([[StatsWindowController statsWindow] window], nil);
134}
135
136- (void) resetStats: (id) sender
137{
138    if (![[NSUserDefaults standardUserDefaults] boolForKey: @"WarningResetStats"])
139    {
140        [self performResetStats];
141        return;
142    }
143   
144    NSAlert * alert = [[NSAlert alloc] init];
145    [alert setMessageText: NSLocalizedString(@"Are you sure you want to reset usage statistics?", "Stats reset -> title")];
146    [alert setInformativeText: NSLocalizedString(@"This will clear the global statistics displayed by Transmission."
147                                " Individual transfer statistics will not be affected.", "Stats reset -> message")];
148    [alert setAlertStyle: NSWarningAlertStyle];
149    [alert addButtonWithTitle: NSLocalizedString(@"Reset", "Stats reset -> button")];
150    [alert addButtonWithTitle: NSLocalizedString(@"Cancel", "Stats reset -> button")];
151    [alert setShowsSuppressionButton: YES];
152   
153    [alert beginSheetModalForWindow: [self window] modalDelegate: self
154        didEndSelector: @selector(resetSheetClosed:returnCode:contextInfo:) contextInfo: nil];
155}
156
157- (NSString *) windowFrameAutosaveName
158{
159    return @"StatsWindow";
160}
161
162@end
163
164@implementation StatsWindowController (Private)
165
166- (void) updateStats
167{
168    tr_session_stats statsAll, statsSession;
169    tr_sessionGetCumulativeStats(fLib, &statsAll);
170    tr_sessionGetStats(fLib, &statsSession);
171   
172    NSByteCountFormatter * byteFormatter = nil;
173    if ([NSApp isOnMountainLionOrBetter])
174    {
175        byteFormatter = [[NSByteCountFormatterMtLion alloc] init];
176        [byteFormatter setAllowedUnits: NSByteCountFormatterUseBytes];
177    }
178   
179    [fUploadedField setStringValue: [NSString stringForFileSize: statsSession.uploadedBytes]];
180    [fUploadedField setToolTip: [NSApp isOnMountainLionOrBetter] ? [byteFormatter stringFromByteCount: statsSession.uploadedBytes] : [NSString stringWithFormat: NSLocalizedString(@"%@ bytes", "stats -> bytes"), [NSString formattedUInteger: statsSession.uploadedBytes]]];
181    [fUploadedAllField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%@ total", "stats total"), [NSString stringForFileSize: statsAll.uploadedBytes]]];
182    [fUploadedAllField setToolTip: [NSApp isOnMountainLionOrBetter] ? [byteFormatter stringFromByteCount: statsAll.uploadedBytes] : [NSString stringWithFormat: NSLocalizedString(@"%@ bytes", "stats -> bytes"), [NSString formattedUInteger: statsAll.uploadedBytes]]];
183   
184    [fDownloadedField setStringValue: [NSString stringForFileSize: statsSession.downloadedBytes]];
185    [fDownloadedField setToolTip: [NSApp isOnMountainLionOrBetter] ? [byteFormatter stringFromByteCount: statsSession.downloadedBytes] : [NSString stringWithFormat: NSLocalizedString(@"%@ bytes", "stats -> bytes"), [NSString formattedUInteger: statsSession.downloadedBytes]]];
186    [fDownloadedAllField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%@ total", "stats total"), [NSString stringForFileSize: statsAll.downloadedBytes]]];
187    [fDownloadedAllField setToolTip: [NSApp isOnMountainLionOrBetter] ? [byteFormatter stringFromByteCount: statsAll.downloadedBytes] : [NSString stringWithFormat: NSLocalizedString(@"%@ bytes", "stats -> bytes"), [NSString formattedUInteger: statsAll.downloadedBytes]]];
188   
189    [byteFormatter release];
190   
191    [fRatioField setStringValue: [NSString stringForRatio: statsSession.ratio]];
192   
193    NSString * totalRatioString = statsAll.ratio != TR_RATIO_NA
194        ? [NSString stringWithFormat: NSLocalizedString(@"%@ total", "stats total"), [NSString stringForRatio: statsAll.ratio]]
195        : NSLocalizedString(@"Total N/A", "stats total");
196    [fRatioAllField setStringValue: totalRatioString];
197   
198    if ([NSApp isOnYosemiteOrBetter]) {
199        static NSDateComponentsFormatter *timeFormatter;
200        static dispatch_once_t onceToken;
201        dispatch_once(&onceToken, ^{
202            timeFormatter = [NSDateComponentsFormatter new];
203            timeFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;
204            timeFormatter.maximumUnitCount = 3;
205            timeFormatter.allowedUnits = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitWeekOfMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute;
206        });
207       
208        [fTimeField setStringValue: [timeFormatter stringFromTimeInterval:statsSession.secondsActive]];
209        [fTimeAllField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%@ total", "stats total"), [timeFormatter stringFromTimeInterval:statsAll.secondsActive]]];
210    }
211    else {
212        [fTimeField setStringValue: [NSString timeString: statsSession.secondsActive includesTimeRemainingPhrase:NO showSeconds: NO]];
213        [fTimeAllField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%@ total", "stats total"), [NSString timeString: statsAll.secondsActive includesTimeRemainingPhrase:NO showSeconds: NO]]];
214    }
215   
216    if (statsAll.sessionCount == 1)
217        [fNumOpenedField setStringValue: NSLocalizedString(@"1 time", "stats window -> times opened")];
218    else
219        [fNumOpenedField setStringValue: [NSString stringWithFormat: NSLocalizedString(@"%@ times", "stats window -> times opened"), [NSString formattedUInteger: statsAll.sessionCount]]];
220}
221
222- (void) performResetStats
223{
224    tr_sessionClearStats(fLib);
225    [self updateStats];
226}
227
228- (void) resetSheetClosed: (NSAlert *) alert returnCode: (NSInteger) code contextInfo: (void *) info
229{
230    [[alert window] orderOut: nil];
231   
232    if ([[alert suppressionButton] state] == NSOnState)
233        [[NSUserDefaults standardUserDefaults] setBool: NO forKey: @"WarningResetStats"];
234   
235    if (code == NSAlertFirstButtonReturn)
236        [self performResetStats];
237}
238
239@end
Note: See TracBrowser for help on using the repository browser.