transmission/macosx/StatusBarController.m

265 lines
9.6 KiB
Objective-C

/******************************************************************************
* Copyright (c) 2011-2012 Transmission authors and contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
#include <libtransmission/transmission.h>
#import "StatusBarController.h"
#import "NSStringAdditions.h"
#define STATUS_RATIO_TOTAL @"RatioTotal"
#define STATUS_RATIO_SESSION @"RatioSession"
#define STATUS_TRANSFER_TOTAL @"TransferTotal"
#define STATUS_TRANSFER_SESSION @"TransferSession"
typedef NS_ENUM(unsigned int, statusTag) {
STATUS_RATIO_TOTAL_TAG = 0,
STATUS_RATIO_SESSION_TAG = 1,
STATUS_TRANSFER_TOTAL_TAG = 2,
STATUS_TRANSFER_SESSION_TAG = 3
};
@interface StatusBarController (Private)
- (void) resizeStatusButton;
@end
@implementation StatusBarController
- (instancetype) initWithLib: (tr_session *) lib
{
if ((self = [super initWithNibName: @"StatusBar" bundle: nil]))
{
fLib = lib;
fPreviousDownloadRate = -1.0;
fPreviousUploadRate = -1.0;
}
return self;
}
- (void) awakeFromNib
{
//localize menu items
[fStatusButton.menu itemWithTag: STATUS_RATIO_TOTAL_TAG].title = NSLocalizedString(@"Total Ratio",
"Status Bar -> status menu");
[fStatusButton.menu itemWithTag: STATUS_RATIO_SESSION_TAG].title = NSLocalizedString(@"Session Ratio",
"Status Bar -> status menu");
[fStatusButton.menu itemWithTag: STATUS_TRANSFER_TOTAL_TAG].title = NSLocalizedString(@"Total Transfer",
"Status Bar -> status menu");
[fStatusButton.menu itemWithTag: STATUS_TRANSFER_SESSION_TAG].title = NSLocalizedString(@"Session Transfer",
"Status Bar -> status menu");
fStatusButton.cell.backgroundStyle = NSBackgroundStyleRaised;
fTotalDLField.cell.backgroundStyle = NSBackgroundStyleRaised;
fTotalULField.cell.backgroundStyle = NSBackgroundStyleRaised;
fTotalDLImageView.cell.backgroundStyle = NSBackgroundStyleRaised;
fTotalULImageView.cell.backgroundStyle = NSBackgroundStyleRaised;
[self updateSpeedFieldsToolTips];
//update when speed limits are changed
[NSNotificationCenter.defaultCenter addObserver: self selector: @selector(updateSpeedFieldsToolTips)
name: @"SpeedLimitUpdate" object: nil];
[NSNotificationCenter.defaultCenter addObserver: self selector: @selector(resizeStatusButton)
name: NSWindowDidResizeNotification object: self.view.window];
}
- (void) dealloc
{
[NSNotificationCenter.defaultCenter removeObserver: self];
}
- (void) updateWithDownload: (CGFloat) dlRate upload: (CGFloat) ulRate
{
//set rates
if (dlRate != fPreviousDownloadRate)
{
fTotalDLField.stringValue = [NSString stringForSpeed: dlRate];
fPreviousDownloadRate = dlRate;
}
if (ulRate != fPreviousUploadRate)
{
fTotalULField.stringValue = [NSString stringForSpeed: ulRate];
fPreviousUploadRate = ulRate;
}
//set status button text
NSString * statusLabel = [NSUserDefaults.standardUserDefaults stringForKey: @"StatusLabel"], * statusString;
BOOL total;
if ((total = [statusLabel isEqualToString: STATUS_RATIO_TOTAL]) || [statusLabel isEqualToString: STATUS_RATIO_SESSION])
{
tr_session_stats stats;
if (total)
tr_sessionGetCumulativeStats(fLib, &stats);
else
tr_sessionGetStats(fLib, &stats);
statusString = [NSLocalizedString(@"Ratio", "status bar -> status label") stringByAppendingFormat: @": %@",
[NSString stringForRatio: stats.ratio]];
}
else //STATUS_TRANSFER_TOTAL or STATUS_TRANSFER_SESSION
{
total = [statusLabel isEqualToString: STATUS_TRANSFER_TOTAL];
tr_session_stats stats;
if (total)
tr_sessionGetCumulativeStats(fLib, &stats);
else
tr_sessionGetStats(fLib, &stats);
statusString = [NSString stringWithFormat: @"%@: %@ %@: %@",
NSLocalizedString(@"DL", "status bar -> status label"), [NSString stringForFileSize: stats.downloadedBytes],
NSLocalizedString(@"UL", "status bar -> status label"), [NSString stringForFileSize: stats.uploadedBytes]];
}
if (![fStatusButton.title isEqualToString: statusString])
{
fStatusButton.title = statusString;
[self resizeStatusButton];
}
}
- (void) setStatusLabel: (id) sender
{
NSString * statusLabel;
switch ([sender tag])
{
case STATUS_RATIO_TOTAL_TAG:
statusLabel = STATUS_RATIO_TOTAL;
break;
case STATUS_RATIO_SESSION_TAG:
statusLabel = STATUS_RATIO_SESSION;
break;
case STATUS_TRANSFER_TOTAL_TAG:
statusLabel = STATUS_TRANSFER_TOTAL;
break;
case STATUS_TRANSFER_SESSION_TAG:
statusLabel = STATUS_TRANSFER_SESSION;
break;
default:
NSAssert1(NO, @"Unknown status label tag received: %ld", [sender tag]);
return;
}
[NSUserDefaults.standardUserDefaults setObject: statusLabel forKey: @"StatusLabel"];
[NSNotificationCenter.defaultCenter postNotificationName: @"UpdateUI" object: nil];
}
- (void) updateSpeedFieldsToolTips
{
NSString * uploadText, * downloadText;
if ([NSUserDefaults.standardUserDefaults boolForKey: @"SpeedLimit"])
{
NSString * speedString = [NSString stringWithFormat: @"%@ (%@)", NSLocalizedString(@"%d KB/s", "Status Bar -> speed tooltip"),
NSLocalizedString(@"Speed Limit", "Status Bar -> speed tooltip")];
uploadText = [NSString stringWithFormat: speedString,
[NSUserDefaults.standardUserDefaults integerForKey: @"SpeedLimitUploadLimit"]];
downloadText = [NSString stringWithFormat: speedString,
[NSUserDefaults.standardUserDefaults integerForKey: @"SpeedLimitDownloadLimit"]];
}
else
{
if ([NSUserDefaults.standardUserDefaults boolForKey: @"CheckUpload"])
uploadText = [NSString stringWithFormat: NSLocalizedString(@"%d KB/s", "Status Bar -> speed tooltip"),
[NSUserDefaults.standardUserDefaults integerForKey: @"UploadLimit"]];
else
uploadText = NSLocalizedString(@"unlimited", "Status Bar -> speed tooltip");
if ([NSUserDefaults.standardUserDefaults boolForKey: @"CheckDownload"])
downloadText = [NSString stringWithFormat: NSLocalizedString(@"%d KB/s", "Status Bar -> speed tooltip"),
[NSUserDefaults.standardUserDefaults integerForKey: @"DownloadLimit"]];
else
downloadText = NSLocalizedString(@"unlimited", "Status Bar -> speed tooltip");
}
uploadText = [NSLocalizedString(@"Global upload limit", "Status Bar -> speed tooltip")
stringByAppendingFormat: @": %@", uploadText];
downloadText = [NSLocalizedString(@"Global download limit", "Status Bar -> speed tooltip")
stringByAppendingFormat: @": %@", downloadText];
fTotalULField.toolTip = uploadText;
fTotalDLField.toolTip = downloadText;
}
- (BOOL) validateMenuItem: (NSMenuItem *) menuItem
{
const SEL action = menuItem.action;
//enable sort options
if (action == @selector(setStatusLabel:))
{
NSString * statusLabel;
switch (menuItem.tag)
{
case STATUS_RATIO_TOTAL_TAG:
statusLabel = STATUS_RATIO_TOTAL;
break;
case STATUS_RATIO_SESSION_TAG:
statusLabel = STATUS_RATIO_SESSION;
break;
case STATUS_TRANSFER_TOTAL_TAG:
statusLabel = STATUS_TRANSFER_TOTAL;
break;
case STATUS_TRANSFER_SESSION_TAG:
statusLabel = STATUS_TRANSFER_SESSION;
break;
default:
NSAssert1(NO, @"Unknown status label tag received: %ld", menuItem.tag);
statusLabel = STATUS_RATIO_TOTAL;
}
menuItem.state = [statusLabel isEqualToString: [NSUserDefaults.standardUserDefaults stringForKey: @"StatusLabel"]]
? NSOnState : NSOffState;
return YES;
}
return YES;
}
@end
@implementation StatusBarController (Private)
- (void) resizeStatusButton
{
[fStatusButton sizeToFit];
//width ends up being too long
NSRect statusFrame = fStatusButton.frame;
statusFrame.size.width -= 25.0;
const CGFloat difference = NSMaxX(statusFrame) + 5.0 - NSMinX(fTotalDLImageView.frame);
if (difference > 0.0)
statusFrame.size.width -= difference;
fStatusButton.frame = statusFrame;
}
@end