├── WakaLet ├── en.lproj │ ├── InfoPlist.strings │ ├── Credits.rtf │ └── MainMenu.xib ├── waka.png ├── menubaricon.png ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── waka128.png │ │ ├── waka16.png │ │ ├── waka256.png │ │ ├── waka32-1.png │ │ ├── waka32.png │ │ ├── waka512.png │ │ ├── waka64.png │ │ ├── waka256-1.png │ │ ├── waka512-1.png │ │ └── Contents.json │ └── AppIconTransparent.appiconset │ │ ├── waka128.png │ │ ├── waka16.png │ │ ├── waka256.png │ │ ├── waka32.png │ │ ├── waka512.png │ │ ├── waka64.png │ │ ├── waka256-1.png │ │ ├── waka32-1.png │ │ ├── waka512-1.png │ │ └── Contents.json ├── wakalet-Prefix.pch ├── main.m ├── WLMenu.h ├── NSMenuItem+Equal.h ├── AppDelegate.h ├── NSMenuItem+Equal.m ├── wakalet-Info.plist ├── WLMenu.m └── AppDelegate.m ├── Screenshots └── screen1.png ├── README.md └── wakalet.xcodeproj ├── xcuserdata ├── macbook.xcuserdatad │ ├── xcdebugger │ │ └── Breakpoints.xcbkptlist │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ └── TextLet.xcscheme └── jontelang.xcuserdatad │ ├── xcschemes │ ├── xcschememanagement.plist │ ├── WakaLet Release.xcscheme │ └── WakaLet Debug.xcscheme │ └── xcdebugger │ └── Breakpoints_v2.xcbkptlist ├── project.xcworkspace ├── contents.xcworkspacedata ├── xcuserdata │ ├── macbook.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings │ └── jontelang.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings └── xcshareddata │ └── wakalet.xccheckout └── project.pbxproj /WakaLet/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /WakaLet/waka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/waka.png -------------------------------------------------------------------------------- /Screenshots/screen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/Screenshots/screen1.png -------------------------------------------------------------------------------- /WakaLet/menubaricon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/menubaricon.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WakaLet 2 | Wakatime.com OSX menulet (menubar application) 3 | 4 | ![Screenshot of the app](Screenshots/screen1.png) -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIcon.appiconset/waka128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIcon.appiconset/waka128.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIcon.appiconset/waka16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIcon.appiconset/waka16.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIcon.appiconset/waka256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIcon.appiconset/waka256.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIcon.appiconset/waka32-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIcon.appiconset/waka32-1.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIcon.appiconset/waka32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIcon.appiconset/waka32.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIcon.appiconset/waka512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIcon.appiconset/waka512.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIcon.appiconset/waka64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIcon.appiconset/waka64.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIcon.appiconset/waka256-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIcon.appiconset/waka256-1.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIcon.appiconset/waka512-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIcon.appiconset/waka512-1.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka128.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka16.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka256.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka32.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka512.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka64.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka256-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka256-1.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka32-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka32-1.png -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka512-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/WakaLet/Images.xcassets/AppIconTransparent.appiconset/waka512-1.png -------------------------------------------------------------------------------- /wakalet.xcodeproj/xcuserdata/macbook.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /WakaLet/wakalet-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'WakaLet' target in the 'WakaLet' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /wakalet.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /wakalet.xcodeproj/project.xcworkspace/xcuserdata/macbook.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/wakalet.xcodeproj/project.xcworkspace/xcuserdata/macbook.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /wakalet.xcodeproj/project.xcworkspace/xcuserdata/jontelang.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontelang/WakaLet/HEAD/wakalet.xcodeproj/project.xcworkspace/xcuserdata/jontelang.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WakaLet/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WakaLet 4 | // 5 | // Created by Jonathan Winger Lang on 13/01/13. 6 | // Copyright (c) 2013 Jonathan Winger Lang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | return NSApplicationMain(argc, (const char **)argv); 14 | } 15 | -------------------------------------------------------------------------------- /WakaLet/WLMenu.h: -------------------------------------------------------------------------------- 1 | // 2 | // WLMenu.h 3 | // wakalet 4 | // 5 | // Created by Sergey Ryazanov on 28.04.15. 6 | // Copyright (c) 2015 Jonathan Winger Lang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface WLMenu : NSMenu 12 | 13 | @property (nonatomic, assign) BOOL showQuitButton; // Default: YES 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WakaLet/NSMenuItem+Equal.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSMenuItem+Equal.h 3 | // wakalet 4 | // 5 | // Created by Sergey Ryazanov on 06.05.15. 6 | // Copyright (c) 2015 Jonathan Winger Lang. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSMenuItem (Equal) 12 | 13 | - (BOOL)isSameWithMenuItem:(NSMenuItem *)checkItem; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /WakaLet/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WakaLet 4 | // 5 | // Created by Jonathan Winger Lang on 13/01/13. 6 | // Copyright (c) 2013 Jonathan Winger Lang. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "WLMenu.h" 11 | 12 | @interface AppDelegate : NSObject 13 | { 14 | NSStatusItem *statusItem; 15 | WLMenu *statusMenu; 16 | } 17 | @end 18 | -------------------------------------------------------------------------------- /wakalet.xcodeproj/project.xcworkspace/xcuserdata/jontelang.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /wakalet.xcodeproj/project.xcworkspace/xcuserdata/macbook.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /WakaLet/en.lproj/Credits.rtf: -------------------------------------------------------------------------------- 1 | {\rtf0\ansi{\fonttbl\f0\fswiss Helvetica;} 2 | {\colortbl;\red255\green255\blue255;} 3 | \paperw9840\paperh8400 4 | \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural 5 | 6 | \f0\b\fs24 \cf0 Engineering: 7 | \b0 \ 8 | Some people\ 9 | \ 10 | 11 | \b Human Interface Design: 12 | \b0 \ 13 | Some other people\ 14 | \ 15 | 16 | \b Testing: 17 | \b0 \ 18 | Hopefully not nobody\ 19 | \ 20 | 21 | \b Documentation: 22 | \b0 \ 23 | Whoever\ 24 | \ 25 | 26 | \b With special thanks to: 27 | \b0 \ 28 | Mom\ 29 | } 30 | -------------------------------------------------------------------------------- /wakalet.xcodeproj/xcuserdata/macbook.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | TextLet.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | FA0DC49116A2F38A00E72B66 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /WakaLet/NSMenuItem+Equal.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSMenuItem+Equal.m 3 | // wakalet 4 | // 5 | // Created by Sergey Ryazanov on 06.05.15. 6 | // Copyright (c) 2015 Jonathan Winger Lang. All rights reserved. 7 | // 8 | 9 | #import "NSMenuItem+Equal.h" 10 | 11 | @implementation NSMenuItem (Equal) 12 | 13 | - (BOOL)isSameWithMenuItem:(NSMenuItem *)checkItem 14 | { 15 | if ([self.title isEqualToString:checkItem.title] 16 | && [NSStringFromSelector(self.action) isEqualToString:NSStringFromSelector(checkItem.action)] 17 | && [self.keyEquivalent isEqualToString:checkItem.keyEquivalent]) 18 | { 19 | return YES; 20 | } 21 | return NO; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /wakalet.xcodeproj/xcuserdata/jontelang.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WakaLet Debug.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | WakaLet Release.xcscheme 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | FA0DC49116A2F38A00E72B66 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /WakaLet/wakalet-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.jontelang.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 0.3 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSApplicationCategoryType 24 | public.app-category.utilities 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | LSUIElement 28 | 29 | NSHumanReadableCopyright 30 | Copyright © 2013 Jonathan Winger Lang. All rights reserved. 31 | NSMainNibFile 32 | MainMenu 33 | NSPrincipalClass 34 | NSApplication 35 | 36 | 37 | -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "waka16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "waka32-1.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "waka32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "waka64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "waka128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "waka256-1.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "waka256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "waka512-1.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "waka512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "idiom" : "mac", 59 | "size" : "512x512", 60 | "scale" : "2x" 61 | } 62 | ], 63 | "info" : { 64 | "version" : 1, 65 | "author" : "xcode" 66 | } 67 | } -------------------------------------------------------------------------------- /WakaLet/Images.xcassets/AppIconTransparent.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "waka16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "waka32-1.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "waka32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "waka64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "waka128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "waka256-1.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "waka256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "waka512-1.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "waka512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "idiom" : "mac", 59 | "size" : "512x512", 60 | "scale" : "2x" 61 | } 62 | ], 63 | "info" : { 64 | "version" : 1, 65 | "author" : "xcode" 66 | } 67 | } -------------------------------------------------------------------------------- /wakalet.xcodeproj/xcuserdata/jontelang.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /wakalet.xcodeproj/project.xcworkspace/xcshareddata/wakalet.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 7A1DE2F4-1FED-4AA6-8B55-0C033B8E580D 9 | IDESourceControlProjectName 10 | wakalet 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 55911430A31892DF20010BE2A32B8C6E2FC8F81C 14 | https://github.com/jontelang/WakaLet.git 15 | 16 | IDESourceControlProjectPath 17 | wakalet.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 55911430A31892DF20010BE2A32B8C6E2FC8F81C 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/jontelang/WakaLet.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 55911430A31892DF20010BE2A32B8C6E2FC8F81C 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 55911430A31892DF20010BE2A32B8C6E2FC8F81C 36 | IDESourceControlWCCName 37 | OSX_wakalet 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /WakaLet/WLMenu.m: -------------------------------------------------------------------------------- 1 | // 2 | // WLMenu.m 3 | // wakalet 4 | // 5 | // Created by Sergey Ryazanov on 28.04.15. 6 | // Copyright (c) 2015 Jonathan Winger Lang. All rights reserved. 7 | // 8 | 9 | #import "WLMenu.h" 10 | 11 | @interface WLMenu () 12 | 13 | @property (nonatomic, retain) NSMenuItem *quitItem; 14 | 15 | @end 16 | 17 | @implementation WLMenu 18 | 19 | - (instancetype)init 20 | { 21 | self = [super init]; 22 | if (self) { 23 | self.quitItem = [[NSMenuItem alloc] initWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@"q"]; 24 | self.showQuitButton = YES; 25 | } 26 | return self; 27 | } 28 | 29 | #pragma mark - 30 | 31 | - (NSMenuItem *)addItemWithTitle:(NSString *)aString action:(SEL)aSelector keyEquivalent:(NSString *)charCode 32 | { 33 | NSMenuItem *newItem = [[NSMenuItem alloc] initWithTitle:aString action:aSelector keyEquivalent:charCode]; 34 | [self addItem:newItem]; 35 | return newItem; 36 | } 37 | 38 | 39 | - (void)addItem:(NSMenuItem *)newItem 40 | { 41 | if (newItem) { 42 | [super addItem:newItem]; 43 | [self updateQuitButton]; 44 | } 45 | } 46 | 47 | #pragma mark - Quit button 48 | 49 | - (void)updateQuitButton 50 | { 51 | [self removeQuitButton]; 52 | [self addQuitButtonIfNeeded]; 53 | } 54 | 55 | - (void)removeQuitButton 56 | { 57 | NSInteger index = [self indexOfItem:_quitItem]; 58 | if (index != -1 && index < self.numberOfItems) { 59 | [self removeItemAtIndex:index]; 60 | } 61 | } 62 | 63 | - (void)addQuitButtonIfNeeded 64 | { 65 | if (_quitItem) { 66 | if (self.showQuitButton) { 67 | [self insertItem:_quitItem atIndex:self.numberOfItems]; 68 | } 69 | } 70 | } 71 | 72 | #pragma mark - Setters 73 | 74 | - (void)setShowQuitButton:(BOOL)showQuitButton 75 | { 76 | _showQuitButton = showQuitButton; 77 | [self updateQuitButton]; 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /wakalet.xcodeproj/xcuserdata/macbook.xcuserdatad/xcschemes/TextLet.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /wakalet.xcodeproj/xcuserdata/jontelang.xcuserdatad/xcschemes/WakaLet Release.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /wakalet.xcodeproj/xcuserdata/jontelang.xcuserdatad/xcschemes/WakaLet Debug.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /WakaLet/en.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1080 5 | 12C54 6 | 2843 7 | 1187.34 8 | 625.00 9 | 10 | com.apple.InterfaceBuilder.CocoaPlugin 11 | 2843 12 | 13 | 14 | NSCustomObject 15 | 16 | 17 | com.apple.InterfaceBuilder.CocoaPlugin 18 | 19 | 20 | PluginDependencyRecalculationVersion 21 | 22 | 23 | 24 | 25 | NSApplication 26 | 27 | 28 | FirstResponder 29 | 30 | 31 | NSApplication 32 | 33 | 34 | AppDelegate 35 | 36 | 37 | NSFontManager 38 | 39 | 40 | 41 | 42 | 43 | 44 | delegate 45 | 46 | 47 | 48 | 495 49 | 50 | 51 | 52 | 53 | 54 | 0 55 | 56 | 57 | 58 | 59 | 60 | -2 61 | 62 | 63 | File's Owner 64 | 65 | 66 | -1 67 | 68 | 69 | First Responder 70 | 71 | 72 | -3 73 | 74 | 75 | Application 76 | 77 | 78 | 420 79 | 80 | 81 | 82 | 83 | 494 84 | 85 | 86 | 87 | 88 | 89 | 90 | com.apple.InterfaceBuilder.CocoaPlugin 91 | com.apple.InterfaceBuilder.CocoaPlugin 92 | com.apple.InterfaceBuilder.CocoaPlugin 93 | com.apple.InterfaceBuilder.CocoaPlugin 94 | com.apple.InterfaceBuilder.CocoaPlugin 95 | 96 | 97 | 98 | 99 | 100 | 567 101 | 102 | 103 | 0 104 | IBCocoaFramework 105 | YES 106 | 3 107 | YES 108 | 109 | 110 | -------------------------------------------------------------------------------- /WakaLet/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WakaLet 4 | // 5 | // Created by Jonathan Winger Lang on 13/01/13. 6 | // Copyright (c) 2013 Jonathan Winger Lang. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import 11 | #import "NSMenuItem+Equal.h" 12 | 13 | @implementation AppDelegate 14 | 15 | -(void)applicationDidFinishLaunching:(NSNotification *)aNotification{ 16 | // Insert code here to initialize your application 17 | } 18 | 19 | -(void)awakeFromNib{ 20 | statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength]; 21 | [statusItem setTitle:@"W"]; 22 | //[statusItem setImage:[NSImage imageNamed:@"menubaricon.png"]]; 23 | [statusItem setHighlightMode:YES]; 24 | statusMenu = [[WLMenu alloc] init]; 25 | [statusMenu setDelegate:self]; 26 | [statusItem setMenu:statusMenu]; 27 | [self checkAPIAndBuildMenu]; 28 | } 29 | 30 | -(void)checkAPIAndBuildMenu{ 31 | // Get the manually set API key 32 | NSString *api_key = [[NSUserDefaults standardUserDefaults] valueForKey:@"api_key"]; 33 | 34 | // If there is no key though, just show the add-API-key entry 35 | if( api_key == nil ){ 36 | [self addItemInMenuIfNeeded:[[NSMenuItem alloc] initWithTitle:@"Set API key" action:@selector(openSetApi) keyEquivalent:@"a"]]; 37 | } 38 | 39 | // If there is one, initiate the request 40 | else{ 41 | // Get the current date, and 7 days back 42 | NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 43 | [formatter setDateFormat:@"MM/dd/YYYY"]; 44 | NSString *todayDate = [formatter stringFromDate:[NSDate date]]; 45 | NSString *someDaysAgoDate = [formatter stringFromDate:[[NSDate date] dateByAddingTimeInterval:3600*24*7*-1]]; 46 | 47 | // Build the parameters for the string 48 | NSString *dataString = [NSString stringWithFormat:@"?start=%@&end=%@&api_key=%@",someDaysAgoDate,todayDate,api_key]; 49 | 50 | // The general API url 51 | NSString *urlString = [@"https://wakatime.com/api/v1/users/current/summaries" stringByAppendingString:dataString]; 52 | 53 | // Request the data 54 | NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]; 55 | 56 | // Let the user know we are refreshing 57 | [statusMenu removeAllItems]; 58 | [self addItemInMenuIfNeeded:[[NSMenuItem alloc] initWithTitle:@"Refreshing.." action:nil keyEquivalent:@""]]; 59 | 60 | // Record the date of the refresh/api get 61 | [[NSUserDefaults standardUserDefaults] setValue:[NSDate date] 62 | forKey:@"refresh"]; 63 | 64 | // Go go go 65 | //NSLog(@"Request: %@", request); 66 | [NSURLConnection sendAsynchronousRequest:request 67 | queue:[[NSOperationQueue alloc] init] 68 | completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { 69 | 70 | // Show possible errors 71 | if( connectionError != nil ){ 72 | [self addItemInMenuIfNeeded:[[NSMenuItem alloc] initWithTitle:connectionError.localizedDescription 73 | action:@selector(openSetApi) 74 | keyEquivalent:@""]]; 75 | } 76 | 77 | // Else just try to build the menu 78 | else{ 79 | // The data 80 | NSError *err; 81 | NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&err]; 82 | 83 | // If there is no error, build the wakalet 84 | if( err == nil ) { 85 | [self performSelectorOnMainThread:@selector(buildMenuWithData:) withObject:dict waitUntilDone:NO]; 86 | } 87 | 88 | // Otherwise let's show the error somehow 89 | else{ 90 | [self addItemInMenuIfNeeded:[[NSMenuItem alloc] initWithTitle:err.localizedDescription 91 | action:@selector(openSetApi) 92 | keyEquivalent:@""]]; 93 | } 94 | } 95 | }]; 96 | } 97 | } 98 | 99 | -(void)addApiMenuWithTitle:(NSString *)title{ 100 | dispatch_async(dispatch_get_main_queue(), ^{ 101 | [statusMenu addItem:[[NSMenuItem alloc] initWithTitle:title action:@selector(openSetApi) keyEquivalent:@""]]; 102 | }); 103 | } 104 | 105 | -(void)openSetApi{ 106 | NSString *old_apo_key = [[NSUserDefaults standardUserDefaults] valueForKey:@"api_key"]; 107 | NSString *api_key = [self input:@"Enter your API key" defaultValue:old_apo_key==nil?@"":old_apo_key]; 108 | 109 | if( api_key != nil ){ 110 | [[NSUserDefaults standardUserDefaults] setValue:api_key forKey:@"api_key"]; 111 | [[NSUserDefaults standardUserDefaults] synchronize]; 112 | } 113 | 114 | [self checkAPIAndBuildMenu]; 115 | } 116 | 117 | -(NSString*)input:(NSString *)prompt defaultValue:(NSString*)defaultValue{ 118 | NSAlert *alert = [NSAlert alertWithMessageText:prompt 119 | defaultButton:@"OK" 120 | alternateButton:@"Cancel" 121 | otherButton:nil 122 | informativeTextWithFormat:@"You can find your API key at https://wakatime.com/settings#apikey"]; 123 | 124 | NSTextField *input = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 400, 24)]; 125 | [input setStringValue:defaultValue]; 126 | [alert setAccessoryView:input]; 127 | [alert setIcon:[NSImage imageNamed:@"waka.png"]]; 128 | NSInteger button = [alert runModal]; 129 | if (button == NSAlertDefaultReturn) { 130 | [input validateEditing]; 131 | return [input stringValue]; 132 | } else if (button == NSAlertAlternateReturn) { 133 | return nil; 134 | } else { 135 | NSAssert1(NO, @"Invalid input dialog button %lu", (long)button); 136 | return nil; 137 | } 138 | } 139 | 140 | -(void)menuWillOpen:(NSMenu *)menu{ 141 | NSMenuItem* timeSinceRefreshItem = [menu itemWithTag:1337]; 142 | timeSinceRefreshItem.title = [self getTimeSinceRefreshTitle]; 143 | } 144 | 145 | -(void)buildMenuWithData:(NSDictionary*)dict{ 146 | //NSLog(@"%@",dict); 147 | 148 | // Remove any existing menu 149 | [statusMenu removeAllItems]; 150 | 151 | // This is a spacer object only 152 | NSMenuItem *spacer = [[NSMenuItem alloc] init]; 153 | [spacer setView:[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 1, 7)]]; 154 | [statusMenu addItem:spacer]; 155 | 156 | // Let's find some data, reverse it to get it in the right order 157 | NSArray *dataObjArray = [[[dict valueForKey:@"data"] reverseObjectEnumerator] allObjects]; 158 | 159 | // Build stuff 160 | for (int i = 0; i < [dataObjArray count]; i++) { 161 | 162 | // Get some data 163 | NSDictionary *dataObj = [dataObjArray objectAtIndex:i]; 164 | NSDictionary *grandObj = [dataObj objectForKey:@"grand_total"]; 165 | NSInteger *totalseconds = [[grandObj valueForKey:@"total_seconds"] integerValue]; 166 | NSDictionary *rangeObj = [dataObj objectForKey:@"range"]; 167 | NSString* date = [rangeObj valueForKey:@"date"]; 168 | NSString* date_human = [rangeObj valueForKey:@"text"]; 169 | NSString* grand_total_text = [grandObj valueForKey:@"text"]; 170 | 171 | // Each item is clickable, we store the url to the date in it's tooltip 172 | NSMenuItem *dateItem = [[NSMenuItem alloc] initWithTitle:date_human 173 | action:@selector(openUrlFromMenuItemTooltip:) 174 | keyEquivalent:@""]; 175 | dateItem.toolTip = [NSString stringWithFormat:@"http://www.wakatime.com/dashboard/day?date=%@",date]; 176 | [statusMenu addItem:dateItem]; 177 | 178 | // We only grab more data if there is data recorded 179 | if( totalseconds > 0 ){ 180 | 181 | // Get stuff from the projects object 182 | NSArray *projectsObjArray = [dataObj objectForKey:@"projects"]; 183 | for (int j = 0; j < [projectsObjArray count]; j++) { 184 | NSDictionary *projectObj = [projectsObjArray objectAtIndex:j]; 185 | NSString *name = [projectObj valueForKey:@"name"]; 186 | NSString *time = [projectObj valueForKey:@"digital"]; 187 | name = [NSString stringWithFormat:@" %@ (%@)", name, time]; 188 | NSMenuItem *item = [[NSMenuItem alloc] init]; 189 | item.enabled = NO; 190 | [item setTitle:name]; 191 | [item setTag:i]; 192 | [item setKeyEquivalent:@""]; 193 | [item setAction:nil]; 194 | [item setImage:nil]; 195 | item.toolTip = [NSString stringWithFormat:@"Total for day: %@",grand_total_text]; 196 | [statusMenu addItem:item]; 197 | } 198 | } 199 | 200 | // Otherwise just show that there is no data for the date 201 | else{ 202 | NSMenuItem *noDataItem = [[NSMenuItem alloc] initWithTitle:@" No data" action:nil keyEquivalent:@""]; 203 | noDataItem.enabled = NO; 204 | [statusMenu addItem:noDataItem]; 205 | } 206 | 207 | // 208 | NSMenuItem *spacer = [[NSMenuItem alloc] init]; 209 | [spacer setView:[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 1, 7)]]; 210 | [statusMenu addItem:spacer]; 211 | } 212 | 213 | // Add verious other menu items 214 | [statusMenu addItem:[NSMenuItem separatorItem]]; 215 | 216 | // Calculate the last refresh time 217 | NSMenuItem *timeSinceRefreshItem = [[NSMenuItem alloc] initWithTitle:[self getTimeSinceRefreshTitle] 218 | action:nil keyEquivalent:@""]; 219 | timeSinceRefreshItem.enabled = NO; 220 | timeSinceRefreshItem.tag = 1337; 221 | [statusMenu addItem:timeSinceRefreshItem]; 222 | 223 | // Add more various stuffs 224 | [self addItemInMenuIfNeeded:[[NSMenuItem alloc] initWithTitle:@"Refresh now" action:@selector(checkAPIAndBuildMenu) keyEquivalent:@"r"]]; 225 | [self addItemInMenuIfNeeded:[[NSMenuItem alloc] initWithTitle:@"Dashboard" action:@selector(openWakaletDashboard) keyEquivalent:@"d"]]; 226 | [self addItemInMenuIfNeeded:[[NSMenuItem alloc] initWithTitle:@"Set API key" action:@selector(openSetApi) keyEquivalent:@"a"]]; 227 | 228 | } 229 | 230 | #pragma mark - 231 | 232 | -(BOOL)checkIsItemInMenu:(NSMenuItem *)checkItem{ 233 | for (NSMenuItem *item in statusMenu.itemArray) { 234 | if ([item isSameWithMenuItem:checkItem]) { 235 | return YES; 236 | } 237 | } 238 | return NO; 239 | } 240 | 241 | -(void)addItemInMenuIfNeeded:(NSMenuItem *)menuItem{ 242 | if (NO == [self checkIsItemInMenu:menuItem]) { 243 | [statusMenu addItem:menuItem]; 244 | } 245 | } 246 | 247 | 248 | #pragma mark Clicky methods 249 | 250 | -(void)openUrlFromMenuItemTooltip:(NSMenuItem*)menuItem{ 251 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:menuItem.toolTip]]; 252 | } 253 | 254 | -(void)openWakaletDashboard{ 255 | [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.wakatime.com/dashboard"]]; 256 | } 257 | 258 | -(NSString*)getTimeSinceRefreshTitle{ 259 | NSDate *refreshDate = (NSDate*)[[NSUserDefaults standardUserDefaults] valueForKey:@"refresh"]; 260 | int lastRefreshTimeStamp = (int)[refreshDate timeIntervalSince1970]; 261 | int currentTimeStamp = (int)[[NSDate date] timeIntervalSince1970]; 262 | int secondsAgo = currentTimeStamp - lastRefreshTimeStamp; 263 | if( secondsAgo < 60 ){ 264 | if( secondsAgo == 1 ){ 265 | return [NSString stringWithFormat:@"Last refresh: %i second ago",secondsAgo]; 266 | }else{ 267 | return [NSString stringWithFormat:@"Last refresh: %i seconds ago",secondsAgo]; 268 | } 269 | } 270 | else if( secondsAgo < 3600 ){ 271 | if( secondsAgo/60 == 1 ){ 272 | return [NSString stringWithFormat:@"Last refresh: Around %i minute ago",secondsAgo/60]; 273 | }else{ 274 | return [NSString stringWithFormat:@"Last refresh: Around %i minutes ago",secondsAgo/60]; 275 | } 276 | } 277 | else if( secondsAgo < 3600*24){ 278 | if( secondsAgo/3600 == 1 ){ 279 | return [NSString stringWithFormat:@"Last refresh: Around %i hour ago",secondsAgo/3600]; 280 | }else{ 281 | return [NSString stringWithFormat:@"Last refresh: Around %i hours ago",secondsAgo/3600]; 282 | } 283 | } 284 | else{ 285 | return [NSString stringWithFormat:@"Last refresh: A looong time ago"]; 286 | } 287 | } 288 | 289 | @end 290 | -------------------------------------------------------------------------------- /wakalet.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4D2F75951AFA5DF6000C9923 /* NSMenuItem+Equal.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D2F75941AFA5DF6000C9923 /* NSMenuItem+Equal.m */; }; 11 | 4D2F75991AFA5F60000C9923 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4D2F75981AFA5F60000C9923 /* Images.xcassets */; }; 12 | 4D4629C31AD990D400D14216 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D4629B61AD990D400D14216 /* AppDelegate.m */; }; 13 | 4D4629C41AD990D400D14216 /* Credits.rtf in Resources */ = {isa = PBXBuildFile; fileRef = 4D4629B81AD990D400D14216 /* Credits.rtf */; }; 14 | 4D4629C51AD990D400D14216 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 4D4629BA1AD990D400D14216 /* InfoPlist.strings */; }; 15 | 4D4629C61AD990D400D14216 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4D4629BC1AD990D400D14216 /* MainMenu.xib */; }; 16 | 4D4629C71AD990D400D14216 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4D4629BE1AD990D400D14216 /* main.m */; }; 17 | 4D4629C81AD990D400D14216 /* menubaricon.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D4629BF1AD990D400D14216 /* menubaricon.png */; }; 18 | 4D4629C91AD990D400D14216 /* waka.png in Resources */ = {isa = PBXBuildFile; fileRef = 4D4629C01AD990D400D14216 /* waka.png */; }; 19 | 52E329551AEFE17700D1D671 /* WLMenu.m in Sources */ = {isa = PBXBuildFile; fileRef = 52E329541AEFE17700D1D671 /* WLMenu.m */; }; 20 | FA0DC49716A2F38A00E72B66 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA0DC49616A2F38A00E72B66 /* Cocoa.framework */; }; 21 | FABDA2F716A303A700FA3399 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FABDA2F616A303A700FA3399 /* QuartzCore.framework */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | 4D2F75931AFA5DF6000C9923 /* NSMenuItem+Equal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSMenuItem+Equal.h"; path = "WakaLet/NSMenuItem+Equal.h"; sourceTree = SOURCE_ROOT; }; 26 | 4D2F75941AFA5DF6000C9923 /* NSMenuItem+Equal.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSMenuItem+Equal.m"; path = "WakaLet/NSMenuItem+Equal.m"; sourceTree = SOURCE_ROOT; }; 27 | 4D2F75981AFA5F60000C9923 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = wakalet/Images.xcassets; sourceTree = ""; }; 28 | 4D4629B51AD990D400D14216 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = WakaLet/AppDelegate.h; sourceTree = SOURCE_ROOT; }; 29 | 4D4629B61AD990D400D14216 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = WakaLet/AppDelegate.m; sourceTree = SOURCE_ROOT; }; 30 | 4D4629B91AD990D400D14216 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = Credits.rtf; sourceTree = ""; }; 31 | 4D4629BB1AD990D400D14216 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = InfoPlist.strings; sourceTree = ""; }; 32 | 4D4629BD1AD990D400D14216 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = MainMenu.xib; sourceTree = ""; }; 33 | 4D4629BE1AD990D400D14216 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = WakaLet/main.m; sourceTree = SOURCE_ROOT; }; 34 | 4D4629BF1AD990D400D14216 /* menubaricon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = menubaricon.png; path = WakaLet/menubaricon.png; sourceTree = SOURCE_ROOT; }; 35 | 4D4629C01AD990D400D14216 /* waka.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = waka.png; path = WakaLet/waka.png; sourceTree = SOURCE_ROOT; }; 36 | 4D4629C11AD990D400D14216 /* wakalet-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "wakalet-Info.plist"; path = "WakaLet/wakalet-Info.plist"; sourceTree = SOURCE_ROOT; }; 37 | 4D4629C21AD990D400D14216 /* wakalet-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "wakalet-Prefix.pch"; path = "WakaLet/wakalet-Prefix.pch"; sourceTree = SOURCE_ROOT; }; 38 | 4D4629CC1AD990ED00D14216 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; name = en; path = WakaLet/en.lproj/Credits.rtf; sourceTree = SOURCE_ROOT; }; 39 | 4D4629CE1AD990ED00D14216 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = WakaLet/en.lproj/InfoPlist.strings; sourceTree = SOURCE_ROOT; }; 40 | 4D4629D01AD990ED00D14216 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = WakaLet/en.lproj/MainMenu.xib; sourceTree = SOURCE_ROOT; }; 41 | 52E329531AEFE17700D1D671 /* WLMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WLMenu.h; path = WakaLet/WLMenu.h; sourceTree = SOURCE_ROOT; }; 42 | 52E329541AEFE17700D1D671 /* WLMenu.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WLMenu.m; path = WakaLet/WLMenu.m; sourceTree = SOURCE_ROOT; }; 43 | FA0DC49216A2F38A00E72B66 /* wakalet.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = wakalet.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | FA0DC49616A2F38A00E72B66 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 45 | FA0DC49916A2F38A00E72B66 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 46 | FA0DC49A16A2F38A00E72B66 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 47 | FA0DC49B16A2F38A00E72B66 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 48 | FABDA2F616A303A700FA3399 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 49 | /* End PBXFileReference section */ 50 | 51 | /* Begin PBXFrameworksBuildPhase section */ 52 | FA0DC48F16A2F38A00E72B66 /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | FABDA2F716A303A700FA3399 /* QuartzCore.framework in Frameworks */, 57 | FA0DC49716A2F38A00E72B66 /* Cocoa.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 4D4629B71AD990D400D14216 /* en.lproj */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 4D4629B81AD990D400D14216 /* Credits.rtf */, 68 | 4D4629BA1AD990D400D14216 /* InfoPlist.strings */, 69 | 4D4629BC1AD990D400D14216 /* MainMenu.xib */, 70 | ); 71 | name = en.lproj; 72 | path = WakaLet/en.lproj; 73 | sourceTree = SOURCE_ROOT; 74 | }; 75 | FA0DC48716A2F38A00E72B66 = { 76 | isa = PBXGroup; 77 | children = ( 78 | 4D2F75981AFA5F60000C9923 /* Images.xcassets */, 79 | FA0DC49C16A2F38A00E72B66 /* WakaLet */, 80 | FA0DC49516A2F38A00E72B66 /* Frameworks */, 81 | FA0DC49316A2F38A00E72B66 /* Products */, 82 | ); 83 | sourceTree = ""; 84 | }; 85 | FA0DC49316A2F38A00E72B66 /* Products */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | FA0DC49216A2F38A00E72B66 /* wakalet.app */, 89 | ); 90 | name = Products; 91 | sourceTree = ""; 92 | }; 93 | FA0DC49516A2F38A00E72B66 /* Frameworks */ = { 94 | isa = PBXGroup; 95 | children = ( 96 | FABDA2F616A303A700FA3399 /* QuartzCore.framework */, 97 | FA0DC49616A2F38A00E72B66 /* Cocoa.framework */, 98 | FA0DC49816A2F38A00E72B66 /* Other Frameworks */, 99 | ); 100 | name = Frameworks; 101 | sourceTree = ""; 102 | }; 103 | FA0DC49816A2F38A00E72B66 /* Other Frameworks */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | FA0DC49916A2F38A00E72B66 /* AppKit.framework */, 107 | FA0DC49A16A2F38A00E72B66 /* CoreData.framework */, 108 | FA0DC49B16A2F38A00E72B66 /* Foundation.framework */, 109 | ); 110 | name = "Other Frameworks"; 111 | sourceTree = ""; 112 | }; 113 | FA0DC49C16A2F38A00E72B66 /* WakaLet */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 4D2F75931AFA5DF6000C9923 /* NSMenuItem+Equal.h */, 117 | 4D2F75941AFA5DF6000C9923 /* NSMenuItem+Equal.m */, 118 | 52E329531AEFE17700D1D671 /* WLMenu.h */, 119 | 52E329541AEFE17700D1D671 /* WLMenu.m */, 120 | 4D4629B51AD990D400D14216 /* AppDelegate.h */, 121 | 4D4629B61AD990D400D14216 /* AppDelegate.m */, 122 | 4D4629B71AD990D400D14216 /* en.lproj */, 123 | 4D4629BE1AD990D400D14216 /* main.m */, 124 | 4D4629BF1AD990D400D14216 /* menubaricon.png */, 125 | 4D4629C01AD990D400D14216 /* waka.png */, 126 | 4D4629C11AD990D400D14216 /* wakalet-Info.plist */, 127 | 4D4629C21AD990D400D14216 /* wakalet-Prefix.pch */, 128 | FA0DC49D16A2F38A00E72B66 /* Supporting Files */, 129 | ); 130 | name = WakaLet; 131 | path = TextLet; 132 | sourceTree = ""; 133 | }; 134 | FA0DC49D16A2F38A00E72B66 /* Supporting Files */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 4D4629CB1AD990ED00D14216 /* Credits.rtf */, 138 | 4D4629CD1AD990ED00D14216 /* InfoPlist.strings */, 139 | 4D4629CF1AD990ED00D14216 /* MainMenu.xib */, 140 | ); 141 | name = "Supporting Files"; 142 | sourceTree = ""; 143 | }; 144 | /* End PBXGroup section */ 145 | 146 | /* Begin PBXNativeTarget section */ 147 | FA0DC49116A2F38A00E72B66 /* wakalet */ = { 148 | isa = PBXNativeTarget; 149 | buildConfigurationList = FA0DC4B016A2F38A00E72B66 /* Build configuration list for PBXNativeTarget "wakalet" */; 150 | buildPhases = ( 151 | FA0DC48E16A2F38A00E72B66 /* Sources */, 152 | FA0DC48F16A2F38A00E72B66 /* Frameworks */, 153 | FA0DC49016A2F38A00E72B66 /* Resources */, 154 | ); 155 | buildRules = ( 156 | ); 157 | dependencies = ( 158 | ); 159 | name = wakalet; 160 | productName = TextLet; 161 | productReference = FA0DC49216A2F38A00E72B66 /* wakalet.app */; 162 | productType = "com.apple.product-type.application"; 163 | }; 164 | /* End PBXNativeTarget section */ 165 | 166 | /* Begin PBXProject section */ 167 | FA0DC48916A2F38A00E72B66 /* Project object */ = { 168 | isa = PBXProject; 169 | attributes = { 170 | LastUpgradeCheck = 0620; 171 | ORGANIZATIONNAME = "Jonathan Winger Lang"; 172 | }; 173 | buildConfigurationList = FA0DC48C16A2F38A00E72B66 /* Build configuration list for PBXProject "wakalet" */; 174 | compatibilityVersion = "Xcode 3.2"; 175 | developmentRegion = English; 176 | hasScannedForEncodings = 0; 177 | knownRegions = ( 178 | en, 179 | ); 180 | mainGroup = FA0DC48716A2F38A00E72B66; 181 | productRefGroup = FA0DC49316A2F38A00E72B66 /* Products */; 182 | projectDirPath = ""; 183 | projectRoot = ""; 184 | targets = ( 185 | FA0DC49116A2F38A00E72B66 /* wakalet */, 186 | ); 187 | }; 188 | /* End PBXProject section */ 189 | 190 | /* Begin PBXResourcesBuildPhase section */ 191 | FA0DC49016A2F38A00E72B66 /* Resources */ = { 192 | isa = PBXResourcesBuildPhase; 193 | buildActionMask = 2147483647; 194 | files = ( 195 | 4D4629C91AD990D400D14216 /* waka.png in Resources */, 196 | 4D4629C51AD990D400D14216 /* InfoPlist.strings in Resources */, 197 | 4D2F75991AFA5F60000C9923 /* Images.xcassets in Resources */, 198 | 4D4629C81AD990D400D14216 /* menubaricon.png in Resources */, 199 | 4D4629C41AD990D400D14216 /* Credits.rtf in Resources */, 200 | 4D4629C61AD990D400D14216 /* MainMenu.xib in Resources */, 201 | ); 202 | runOnlyForDeploymentPostprocessing = 0; 203 | }; 204 | /* End PBXResourcesBuildPhase section */ 205 | 206 | /* Begin PBXSourcesBuildPhase section */ 207 | FA0DC48E16A2F38A00E72B66 /* Sources */ = { 208 | isa = PBXSourcesBuildPhase; 209 | buildActionMask = 2147483647; 210 | files = ( 211 | 4D4629C71AD990D400D14216 /* main.m in Sources */, 212 | 4D2F75951AFA5DF6000C9923 /* NSMenuItem+Equal.m in Sources */, 213 | 52E329551AEFE17700D1D671 /* WLMenu.m in Sources */, 214 | 4D4629C31AD990D400D14216 /* AppDelegate.m in Sources */, 215 | ); 216 | runOnlyForDeploymentPostprocessing = 0; 217 | }; 218 | /* End PBXSourcesBuildPhase section */ 219 | 220 | /* Begin PBXVariantGroup section */ 221 | 4D4629B81AD990D400D14216 /* Credits.rtf */ = { 222 | isa = PBXVariantGroup; 223 | children = ( 224 | 4D4629B91AD990D400D14216 /* en */, 225 | ); 226 | name = Credits.rtf; 227 | sourceTree = ""; 228 | }; 229 | 4D4629BA1AD990D400D14216 /* InfoPlist.strings */ = { 230 | isa = PBXVariantGroup; 231 | children = ( 232 | 4D4629BB1AD990D400D14216 /* en */, 233 | ); 234 | name = InfoPlist.strings; 235 | sourceTree = ""; 236 | }; 237 | 4D4629BC1AD990D400D14216 /* MainMenu.xib */ = { 238 | isa = PBXVariantGroup; 239 | children = ( 240 | 4D4629BD1AD990D400D14216 /* en */, 241 | ); 242 | name = MainMenu.xib; 243 | sourceTree = ""; 244 | }; 245 | 4D4629CB1AD990ED00D14216 /* Credits.rtf */ = { 246 | isa = PBXVariantGroup; 247 | children = ( 248 | 4D4629CC1AD990ED00D14216 /* en */, 249 | ); 250 | name = Credits.rtf; 251 | sourceTree = ""; 252 | }; 253 | 4D4629CD1AD990ED00D14216 /* InfoPlist.strings */ = { 254 | isa = PBXVariantGroup; 255 | children = ( 256 | 4D4629CE1AD990ED00D14216 /* en */, 257 | ); 258 | name = InfoPlist.strings; 259 | sourceTree = ""; 260 | }; 261 | 4D4629CF1AD990ED00D14216 /* MainMenu.xib */ = { 262 | isa = PBXVariantGroup; 263 | children = ( 264 | 4D4629D01AD990ED00D14216 /* en */, 265 | ); 266 | name = MainMenu.xib; 267 | sourceTree = ""; 268 | }; 269 | /* End PBXVariantGroup section */ 270 | 271 | /* Begin XCBuildConfiguration section */ 272 | FA0DC4AE16A2F38A00E72B66 /* Debug */ = { 273 | isa = XCBuildConfiguration; 274 | buildSettings = { 275 | ALWAYS_SEARCH_USER_PATHS = NO; 276 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 277 | CLANG_CXX_LIBRARY = "libc++"; 278 | CLANG_ENABLE_OBJC_ARC = YES; 279 | CLANG_WARN_EMPTY_BODY = YES; 280 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 281 | COPY_PHASE_STRIP = NO; 282 | GCC_C_LANGUAGE_STANDARD = gnu99; 283 | GCC_DYNAMIC_NO_PIC = NO; 284 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 285 | GCC_OPTIMIZATION_LEVEL = 0; 286 | GCC_PREPROCESSOR_DEFINITIONS = ( 287 | "DEBUG=1", 288 | "$(inherited)", 289 | ); 290 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 291 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 292 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 293 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 294 | GCC_WARN_UNUSED_VARIABLE = YES; 295 | MACOSX_DEPLOYMENT_TARGET = 10.8; 296 | ONLY_ACTIVE_ARCH = YES; 297 | SDKROOT = macosx; 298 | }; 299 | name = Debug; 300 | }; 301 | FA0DC4AF16A2F38A00E72B66 /* Release */ = { 302 | isa = XCBuildConfiguration; 303 | buildSettings = { 304 | ALWAYS_SEARCH_USER_PATHS = NO; 305 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 306 | CLANG_CXX_LIBRARY = "libc++"; 307 | CLANG_ENABLE_OBJC_ARC = YES; 308 | CLANG_WARN_EMPTY_BODY = YES; 309 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 310 | COPY_PHASE_STRIP = YES; 311 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 312 | GCC_C_LANGUAGE_STANDARD = gnu99; 313 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 314 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 315 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 316 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 317 | GCC_WARN_UNUSED_VARIABLE = YES; 318 | MACOSX_DEPLOYMENT_TARGET = 10.8; 319 | SDKROOT = macosx; 320 | }; 321 | name = Release; 322 | }; 323 | FA0DC4B116A2F38A00E72B66 /* Debug */ = { 324 | isa = XCBuildConfiguration; 325 | buildSettings = { 326 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 327 | COMBINE_HIDPI_IMAGES = YES; 328 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 329 | GCC_PREFIX_HEADER = "WakaLet/wakalet-Prefix.pch"; 330 | INFOPLIST_FILE = "WakaLet/wakalet-Info.plist"; 331 | PRODUCT_NAME = wakalet; 332 | WRAPPER_EXTENSION = app; 333 | }; 334 | name = Debug; 335 | }; 336 | FA0DC4B216A2F38A00E72B66 /* Release */ = { 337 | isa = XCBuildConfiguration; 338 | buildSettings = { 339 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 340 | COMBINE_HIDPI_IMAGES = YES; 341 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 342 | GCC_PREFIX_HEADER = "WakaLet/wakalet-Prefix.pch"; 343 | INFOPLIST_FILE = "WakaLet/wakalet-Info.plist"; 344 | PRODUCT_NAME = wakalet; 345 | WRAPPER_EXTENSION = app; 346 | }; 347 | name = Release; 348 | }; 349 | /* End XCBuildConfiguration section */ 350 | 351 | /* Begin XCConfigurationList section */ 352 | FA0DC48C16A2F38A00E72B66 /* Build configuration list for PBXProject "wakalet" */ = { 353 | isa = XCConfigurationList; 354 | buildConfigurations = ( 355 | FA0DC4AE16A2F38A00E72B66 /* Debug */, 356 | FA0DC4AF16A2F38A00E72B66 /* Release */, 357 | ); 358 | defaultConfigurationIsVisible = 0; 359 | defaultConfigurationName = Release; 360 | }; 361 | FA0DC4B016A2F38A00E72B66 /* Build configuration list for PBXNativeTarget "wakalet" */ = { 362 | isa = XCConfigurationList; 363 | buildConfigurations = ( 364 | FA0DC4B116A2F38A00E72B66 /* Debug */, 365 | FA0DC4B216A2F38A00E72B66 /* Release */, 366 | ); 367 | defaultConfigurationIsVisible = 0; 368 | defaultConfigurationName = Release; 369 | }; 370 | /* End XCConfigurationList section */ 371 | }; 372 | rootObject = FA0DC48916A2F38A00E72B66 /* Project object */; 373 | } 374 | --------------------------------------------------------------------------------