Skip to content

Commit

Permalink
Refactor code
Browse files Browse the repository at this point in the history
  • Loading branch information
codler committed Aug 17, 2012
1 parent 480ca6a commit 5db71a8
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 75 deletions.
18 changes: 14 additions & 4 deletions Battery Time Remaining/AppDelegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,27 @@

#import <Cocoa/Cocoa.h>

#ifndef _BTR_MENU
#define _BTR_MENU

#define kBTRMenuPowerSourcePercent 1
#define kBTRMenuPowerSourceState 2
#define kBTRMenuStartAtLogin 3
#define kBTRMenuNotification 4
#define kBTRMenuAdvancedMode 5
#define kBTRMenuEnergySaverSetting 6
#define kBTRMenuUpdater 7
#define kBTRMenuQuitKey 8

#endif

@interface AppDelegate : NSObject <NSApplicationDelegate, NSUserNotificationCenterDelegate, NSMenuDelegate>

- (void)updateStatusItem;
- (NSImage *)getBatteryIconNamed:(NSString *)iconName;
- (NSImage *)getBatteryIconPercent:(NSInteger)percent;

@property (strong) NSStatusItem *statusItem;
@property (strong) NSMenuItem *startupToggle;
@property (strong) NSMenuItem *updaterMenu;
@property (strong) NSMenuItem *psTimeMenu;
@property (strong) NSMenuItem *psStateMenu;
@property (nonatomic) NSInteger previousPercent;
@property (strong) NSMutableDictionary *notifications;

Expand Down
177 changes: 106 additions & 71 deletions Battery Time Remaining/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,45 @@ static void PowerSourceChanged(void * context)

@implementation AppDelegate

@synthesize statusItem, startupToggle, notifications, previousPercent;
@synthesize statusItem, notifications, previousPercent;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
// Init notification
[[NSUserNotificationCenter defaultUserNotificationCenter] setDelegate:self];
[self fetchNotificationSettings];

