diff --git a/BateryProlonger.xcodeproj/project.pbxproj b/BateryProlonger.xcodeproj/project.pbxproj index 7b82427..2fc74fb 100644 --- a/BateryProlonger.xcodeproj/project.pbxproj +++ b/BateryProlonger.xcodeproj/project.pbxproj @@ -21,6 +21,8 @@ 2619225617FA13B20062FC1D /* Growl.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 2619225317FA13880062FC1D /* Growl.framework */; }; 2619225C17FA1F4F0062FC1D /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2619225B17FA1F4F0062FC1D /* IOKit.framework */; }; 264D273317FC856700AA3E61 /* Growl.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2619225317FA13880062FC1D /* Growl.framework */; }; + 268BEBF018142364003A6B1D /* PreferencesController.m in Sources */ = {isa = PBXBuildFile; fileRef = 268BEBEE18142364003A6B1D /* PreferencesController.m */; }; + 268BEBF118142364003A6B1D /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 268BEBEF18142364003A6B1D /* Preferences.xib */; }; 269BD71717FB44400045D9B4 /* About.xib in Resources */ = {isa = PBXBuildFile; fileRef = 269BD71617FB44400045D9B4 /* About.xib */; }; 269BD71A17FB44670045D9B4 /* AboutController.m in Sources */ = {isa = PBXBuildFile; fileRef = 269BD71917FB44670045D9B4 /* AboutController.m */; }; 269BD72017FB50AD0045D9B4 /* icon-small.png in Resources */ = {isa = PBXBuildFile; fileRef = 269BD71F17FB50AD0045D9B4 /* icon-small.png */; }; @@ -73,6 +75,9 @@ 2619224917FA0AAD0062FC1D /* BateryProlongerTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BateryProlongerTests.m; sourceTree = ""; }; 2619225317FA13880062FC1D /* Growl.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Growl.framework; sourceTree = ""; }; 2619225B17FA1F4F0062FC1D /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; + 268BEBED18142364003A6B1D /* PreferencesController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreferencesController.h; sourceTree = ""; }; + 268BEBEE18142364003A6B1D /* PreferencesController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PreferencesController.m; sourceTree = ""; }; + 268BEBEF18142364003A6B1D /* Preferences.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = Preferences.xib; sourceTree = ""; }; 269BD71617FB44400045D9B4 /* About.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = About.xib; sourceTree = ""; }; 269BD71817FB44670045D9B4 /* AboutController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AboutController.h; sourceTree = ""; }; 269BD71917FB44670045D9B4 /* AboutController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AboutController.m; sourceTree = ""; }; @@ -159,6 +164,9 @@ 2619223217FA0AAC0062FC1D /* AppDelegate.m */, 2619223417FA0AAC0062FC1D /* MainMenu.xib */, 2619222617FA0AAC0062FC1D /* Supporting Files */, + 268BEBED18142364003A6B1D /* PreferencesController.h */, + 268BEBEE18142364003A6B1D /* PreferencesController.m */, + 268BEBEF18142364003A6B1D /* Preferences.xib */, ); path = BateryProlonger; sourceTree = ""; @@ -273,6 +281,7 @@ 269BD72017FB50AD0045D9B4 /* icon-small.png in Resources */, 269BD72417FB5FBD0045D9B4 /* battery.iconset in Resources */, 269BD72617FB6F190045D9B4 /* .gitignore in Resources */, + 268BEBF118142364003A6B1D /* Preferences.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -310,6 +319,7 @@ 2619222C17FA0AAC0062FC1D /* main.m in Sources */, 2619223317FA0AAC0062FC1D /* AppDelegate.m in Sources */, 269BD71A17FB44670045D9B4 /* AboutController.m in Sources */, + 268BEBF018142364003A6B1D /* PreferencesController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -437,6 +447,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "BateryProlonger/BateryProlonger-Prefix.pch"; INFOPLIST_FILE = "BateryProlonger/BateryProlonger-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.7; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; @@ -453,6 +464,7 @@ GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "BateryProlonger/BateryProlonger-Prefix.pch"; INFOPLIST_FILE = "BateryProlonger/BateryProlonger-Info.plist"; + MACOSX_DEPLOYMENT_TARGET = 10.7; PRODUCT_NAME = "$(TARGET_NAME)"; WRAPPER_EXTENSION = app; }; diff --git a/BateryProlonger.xcodeproj/project.xcworkspace/xcuserdata/pavellinkesch.xcuserdatad/UserInterfaceState.xcuserstate b/BateryProlonger.xcodeproj/project.xcworkspace/xcuserdata/pavellinkesch.xcuserdatad/UserInterfaceState.xcuserstate index ca9885c..7a0e3ad 100644 Binary files a/BateryProlonger.xcodeproj/project.xcworkspace/xcuserdata/pavellinkesch.xcuserdatad/UserInterfaceState.xcuserstate and b/BateryProlonger.xcodeproj/project.xcworkspace/xcuserdata/pavellinkesch.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/BateryProlonger/About.xib b/BateryProlonger/About.xib index 17e1f18..7c44d4a 100644 --- a/BateryProlonger/About.xib +++ b/BateryProlonger/About.xib @@ -38,7 +38,7 @@ 3 2 - {{196, 240}, {484, 388}} + {{196, 240}, {484, 408}} 544735232 About NSWindow @@ -51,7 +51,7 @@ 268 - {{159, 340}, {167, 22}} + {{159, 360}, {167, 22}} @@ -91,7 +91,7 @@ 268 - {{124, 240}, {237, 51}} + {{109, 243}, {267, 68}} @@ -100,8 +100,8 @@ 70254657 4195328 - VmVyc2lvbjoJCTAuMeKAqEF1dGhvcjoJCVBhdmVsIExpbmtlc2No4oCoCQkJaHR0cDovL3d3dy5saW5r -ZXNjaC5zaw + VmVyc2lvbjoJCTAuMS4x4oCoQXV0aG9yOgkJUGF2ZWwgTGlua2VzY2gKICAgICAgICAgICAgICAgICAg +ICBAbGlua2VzY2ggfCB3d3cubGlua2VzY2guc2s LucidaGrande 13 @@ -116,7 +116,7 @@ ZXNjaC5zaw 268 - {{94, 315}, {297, 17}} + {{106, 335}, {272, 17}} @@ -125,7 +125,7 @@ ZXNjaC5zaw 70254657 138413056 - https://github.com/orthes/Battery-Prolonger + http://orthes.github.io/Battery-Prolonger _NS:1535 @@ -136,10 +136,10 @@ ZXNjaC5zaw 268 - {{20, 20}, {444, 192}} + {{20, 45}, {444, 192}} - + _NS:9 {250, 750} YES @@ -175,8 +175,28 @@ CgpodHRwOi8vd3d3LndpcmVkLmNvbS9nYWRnZXRsYWIvMjAxMy8wOS9sYXB0b3AtYmF0dGVyeQ + + + 268 + {{17, 20}, {450, 17}} + + + + _NS:1535 + YES + + 70254657 + 272630784 + Icons by http://www.visualpharm.com and http://www.iconshock.com + + _NS:1535 + + + + + - {484, 388} + {484, 408} @@ -235,36 +255,52 @@ CgpodHRwOi8vd3d3LndpcmVkLmNvbS9nYWRnZXRsYWIvMjAxMy8wOS9sYXB0b3AtYmF0dGVyeQ2 - - - 9 + + + 4 + 0 + + 4 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 3 0 - 9 + 4 1 - - 0.0 + + 8 1000 6 24 - 2 + 3 - - - 3 + + + 5 0 - 3 + 5 1 - - 97 + + 20 1000 - 3 - 9 + 8 + 29 3 @@ -299,31 +335,47 @@ CgpodHRwOi8vd3d3LndpcmVkLmNvbS9nYWRnZXRsYWIvMjAxMy8wOS9sYXB0b3AtYmF0dGVyeQ29 3 - - - 4 + + + 3 0 - - 4 + + 3 1 - - 20 + + 26 1000 - 8 - 29 + 3 + 9 3 - - + + + 9 + 0 + + 9 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + 3 0 3 1 - 26 + 97 1000 @@ -382,6 +434,7 @@ CgpodHRwOi8vd3d3LndpcmVkLmNvbS9nYWRnZXRsYWIvMjAxMy8wOS9sYXB0b3AtYmF0dGVyeQ + @@ -409,15 +462,15 @@ CgpodHRwOi8vd3d3LndpcmVkLmNvbS9nYWRnZXRsYWIvMjAxMy8wOS9sYXB0b3AtYmF0dGVyeQ - + - 7 + 8 0 0 1 - 231 + 68 1000 @@ -495,11 +548,6 @@ CgpodHRwOi8vd3d3LndpcmVkLmNvbS9nYWRnZXRsYWIvMjAxMy8wOS9sYXB0b3AtYmF0dGVyeQ - - 57 - - - 60 @@ -521,8 +569,36 @@ CgpodHRwOi8vd3d3LndpcmVkLmNvbS9nYWRnZXRsYWIvMjAxMy8wOS9sYXB0b3AtYmF0dGVyeQ - 65 - + 67 + + + + + + + + 68 + + + + + 71 + + + + + 72 + + + + + 73 + + + + + 74 + @@ -535,8 +611,8 @@ CgpodHRwOi8vd3d3LndpcmVkLmNvbS9nYWRnZXRsYWIvMjAxMy8wOS9sYXB0b3AtYmF0dGVyeQ{{357, 418}, {480, 270}} com.apple.InterfaceBuilder.CocoaPlugin - - + + com.apple.InterfaceBuilder.CocoaPlugin @@ -548,12 +624,14 @@ CgpodHRwOi8vd3d3LndpcmVkLmNvbS9nYWRnZXRsYWIvMjAxMy8wOS9sYXB0b3AtYmF0dGVyeQ + + - - - + + + com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -569,18 +647,23 @@ CgpodHRwOi8vd3d3LndpcmVkLmNvbS9nYWRnZXRsYWIvMjAxMy8wOS9sYXB0b3AtYmF0dGVyeQ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin - 65 + 74 diff --git a/BateryProlonger/AppDelegate.h b/BateryProlonger/AppDelegate.h index 56d3938..6b41fc3 100644 --- a/BateryProlonger/AppDelegate.h +++ b/BateryProlonger/AppDelegate.h @@ -11,21 +11,19 @@ #import #import @class AboutController; +@class PreferencesController; @interface AppDelegate : NSObject { IBOutlet NSMenu *statusMenu; NSStatusItem *statusItem; - IBOutlet NSMenuItem *startAtLoginMenuItem; AboutController *aboutController; + PreferencesController *preferencesController; } - (void) refresh:(NSTimer *) theTimer; - (void) showNotification:(NSString *)notification; - (IBAction) openAboutWindow:(id)sender; -- (IBAction) toogleLoginItem:(id)sender; -- (bool) findAppInLoginItem; -- (void) addAppAsLoginItem; -- (void) deleteAppFromLoginItem; +- (IBAction) openPreferencesWindow:(id)sender; @end diff --git a/BateryProlonger/AppDelegate.m b/BateryProlonger/AppDelegate.m index e3b026b..fe2f917 100644 --- a/BateryProlonger/AppDelegate.m +++ b/BateryProlonger/AppDelegate.m @@ -8,6 +8,7 @@ #import "AppDelegate.h" #import "aboutController.h" +#import "preferencesController.h" @implementation AppDelegate @@ -15,6 +16,13 @@ @implementation AppDelegate bool notified2 = false; int lastPowerSource; ++ (void)initialize +{ + NSDictionary *defaults = [NSDictionary dictionaryWithObjectsAndKeys: + @"true", @"autoClose", @"80", @"topLimit", @"40", @"bottomLimit", nil]; + [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; +} + - (void)awakeFromNib { statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain]; @@ -24,11 +32,6 @@ - (void)awakeFromNib [statusItem setImage:icon]; [statusItem setMenu:statusMenu]; [statusItem setHighlightMode:YES]; - - if ([self findAppInLoginItem]) - { - [startAtLoginMenuItem setState: NSOnState]; - } [self refresh:NULL]; @@ -41,6 +44,8 @@ - (void) refresh:(NSTimer *) theTimer CFTypeRef info; CFArrayRef list; CFDictionaryRef battery; + NSInteger topLimit; + NSInteger bottomLimit; bool batteryCharging; int batteryCurrent; @@ -73,17 +78,20 @@ - (void) refresh:(NSTimer *) theTimer notified1 = notified2 = false; } - if(batteryCharging == 1 && batteryCurrent > 80 && notified1 == false) + topLimit = [[[NSUserDefaults standardUserDefaults] objectForKey:@"topLimit"] integerValue]; + bottomLimit = [[[NSUserDefaults standardUserDefaults] objectForKey:@"bottomLimit"] integerValue]; + + if(batteryCharging == 1 && batteryCurrent > topLimit && notified1 == false) { NSString *notification = @"Your battery is charged enough.\n\nYou can unplug your MacBook now."; [self showNotification:notification]; notified1 = true; notified2 = false; } - else if(batteryCharging == 0 && batteryCurrent < 40 && notified2 == false) + else if(batteryCharging == 0 && batteryCurrent < bottomLimit && notified2 == false) { - NSString *notification = @"Your battery is charged on less than 40%.\n\nPlease, plug in your MacBook to power adapter."; + NSString *notification =[NSString stringWithFormat:@"Your battery is charged to less than %li%%.\n\nPlease, plug in your MacBook to a power adapter.", bottomLimit]; [self showNotification:notification]; notified1 = false; notified2 = true; @@ -104,12 +112,23 @@ - (void)showNotification:(NSString *)notification NSBundle *myBundle = [NSBundle bundleForClass:[AppDelegate class]]; NSString *growlPath = [[myBundle privateFrameworksPath] stringByAppendingPathComponent:@"Growl.framework"]; NSBundle *growlBundle = [NSBundle bundleWithPath:growlPath]; + Boolean isSticky = YES; + + if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"autoClose"] isEqual: @"true"]) + { + isSticky = NO; + } if (growlBundle && [growlBundle load]) { [GrowlApplicationBridge setGrowlDelegate:self]; - [GrowlApplicationBridge notifyWithTitle:@"Alert" description:notification notificationName:@"Notification" iconData:nil priority:2 isSticky:NO clickContext:[NSDate date]]; + [GrowlApplicationBridge notifyWithTitle:@"Battery Prolonger" description:notification notificationName:@"Notification" iconData:nil priority:2 isSticky:isSticky clickContext:[NSDate date]]; + + if ([[[NSUserDefaults standardUserDefaults] objectForKey:@"playSound"] isEqual: @"true"]) + { + [[NSSound soundNamed:@"Purr"] play]; + } } } @@ -122,114 +141,13 @@ - (IBAction)openAboutWindow:(id)sender [aboutController showWindow:self]; } -- (IBAction) toogleLoginItem:(id)sender +- (IBAction)openPreferencesWindow:(id)sender { - if ([self findAppInLoginItem]) - { - [startAtLoginMenuItem setState: NSOffState]; - [self deleteAppFromLoginItem]; - } - else + if (!preferencesController) { - [startAtLoginMenuItem setState: NSOnState]; - [self addAppAsLoginItem]; + preferencesController = [[PreferencesController alloc] initWithWindowNibName:@"Preferences"]; } -} - -- (bool) findAppInLoginItem -{ - NSString * appPath = [[NSBundle mainBundle] bundlePath]; - - // This will retrieve the path for the application - // For example, /Applications/test.app - CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:appPath]; - - // Create a reference to the shared file list. - LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, - kLSSharedFileListSessionLoginItems, NULL); - - if (loginItems) { - UInt32 seedValue; - //Retrieve the list of Login Items and cast them to - // a NSArray so that it will be easier to iterate. - NSArray *loginItemsArray = (NSArray *)LSSharedFileListCopySnapshot(loginItems, &seedValue); - int i = 0; - for(i = 0 ; i< [loginItemsArray count]; i++){ - LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)[loginItemsArray - objectAtIndex:i]; - //Resolve the item with URL - if (LSSharedFileListItemResolve(itemRef, 0, (CFURLRef*) &url, NULL) == noErr) { - NSString * urlPath = [(NSURL*)url path]; - if ([urlPath compare:appPath] == NSOrderedSame){ - return true; - } - } - } - [loginItemsArray release]; - } - - return false; -} - -- (void) addAppAsLoginItem -{ - NSString * appPath = [[NSBundle mainBundle] bundlePath]; - - // This will retrieve the path for the application - // For example, /Applications/test.app - CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:appPath]; - - // Create a reference to the shared file list. - // We are adding it to the current user only. - // If we want to add it all users, use - // kLSSharedFileListGlobalLoginItems instead of - //kLSSharedFileListSessionLoginItems - LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, - kLSSharedFileListSessionLoginItems, NULL); - if (loginItems) { - //Insert an item to the list. - LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(loginItems, - kLSSharedFileListItemLast, NULL, NULL, - url, NULL, NULL); - if (item){ - CFRelease(item); - } - } - - CFRelease(loginItems); -} - -- (void) deleteAppFromLoginItem -{ - NSString * appPath = [[NSBundle mainBundle] bundlePath]; - - // This will retrieve the path for the application - // For example, /Applications/test.app - CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:appPath]; - - // Create a reference to the shared file list. - LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, - kLSSharedFileListSessionLoginItems, NULL); - - if (loginItems) { - UInt32 seedValue; - //Retrieve the list of Login Items and cast them to - // a NSArray so that it will be easier to iterate. - NSArray *loginItemsArray = (NSArray *)LSSharedFileListCopySnapshot(loginItems, &seedValue); - int i = 0; - for(i = 0 ; i< [loginItemsArray count]; i++){ - LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)[loginItemsArray - objectAtIndex:i]; - //Resolve the item with URL - if (LSSharedFileListItemResolve(itemRef, 0, (CFURLRef*) &url, NULL) == noErr) { - NSString * urlPath = [(NSURL*)url path]; - if ([urlPath compare:appPath] == NSOrderedSame){ - LSSharedFileListItemRemove(loginItems,itemRef); - } - } - } - [loginItemsArray release]; - } + [preferencesController showWindow:self]; } @end diff --git a/BateryProlonger/BateryProlonger-Info.plist b/BateryProlonger/BateryProlonger-Info.plist index 8a1c9ba..a17216a 100644 --- a/BateryProlonger/BateryProlonger-Info.plist +++ b/BateryProlonger/BateryProlonger-Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.1 + 0.1.1 CFBundleSignature ???? CFBundleVersion diff --git a/BateryProlonger/Preferences.xib b/BateryProlonger/Preferences.xib new file mode 100644 index 0000000..c650f1b --- /dev/null +++ b/BateryProlonger/Preferences.xib @@ -0,0 +1,1496 @@ + + + + 1070 + 11G63 + 3084 + 1138.51 + 569.00 + + com.apple.InterfaceBuilder.CocoaPlugin + 3084 + + + IBNSLayoutConstraint + NSButton + NSButtonCell + NSCustomObject + NSSlider + NSSliderCell + NSTextField + NSTextFieldCell + NSView + NSWindowTemplate + + + com.apple.InterfaceBuilder.CocoaPlugin + + + PluginDependencyRecalculationVersion + + + + + PreferencesController + + + FirstResponder + + + NSApplication + + + 3 + 2 + {{196, 240}, {414, 182}} + 544735232 + Preferences + NSWindow + + + + + 256 + + + + 268 + {{124, 142}, {108, 18}} + + + + _NS:9 + YES + + 67108864 + 268435456 + Start on login + + LucidaGrande + 13 + 1044 + + _NS:9 + + 1211912448 + 2 + + NSImage + NSSwitch + + + NSSwitch + + + + 200 + 25 + + + + + 268 + {{42, 143}, {57, 17}} + + + + _NS:1535 + YES + + 68157504 + 272630784 + General: + + _NS:1535 + + + 6 + System + controlColor + + 3 + MC42NjY2NjY2NjY3AA + + + + 6 + System + controlTextColor + + 3 + MAA + + + + + + + 268 + {{124, 107}, {90, 18}} + + + + _NS:9 + YES + + 67108864 + 8388608 + Play sound + + _NS:9 + + 1211912448 + 2 + + + + + 200 + 25 + + + + + 268 + {{124, 87}, {215, 18}} + + + + _NS:9 + YES + + 67108864 + 268435456 + Auto close after a few seconds + + _NS:9 + + 1211912448 + 2 + + + + + 200 + 25 + + + + + 268 + {{17, 108}, {82, 17}} + + + + _NS:1535 + YES + + 68157504 + 272630784 + Notification: + + _NS:1535 + + + + + + + + 268 + {{54, 47}, {47, 17}} + + + + _NS:1535 + YES + + 68157504 + 272630784 + Limits: + + _NS:1535 + + + + + + + + 268 + {{124, 44}, {96, 21}} + + + + _NS:9 + YES + + -2080112384 + 0 + + _NS:9 + + 100 + 0.0 + 50 + 0.0 + 0 + 1 + YES + NO + + + + + 268 + {{231, 49}, {29, 17}} + + + + _NS:1535 + YES + + 68157504 + 138413056 + + + ### + _NS:1535 + + + + + + + + 268 + {{124, 16}, {96, 21}} + + + + _NS:9 + YES + + -2080112384 + 0 + + _NS:9 + + 100 + 0.0 + 50 + 0.0 + 0 + 1 + YES + NO + + + + + 268 + {{231, 19}, {29, 17}} + + + + _NS:1535 + YES + + 68157504 + 138413056 + + + ### + _NS:1535 + + + + + + + + 268 + {{269, 48}, {128, 17}} + + + + _NS:1535 + YES + + 68157504 + 272630784 + (recommended: 80) + + _NS:1535 + + + + 6 + System + disabledControlTextColor + + 3 + MC4zMzMzMzMzMzMzAA + + + + + + + 268 + {{269, 19}, {128, 17}} + + + + _NS:1535 + YES + + 68157504 + 272630784 + (recommended: 40) + + _NS:1535 + + + + + + + {414, 182} + + + + + {{0, 0}, {1280, 800}} + {10000000000000, 10000000000000} + YES + + + + + + + window + + + + 3 + + + + toogleLoginItem: + + + + 134 + + + + startAtLoginMenuItem + + + + 135 + + + + togglePlaySoundItem: + + + + 142 + + + + toggleAutoCloseItem: + + + + 145 + + + + playSoundItem + + + + 149 + + + + autoCloseItem + + + + 150 + + + + changeTopLimit: + + + + 265 + + + + changeBottomLimit: + + + + 267 + + + + topLimitSlider + + + + 270 + + + + bottomLimitSlider + + + + 271 + + + + topLimit + + + + 272 + + + + bottomLimit + + + + 273 + + + + + + 0 + + + + + + -2 + + + File's Owner + + + -1 + + + First Responder + + + -3 + + + Application + + + 1 + + + + + + + + 2 + + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 11 + 0 + + 11 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 6 + 0 + + 6 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 11 + 0 + + 11 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 6 + 0 + + 6 + 1 + + 157 + + 1000 + + 3 + 9 + 3 + + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 4 + 0 + + 4 + 1 + + 49 + + 1000 + + 3 + 9 + 3 + + + + 4 + 0 + + 4 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 3 + 0 + + 4 + 1 + + 6 + + 1000 + + 6 + 24 + 3 + + + + 5 + 0 + + 5 + 1 + + 57 + + 1000 + + 3 + 9 + 3 + + + + 10 + 0 + + 10 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 4 + 0 + + 4 + 1 + + 47 + + 1000 + + 3 + 9 + 3 + + + + 5 + 0 + + 5 + 1 + + 126 + + 1000 + + 3 + 9 + 3 + + + + 5 + 0 + + 5 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 5 + 0 + + 5 + 1 + + 20 + + 1000 + + 8 + 29 + 3 + + + + 11 + 0 + + 11 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 3 + 0 + + 3 + 1 + + 57 + + 1000 + + 3 + 9 + 3 + + + + 3 + 0 + + 3 + 1 + + 22 + + 1000 + + 3 + 9 + 3 + + + + 11 + 0 + + 11 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + 6 + 0 + + 6 + 1 + + 0.0 + + 1000 + + 6 + 24 + 2 + + + + + + + + + + + + + + + + + + 15 + + + + + + + + 16 + + + + + 45 + + + + + + + + 46 + + + + + 55 + + + + + + + + 56 + + + + + + + + 57 + + + + + 58 + + + + + 69 + + + + + + + + 70 + + + + + 133 + + + + + 73 + + + + + 126 + + + + + 75 + + + + + 161 + + + + + + + + 162 + + + + + 217 + + + + + + 7 + 0 + + 0 + 1 + + 92 + + 1000 + + 3 + 9 + 1 + + + + + + 218 + + + + + 221 + + + + + 222 + + + + + + 7 + 0 + + 0 + 1 + + 23 + + 1000 + + 3 + 9 + 1 + + + + + + 223 + + + + + 232 + + + + + + + + 233 + + + + + + + + 234 + + + + + 236 + + + + + 252 + + + + + 255 + + + + + 256 + + + + + 279 + + + + + 280 + + + + + + + + 281 + + + + + 297 + + + + + + + + 298 + + + + + 307 + + + + + 310 + + + + + 316 + + + + + 318 + + + + + 320 + + + + + 321 + + + + + 322 + + + + + 323 + + + + + 324 + + + + + 327 + + + + + 328 + + + + + 329 + + + + + 330 + + + + + 331 + + + + + 332 + + + + + 333 + + + + + 334 + + + + + 335 + + + + + 336 + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + {{357, 418}, {480, 270}} + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + + + + + + + + + + + + + + + + + + + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + + + + + + 336 + + + + + NSLayoutConstraint + NSObject + + IBProjectSource + ./Classes/NSLayoutConstraint.h + + + + PreferencesController + NSWindowController + + id + id + id + id + id + + + + changeBottomLimit: + id + + + changeTopLimit: + id + + + toggleAutoCloseItem: + id + + + togglePlaySoundItem: + id + + + toogleLoginItem: + id + + + + NSButton + NSTextField + NSSlider + NSButton + NSButton + NSTextField + NSSlider + + + + autoCloseItem + NSButton + + + bottomLimit + NSTextField + + + bottomLimitSlider + NSSlider + + + playSoundItem + NSButton + + + startAtLoginMenuItem + NSButton + + + topLimit + NSTextField + + + topLimitSlider + NSSlider + + + + IBProjectSource + ./Classes/PreferencesController.h + + + + + 0 + IBCocoaFramework + YES + 3 + + NSSwitch + {15, 15} + + YES + + diff --git a/BateryProlonger/PreferencesController.h b/BateryProlonger/PreferencesController.h new file mode 100644 index 0000000..216667f --- /dev/null +++ b/BateryProlonger/PreferencesController.h @@ -0,0 +1,31 @@ +// +// PreferencesController.h +// BateryProlonger +// +// Created by Pavel Linkesch on 10/20/13. +// Copyright (c) 2013 Pavel Linkesch. All rights reserved. +// + +#import + +@interface PreferencesController : NSWindowController +{ + IBOutlet NSButton *startAtLoginMenuItem; + IBOutlet NSButton *playSoundItem; + IBOutlet NSButton *autoCloseItem; + IBOutlet NSSlider *topLimitSlider; + IBOutlet NSSlider *bottomLimitSlider; + IBOutlet NSTextField *topLimit; + IBOutlet NSTextField *bottomLimit; +} + +- (IBAction) toogleLoginItem:(id)sender; +- (bool) findAppInLoginItem; +- (void) addAppAsLoginItem; +- (void) deleteAppFromLoginItem; +- (IBAction)togglePlaySoundItem:(id)sender; +- (IBAction)toggleAutoCloseItem:(id)sender; +- (IBAction)changeTopLimit:(id)sender; +- (IBAction)changeBottomLimit:(id)sender; + +@end diff --git a/BateryProlonger/PreferencesController.m b/BateryProlonger/PreferencesController.m new file mode 100644 index 0000000..0e8019b --- /dev/null +++ b/BateryProlonger/PreferencesController.m @@ -0,0 +1,207 @@ +// +// PreferencesController.m +// BateryProlonger +// +// Created by Pavel Linkesch on 10/20/13. +// Copyright (c) 2013 Pavel Linkesch. All rights reserved. +// + +#import "PreferencesController.h" + +@interface PreferencesController () + +@end + +@implementation PreferencesController + +- (id)initWithWindow:(NSWindow *)window +{ + self = [super initWithWindow:window]; + if (self) { + + } + + return self; +} + +- (void)windowDidLoad +{ + NSString *default1; + NSString *default2; + NSInteger default3; + NSInteger default4; + NSInteger tempLimit; + + [super windowDidLoad]; + + if ([self findAppInLoginItem]) + { + [startAtLoginMenuItem setState: NSOnState]; + } + + default1 = [[NSUserDefaults standardUserDefaults] objectForKey:@"playSound"]; + if ([default1 isEqual: @"true"]) { + [playSoundItem setState: NSOnState]; + } + default2 = [[NSUserDefaults standardUserDefaults] objectForKey:@"autoClose"]; + if ([default2 isEqual: @"true"]) { + [autoCloseItem setState: NSOnState]; + } + + default3 = [[[NSUserDefaults standardUserDefaults] objectForKey:@"topLimit"] integerValue]; + default4 = [[[NSUserDefaults standardUserDefaults] objectForKey:@"bottomLimit"] integerValue]; + + if (default3 < default4) + { + tempLimit = default3; + default3 = default4; + default4 = tempLimit; + } + + [topLimitSlider setIntegerValue:default3]; + [topLimit setIntegerValue:default3]; + + [bottomLimitSlider setIntegerValue:default4]; + [bottomLimit setIntegerValue:default4]; +} + +- (IBAction) toogleLoginItem:(id)sender +{ + if ([self findAppInLoginItem]) + { + [startAtLoginMenuItem setState: NSOffState]; + [self deleteAppFromLoginItem]; + } + else + { + [startAtLoginMenuItem setState: NSOnState]; + [self addAppAsLoginItem]; + } +} + +- (bool) findAppInLoginItem +{ + NSString * appPath = [[NSBundle mainBundle] bundlePath]; + + // This will retrieve the path for the application + // For example, /Applications/test.app + CFURLRef url = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:appPath]); + + // Create a reference to the shared file list. + LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, + kLSSharedFileListSessionLoginItems, NULL); + + if (loginItems) { + UInt32 seedValue; + //Retrieve the list of Login Items and cast them to + // a NSArray so that it will be easier to iterate. + NSArray *loginItemsArray = (NSArray *)CFBridgingRelease(LSSharedFileListCopySnapshot(loginItems, &seedValue)); + int i = 0; + for(i = 0 ; i< [loginItemsArray count]; i++){ + LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)CFBridgingRetain([loginItemsArray + objectAtIndex:i]); + //Resolve the item with URL + if (LSSharedFileListItemResolve(itemRef, 0, (CFURLRef*) &url, NULL) == noErr) { + NSString * urlPath = [(NSURL*)CFBridgingRelease(url) path]; + if ([urlPath compare:appPath] == NSOrderedSame){ + return true; + } + } + } + //[loginItemsArray release]; + } + + return false; +} + +- (void) addAppAsLoginItem +{ + NSString * appPath = [[NSBundle mainBundle] bundlePath]; + + // This will retrieve the path for the application + // For example, /Applications/test.app + CFURLRef url = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:appPath]); + + // Create a reference to the shared file list. + // We are adding it to the current user only. + // If we want to add it all users, use + // kLSSharedFileListGlobalLoginItems instead of + //kLSSharedFileListSessionLoginItems + LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, + kLSSharedFileListSessionLoginItems, NULL); + if (loginItems) { + //Insert an item to the list. + LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(loginItems, + kLSSharedFileListItemLast, NULL, NULL, + url, NULL, NULL); + if (item){ + CFRelease(item); + } + } + + CFRelease(loginItems); +} + +- (void) deleteAppFromLoginItem +{ + NSString * appPath = [[NSBundle mainBundle] bundlePath]; + + // This will retrieve the path for the application + // For example, /Applications/test.app + CFURLRef url = (CFURLRef)CFBridgingRetain([NSURL fileURLWithPath:appPath]); + + // Create a reference to the shared file list. + LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, + kLSSharedFileListSessionLoginItems, NULL); + + if (loginItems) { + UInt32 seedValue; + //Retrieve the list of Login Items and cast them to + // a NSArray so that it will be easier to iterate. + NSArray *loginItemsArray = (NSArray *)CFBridgingRelease(LSSharedFileListCopySnapshot(loginItems, &seedValue)); + int i = 0; + for(i = 0 ; i< [loginItemsArray count]; i++){ + LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)CFBridgingRetain([loginItemsArray + objectAtIndex:i]); + //Resolve the item with URL + if (LSSharedFileListItemResolve(itemRef, 0, (CFURLRef*) &url, NULL) == noErr) { + NSString * urlPath = [(NSURL*)CFBridgingRelease(url) path]; + if ([urlPath compare:appPath] == NSOrderedSame){ + LSSharedFileListItemRemove(loginItems,itemRef); + } + } + } + //[loginItemsArray release]; + } +} + +- (IBAction)togglePlaySoundItem:(id)sender{ + if ([sender state] == NSOnState) { + [[NSUserDefaults standardUserDefaults] setObject:@"true" forKey:@"playSound"]; + } else { + [[NSUserDefaults standardUserDefaults] setObject:@"false" forKey:@"playSound"]; + } +} + +- (IBAction)toggleAutoCloseItem:(id)sender +{ + if ([sender state] == NSOnState) { + [[NSUserDefaults standardUserDefaults] setObject:@"true" forKey:@"autoClose"]; + } else { + [[NSUserDefaults standardUserDefaults] setObject:@"false" forKey:@"autoClose"]; + } +} + +- (IBAction)changeTopLimit:(id)sender{ + [topLimit setIntegerValue:[sender integerValue]]; + [[NSUserDefaults standardUserDefaults] setObject:[sender stringValue] forKey:@"topLimit"]; +} + +- (IBAction)changeBottomLimit:(id)sender +{ + [bottomLimit setIntegerValue:[sender integerValue]]; + [[NSUserDefaults standardUserDefaults] setObject:[sender stringValue] forKey:@"bottomLimit"]; +} + + +@end diff --git a/BateryProlonger/battery.iconset/icon_128x128.png b/BateryProlonger/battery.iconset/icon_128x128.png index dcd922b..452721b 100644 Binary files a/BateryProlonger/battery.iconset/icon_128x128.png and b/BateryProlonger/battery.iconset/icon_128x128.png differ diff --git a/BateryProlonger/battery.iconset/icon_128x128@2x.png b/BateryProlonger/battery.iconset/icon_128x128@2x.png new file mode 100644 index 0000000..0155ca6 Binary files /dev/null and b/BateryProlonger/battery.iconset/icon_128x128@2x.png differ diff --git a/BateryProlonger/battery.iconset/icon_16x16.png b/BateryProlonger/battery.iconset/icon_16x16.png index abe57b1..fca0bda 100644 Binary files a/BateryProlonger/battery.iconset/icon_16x16.png and b/BateryProlonger/battery.iconset/icon_16x16.png differ diff --git a/BateryProlonger/battery.iconset/icon_16x16@2x.png b/BateryProlonger/battery.iconset/icon_16x16@2x.png new file mode 100644 index 0000000..b3a7627 Binary files /dev/null and b/BateryProlonger/battery.iconset/icon_16x16@2x.png differ diff --git a/BateryProlonger/battery.iconset/icon_256x256.png b/BateryProlonger/battery.iconset/icon_256x256.png index 264f2e3..0155ca6 100644 Binary files a/BateryProlonger/battery.iconset/icon_256x256.png and b/BateryProlonger/battery.iconset/icon_256x256.png differ diff --git a/BateryProlonger/battery.iconset/icon_256x256@2x.png b/BateryProlonger/battery.iconset/icon_256x256@2x.png new file mode 100644 index 0000000..818bcc2 Binary files /dev/null and b/BateryProlonger/battery.iconset/icon_256x256@2x.png differ diff --git a/BateryProlonger/battery.iconset/icon_32x32.png b/BateryProlonger/battery.iconset/icon_32x32.png index fe064e9..b3a7627 100644 Binary files a/BateryProlonger/battery.iconset/icon_32x32.png and b/BateryProlonger/battery.iconset/icon_32x32.png differ diff --git a/BateryProlonger/battery.iconset/icon_32x32@2x.png b/BateryProlonger/battery.iconset/icon_32x32@2x.png new file mode 100644 index 0000000..9140d8f Binary files /dev/null and b/BateryProlonger/battery.iconset/icon_32x32@2x.png differ diff --git a/BateryProlonger/battery.iconset/icon_512x512.png b/BateryProlonger/battery.iconset/icon_512x512.png index 98ef62e..818bcc2 100644 Binary files a/BateryProlonger/battery.iconset/icon_512x512.png and b/BateryProlonger/battery.iconset/icon_512x512.png differ diff --git a/BateryProlonger/battery.iconset/icon_512x512@2x.png b/BateryProlonger/battery.iconset/icon_512x512@2x.png new file mode 100644 index 0000000..6f98faf Binary files /dev/null and b/BateryProlonger/battery.iconset/icon_512x512@2x.png differ diff --git a/BateryProlonger/en.lproj/MainMenu.xib b/BateryProlonger/en.lproj/MainMenu.xib index 761d0f4..7fd3c9e 100644 --- a/BateryProlonger/en.lproj/MainMenu.xib +++ b/BateryProlonger/en.lproj/MainMenu.xib @@ -66,14 +66,13 @@ - + - Start on login + Preferences 2147483647 - 2 @@ -113,21 +112,13 @@ 553 - - - startAtLoginMenuItem - - - - 555 - - toogleLoginItem: + openPreferencesWindow: - + - 556 + 558 @@ -170,10 +161,10 @@ 536 - - + + @@ -193,8 +184,8 @@ - 554 - + 557 + @@ -209,13 +200,13 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin - 556 + 558 @@ -224,32 +215,29 @@ NSObject id - id + id openAboutWindow: id - - toogleLoginItem: + + openPreferencesWindow: id - - NSMenuItem - NSMenu - - - - startAtLoginMenuItem - NSMenuItem - - + + statusMenu + NSMenu + + + statusMenu + statusMenu NSMenu - + IBProjectSource ./Classes/AppDelegate.h diff --git a/BateryProlonger/icon-small.png b/BateryProlonger/icon-small.png index f165291..81b986f 100644 Binary files a/BateryProlonger/icon-small.png and b/BateryProlonger/icon-small.png differ