// Set default settings if not set
if (![self.notifications objectForKey:@"15"]) {
[self loadNotificationSetting];

// Set default notification settings if not set
if (![self.notifications objectForKey:@"15"])
{
[self.notifications setValue:[NSNumber numberWithBool:YES] forKey:@"15"];
}
if (![self.notifications objectForKey:@"100"]) {
if (![self.notifications objectForKey:@"100"])
{
[self.notifications setValue:[NSNumber numberWithBool:YES] forKey:@"100"];
}

[self saveNotificationSettings];
[self saveNotificationSetting];

// Power source menu
self.psTimeMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Loading…", @"Remaining menuitem") action:nil keyEquivalent:@""];
[self.psTimeMenu setEnabled:NO];

self.psStateMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Power source: Unknown", @"Powersource menuitem") action:nil keyEquivalent:@""];
[self.psStateMenu setEnabled:NO];
// Power source menu item
NSMenuItem *psPercentMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Loading…", @"Remaining menuitem") action:nil keyEquivalent:@""];
[psPercentMenu setTag:kBTRMenuPowerSourcePercent];
[psPercentMenu setEnabled:NO];

NSMenuItem *psStateMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Power source: Unknown", @"Powersource menuitem") action:nil keyEquivalent:@""];
[psStateMenu setTag:kBTRMenuPowerSourceState];
[psStateMenu setEnabled:NO];

// Create the startup at login toggle
self.startupToggle = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Start at login", @"Start at login setting") action:@selector(toggleStartAtLogin:) keyEquivalent:@""];
self.startupToggle.target = self;
self.startupToggle.state = ([LLManager launchAtLogin]) ? NSOnState : NSOffState;
// Start at login menu item
NSMenuItem *startAtLoginMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Start at login", @"Start at login setting") action:@selector(toggleStartAtLogin:) keyEquivalent:@""];
[startAtLoginMenu setTag:kBTRMenuStartAtLogin];
startAtLoginMenu.target = self;
startAtLoginMenu.state = ([LLManager launchAtLogin]) ? NSOnState : NSOffState;

// Build the notification submenu
NSMenu *notificationSubmenu = [[NSMenu alloc] initWithTitle:@"Notification Menu"];
for (int i = 5; i <= 100; i = i + 5) {
for (int i = 5; i <= 100; i = i + 5)
{
BOOL state = [[self.notifications valueForKey:[NSString stringWithFormat:@"%d", i]] boolValue];

NSMenuItem *notificationSubmenuItem = [[NSMenuItem alloc] initWithTitle:[NSString stringWithFormat:@"%d%%", i] action:@selector(toggleNotification:) keyEquivalent:@""];
Expand All @@ -63,33 +69,40 @@ - (void)applicationDidFinishLaunching:(NSNotification *)aNotification
[notificationSubmenu addItem:notificationSubmenuItem];
}

// Notification menu item
NSMenuItem *notificationMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Notifications", @"Notification menuitem") action:nil keyEquivalent:@""];
[notificationMenu setTag:kBTRMenuNotification];
[notificationMenu setSubmenu:notificationSubmenu];

// Updater menu
self.updaterMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Checking for updates…", @"Update menuitem") action:nil keyEquivalent:@""];
[self.updaterMenu setEnabled:NO];

// Build the status menu
NSMenu *statusMenu = [[NSMenu alloc] initWithTitle:@"Status Menu"];
[statusMenu setDelegate:self];
[statusMenu addItem:self.psTimeMenu];
[statusMenu addItem:self.psStateMenu];
[statusMenu addItem:[NSMenuItem separatorItem]];
[statusMenu addItem:self.startupToggle];
[statusMenu addItem:notificationMenu];
[statusMenu addItem:[NSMenuItem separatorItem]];

[statusMenu addItemWithTitle:NSLocalizedString(@"Energy Saver Preferences…", @"Open Energy Saver Preferences menuitem") action:@selector(openEnergySaverPreference:) keyEquivalent:@""];
[statusMenu addItem:[NSMenuItem separatorItem]];
[statusMenu addItem:self.updaterMenu];
[statusMenu addItem:[NSMenuItem separatorItem]];
[statusMenu addItemWithTitle:NSLocalizedString(@"Quit", @"Quit menuitem") action:@selector(terminate:) keyEquivalent:@""];

NSMenuItem *updaterMenu = [[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Checking for updates…", @"Update menuitem") action:nil keyEquivalent:@""];
[updaterMenu setTag:kBTRMenuUpdater];
[updaterMenu setEnabled:NO];

// Build the statusbar menu
NSMenu *statusBarMenu = [[NSMenu alloc] initWithTitle:@"Status Menu"];
[statusBarMenu setDelegate:self];

[statusBarMenu addItem:psPercentMenu];
[statusBarMenu addItem:psStateMenu];
[statusBarMenu addItem:[NSMenuItem separatorItem]]; // Separator

[statusBarMenu addItem:startAtLoginMenu];
[statusBarMenu addItem:notificationMenu];
[statusBarMenu addItem:[NSMenuItem separatorItem]]; // Separator

[statusBarMenu addItemWithTitle:NSLocalizedString(@"Energy Saver Preferences…", @"Open Energy Saver Preferences menuitem") action:@selector(openEnergySaverPreference:) keyEquivalent:@""];
[statusBarMenu addItem:[NSMenuItem separatorItem]]; // Separator

[statusBarMenu addItem:updaterMenu];
[statusBarMenu addItem:[NSMenuItem separatorItem]]; // Separator

[statusBarMenu addItemWithTitle:NSLocalizedString(@"Quit", @"Quit menuitem") action:@selector(terminate:) keyEquivalent:@""];

// Create the status item and set initial text
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
statusItem.highlightMode = YES;
statusItem.menu = statusMenu;
statusItem.menu = statusBarMenu;
[self updateStatusItem];

// Capture Power Source updates and make sure our callback is called
Expand All @@ -106,7 +119,7 @@ - (void)updateStatusItem
// Get list of power sources
CFTypeRef psBlob = IOPSCopyPowerSourcesInfo();
CFArrayRef psList = IOPSCopyPowerSourcesList(psBlob);

// Loop through the list of power sources
CFIndex count = CFArrayGetCount(psList);
for (CFIndex i = 0; i < count; i++)
Expand All @@ -126,9 +139,9 @@ - (void)updateStatusItem

NSInteger percent = (int)[currentBatteryCapacity doubleValue] / [maxBatteryCapacity doubleValue] * 100;

// Update menu title
self.psTimeMenu.title = [NSString stringWithFormat:NSLocalizedString(@"%ld %% left", @"Percentage left menuitem"), percent];
self.psStateMenu.title = [NSString stringWithFormat:NSLocalizedString(@"Power source: %@", @"Powersource menuitem"), CFDictionaryGetValue(description, CFSTR(kIOPSPowerSourceStateKey))];
// Set power source data in menu
[self.statusItem.menu itemWithTag:kBTRMenuPowerSourcePercent].title = [NSString stringWithFormat:NSLocalizedString(@"%ld %% left", @"Percentage left menuitem"), percent];
[self.statusItem.menu itemWithTag:kBTRMenuPowerSourceState].title = [NSString stringWithFormat:NSLocalizedString(@"Power source: %@", @"Powersource menuitem"), CFDictionaryGetValue(description, CFSTR(kIOPSPowerSourceStateKey))];

// We're connected to an unlimited power source (AC adapter probably)
if (kIOPSTimeRemainingUnlimited == timeRemaining)
Expand Down Expand Up @@ -160,19 +173,21 @@ - (void)updateStatusItem
// Not charging and on a endless powersource
self.statusItem.image = [self getBatteryIconNamed:@"BatteryCharged"];
self.statusItem.title = @"";

NSNumber *currentBatteryCapacity = CFDictionaryGetValue(description, CFSTR(kIOPSCurrentCapacityKey));
NSNumber *maxBatteryCapacity = CFDictionaryGetValue(description, CFSTR(kIOPSMaxCapacityKey));

// Notify user when battery is charged
if ([currentBatteryCapacity intValue] == [maxBatteryCapacity intValue] &&
self.previousPercent != percent &&
[[self.notifications valueForKey:@"100"] boolValue]) {
[[self.notifications valueForKey:@"100"] boolValue])
{

[self notify:NSLocalizedString(@"Charged", @"Charged notification")];
self.previousPercent = percent;
}
}

}
// Still calculating the estimated time remaining...
else if (kIOPSTimeRemainingUnknown == timeRemaining)
Expand All @@ -190,11 +205,14 @@ - (void)updateStatusItem
// Return the time remaining string
self.statusItem.image = [self getBatteryIconPercent:percent];
self.statusItem.title = [NSString stringWithFormat:@" %ld:%02ld", hour, minute];

for (NSString *key in self.notifications) {
if ([[self.notifications valueForKey:key] boolValue] && [key intValue] == percent) {

for (NSString *key in self.notifications)
{
if ([[self.notifications valueForKey:key] boolValue] && [key intValue] == percent)
{
// Send notification once
if (self.previousPercent != percent) {
if (self.previousPercent != percent)
{
[self notify:[NSString stringWithFormat:NSLocalizedString(@"%ld:%02ld left (%ld%%)", @"Time remaining left notification"), hour, minute, percent]];
}
break;
Expand Down Expand Up @@ -223,6 +241,7 @@ - (NSImage *)getBatteryIconPercent:(NSInteger)percent

sourceRect.size.width -= [batteryDynamic size].width / 100 * (60.f - (60.f / 100.f * percent));

// Set different color at 15 percent
if (percent > 15)
{
[[NSColor blackColor] set];
Expand Down Expand Up @@ -257,12 +276,15 @@ - (void)openHomeUrl:(id)sender

- (void)toggleStartAtLogin:(id)sender
{
if ([LLManager launchAtLogin]) {
if ([LLManager launchAtLogin])
{
[LLManager setLaunchAtLogin:NO];
self.startupToggle.state = NSOffState;
} else {
[self.statusItem.menu itemWithTag:kBTRMenuStartAtLogin].state = NSOffState;
}
else
{
[LLManager setLaunchAtLogin:YES];
self.startupToggle.state = NSOnState;
[self.statusItem.menu itemWithTag:kBTRMenuStartAtLogin].state = NSOnState;
}
}

Expand All @@ -276,19 +298,22 @@ - (void)notify:(NSString *)message
[center scheduleNotification:notification];
}

- (void)fetchNotificationSettings
- (void)loadNotificationSetting
{
// Fetch user settings for notifications
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSDictionary *immutableNotifications = [defaults dictionaryForKey:@"notifications"];
if (immutableNotifications) {
if (immutableNotifications)
{
self.notifications = [immutableNotifications mutableCopy];
} else {
}
else
{
self.notifications = [NSMutableDictionary new];
}
}

- (void)saveNotificationSettings
- (void)saveNotificationSetting
{
// Save user settings for notifications
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
Expand All @@ -303,10 +328,10 @@ - (void)toggleNotification:(id)sender

// Toggle state
item.state = (item.state==NSOnState) ? NSOffState : NSOnState;

[self.notifications setValue:[NSNumber numberWithBool:(item.state==NSOnState)?YES:NO] forKey:[NSString stringWithFormat:@"%ld", item.tag]];

[self saveNotificationSettings];
[self saveNotificationSetting];
}

#pragma mark - NSUserNotificationCenterDelegate methods
Expand All @@ -319,7 +344,9 @@ - (BOOL)userNotificationCenter:(NSUserNotificationCenter *)center shouldPresentN

- (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNotification:(NSUserNotification *)notification
{
if ([[notification informativeText] isEqualToString:NSLocalizedString(@"A newer version is available", @"Update menuitem")]) {
// User has clicked on the notification and will open home URL if newer version is available
if ([[notification informativeText] isEqualToString:NSLocalizedString(@"A newer version is available", @"Update menuitem")])
{
[self openHomeUrl:nil];
}
}
Expand All @@ -328,32 +355,40 @@ - (void)userNotificationCenter:(NSUserNotificationCenter *)center didActivateNot

- (void)menuWillOpen:(NSMenu *)menu
{
NSMenuItem *updaterMenu = [self.statusItem.menu itemWithTag:kBTRMenuUpdater];

// Stop checking if newer version is available
if ([self.updaterMenu isEnabled]) {
if ([updaterMenu isEnabled])
{
return;
}

// Check for newer version
[[HttpGet new] url:@"https://raw.github.com/codler/Battery-Time-Remaining/master/build_version" success:^(NSString *result){
[[HttpGet new] url:@"https://raw.github.com/codler/Battery-Time-Remaining/master/build_version" success:^(NSString *result) {
NSInteger latestBuildVersion = [result integerValue];
NSInteger currentBuildVersion = [[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"] integerValue];

if (!latestBuildVersion) {
self.updaterMenu.title = NSLocalizedString(@"Could not check for updates", @"Update menuitem");
// Wrong format build version
if (!latestBuildVersion)
{
updaterMenu.title = NSLocalizedString(@"Could not check for updates", @"Update menuitem");
return;
}

// Newer version available
if (latestBuildVersion > currentBuildVersion) {
self.updaterMenu.title = NSLocalizedString(@"A newer version is available", @"Update menuitem");
[self.updaterMenu setAction:@selector(openHomeUrl:)];
[self.updaterMenu setEnabled:YES];
if (latestBuildVersion > currentBuildVersion)
{
updaterMenu.title = NSLocalizedString(@"A newer version is available", @"Update menuitem");
[updaterMenu setAction:@selector(openHomeUrl:)];
[updaterMenu setEnabled:YES];
[self notify:NSLocalizedString(@"A newer version is available", @"Update notification")];
} else {
self.updaterMenu.title = NSLocalizedString(@"Up to date", @"Update menuitem");
}
else
{
updaterMenu.title = NSLocalizedString(@"Up to date", @"Update menuitem");
}
} error:^(NSError *error) {
self.updaterMenu.title = NSLocalizedString(@"Could not check for updates", @"Update menuitem");
updaterMenu.title = NSLocalizedString(@"Could not check for updates", @"Update menuitem");
}];
}

Expand Down

0 comments on commit 5db71a8

Please sign in to comment.