├── NAKL ├── ShortcutTableView.m ├── NAKL.icns ├── icon.png ├── icon24.png ├── NAKL-Prefix.pch ├── en.lproj │ ├── InfoPlist.strings │ ├── ShortcutRecorder.strings │ └── NAKL-Info.plist ├── icon_blue_24.png ├── Images-2.xcassets │ └── AppIcon.appiconset │ │ ├── icon.png │ │ ├── icon32.png │ │ ├── icon64.png │ │ ├── icon copy.png │ │ ├── icon256.png │ │ ├── icon32-1.png │ │ ├── icon64-1.png │ │ ├── icon copy-1.png │ │ ├── icon copy-2.png │ │ ├── icon copy-3.png │ │ └── Contents.json ├── Images.xcassets │ └── AppIcon.appiconset │ │ ├── icon16.png │ │ ├── icon32.png │ │ ├── icon128.png │ │ ├── icon16-1.png │ │ ├── icon256.png │ │ ├── icon32-1.png │ │ ├── icon128-1.png │ │ ├── icon256-1.png │ │ ├── icon256-2.png │ │ ├── icon256-3.png │ │ └── Contents.json ├── ShortcutRecorder │ ├── SRKeyCodeTransformer.h │ ├── SRValidator.h │ ├── SRRecorderControl.h │ ├── SRRecorderCell.h │ ├── SRCommon.h │ ├── SRKeyCodeTransformer.m │ ├── SRValidator.m │ ├── SRRecorderControl.m │ └── SRCommon.m ├── main.h ├── HotKey │ ├── PTKeyCodeTranslator.h │ ├── PTHotKeyCenter.h │ ├── PTKeyCombo.h │ ├── PTHotKey.h │ ├── PTKeyCodeTranslator.m │ ├── PTHotKey.m │ ├── PTKeyCombo.m │ └── PTHotKeyCenter.m ├── main.m ├── ShortcutSetting.h ├── vi.lproj │ └── NAKL-Info.plist ├── ExcludedAppsTableViewController.h ├── ShortcutTableViewController.h ├── NAKL-Info.plist ├── NSFileManager+DirectoryLocations.h ├── ShortcutSetting.m ├── PreferencesController.h ├── KeyboardHandler.h ├── AppDelegate.h ├── AppData.h ├── utf8.h ├── CWLSynthesizeSingleton.h ├── ShortcutTableViewController.m ├── AppData.m ├── ExcludedAppsTableViewController.m ├── NSFileManager+DirectoryLocations.m ├── PreferencesController.m ├── keymap.h ├── AppDelegate.m └── KeyboardHandler.m ├── scripts └── EnableAssistiveDevices.applescript ├── .gitignore ├── README.md └── NAKL.xcodeproj └── project.pbxproj /NAKL/ShortcutTableView.m: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /NAKL/NAKL.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/NAKL.icns -------------------------------------------------------------------------------- /NAKL/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/icon.png -------------------------------------------------------------------------------- /NAKL/icon24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/icon24.png -------------------------------------------------------------------------------- /NAKL/NAKL-Prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | -------------------------------------------------------------------------------- /NAKL/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /NAKL/icon_blue_24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/icon_blue_24.png -------------------------------------------------------------------------------- /NAKL/en.lproj/ShortcutRecorder.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/en.lproj/ShortcutRecorder.strings -------------------------------------------------------------------------------- /scripts/EnableAssistiveDevices.applescript: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/scripts/EnableAssistiveDevices.applescript -------------------------------------------------------------------------------- /NAKL/Images-2.xcassets/AppIcon.appiconset/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images-2.xcassets/AppIcon.appiconset/icon.png -------------------------------------------------------------------------------- /NAKL/Images.xcassets/AppIcon.appiconset/icon16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images.xcassets/AppIcon.appiconset/icon16.png -------------------------------------------------------------------------------- /NAKL/Images.xcassets/AppIcon.appiconset/icon32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images.xcassets/AppIcon.appiconset/icon32.png -------------------------------------------------------------------------------- /NAKL/Images-2.xcassets/AppIcon.appiconset/icon32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images-2.xcassets/AppIcon.appiconset/icon32.png -------------------------------------------------------------------------------- /NAKL/Images-2.xcassets/AppIcon.appiconset/icon64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images-2.xcassets/AppIcon.appiconset/icon64.png -------------------------------------------------------------------------------- /NAKL/Images.xcassets/AppIcon.appiconset/icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images.xcassets/AppIcon.appiconset/icon128.png -------------------------------------------------------------------------------- /NAKL/Images.xcassets/AppIcon.appiconset/icon16-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images.xcassets/AppIcon.appiconset/icon16-1.png -------------------------------------------------------------------------------- /NAKL/Images.xcassets/AppIcon.appiconset/icon256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images.xcassets/AppIcon.appiconset/icon256.png -------------------------------------------------------------------------------- /NAKL/Images.xcassets/AppIcon.appiconset/icon32-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images.xcassets/AppIcon.appiconset/icon32-1.png -------------------------------------------------------------------------------- /NAKL/Images-2.xcassets/AppIcon.appiconset/icon copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images-2.xcassets/AppIcon.appiconset/icon copy.png -------------------------------------------------------------------------------- /NAKL/Images-2.xcassets/AppIcon.appiconset/icon256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images-2.xcassets/AppIcon.appiconset/icon256.png -------------------------------------------------------------------------------- /NAKL/Images-2.xcassets/AppIcon.appiconset/icon32-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images-2.xcassets/AppIcon.appiconset/icon32-1.png -------------------------------------------------------------------------------- /NAKL/Images-2.xcassets/AppIcon.appiconset/icon64-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images-2.xcassets/AppIcon.appiconset/icon64-1.png -------------------------------------------------------------------------------- /NAKL/Images.xcassets/AppIcon.appiconset/icon128-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images.xcassets/AppIcon.appiconset/icon128-1.png -------------------------------------------------------------------------------- /NAKL/Images.xcassets/AppIcon.appiconset/icon256-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images.xcassets/AppIcon.appiconset/icon256-1.png -------------------------------------------------------------------------------- /NAKL/Images.xcassets/AppIcon.appiconset/icon256-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images.xcassets/AppIcon.appiconset/icon256-2.png -------------------------------------------------------------------------------- /NAKL/Images.xcassets/AppIcon.appiconset/icon256-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images.xcassets/AppIcon.appiconset/icon256-3.png -------------------------------------------------------------------------------- /NAKL/Images-2.xcassets/AppIcon.appiconset/icon copy-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images-2.xcassets/AppIcon.appiconset/icon copy-1.png -------------------------------------------------------------------------------- /NAKL/Images-2.xcassets/AppIcon.appiconset/icon copy-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images-2.xcassets/AppIcon.appiconset/icon copy-2.png -------------------------------------------------------------------------------- /NAKL/Images-2.xcassets/AppIcon.appiconset/icon copy-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/huyphan/NAKL/HEAD/NAKL/Images-2.xcassets/AppIcon.appiconset/icon copy-3.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | build/* 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | *.xcworkspace 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | .DS_Store 17 | -------------------------------------------------------------------------------- /NAKL/ShortcutRecorder/SRKeyCodeTransformer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRKeyCodeTransformer.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import 15 | 16 | @interface SRKeyCodeTransformer : NSValueTransformer {} @end 17 | -------------------------------------------------------------------------------- /NAKL/main.h: -------------------------------------------------------------------------------- 1 | // 2 | // main.h 3 | // Test 4 | // 5 | // Created by Huy Phan on 18/4/12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | 12 | #ifndef __MACVNKB_MAIN_H 13 | #define __MACVNKB_MAIN_H 14 | 15 | 16 | CGEventRef KeyHandler(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon); 17 | 18 | #endif -------------------------------------------------------------------------------- /NAKL/HotKey/PTKeyCodeTranslator.h: -------------------------------------------------------------------------------- 1 | // 2 | // PTKeyCodeTranslator.h 3 | // Chercher 4 | // 5 | // Created by Finlay Dobbie on Sat Oct 11 2003. 6 | // Copyright (c) 2003 Cliché Software. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PTKeyCodeTranslator : NSObject 12 | { 13 | TISInputSourceRef keyboardLayout; 14 | const UCKeyboardLayout *uchrData; 15 | UInt32 keyTranslateState; 16 | UInt32 deadKeyState; 17 | } 18 | 19 | + (id)currentTranslator; 20 | 21 | - (id)initWithKeyboardLayout:(TISInputSourceRef)aLayout; 22 | - (NSString *)translateKeyCode:(short)keyCode; 23 | 24 | - (TISInputSourceRef)keyboardLayout; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /NAKL/HotKey/PTHotKeyCenter.h: -------------------------------------------------------------------------------- 1 | // 2 | // PTHotKeyCenter.h 3 | // Protein 4 | // 5 | // Created by Quentin Carnicelli on Sat Aug 02 2003. 6 | // Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved. 7 | // 8 | // Contributors: 9 | // Quentin D. Carnicelli 10 | // Finlay Dobbie 11 | // Vincent Pottier 12 | // Andy Kim 13 | 14 | #import 15 | 16 | @class PTHotKey; 17 | 18 | @interface PTHotKeyCenter : NSObject 19 | { 20 | NSMutableDictionary* mHotKeys; //Keys are carbon hot key IDs 21 | BOOL mEventHandlerInstalled; 22 | UInt32 mHotKeyCount; // Used to assign new hot key ID 23 | } 24 | 25 | + (PTHotKeyCenter *)sharedCenter; 26 | 27 | - (BOOL)registerHotKey: (PTHotKey*)hotKey; 28 | - (void)unregisterHotKey: (PTHotKey*)hotKey; 29 | 30 | - (NSArray*)allHotKeys; 31 | - (PTHotKey*)hotKeyWithIdentifier: (id)ident; 32 | 33 | - (void)sendEvent: (NSEvent*)event; 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /NAKL/HotKey/PTKeyCombo.h: -------------------------------------------------------------------------------- 1 | // 2 | // PTKeyCombo.h 3 | // Protein 4 | // 5 | // Created by Quentin Carnicelli on Sat Aug 02 2003. 6 | // Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PTKeyCombo : NSObject 12 | { 13 | NSInteger mKeyCode; 14 | NSUInteger mModifiers; 15 | } 16 | 17 | + (id)clearKeyCombo; 18 | + (id)keyComboWithKeyCode: (NSInteger)keyCode modifiers: (NSUInteger)modifiers; 19 | - (id)initWithKeyCode: (NSInteger)keyCode modifiers: (NSUInteger)modifiers; 20 | 21 | - (id)initWithPlistRepresentation: (id)plist; 22 | - (id)plistRepresentation; 23 | 24 | - (BOOL)isEqual: (PTKeyCombo*)combo; 25 | 26 | - (NSInteger)keyCode; 27 | - (NSUInteger)modifiers; 28 | 29 | - (BOOL)isClearCombo; 30 | - (BOOL)isValidHotKeyCombo; 31 | 32 | @end 33 | 34 | 35 | @interface PTKeyCombo (UserDisplayAdditions) 36 | - (NSString*)keyCodeString; 37 | - (NSUInteger)modifierMask; 38 | @end 39 | -------------------------------------------------------------------------------- /NAKL/ShortcutRecorder/SRValidator.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRValidator.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import 15 | 16 | @interface SRValidator : NSObject { 17 | id delegate; 18 | } 19 | 20 | - (id) initWithDelegate:(id)theDelegate; 21 | 22 | - (BOOL) isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags error:(NSError **)error; 23 | - (BOOL) isKeyCode:(NSInteger)keyCode andFlags:(NSUInteger)flags takenInMenu:(NSMenu *)menu error:(NSError **)error; 24 | 25 | - (id) delegate; 26 | - (void) setDelegate: (id) theDelegate; 27 | 28 | @end 29 | 30 | #pragma mark - 31 | 32 | @interface NSObject( SRValidation ) 33 | - (BOOL) shortcutValidator:(SRValidator *)validator isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags reason:(NSString **)aReason; 34 | @end 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | NAKL - Yet another Vietnamese input keyboard for Mac OS 2 | ======= 3 | 4 | * Please visit [homepage](http://huyphan.github.com/NAKL) of this project. 5 | 6 | Contributing 7 | ======= 8 | 9 | * Please report issues on the [GitHub issue tracker](https://github.com/huyphan/NAKL/issues). Personal emails are not appropriate for bug reports. 10 | * Patches are preferred as GitHub pull requests. Contributors are welcome to request free beer from author of this project. 11 | 12 | Credits 13 | ======= 14 | * chuoi (a.k.a Dao Hai Lam): author of [xvnkb](http://xvnkb.sourceforge.net). 15 | * Thanks to mybb (a.k.a hieuln) and pmquan (a.k.a co`i) for helping me testing out this software. 16 | 17 | 18 | License 19 | ======= 20 | * Distributed under the GNU GPLv3. See the file [LICENSE](https://github.com/huyphan/NAKL/blob/master/LICENSE). 21 | * Key handling algorithm and keymap of this project are based on [xvnkb](http://xvnkb.sourceforge.net/) written by Dao Hai Lam. 22 | * HotKey setting is based on [ShortcutRecorder](http://wafflesoftware.net/shortcut/) library. -------------------------------------------------------------------------------- /NAKL/main.m: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | 20 | #import 21 | 22 | int main(int argc, char *argv[]) 23 | { 24 | return NSApplicationMain(argc, (const char **)argv); 25 | } -------------------------------------------------------------------------------- /NAKL/ShortcutSetting.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | #import 20 | 21 | @interface ShortcutSetting : NSObject { 22 | NSString *shortcut; 23 | NSString *text; 24 | } 25 | 26 | @property (nonatomic, readwrite, retain) NSString *shortcut; 27 | @property (nonatomic, readwrite, retain) NSString *text; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /NAKL/HotKey/PTHotKey.h: -------------------------------------------------------------------------------- 1 | // 2 | // PTHotKey.h 3 | // Protein 4 | // 5 | // Created by Quentin Carnicelli on Sat Aug 02 2003. 6 | // Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved. 7 | // 8 | // Contributors: 9 | // Andy Kim 10 | 11 | #import 12 | #import 13 | #import "PTKeyCombo.h" 14 | 15 | @interface PTHotKey : NSObject 16 | { 17 | NSString* mIdentifier; 18 | NSString* mName; 19 | PTKeyCombo* mKeyCombo; 20 | id mTarget; 21 | SEL mAction; 22 | 23 | NSUInteger mCarbonHotKeyID; 24 | EventHotKeyRef mCarbonEventHotKeyRef; 25 | } 26 | 27 | - (id)initWithIdentifier: (id)identifier keyCombo: (PTKeyCombo*)combo; 28 | - (id)init; 29 | 30 | - (void)setIdentifier: (id)ident; 31 | - (id)identifier; 32 | 33 | - (void)setName: (NSString*)name; 34 | - (NSString*)name; 35 | 36 | - (void)setKeyCombo: (PTKeyCombo*)combo; 37 | - (PTKeyCombo*)keyCombo; 38 | 39 | - (void)setTarget: (id)target; 40 | - (id)target; 41 | - (void)setAction: (SEL)action; 42 | - (SEL)action; 43 | 44 | - (NSUInteger)carbonHotKeyID; 45 | - (void)setCarbonHotKeyID: (NSUInteger)hotKeyID; 46 | 47 | - (EventHotKeyRef)carbonEventHotKeyRef; 48 | - (void)setCarbonEventHotKeyRef:(EventHotKeyRef)hotKeyRef; 49 | 50 | - (void)invoke; 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /NAKL/vi.lproj/NAKL-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.zepvn.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSHumanReadableCopyright 28 | Huy Phan <dachuy@gmail.com> 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | LSUIElement 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /NAKL/en.lproj/NAKL-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | icon24.png 11 | CFBundleIdentifier 12 | com.zepvn.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSHumanReadableCopyright 28 | Huy Phan <dachuy@gmail.com> 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | LSUIElement 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /NAKL/ExcludedAppsTableViewController.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | #import 20 | #import "AppData.h" 21 | 22 | @interface ExcludedAppsTableViewController : NSObject { 23 | IBOutlet NSTableView *tableView; 24 | } 25 | 26 | @property (readwrite,assign) NSMutableArray *list; 27 | 28 | - (IBAction) add:(id)sender; 29 | - (IBAction) remove:(id)sender; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /NAKL/ShortcutTableViewController.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | #import 20 | 21 | @interface ShortcutTableViewController : NSObject { 22 | IBOutlet NSTableView *tableView; 23 | NSMutableArray *list; 24 | } 25 | 26 | @property (readwrite,assign) NSMutableArray *list; 27 | 28 | - (IBAction) add:(id)sender; 29 | - (IBAction) remove:(id)sender; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /NAKL/NAKL-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.zepvn.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 0.3 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 42 25 | LSApplicationCategoryType 26 | public.app-category.utilities 27 | LSMinimumSystemVersion 28 | ${MACOSX_DEPLOYMENT_TARGET} 29 | LSUIElement 30 | 31 | NSHumanReadableCopyright 32 | Huy Phan <dachuy@gmail.com> 33 | NSMainNibFile 34 | MainMenu 35 | NSPrincipalClass 36 | NSApplication 37 | 38 | 39 | -------------------------------------------------------------------------------- /NAKL/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon16-1.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon32-1.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon128-1.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon256-1.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon256-2.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon256-3.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /NAKL/Images-2.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "icon64-1.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "icon32-1.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "icon32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "icon64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "icon.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "icon copy-3.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "icon copy-2.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "icon copy-1.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "icon copy.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "icon256.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /NAKL/NSFileManager+DirectoryLocations.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSFileManager+DirectoryLocations.h 3 | // 4 | // Created by Matt Gallagher on 06 May 2010 5 | // 6 | // This software is provided 'as-is', without any express or implied 7 | // warranty. In no event will the authors be held liable for any damages 8 | // arising from the use of this software. Permission is granted to anyone to 9 | // use this software for any purpose, including commercial applications, and to 10 | // alter it and redistribute it freely, subject to the following restrictions: 11 | // 12 | // 1. The origin of this software must not be misrepresented; you must not 13 | // claim that you wrote the original software. If you use this software 14 | // in a product, an acknowledgment in the product documentation would be 15 | // appreciated but is not required. 16 | // 2. Altered source versions must be plainly marked as such, and must not be 17 | // misrepresented as being the original software. 18 | // 3. This notice may not be removed or altered from any source 19 | // distribution. 20 | // 21 | 22 | #import 23 | 24 | // 25 | // DirectoryLocations is a set of global methods for finding the fixed location 26 | // directoriess. 27 | // 28 | @interface NSFileManager (DirectoryLocations) 29 | 30 | - (NSString *)findOrCreateDirectory:(NSSearchPathDirectory)searchPathDirectory 31 | inDomain:(NSSearchPathDomainMask)domainMask 32 | appendPathComponent:(NSString *)appendComponent 33 | error:(NSError **)errorOut; 34 | - (NSString *)applicationSupportDirectory; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /NAKL/ShortcutSetting.m: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | #import "ShortcutSetting.h" 20 | 21 | @implementation ShortcutSetting 22 | 23 | @synthesize shortcut; 24 | @synthesize text; 25 | 26 | - (id) init 27 | { 28 | self = [super init]; 29 | return self; 30 | } 31 | 32 | - (void) encodeWithCoder:(NSCoder *)coder { 33 | [coder encodeObject:self.shortcut forKey:@"shortcut"]; 34 | [coder encodeObject:self.text forKey:@"text"]; 35 | } 36 | 37 | - (id) initWithCoder:(NSCoder *)coder { 38 | if ((self = [super init])) 39 | { 40 | self.shortcut = [[coder decodeObjectForKey:@"shortcut"] retain]; 41 | self.text = [[coder decodeObjectForKey:@"text"] retain]; 42 | } 43 | return self; 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /NAKL/PreferencesController.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | #import 20 | #import "AppData.h" 21 | #import "ShortcutSetting.h" 22 | 23 | @class SRRecorderControl; 24 | 25 | @interface PreferencesController : NSWindowController { 26 | SRRecorderControl *_toggleHotKey; 27 | SRRecorderControl *_switchMethodHotKey; 28 | NSString *versionString; 29 | NSArrayController *shortcuts; 30 | IBOutlet NSTableView *shortcutsTableView; 31 | } 32 | 33 | @property (nonatomic, readwrite, retain) IBOutlet SRRecorderControl *toggleHotKey; 34 | @property (nonatomic, readwrite, retain) IBOutlet SRRecorderControl *switchMethodHotKey; 35 | @property (nonatomic, readwrite, retain) NSString *versionString; 36 | @property (nonatomic, readwrite, retain) NSArrayController *shortcuts; 37 | 38 | - (IBAction) startupOptionClick:(id)sender; 39 | 40 | @end -------------------------------------------------------------------------------- /NAKL/KeyboardHandler.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | #import 20 | 21 | #ifndef WORDSIZE 22 | #define WORDSIZE 32 23 | #endif 24 | 25 | #define BACKSPACE_BUFFER 20 26 | 27 | @interface KeyboardHandler : NSObject { 28 | int kbBLength, kbPLength; 29 | int kbMethod; 30 | UniChar _kbBuffer[256]; 31 | UniChar* kbBuffer; 32 | NSArray *vowelsMap; 33 | UniChar word[WORDSIZE]; 34 | } 35 | 36 | @property(nonatomic, assign) UniChar* kbBuffer; 37 | @property(nonatomic) int kbBLength; 38 | @property(nonatomic) int kbPLength; 39 | @property(nonatomic) int kbMethod; 40 | @property(nonatomic, retain) NSArray *vowelsMap; 41 | 42 | - (id)init; 43 | - (void) mapToCharset:(ushort*)w :(int)count; 44 | - (int) uiGroup: (ushort) u; 45 | - (int) utfVnCmp: (ushort)u1 :(ushort)u2; 46 | 47 | - (bool) isValidModifier: (UniChar)c :(char) key; 48 | - (void) append: (ushort)lastkey :(UniChar)key; 49 | - (void) clearBuffer; 50 | - (void) shiftBuffer; 51 | - (void) updateBuffer; 52 | - (int) addKey: (UniChar) key; 53 | 54 | @end 55 | -------------------------------------------------------------------------------- /NAKL/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | 20 | #import 21 | #import "ShortcutRecorder/SRRecorderControl.h" 22 | #import "PreferencesController.h" 23 | #import "KeyboardHandler.h" 24 | #import "PTHotKey.h" 25 | #import "AppData.h" 26 | #import "keymap.h" 27 | 28 | #define NAKL_MAGIC_NUMBER 536870912L // 1<<29 29 | 30 | typedef enum { 31 | VKM_OFF, VKM_VNI, VKM_TELEX 32 | } NAKL_METHOD; 33 | 34 | @interface AppDelegate : NSObject { 35 | PreferencesController *preferencesController; 36 | NSWindow *_window; 37 | IBOutlet NSMenu *statusMenu; 38 | NSStatusItem * statusItem; 39 | NSImage *viStatusImage; 40 | NSImage *enStatusImage; 41 | NSImage *statusHighlightImage; 42 | CFMachPortRef eventTap; 43 | } 44 | 45 | + (void)initialize; 46 | - (IBAction) methodSelected:(id)sender; 47 | - (IBAction) quit:(id)sender; 48 | - (IBAction) showPreferences:(id)sender; 49 | - (void) updateStatusItem; 50 | - (void) updateCheckedItem; 51 | 52 | @property (assign) IBOutlet NSWindow *window; 53 | @property (assign) CFMachPortRef eventTap; 54 | @property (retain) PreferencesController *preferencesController; 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /NAKL/HotKey/PTKeyCodeTranslator.m: -------------------------------------------------------------------------------- 1 | // 2 | // PTKeyCodeTranslator.m 3 | // Chercher 4 | // 5 | // Created by Finlay Dobbie on Sat Oct 11 2003. 6 | // Copyright (c) 2003 Cliché Software. All rights reserved. 7 | // 8 | 9 | #import "PTKeyCodeTranslator.h" 10 | 11 | 12 | @implementation PTKeyCodeTranslator 13 | 14 | + (id)currentTranslator 15 | { 16 | static PTKeyCodeTranslator *current = nil; 17 | TISInputSourceRef currentLayout = TISCopyCurrentKeyboardLayoutInputSource(); 18 | 19 | if (current == nil) { 20 | current = [[PTKeyCodeTranslator alloc] initWithKeyboardLayout:currentLayout]; 21 | } else if ([current keyboardLayout] != currentLayout) { 22 | [current release]; 23 | current = [[PTKeyCodeTranslator alloc] initWithKeyboardLayout:currentLayout]; 24 | } 25 | 26 | CFRelease(currentLayout); 27 | 28 | return current; 29 | } 30 | 31 | - (id)initWithKeyboardLayout:(TISInputSourceRef)aLayout 32 | { 33 | if ((self = [super init]) != nil) { 34 | keyboardLayout = aLayout; 35 | 36 | CFRetain(keyboardLayout); 37 | 38 | CFDataRef uchr = TISGetInputSourceProperty( keyboardLayout , kTISPropertyUnicodeKeyLayoutData ); 39 | uchrData = ( const UCKeyboardLayout* )CFDataGetBytePtr(uchr); 40 | } 41 | 42 | return self; 43 | } 44 | 45 | - (void)dealloc 46 | { 47 | CFRelease(keyboardLayout); 48 | 49 | [super dealloc]; 50 | } 51 | 52 | - (NSString *)translateKeyCode:(short)keyCode { 53 | UniCharCount maxStringLength = 4, actualStringLength; 54 | UniChar unicodeString[4]; 55 | UCKeyTranslate( uchrData, keyCode, kUCKeyActionDisplay, 0, LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &deadKeyState, maxStringLength, &actualStringLength, unicodeString ); 56 | return [NSString stringWithCharacters:unicodeString length:1]; 57 | } 58 | 59 | - (TISInputSourceRef)keyboardLayout { 60 | return keyboardLayout; 61 | } 62 | 63 | - (NSString *)description { 64 | NSString *kind; 65 | kind = @"uchr"; 66 | 67 | NSString *layoutName; 68 | layoutName = TISGetInputSourceProperty( keyboardLayout, kTISPropertyLocalizedName ); 69 | return [NSString stringWithFormat:@"PTKeyCodeTranslator layout=%@ (%@)", layoutName, kind]; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /NAKL/ShortcutRecorder/SRRecorderControl.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRRecorderControl.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import 15 | #import "SRRecorderCell.h" 16 | 17 | @interface SRRecorderControl : NSControl 18 | { 19 | IBOutlet id delegate; 20 | } 21 | 22 | #pragma mark *** Aesthetics *** 23 | - (BOOL)animates; 24 | - (void)setAnimates:(BOOL)an; 25 | - (SRRecorderStyle)style; 26 | - (void)setStyle:(SRRecorderStyle)nStyle; 27 | 28 | #pragma mark *** Delegate *** 29 | - (id)delegate; 30 | - (void)setDelegate:(id)aDelegate; 31 | 32 | #pragma mark *** Key Combination Control *** 33 | 34 | - (NSUInteger)allowedFlags; 35 | - (void)setAllowedFlags:(NSUInteger)flags; 36 | 37 | - (BOOL)allowsKeyOnly; 38 | - (void)setAllowsKeyOnly:(BOOL)nAllowsKeyOnly escapeKeysRecord:(BOOL)nEscapeKeysRecord; 39 | - (BOOL)escapeKeysRecord; 40 | 41 | - (BOOL)canCaptureGlobalHotKeys; 42 | - (void)setCanCaptureGlobalHotKeys:(BOOL)inState; 43 | 44 | - (NSUInteger)requiredFlags; 45 | - (void)setRequiredFlags:(NSUInteger)flags; 46 | 47 | - (KeyCombo)keyCombo; 48 | - (void)setKeyCombo:(KeyCombo)aKeyCombo; 49 | 50 | - (NSString *)keyChars; 51 | - (NSString *)keyCharsIgnoringModifiers; 52 | 53 | #pragma mark *** Autosave Control *** 54 | 55 | - (NSString *)autosaveName; 56 | - (void)setAutosaveName:(NSString *)aName; 57 | 58 | #pragma mark - 59 | 60 | // Returns the displayed key combination if set 61 | - (NSString *)keyComboString; 62 | 63 | #pragma mark *** Conversion Methods *** 64 | 65 | - (NSUInteger)cocoaToCarbonFlags:(NSUInteger)cocoaFlags; 66 | - (NSUInteger)carbonToCocoaFlags:(NSUInteger)carbonFlags; 67 | 68 | #pragma mark *** Binding Methods *** 69 | 70 | - (NSDictionary *)objectValue; 71 | - (void)setObjectValue:(NSDictionary *)shortcut; 72 | 73 | @end 74 | 75 | // Delegate Methods 76 | @interface NSObject (SRRecorderDelegate) 77 | - (BOOL)shortcutRecorder:(SRRecorderControl *)aRecorder isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags reason:(NSString **)aReason; 78 | - (void)shortcutRecorder:(SRRecorderControl *)aRecorder keyComboDidChange:(KeyCombo)newKeyCombo; 79 | @end 80 | -------------------------------------------------------------------------------- /NAKL/AppData.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | #import 20 | #import "ShortcutRecorder/SRRecorderControl.h" 21 | #import "CWLSynthesizeSingleton.h" 22 | 23 | #define NAKL_HOTKEY_TOGGLE 10 24 | #define NAKL_HOTKEY_SWITCH_METHOD 20 25 | 26 | #define NAKL_KEYBOARD_METHOD @"NAKLKeyboardMethod" 27 | #define NAKL_LOAD_AT_LOGIN @"NAKLLoadAtLogin" 28 | #define NAKL_TOGGLE_HOTKEY @"NAKLToggleHotKey" 29 | #define NAKL_SWITCH_METHOD_HOTKEY @"NAKLSwitchMethodHotKey" 30 | #define NAKL_EXCLUDED_APPS @"NAKLExcludedAppBundleIds" 31 | 32 | @interface AppData : NSObject { 33 | NSUserDefaults *userPrefs; 34 | KeyCombo toggleCombo; 35 | KeyCombo switchMethodCombo; 36 | NSMutableArray *shortcuts; 37 | NSMutableDictionary *shortcutDictionary; 38 | NSMutableDictionary *excludedApps; 39 | } 40 | 41 | CWL_DECLARE_SINGLETON_FOR_CLASS(AppData) 42 | 43 | @property (readwrite,assign) NSUserDefaults *userPrefs; 44 | @property (readwrite,assign) KeyCombo toggleCombo; 45 | @property (readwrite,assign) KeyCombo switchMethodCombo; 46 | @property (readwrite,assign) NSMutableArray *shortcuts; 47 | @property (readwrite,assign) NSMutableDictionary *shortcutDictionary; 48 | @property (readwrite,assign) NSMutableDictionary *excludedApps; 49 | 50 | + (void) loadUserPrefs; 51 | + (void) loadHotKeys; 52 | + (void) loadShortcuts; 53 | + (void) loadExcludedApps; 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /NAKL/utf8.h: -------------------------------------------------------------------------------- 1 | /*----------------------------------------------------------------------------*/ 2 | /* utf8.h */ 3 | /*----------------------------------------------------------------------------*/ 4 | /* copyright : (C) 2002 by Dao Hai Lam */ 5 | /* VISC Software & Security Consultant Company */ 6 | /* Hall 3, Quang Trung Software City */ 7 | /* Tan Chanh Hiep Ward, District 12, */ 8 | /* Ho Chi Minh city, VIETNAM */ 9 | /* website : http://www.visc-network.com */ 10 | /* email : lam@visc-network.com */ 11 | /* last modify : Thu, 18 Apr 2002 22:00:33 +0700 */ 12 | /*----------------------------------------------------------------------------*/ 13 | /* */ 14 | /* This program is free software; you can redistribute it and/or modify */ 15 | /* it under the terms of the GNU General Public License as published by */ 16 | /* the Free Software Foundation; either version 2 of the License, or */ 17 | /* (at your option) any later version. */ 18 | /* */ 19 | /*----------------------------------------------------------------------------*/ 20 | 21 | char *UTF8[] = { 22 | "A","Á","À","Ả","Ã","Ạ", 23 | "Â","Ấ","Ầ","Ẩ","Ẫ","Ậ", 24 | "Ă","Ắ","Ằ","Ẳ","Ẵ","Ặ", 25 | "E","É","È","Ẻ","Ẽ","Ẹ", 26 | "Ê","Ế","Ề","Ể","Ễ","Ệ", 27 | "O","Ó","Ò","Ỏ","Õ","Ọ", 28 | "Ô","Ố","Ồ","Ổ","Ỗ","Ộ", 29 | "Ơ","Ớ","Ờ","Ở","Ỡ","Ợ", 30 | "U","Ú","Ù","Ủ","Ũ","Ụ", 31 | "Ư","Ứ","Ừ","Ử","Ữ","Ự", 32 | "I","Í","Ì","Ỉ","Ĩ","Ị", 33 | "Y","Ý","Ỳ","Ỷ","Ỹ","Ỵ", 34 | "Đ", 35 | "a","á","à","ả","ã","ạ", 36 | "â","ấ","ầ","ẩ","ẫ","ậ", 37 | "ă","ắ","ằ","ẳ","ẵ","ặ", 38 | "e","é","è","ẻ","ẽ","ẹ", 39 | "ê","ế","ề","ể","ễ","ệ", 40 | "o","ó","ò","ỏ","õ","ọ", 41 | "ô","ố","ồ","ổ","ỗ","ộ", 42 | "ơ","ớ","ờ","ở","ỡ","ợ", 43 | "u","ú","ù","ủ","ũ","ụ", 44 | "ư","ứ","ừ","ử","ữ","ự", 45 | "i","í","ì","ỉ","ĩ","ị", 46 | "y","ý","ỳ","ỷ","ỹ","ỵ", 47 | "đ", 48 | "₫" 49 | }; 50 | /*----------------------------------------------------------------------------*/ 51 | -------------------------------------------------------------------------------- /NAKL/HotKey/PTHotKey.m: -------------------------------------------------------------------------------- 1 | // 2 | // PTHotKey.m 3 | // Protein 4 | // 5 | // Created by Quentin Carnicelli on Sat Aug 02 2003. 6 | // Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved. 7 | // 8 | 9 | #import "PTHotKey.h" 10 | 11 | #import "PTHotKeyCenter.h" 12 | #import "PTKeyCombo.h" 13 | 14 | @implementation PTHotKey 15 | 16 | - (id)init 17 | { 18 | return [self initWithIdentifier: nil keyCombo: nil]; 19 | } 20 | 21 | - (id)initWithIdentifier: (id)identifier keyCombo: (PTKeyCombo*)combo 22 | { 23 | self = [super init]; 24 | 25 | if( self ) 26 | { 27 | [self setIdentifier: identifier]; 28 | [self setKeyCombo: combo]; 29 | } 30 | 31 | return self; 32 | } 33 | 34 | - (void)dealloc 35 | { 36 | [mIdentifier release]; 37 | [mName release]; 38 | [mKeyCombo release]; 39 | 40 | [super dealloc]; 41 | } 42 | 43 | - (NSString*)description 44 | { 45 | return [NSString stringWithFormat: @"<%@: %@, %@>", NSStringFromClass( [self class] ), [self identifier], [self keyCombo]]; 46 | } 47 | 48 | #pragma mark - 49 | 50 | - (void)setIdentifier: (id)ident 51 | { 52 | [ident retain]; 53 | [mIdentifier release]; 54 | mIdentifier = ident; 55 | } 56 | 57 | - (id)identifier 58 | { 59 | return mIdentifier; 60 | } 61 | 62 | - (void)setKeyCombo: (PTKeyCombo*)combo 63 | { 64 | if( combo == nil ) 65 | combo = [PTKeyCombo clearKeyCombo]; 66 | 67 | [combo retain]; 68 | [mKeyCombo release]; 69 | mKeyCombo = combo; 70 | } 71 | 72 | - (PTKeyCombo*)keyCombo 73 | { 74 | return mKeyCombo; 75 | } 76 | 77 | - (void)setName: (NSString*)name 78 | { 79 | [name retain]; 80 | [mName release]; 81 | mName = name; 82 | } 83 | 84 | - (NSString*)name 85 | { 86 | return mName; 87 | } 88 | 89 | - (void)setTarget: (id)target 90 | { 91 | mTarget = target; 92 | } 93 | 94 | - (id)target 95 | { 96 | return mTarget; 97 | } 98 | 99 | - (void)setAction: (SEL)action 100 | { 101 | mAction = action; 102 | } 103 | 104 | - (SEL)action 105 | { 106 | return mAction; 107 | } 108 | 109 | - (NSUInteger)carbonHotKeyID 110 | { 111 | return mCarbonHotKeyID; 112 | } 113 | 114 | - (void)setCarbonHotKeyID: (NSUInteger)hotKeyID; 115 | { 116 | mCarbonHotKeyID = hotKeyID; 117 | } 118 | 119 | - (EventHotKeyRef)carbonEventHotKeyRef 120 | { 121 | return mCarbonEventHotKeyRef; 122 | } 123 | 124 | - (void)setCarbonEventHotKeyRef: (EventHotKeyRef)hotKeyRef 125 | { 126 | mCarbonEventHotKeyRef = hotKeyRef; 127 | } 128 | 129 | #pragma mark - 130 | 131 | - (void)invoke 132 | { 133 | [mTarget performSelector: mAction withObject: self]; 134 | } 135 | 136 | @end 137 | -------------------------------------------------------------------------------- /NAKL/CWLSynthesizeSingleton.h: -------------------------------------------------------------------------------- 1 | // 2 | // CWLSynthesizeSingleton.h 3 | // CocoaWithLove 4 | // 5 | // Created by Matt Gallagher on 2011/08/23. 6 | // Copyright (c) 2011 Matt Gallagher. All rights reserved. 7 | // 8 | // Permission is given to use this source code file, free of charge, in any 9 | // project, commercial or otherwise, entirely at your risk, with the condition 10 | // that any redistribution (in part or whole) of source code must retain 11 | // this copyright and permission notice. Attribution in compiled projects is 12 | // appreciated but not required. 13 | // 14 | 15 | #import 16 | 17 | #define CWL_DECLARE_SINGLETON_FOR_CLASS_WITH_ACCESSOR(classname, accessorMethodName) \ 18 | + (classname *)accessorMethodName; 19 | 20 | #if __has_feature(objc_arc) 21 | #define CWL_SYNTHESIZE_SINGLETON_RETAIN_METHODS 22 | #else 23 | #define CWL_SYNTHESIZE_SINGLETON_RETAIN_METHODS \ 24 | - (id)retain \ 25 | { \ 26 | return self; \ 27 | } \ 28 | \ 29 | - (NSUInteger)retainCount \ 30 | { \ 31 | return NSUIntegerMax; \ 32 | } \ 33 | \ 34 | - (oneway void)release \ 35 | { \ 36 | } \ 37 | \ 38 | - (id)autorelease \ 39 | { \ 40 | return self; \ 41 | } 42 | #endif 43 | 44 | #define CWL_SYNTHESIZE_SINGLETON_FOR_CLASS_WITH_ACCESSOR(classname, accessorMethodName) \ 45 | \ 46 | static classname *accessorMethodName##Instance = nil; \ 47 | \ 48 | + (classname *)accessorMethodName \ 49 | { \ 50 | @synchronized(self) \ 51 | { \ 52 | if (accessorMethodName##Instance == nil) \ 53 | { \ 54 | accessorMethodName##Instance = [super allocWithZone:NULL]; \ 55 | accessorMethodName##Instance = [accessorMethodName##Instance init]; \ 56 | method_exchangeImplementations(\ 57 | class_getClassMethod([accessorMethodName##Instance class], @selector(accessorMethodName)),\ 58 | class_getClassMethod([accessorMethodName##Instance class], @selector(cwl_lockless_##accessorMethodName)));\ 59 | method_exchangeImplementations(\ 60 | class_getInstanceMethod([accessorMethodName##Instance class], @selector(init)),\ 61 | class_getInstanceMethod([accessorMethodName##Instance class], @selector(cwl_onlyInitOnce)));\ 62 | } \ 63 | } \ 64 | \ 65 | return accessorMethodName##Instance; \ 66 | } \ 67 | \ 68 | + (classname *)cwl_lockless_##accessorMethodName \ 69 | { \ 70 | return accessorMethodName##Instance; \ 71 | } \ 72 | \ 73 | + (id)allocWithZone:(NSZone *)zone \ 74 | { \ 75 | return [self accessorMethodName]; \ 76 | } \ 77 | \ 78 | - (id)copyWithZone:(NSZone *)zone \ 79 | { \ 80 | return self; \ 81 | } \ 82 | - (id)cwl_onlyInitOnce \ 83 | { \ 84 | return self;\ 85 | } \ 86 | \ 87 | CWL_SYNTHESIZE_SINGLETON_RETAIN_METHODS 88 | 89 | #define CWL_DECLARE_SINGLETON_FOR_CLASS(classname) CWL_DECLARE_SINGLETON_FOR_CLASS_WITH_ACCESSOR(classname, shared##classname) 90 | #define CWL_SYNTHESIZE_SINGLETON_FOR_CLASS(classname) CWL_SYNTHESIZE_SINGLETON_FOR_CLASS_WITH_ACCESSOR(classname, shared##classname) 91 | -------------------------------------------------------------------------------- /NAKL/ShortcutTableViewController.m: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | #import "ShortcutTableViewController.h" 20 | #import "AppData.h" 21 | #import "ShortcutSetting.h" 22 | #import "NSFileManager+DirectoryLocations.h" 23 | 24 | @implementation ShortcutTableViewController 25 | 26 | @synthesize list; 27 | 28 | - (id)init 29 | { 30 | self = [super init]; 31 | if (self) { 32 | [tableView usesAlternatingRowBackgroundColors]; 33 | } 34 | return self; 35 | } 36 | 37 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView 38 | { 39 | return [[AppData sharedAppData].shortcuts count]; 40 | } 41 | 42 | - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 43 | { 44 | ShortcutSetting *p = [[AppData sharedAppData].shortcuts objectAtIndex:row]; 45 | NSString *identifier = [tableColumn identifier]; 46 | return [p valueForKey:identifier]; 47 | } 48 | 49 | - (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 50 | { 51 | ShortcutSetting *s = [[AppData sharedAppData].shortcuts objectAtIndex:row]; 52 | NSString *identifier = [tableColumn identifier]; 53 | [s setValue:object forKey:identifier]; 54 | } 55 | 56 | - (IBAction)add:(id)sender 57 | { 58 | ShortcutSetting *shortcut = [[ShortcutSetting alloc] init]; 59 | [[AppData sharedAppData].shortcuts addObject:shortcut]; 60 | [tableView reloadData]; 61 | [tableView editColumn:0 row:([[AppData sharedAppData].shortcuts count] - 1) withEvent:nil select:YES]; 62 | [shortcut release]; 63 | } 64 | 65 | - (IBAction)remove:(id)sender 66 | { 67 | NSInteger row = [tableView selectedRow]; 68 | [tableView abortEditing]; 69 | if (row != -1) { 70 | [[AppData sharedAppData].shortcuts removeObjectAtIndex:row]; 71 | } 72 | [tableView reloadData]; 73 | } 74 | 75 | - (void) dealloc 76 | { 77 | [super dealloc]; 78 | } 79 | 80 | @end -------------------------------------------------------------------------------- /NAKL/AppData.m: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | #import "AppData.h" 20 | #import "PTHotKey.h" 21 | #import "NSFileManager+DirectoryLocations.h" 22 | #import "ShortcutSetting.h" 23 | 24 | @implementation AppData 25 | 26 | @synthesize userPrefs; 27 | @synthesize toggleCombo; 28 | @synthesize switchMethodCombo; 29 | @synthesize shortcuts; 30 | @synthesize shortcutDictionary; 31 | @synthesize excludedApps; 32 | 33 | CWL_SYNTHESIZE_SINGLETON_FOR_CLASS(AppData); 34 | 35 | + (void) loadUserPrefs 36 | { 37 | [AppData sharedAppData].userPrefs = [NSUserDefaults standardUserDefaults]; 38 | } 39 | 40 | + (void) loadHotKeys 41 | { 42 | NSDictionary *dictionary = [[AppData sharedAppData].userPrefs dictionaryForKey:NAKL_TOGGLE_HOTKEY]; 43 | PTKeyCombo *keyCombo = [[PTKeyCombo alloc] initWithPlistRepresentation:dictionary]; 44 | [AppData sharedAppData].toggleCombo = SRMakeKeyCombo([keyCombo keyCode], [keyCombo modifiers]); 45 | [keyCombo release]; 46 | 47 | dictionary = [[AppData sharedAppData].userPrefs dictionaryForKey:NAKL_SWITCH_METHOD_HOTKEY]; 48 | keyCombo = [[PTKeyCombo alloc] initWithPlistRepresentation:dictionary]; 49 | [AppData sharedAppData].switchMethodCombo = SRMakeKeyCombo([keyCombo keyCode], [keyCombo modifiers]); 50 | [keyCombo release]; 51 | } 52 | 53 | + (void) loadShortcuts 54 | { 55 | NSString *filePath = [[[NSFileManager defaultManager] applicationSupportDirectory] stringByAppendingPathComponent:@"shortcuts.setting"]; 56 | NSData *data = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath]; 57 | [AppData sharedAppData].shortcuts = [[NSMutableArray alloc] init]; 58 | [AppData sharedAppData].shortcutDictionary = [[NSMutableDictionary alloc] init]; 59 | 60 | if (data != nil) { 61 | NSArray *savedArray = [NSKeyedUnarchiver unarchiveObjectWithData:data]; 62 | if (savedArray != nil) { 63 | [[AppData sharedAppData].shortcuts setArray:savedArray]; 64 | } 65 | } 66 | 67 | for (ShortcutSetting *s in [AppData sharedAppData].shortcuts) { 68 | [[AppData sharedAppData].shortcutDictionary setObject:s.text forKey:s.shortcut]; 69 | } 70 | } 71 | 72 | + (void) loadExcludedApps 73 | { 74 | [AppData sharedAppData].excludedApps = [[NSMutableDictionary alloc] init]; 75 | NSDictionary *excludedApps = [[AppData sharedAppData].userPrefs dictionaryForKey:NAKL_EXCLUDED_APPS]; 76 | if (excludedApps != nil) { 77 | [[AppData sharedAppData].excludedApps setDictionary:excludedApps]; 78 | } 79 | } 80 | 81 | @end 82 | -------------------------------------------------------------------------------- /NAKL/ExcludedAppsTableViewController.m: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | #import "ExcludedAppsTableViewController.h" 20 | #import "AppData.h" 21 | 22 | @implementation ExcludedAppsTableViewController 23 | 24 | - (id)init 25 | { 26 | self = [super init]; 27 | if (self) { 28 | [tableView usesAlternatingRowBackgroundColors]; 29 | } 30 | return self; 31 | } 32 | 33 | - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView 34 | { 35 | return [[[AppData sharedAppData].excludedApps allKeys] count]; 36 | } 37 | 38 | - (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row 39 | { 40 | return [[AppData sharedAppData].excludedApps objectForKey:[[[AppData sharedAppData].excludedApps allKeys] objectAtIndex:row]]; 41 | } 42 | 43 | - (IBAction)add:(id)sender 44 | { 45 | NSOpenPanel* dialog = [NSOpenPanel openPanel]; 46 | [dialog setCanChooseFiles:YES]; 47 | [dialog setAllowsMultipleSelection:YES]; 48 | [dialog setCanChooseDirectories:NO]; 49 | [dialog setDirectory:@"/Applications"]; 50 | 51 | if ([dialog runModal] == NSOKButton) { 52 | NSArray* selectedPaths = [dialog filenames]; 53 | for (NSString* path in selectedPaths) { 54 | NSDictionary* plistData = [NSDictionary dictionaryWithContentsOfFile:[path stringByAppendingString:@"/Contents/Info.plist"]]; 55 | NSString *appBundleIdentifier = [plistData valueForKeyPath:@"CFBundleIdentifier"]; 56 | NSString *appName = [plistData valueForKeyPath:@"CFBundleName"]; 57 | if ((appName == nil) || [appName isEqualToString:@""]) { 58 | appName = [[path lastPathComponent] stringByDeletingPathExtension]; 59 | } 60 | if ((appBundleIdentifier != nil) && ![[AppData sharedAppData].excludedApps objectForKey:appBundleIdentifier]) { 61 | [[AppData sharedAppData].excludedApps setObject:appName forKey:appBundleIdentifier]; 62 | [self.list addObject:appBundleIdentifier]; 63 | } 64 | } 65 | [[AppData sharedAppData].userPrefs setObject:[AppData sharedAppData].excludedApps forKey:NAKL_EXCLUDED_APPS]; 66 | [tableView reloadData]; 67 | } 68 | } 69 | 70 | - (IBAction)remove:(id)sender 71 | { 72 | NSInteger row = [tableView selectedRow]; 73 | [tableView abortEditing]; 74 | if (row != -1) { 75 | NSString* appBundleIdentifier = [[[AppData sharedAppData].excludedApps allKeys] objectAtIndex:row]; 76 | [[AppData sharedAppData].excludedApps removeObjectForKey:appBundleIdentifier]; 77 | } 78 | [tableView reloadData]; 79 | [[AppData sharedAppData].userPrefs setObject:[AppData sharedAppData].excludedApps forKey:NAKL_EXCLUDED_APPS]; 80 | } 81 | 82 | - (void) dealloc 83 | { 84 | [super dealloc]; 85 | } 86 | 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /NAKL/ShortcutRecorder/SRRecorderCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRRecorderCell.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import 15 | #import "SRCommon.h" 16 | 17 | #define SRMinWidth 50 18 | #define SRMaxHeight 22 19 | 20 | #define SRTransitionFPS 30.0f 21 | #define SRTransitionDuration 0.35f 22 | //#define SRTransitionDuration 2.35 23 | #define SRTransitionFrames (SRTransitionFPS*SRTransitionDuration) 24 | #define SRAnimationAxisIsY YES 25 | #define ShortcutRecorderNewStyleDrawing 26 | 27 | #define SRAnimationOffsetRect(X,Y) (SRAnimationAxisIsY ? NSOffsetRect(X,0.0f,-NSHeight(Y)) : NSOffsetRect(X,NSWidth(Y),0.0f)) 28 | 29 | @class SRRecorderControl, SRValidator; 30 | 31 | enum SRRecorderStyle { 32 | SRGradientBorderStyle = 0, 33 | SRGreyStyle = 1 34 | }; 35 | typedef enum SRRecorderStyle SRRecorderStyle; 36 | 37 | @interface SRRecorderCell : NSActionCell 38 | { 39 | NSGradient *recordingGradient; 40 | NSString *autosaveName; 41 | 42 | BOOL isRecording; 43 | BOOL mouseInsideTrackingArea; 44 | BOOL mouseDown; 45 | 46 | SRRecorderStyle style; 47 | 48 | BOOL isAnimating; 49 | CGFloat transitionProgress; 50 | BOOL isAnimatingNow; 51 | BOOL isAnimatingTowardsRecording; 52 | BOOL comboJustChanged; 53 | 54 | NSTrackingRectTag removeTrackingRectTag; 55 | NSTrackingRectTag snapbackTrackingRectTag; 56 | 57 | KeyCombo keyCombo; 58 | BOOL hasKeyChars; 59 | NSString *keyChars; 60 | NSString *keyCharsIgnoringModifiers; 61 | 62 | NSUInteger allowedFlags; 63 | NSUInteger requiredFlags; 64 | NSUInteger recordingFlags; 65 | 66 | BOOL allowsKeyOnly; 67 | BOOL escapeKeysRecord; 68 | 69 | NSSet *cancelCharacterSet; 70 | 71 | SRValidator *validator; 72 | 73 | IBOutlet id delegate; 74 | BOOL globalHotKeys; 75 | void *hotKeyModeToken; 76 | } 77 | 78 | - (void)resetTrackingRects; 79 | 80 | #pragma mark *** Aesthetics *** 81 | 82 | + (BOOL)styleSupportsAnimation:(SRRecorderStyle)style; 83 | 84 | - (BOOL)animates; 85 | - (void)setAnimates:(BOOL)an; 86 | - (SRRecorderStyle)style; 87 | - (void)setStyle:(SRRecorderStyle)nStyle; 88 | 89 | #pragma mark *** Delegate *** 90 | 91 | - (id)delegate; 92 | - (void)setDelegate:(id)aDelegate; 93 | 94 | #pragma mark *** Responder Control *** 95 | 96 | - (BOOL)becomeFirstResponder; 97 | - (BOOL)resignFirstResponder; 98 | 99 | #pragma mark *** Key Combination Control *** 100 | 101 | - (BOOL)performKeyEquivalent:(NSEvent *)theEvent; 102 | - (void)flagsChanged:(NSEvent *)theEvent; 103 | 104 | - (NSUInteger)allowedFlags; 105 | - (void)setAllowedFlags:(NSUInteger)flags; 106 | 107 | - (NSUInteger)requiredFlags; 108 | - (void)setRequiredFlags:(NSUInteger)flags; 109 | 110 | - (BOOL)allowsKeyOnly; 111 | - (void)setAllowsKeyOnly:(BOOL)nAllowsKeyOnly; 112 | - (void)setAllowsKeyOnly:(BOOL)nAllowsKeyOnly escapeKeysRecord:(BOOL)nEscapeKeysRecord; 113 | - (BOOL)escapeKeysRecord; 114 | - (void)setEscapeKeysRecord:(BOOL)nEscapeKeysRecord; 115 | 116 | - (BOOL)canCaptureGlobalHotKeys; 117 | - (void)setCanCaptureGlobalHotKeys:(BOOL)inState; 118 | 119 | - (KeyCombo)keyCombo; 120 | - (void)setKeyCombo:(KeyCombo)aKeyCombo; 121 | 122 | #pragma mark *** Autosave Control *** 123 | 124 | - (NSString *)autosaveName; 125 | - (void)setAutosaveName:(NSString *)aName; 126 | 127 | // Returns the displayed key combination if set 128 | - (NSString *)keyComboString; 129 | 130 | - (NSString *)keyChars; 131 | - (NSString *)keyCharsIgnoringModifiers; 132 | 133 | @end 134 | 135 | // Delegate Methods 136 | @interface NSObject (SRRecorderCellDelegate) 137 | - (BOOL)shortcutRecorderCell:(SRRecorderCell *)aRecorderCell isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags reason:(NSString **)aReason; 138 | - (void)shortcutRecorderCell:(SRRecorderCell *)aRecorderCell keyComboDidChange:(KeyCombo)newCombo; 139 | @end 140 | -------------------------------------------------------------------------------- /NAKL/NSFileManager+DirectoryLocations.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSFileManager+DirectoryLocations.m 3 | // 4 | // Created by Matt Gallagher on 06 May 2010 5 | // 6 | // This software is provided 'as-is', without any express or implied 7 | // warranty. In no event will the authors be held liable for any damages 8 | // arising from the use of this software. Permission is granted to anyone to 9 | // use this software for any purpose, including commercial applications, and to 10 | // alter it and redistribute it freely, subject to the following restrictions: 11 | // 12 | // 1. The origin of this software must not be misrepresented; you must not 13 | // claim that you wrote the original software. If you use this software 14 | // in a product, an acknowledgment in the product documentation would be 15 | // appreciated but is not required. 16 | // 2. Altered source versions must be plainly marked as such, and must not be 17 | // misrepresented as being the original software. 18 | // 3. This notice may not be removed or altered from any source 19 | // distribution. 20 | // 21 | 22 | #import "NSFileManager+DirectoryLocations.h" 23 | 24 | enum 25 | { 26 | DirectoryLocationErrorNoPathFound, 27 | DirectoryLocationErrorFileExistsAtLocation 28 | }; 29 | 30 | NSString * const DirectoryLocationDomain = @"DirectoryLocationDomain"; 31 | 32 | @implementation NSFileManager (DirectoryLocations) 33 | 34 | // 35 | // findOrCreateDirectory:inDomain:appendPathComponent:error: 36 | // 37 | // Method to tie together the steps of: 38 | // 1) Locate a standard directory by search path and domain mask 39 | // 2) Select the first path in the results 40 | // 3) Append a subdirectory to that path 41 | // 4) Create the directory and intermediate directories if needed 42 | // 5) Handle errors by emitting a proper NSError object 43 | // 44 | // Parameters: 45 | // searchPathDirectory - the search path passed to NSSearchPathForDirectoriesInDomains 46 | // domainMask - the domain mask passed to NSSearchPathForDirectoriesInDomains 47 | // appendComponent - the subdirectory appended 48 | // errorOut - any error from file operations 49 | // 50 | // returns the path to the directory (if path found and exists), nil otherwise 51 | // 52 | - (NSString *)findOrCreateDirectory:(NSSearchPathDirectory)searchPathDirectory 53 | inDomain:(NSSearchPathDomainMask)domainMask 54 | appendPathComponent:(NSString *)appendComponent 55 | error:(NSError **)errorOut 56 | { 57 | // 58 | // Search for the path 59 | // 60 | NSArray* paths = NSSearchPathForDirectoriesInDomains( 61 | searchPathDirectory, 62 | domainMask, 63 | YES); 64 | if ([paths count] == 0) 65 | { 66 | if (errorOut) 67 | { 68 | NSDictionary *userInfo = 69 | [NSDictionary dictionaryWithObjectsAndKeys: 70 | NSLocalizedStringFromTable( 71 | @"No path found for directory in domain.", 72 | @"Errors", 73 | nil), 74 | NSLocalizedDescriptionKey, 75 | [NSNumber numberWithInteger:searchPathDirectory], 76 | @"NSSearchPathDirectory", 77 | [NSNumber numberWithInteger:domainMask], 78 | @"NSSearchPathDomainMask", 79 | nil]; 80 | *errorOut = 81 | [NSError 82 | errorWithDomain:DirectoryLocationDomain 83 | code:DirectoryLocationErrorNoPathFound 84 | userInfo:userInfo]; 85 | } 86 | return nil; 87 | } 88 | 89 | // 90 | // Normally only need the first path returned 91 | // 92 | NSString *resolvedPath = [paths objectAtIndex:0]; 93 | 94 | // 95 | // Append the extra path component 96 | // 97 | if (appendComponent) 98 | { 99 | resolvedPath = [resolvedPath 100 | stringByAppendingPathComponent:appendComponent]; 101 | } 102 | 103 | // 104 | // Create the path if it doesn't exist 105 | // 106 | NSError *error = nil; 107 | BOOL success = [self 108 | createDirectoryAtPath:resolvedPath 109 | withIntermediateDirectories:YES 110 | attributes:nil 111 | error:&error]; 112 | if (!success) 113 | { 114 | if (errorOut) 115 | { 116 | *errorOut = error; 117 | } 118 | return nil; 119 | } 120 | 121 | // 122 | // If we've made it this far, we have a success 123 | // 124 | if (errorOut) 125 | { 126 | *errorOut = nil; 127 | } 128 | return resolvedPath; 129 | } 130 | 131 | // 132 | // applicationSupportDirectory 133 | // 134 | // Returns the path to the applicationSupportDirectory (creating it if it doesn't 135 | // exist). 136 | // 137 | - (NSString *)applicationSupportDirectory 138 | { 139 | NSString *executableName = 140 | [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"]; 141 | NSError *error; 142 | NSString *result = 143 | [self 144 | findOrCreateDirectory:NSApplicationSupportDirectory 145 | inDomain:NSUserDomainMask 146 | appendPathComponent:executableName 147 | error:&error]; 148 | if (!result) 149 | { 150 | NSLog(@"Unable to find or create application support directory:\n%@", error); 151 | } 152 | return result; 153 | } 154 | 155 | @end 156 | -------------------------------------------------------------------------------- /NAKL/PreferencesController.m: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | #import "PreferencesController.h" 20 | #import "ShortcutRecorder/SRRecorderControl.h" 21 | #import "PTHotKeyCenter.h" 22 | #import "PTHotKey.h" 23 | #import "NSFileManager+DirectoryLocations.h" 24 | 25 | @implementation PreferencesController 26 | 27 | @synthesize toggleHotKey = _toggleHotKey; 28 | @synthesize switchMethodHotKey = _switchMethodHotKey; 29 | @synthesize versionString; 30 | @synthesize shortcuts; 31 | 32 | -(id)init { 33 | if (![super initWithWindowNibName:@"Preferences"]) 34 | return nil; 35 | NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 36 | 37 | NSString *buildNumber = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]; 38 | 39 | self.versionString = [NSString stringWithFormat:@"Version %@ (build %@)", version, buildNumber]; 40 | 41 | return self; 42 | } 43 | 44 | - (void)windowDidLoad { 45 | [super windowDidLoad]; 46 | [self.toggleHotKey setKeyCombo: [AppData sharedAppData].toggleCombo]; 47 | [self.switchMethodHotKey setKeyCombo: [AppData sharedAppData].switchMethodCombo]; 48 | 49 | [self.shortcuts setContent:[AppData sharedAppData].shortcuts]; 50 | } 51 | 52 | - (void)windowWillClose :(NSNotification *)notification 53 | { 54 | [self saveSetting]; 55 | } 56 | 57 | - (BOOL)shortcutRecorder:(SRRecorderControl *)aRecorder isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags reason:(NSString **)aReason 58 | { 59 | return NO; 60 | } 61 | 62 | - (void)shortcutRecorder:(SRRecorderControl *)aRecorder keyComboDidChange:(KeyCombo)newKeyCombo 63 | { 64 | PTKeyCombo *keyCombo = [[PTKeyCombo alloc] initWithKeyCode:newKeyCombo.code modifiers:newKeyCombo.flags]; 65 | if (aRecorder == self.toggleHotKey) { 66 | [[AppData sharedAppData].userPrefs setObject:[keyCombo plistRepresentation] forKey:NAKL_TOGGLE_HOTKEY]; 67 | [AppData sharedAppData].toggleCombo = newKeyCombo; 68 | } else { 69 | [[AppData sharedAppData].userPrefs setObject:[keyCombo plistRepresentation] forKey:NAKL_SWITCH_METHOD_HOTKEY]; 70 | [AppData sharedAppData].switchMethodCombo = newKeyCombo; 71 | } 72 | } 73 | 74 | - (void) addAppsAsLoginItem 75 | { 76 | NSString * appPath = [[NSBundle mainBundle] bundlePath]; 77 | 78 | CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:appPath]; 79 | 80 | LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, 81 | kLSSharedFileListSessionLoginItems, NULL); 82 | if (loginItems) { 83 | //Insert an item to the list. 84 | LSSharedFileListItemRef item = LSSharedFileListInsertItemURL(loginItems, 85 | kLSSharedFileListItemLast, NULL, NULL, 86 | url, NULL, NULL); 87 | if (item){ 88 | CFRelease(item); 89 | } 90 | } 91 | 92 | CFRelease(loginItems); 93 | } 94 | 95 | -(void) removeAppFromLoginItem 96 | { 97 | NSString * appPath = [[NSBundle mainBundle] bundlePath]; 98 | 99 | CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:appPath]; 100 | 101 | LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL, 102 | kLSSharedFileListSessionLoginItems, NULL); 103 | 104 | if (loginItems) { 105 | UInt32 seedValue; 106 | NSArray *loginItemsArray = (NSArray *)LSSharedFileListCopySnapshot(loginItems, &seedValue); 107 | int i = 0; 108 | for( ; i< [loginItemsArray count]; i++){ 109 | LSSharedFileListItemRef itemRef = (LSSharedFileListItemRef)[loginItemsArray 110 | objectAtIndex:i]; 111 | if (LSSharedFileListItemResolve(itemRef, 0, (CFURLRef*) &url, NULL) == noErr) { 112 | NSString * urlPath = [(NSURL*)url path]; 113 | if ([urlPath compare:appPath] == NSOrderedSame){ 114 | LSSharedFileListItemRemove(loginItems,itemRef); 115 | } 116 | } 117 | } 118 | [loginItemsArray release]; 119 | } 120 | } 121 | 122 | - (IBAction) startupOptionClick:(id)sender 123 | { 124 | if (((NSButton*) sender).state == NSOnState) { 125 | [self addAppsAsLoginItem]; 126 | } else { 127 | [self removeAppFromLoginItem]; 128 | } 129 | } 130 | 131 | - (void) saveSetting 132 | { 133 | NSString *filePath = [[[NSFileManager defaultManager] applicationSupportDirectory] stringByAppendingPathComponent:@"shortcuts.setting"]; 134 | NSData *theData = [NSKeyedArchiver archivedDataWithRootObject:[AppData sharedAppData].shortcuts]; 135 | [NSKeyedArchiver archiveRootObject:theData toFile:filePath]; 136 | 137 | [[AppData sharedAppData].shortcutDictionary removeAllObjects]; 138 | for (ShortcutSetting *s in [AppData sharedAppData].shortcuts) { 139 | [[AppData sharedAppData].shortcutDictionary setObject:s.text forKey:s.shortcut]; 140 | } 141 | } 142 | 143 | - (void) dealloc { 144 | [shortcutsTableView release]; 145 | [super dealloc]; 146 | } 147 | 148 | @end -------------------------------------------------------------------------------- /NAKL/HotKey/PTKeyCombo.m: -------------------------------------------------------------------------------- 1 | // 2 | // PTKeyCombo.m 3 | // Protein 4 | // 5 | // Created by Quentin Carnicelli on Sat Aug 02 2003. 6 | // Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved. 7 | // 8 | 9 | #import "PTKeyCombo.h" 10 | #import "PTKeyCodeTranslator.h" 11 | 12 | @implementation PTKeyCombo 13 | 14 | + (id)clearKeyCombo 15 | { 16 | return [self keyComboWithKeyCode: -1 modifiers: -1]; 17 | } 18 | 19 | + (id)keyComboWithKeyCode: (NSInteger)keyCode modifiers: (NSUInteger)modifiers 20 | { 21 | return [[[self alloc] initWithKeyCode: keyCode modifiers: modifiers] autorelease]; 22 | } 23 | 24 | - (id)initWithKeyCode: (NSInteger)keyCode modifiers: (NSUInteger)modifiers 25 | { 26 | self = [super init]; 27 | 28 | if( self ) 29 | { 30 | mKeyCode = keyCode; 31 | mModifiers = modifiers; 32 | } 33 | 34 | return self; 35 | } 36 | 37 | - (id)initWithPlistRepresentation: (id)plist 38 | { 39 | int keyCode, modifiers; 40 | 41 | if( !plist || ![plist count] ) 42 | { 43 | keyCode = -1; 44 | modifiers = -1; 45 | } 46 | else 47 | { 48 | keyCode = [[plist objectForKey: @"keyCode"] intValue]; 49 | if( keyCode < 0 ) keyCode = -1; 50 | 51 | modifiers = [[plist objectForKey: @"modifiers"] intValue]; 52 | if( modifiers <= 0 ) modifiers = -1; 53 | } 54 | 55 | return [self initWithKeyCode: keyCode modifiers: modifiers]; 56 | } 57 | 58 | - (id)plistRepresentation 59 | { 60 | return [NSDictionary dictionaryWithObjectsAndKeys: 61 | [NSNumber numberWithInteger: [self keyCode]], @"keyCode", 62 | [NSNumber numberWithInteger: [self modifiers]], @"modifiers", 63 | nil]; 64 | } 65 | 66 | - (id)copyWithZone:(NSZone*)zone; 67 | { 68 | return [self retain]; 69 | } 70 | 71 | - (BOOL)isEqual: (PTKeyCombo*)combo 72 | { 73 | return [self keyCode] == [combo keyCode] && 74 | [self modifiers] == [combo modifiers]; 75 | } 76 | 77 | #pragma mark - 78 | 79 | - (NSInteger)keyCode 80 | { 81 | return mKeyCode; 82 | } 83 | 84 | - (NSUInteger)modifiers 85 | { 86 | return mModifiers; 87 | } 88 | 89 | - (BOOL)isValidHotKeyCombo 90 | { 91 | return mKeyCode >= 0 && mModifiers > 0; 92 | } 93 | 94 | - (BOOL)isClearCombo 95 | { 96 | return mKeyCode == -1 && mModifiers == -1; 97 | } 98 | 99 | @end 100 | 101 | #pragma mark - 102 | 103 | @implementation PTKeyCombo (UserDisplayAdditions) 104 | 105 | + (NSString*)_stringForModifiers: (long)modifiers 106 | { 107 | static unichar modToChar[4][2] = 108 | { 109 | { cmdKey, kCommandUnicode }, 110 | { optionKey, kOptionUnicode }, 111 | { controlKey, kControlUnicode }, 112 | { shiftKey, kShiftUnicode } 113 | }; 114 | 115 | NSString* str = [NSString string]; 116 | long i; 117 | 118 | for( i = 0; i < 4; i++ ) 119 | { 120 | if( modifiers & modToChar[i][0] ) 121 | str = [str stringByAppendingString: [NSString stringWithCharacters: &modToChar[i][1] length: 1]]; 122 | } 123 | 124 | return str; 125 | } 126 | 127 | + (NSDictionary*)_keyCodesDictionary 128 | { 129 | static NSDictionary* keyCodes = nil; 130 | 131 | if( keyCodes == nil ) 132 | { 133 | NSURL *url = [NSURL fileURLWithPath:[[NSBundle bundleForClass: self] pathForResource: @"PTKeyCodes" ofType: @"plist"]]; 134 | NSString *contents = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:NULL]; 135 | keyCodes = [[contents propertyList] retain]; 136 | } 137 | 138 | return keyCodes; 139 | } 140 | 141 | + (NSString*)_stringForKeyCode: (short)keyCode legacyKeyCodeMap: (NSDictionary*)dict 142 | { 143 | id key; 144 | NSString* str; 145 | 146 | key = [NSString stringWithFormat: @"%d", keyCode]; 147 | str = [dict objectForKey: key]; 148 | 149 | if( !str ) 150 | str = [NSString stringWithFormat: @"%X", keyCode]; 151 | 152 | return str; 153 | } 154 | 155 | + (NSString*)_stringForKeyCode: (short)keyCode newKeyCodeMap: (NSDictionary*)dict 156 | { 157 | NSString* result; 158 | NSString* keyCodeStr; 159 | NSDictionary* unmappedKeys; 160 | NSArray* padKeys; 161 | 162 | keyCodeStr = [NSString stringWithFormat: @"%d", keyCode]; 163 | 164 | //Handled if its not handled by translator 165 | unmappedKeys = [dict objectForKey:@"unmappedKeys"]; 166 | result = [unmappedKeys objectForKey: keyCodeStr]; 167 | if( result ) 168 | return result; 169 | 170 | //Translate it 171 | result = [[[PTKeyCodeTranslator currentTranslator] translateKeyCode:keyCode] uppercaseString]; 172 | 173 | //Handle if its a key-pad key 174 | padKeys = [dict objectForKey:@"padKeys"]; 175 | if( [padKeys indexOfObject: keyCodeStr] != NSNotFound ) 176 | { 177 | result = [NSString stringWithFormat:@"%@ %@", [dict objectForKey:@"padKeyString"], result]; 178 | } 179 | 180 | return result; 181 | } 182 | 183 | + (NSString*)_stringForKeyCode: (short)keyCode 184 | { 185 | NSDictionary* dict; 186 | 187 | dict = [self _keyCodesDictionary]; 188 | if( [[dict objectForKey: @"version"] intValue] <= 0 ) 189 | return [self _stringForKeyCode: keyCode legacyKeyCodeMap: dict]; 190 | 191 | return [self _stringForKeyCode: keyCode newKeyCodeMap: dict]; 192 | } 193 | 194 | - (NSString*)keyCodeString 195 | { 196 | // special case: the modifiers for the "clear" key are 0x0 197 | if ( [self isClearCombo] ) return @""; 198 | 199 | return [[self class] _stringForKeyCode:[self keyCode]]; 200 | } 201 | 202 | - (NSUInteger)modifierMask 203 | { 204 | // special case: the modifiers for the "clear" key are 0x0 205 | if ( [self isClearCombo] ) return 0; 206 | 207 | static NSUInteger modToChar[4][2] = 208 | { 209 | { cmdKey, NSCommandKeyMask }, 210 | { optionKey, NSAlternateKeyMask }, 211 | { controlKey, NSControlKeyMask }, 212 | { shiftKey, NSShiftKeyMask } 213 | }; 214 | 215 | NSUInteger i, ret = 0; 216 | 217 | for ( i = 0; i < 4; i++ ) 218 | { 219 | if ( [self modifiers] & modToChar[i][0] ) { 220 | ret |= modToChar[i][1]; 221 | } 222 | } 223 | 224 | return ret; 225 | } 226 | 227 | - (NSString*)description 228 | { 229 | NSString* desc; 230 | 231 | if( [self isValidHotKeyCombo] ) //This might have to change 232 | { 233 | desc = [NSString stringWithFormat: @"%@%@", 234 | [[self class] _stringForModifiers: [self modifiers]], 235 | [[self class] _stringForKeyCode: [self keyCode]]]; 236 | } 237 | else 238 | { 239 | desc = NSLocalizedString( @"(None)", @"Hot Keys: Key Combo text for 'empty' combo" ); 240 | } 241 | 242 | return desc; 243 | } 244 | 245 | @end 246 | -------------------------------------------------------------------------------- /NAKL/keymap.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | 20 | #ifndef NAKL_KEYMAP_H 21 | #define NAKL_KEYMAP_H 22 | 23 | #define XK_VoidSymbol 0xFF /* void symbol */ 24 | 25 | /* 26 | * TTY Functions, cleverly chosen to map to ascii, for convenience of 27 | * programming, but could have been arbitrary (at the cost of lookup 28 | * tables in client code. 29 | */ 30 | 31 | #define XK_BackSpace 0x08 /* back space, back char */ 32 | #define XK_Tab 0x09 33 | #define XK_Linefeed 0x0A /* Linefeed, LF */ 34 | #define XK_Clear 0x0B 35 | #define XK_Return 0x0D /* Return, enter */ 36 | #define XK_Pause 0x13 /* Pause, hold */ 37 | #define XK_Scroll_Lock 0x14 38 | #define XK_Sys_Req 0x15 39 | #define XK_Escape 0x1B 40 | #define XK_SpaceBar 0x20 41 | #define XK_Delete 0xFF /* Delete, rubout */ 42 | 43 | /* Cursor control & motion */ 44 | 45 | #define XK_Home 0x50 46 | #define XK_Left 0x51 /* Move left, left arrow */ 47 | #define XK_Up 0x52 /* Move up, up arrow */ 48 | #define XK_Right 0x53 /* Move right, right arrow */ 49 | #define XK_Down 0x54 /* Move down, down arrow */ 50 | #define XK_Prior 0x55 /* Prior, previous */ 51 | #define XK_Page_Up 0x55 52 | #define XK_Next 0x56 /* Next */ 53 | #define XK_Page_Down 0x56 54 | #define XK_End 0x57 /* EOL */ 55 | #define XK_Begin 0x58 /* BOL */ 56 | 57 | /* Special Windows keyboard keys */ 58 | 59 | #define XK_Win_L 0x5B /* Left-hand Windows */ 60 | #define XK_Win_R 0x5C /* Right-hand Windows */ 61 | #define XK_App 0x5D /* Menu key */ 62 | 63 | /* Misc Functions */ 64 | 65 | #define XK_Select 0x60 /* Select, mark */ 66 | #define XK_Print 0x61 67 | #define XK_Execute 0x62 /* Execute, run, do */ 68 | #define XK_Insert 0x63 /* Insert, insert here */ 69 | #define XK_Undo 0x65 /* Undo, oops */ 70 | #define XK_Redo 0x66 /* redo, again */ 71 | #define XK_Menu 0x67 72 | #define XK_Find 0x68 /* Find, search */ 73 | #define XK_Cancel 0x69 /* Cancel, stop, abort, exit */ 74 | #define XK_Help 0x6A /* Help, ? */ 75 | #define XK_Break 0x6B 76 | #define XK_Mode_switch 0x7E /* Character set switch */ 77 | #define XK_script_switch 0x7E /* Alias for mode_switch */ 78 | #define XK_Num_Lock 0x7F 79 | 80 | /* 81 | * Auxilliary Functions; note the duplicate definitions for left and right 82 | * function keys; Sun keyboards and a few other manufactures have such 83 | * function key groups on the left and/or right sides of the keyboard. 84 | * We've not found a keyboard with more than 35 function keys total. 85 | */ 86 | 87 | #define XK_F1 0xBE 88 | #define XK_F2 0xBF 89 | #define XK_F3 0xC0 90 | #define XK_F4 0xC1 91 | #define XK_F5 0xC2 92 | #define XK_F6 0xC3 93 | #define XK_F7 0xC4 94 | #define XK_F8 0xC5 95 | #define XK_F9 0xC6 96 | #define XK_F10 0xC7 97 | #define XK_F11 0xC8 98 | #define XK_L1 0xC8 99 | #define XK_F12 0xC9 100 | #define XK_L2 0xC9 101 | #define XK_F13 0xCA 102 | #define XK_L3 0xCA 103 | #define XK_F14 0xCB 104 | #define XK_L4 0xCB 105 | #define XK_F15 0xCC 106 | #define XK_L5 0xCC 107 | #define XK_F16 0xCD 108 | #define XK_L6 0xCD 109 | #define XK_F17 0xCE 110 | #define XK_L7 0xCE 111 | #define XK_F18 0xCF 112 | #define XK_L8 0xCF 113 | #define XK_F19 0xD0 114 | #define XK_L9 0xD0 115 | #define XK_F20 0xD1 116 | #define XK_L10 0xD1 117 | #define XK_F21 0xD2 118 | #define XK_R1 0xD2 119 | #define XK_F22 0xD3 120 | #define XK_R2 0xD3 121 | #define XK_F23 0xD4 122 | #define XK_R3 0xD4 123 | #define XK_F24 0xD5 124 | #define XK_R4 0xD5 125 | #define XK_F25 0xD6 126 | #define XK_R5 0xD6 127 | #define XK_F26 0xD7 128 | #define XK_R6 0xD7 129 | #define XK_F27 0xD8 130 | #define XK_R7 0xD8 131 | #define XK_F28 0xD9 132 | #define XK_R8 0xD9 133 | #define XK_F29 0xDA 134 | #define XK_R9 0xDA 135 | #define XK_F30 0xDB 136 | #define XK_R10 0xDB 137 | #define XK_F31 0xDC 138 | #define XK_R11 0xDC 139 | #define XK_F32 0xDD 140 | #define XK_R12 0xDD 141 | #define XK_F33 0xDE 142 | #define XK_R13 0xDE 143 | #define XK_F34 0xDF 144 | #define XK_R14 0xDF 145 | #define XK_F35 0xE0 146 | #define XK_R15 0xE0 147 | 148 | /* Modifiers */ 149 | 150 | #define XK_Shift_L 0xE1 /* Left shift */ 151 | #define XK_Shift_R 0xE2 /* Right shift */ 152 | #define XK_Control_L 0xE3 /* Left control */ 153 | #define XK_Control_R 0xE4 /* Right control */ 154 | #define XK_Caps_Lock 0xE5 /* Caps lock */ 155 | #define XK_Shift_Lock 0xE6 /* Shift lock */ 156 | 157 | #define XK_Meta_L 0xE7 /* Left meta */ 158 | #define XK_Meta_R 0xE8 /* Right meta */ 159 | #define XK_Alt_L 0xE9 /* Left alt */ 160 | #define XK_Alt_R 0xEA /* Right alt */ 161 | #define XK_Super_L 0xEB /* Left super */ 162 | #define XK_Super_R 0xEC /* Right super */ 163 | #define XK_Hyper_L 0xED /* Left hyper */ 164 | #define XK_Hyper_R 0xEE /* Right hyper */ 165 | 166 | 167 | #define KC_BackSpace 0x33 /* back space, back char */ 168 | #define KC_Tab 0x30 169 | #define KC_Return 0x24 /* Return, enter */ 170 | #define KC_Return_Num 0x4c /* BOL */ 171 | #define KC_Escape 0x35 172 | #define KC_SpaceBar 0x31 173 | #define KC_Delete 0x75 /* Delete, rubout */ 174 | 175 | /* Cursor control & motion */ 176 | 177 | #define KC_Home 0x73 178 | #define KC_Left 0x7b /* Move left, left arrow */ 179 | #define KC_Up 0x7e /* Move up, up arrow */ 180 | #define KC_Right 0x7c /* Move right, right arrow */ 181 | #define KC_Down 0x7d /* Move down, down arrow */ 182 | #define KC_Page_Up 0x74 183 | #define KC_Page_Down 0x79 184 | #define KC_End 0x77 /* EOL */ 185 | 186 | 187 | #endif 188 | -------------------------------------------------------------------------------- /NAKL/HotKey/PTHotKeyCenter.m: -------------------------------------------------------------------------------- 1 | // 2 | // PTHotKeyCenter.m 3 | // Protein 4 | // 5 | // Created by Quentin Carnicelli on Sat Aug 02 2003. 6 | // Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved. 7 | // 8 | 9 | #import "PTHotKeyCenter.h" 10 | #import "PTHotKey.h" 11 | #import "PTKeyCombo.h" 12 | #import 13 | 14 | @interface PTHotKeyCenter (Private) 15 | - (PTHotKey*)_hotKeyForCarbonHotKey: (EventHotKeyRef)carbonHotKey; 16 | - (PTHotKey*)_hotKeyForCarbonHotKeyID: (EventHotKeyID)hotKeyID; 17 | 18 | - (void)_updateEventHandler; 19 | - (void)_hotKeyDown: (PTHotKey*)hotKey; 20 | - (void)_hotKeyUp: (PTHotKey*)hotKey; 21 | static OSStatus hotKeyEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void* refCon ); 22 | @end 23 | 24 | @implementation PTHotKeyCenter 25 | 26 | static PTHotKeyCenter *_sharedHotKeyCenter = nil; 27 | 28 | + (PTHotKeyCenter*)sharedCenter 29 | { 30 | if( _sharedHotKeyCenter == nil ) 31 | { 32 | _sharedHotKeyCenter = [[self alloc] init]; 33 | } 34 | 35 | return _sharedHotKeyCenter; 36 | } 37 | 38 | - (id)init 39 | { 40 | self = [super init]; 41 | 42 | if( self ) 43 | { 44 | mHotKeys = [[NSMutableDictionary alloc] init]; 45 | } 46 | 47 | return self; 48 | } 49 | 50 | - (void)dealloc 51 | { 52 | [mHotKeys release]; 53 | [super dealloc]; 54 | } 55 | 56 | #pragma mark - 57 | 58 | - (BOOL)registerHotKey: (PTHotKey*)hotKey 59 | { 60 | OSStatus err; 61 | EventHotKeyID hotKeyID; 62 | EventHotKeyRef carbonHotKey; 63 | 64 | if( [[self allHotKeys] containsObject: hotKey] == YES ) 65 | [self unregisterHotKey: hotKey]; 66 | 67 | if( [[hotKey keyCombo] isValidHotKeyCombo] == NO ) 68 | return YES; 69 | 70 | hotKeyID.signature = 'PTHk'; 71 | hotKeyID.id = ++mHotKeyCount; 72 | 73 | err = RegisterEventHotKey( (SInt32)[[hotKey keyCombo] keyCode], 74 | (UInt32)[[hotKey keyCombo] modifiers], 75 | hotKeyID, 76 | GetEventDispatcherTarget(), 77 | 0, 78 | &carbonHotKey ); 79 | 80 | if( err ) 81 | return NO; 82 | 83 | [hotKey setCarbonHotKeyID:hotKeyID.id]; 84 | [hotKey setCarbonEventHotKeyRef:carbonHotKey]; 85 | 86 | if( hotKey ) 87 | [mHotKeys setObject: hotKey forKey: [NSNumber numberWithInteger:hotKeyID.id]]; 88 | 89 | [self _updateEventHandler]; 90 | 91 | return YES; 92 | } 93 | 94 | - (void)unregisterHotKey: (PTHotKey*)hotKey 95 | { 96 | EventHotKeyRef carbonHotKey; 97 | 98 | if( [[self allHotKeys] containsObject: hotKey] == NO ) 99 | return; 100 | 101 | carbonHotKey = [hotKey carbonEventHotKeyRef]; 102 | 103 | if( carbonHotKey ) 104 | { 105 | UnregisterEventHotKey( carbonHotKey ); 106 | //Watch as we ignore 'err': 107 | 108 | [mHotKeys removeObjectForKey: [NSNumber numberWithInteger:[hotKey carbonHotKeyID]]]; 109 | 110 | [hotKey setCarbonHotKeyID:0]; 111 | [hotKey setCarbonEventHotKeyRef:NULL]; 112 | 113 | [self _updateEventHandler]; 114 | 115 | //See that? Completely ignored 116 | } 117 | } 118 | 119 | - (NSArray*)allHotKeys 120 | { 121 | return [mHotKeys allValues]; 122 | } 123 | 124 | - (PTHotKey*)hotKeyWithIdentifier: (id)ident 125 | { 126 | NSEnumerator* hotKeysEnum = [[self allHotKeys] objectEnumerator]; 127 | PTHotKey* hotKey; 128 | 129 | if( !ident ) 130 | return nil; 131 | 132 | while( (hotKey = [hotKeysEnum nextObject]) != nil ) 133 | { 134 | if( [[hotKey identifier] isEqual: ident] ) 135 | return hotKey; 136 | } 137 | 138 | return nil; 139 | } 140 | 141 | #pragma mark - 142 | 143 | - (PTHotKey*)_hotKeyForCarbonHotKey: (EventHotKeyRef)carbonHotKeyRef 144 | { 145 | NSEnumerator *e = [mHotKeys objectEnumerator]; 146 | PTHotKey *hotkey = nil; 147 | 148 | while( (hotkey = [e nextObject]) ) 149 | { 150 | if( [hotkey carbonEventHotKeyRef] == carbonHotKeyRef ) 151 | return hotkey; 152 | } 153 | 154 | return nil; 155 | } 156 | 157 | - (PTHotKey*)_hotKeyForCarbonHotKeyID: (EventHotKeyID)hotKeyID 158 | { 159 | return [mHotKeys objectForKey:[NSNumber numberWithInteger:hotKeyID.id]]; 160 | } 161 | 162 | - (void)_updateEventHandler 163 | { 164 | if( [mHotKeys count] && mEventHandlerInstalled == NO ) 165 | { 166 | EventTypeSpec eventSpec[2] = { 167 | { kEventClassKeyboard, kEventHotKeyPressed }, 168 | { kEventClassKeyboard, kEventHotKeyReleased } 169 | }; 170 | 171 | InstallEventHandler( GetEventDispatcherTarget(), 172 | (EventHandlerProcPtr)hotKeyEventHandler, 173 | 2, eventSpec, nil, nil); 174 | 175 | mEventHandlerInstalled = YES; 176 | } 177 | } 178 | 179 | - (void)_hotKeyDown: (PTHotKey*)hotKey 180 | { 181 | [hotKey invoke]; 182 | } 183 | 184 | - (void)_hotKeyUp: (PTHotKey*)hotKey 185 | { 186 | } 187 | 188 | - (void)sendEvent: (NSEvent*)event 189 | { 190 | // Not sure why this is needed? - Andy Kim (Aug 23, 2009) 191 | 192 | short subType; 193 | EventHotKeyRef carbonHotKey; 194 | 195 | if( [event type] == NSSystemDefined ) 196 | { 197 | subType = [event subtype]; 198 | 199 | if( subType == 6 ) //6 is hot key down 200 | { 201 | carbonHotKey= (EventHotKeyRef)[event data1]; //data1 is our hot key ref 202 | if( carbonHotKey != nil ) 203 | { 204 | PTHotKey* hotKey = [self _hotKeyForCarbonHotKey: carbonHotKey]; 205 | [self _hotKeyDown: hotKey]; 206 | } 207 | } 208 | else if( subType == 9 ) //9 is hot key up 209 | { 210 | carbonHotKey= (EventHotKeyRef)[event data1]; 211 | if( carbonHotKey != nil ) 212 | { 213 | PTHotKey* hotKey = [self _hotKeyForCarbonHotKey: carbonHotKey]; 214 | [self _hotKeyUp: hotKey]; 215 | } 216 | } 217 | } 218 | } 219 | 220 | - (OSStatus)sendCarbonEvent: (EventRef)event 221 | { 222 | OSStatus err; 223 | EventHotKeyID hotKeyID; 224 | PTHotKey* hotKey; 225 | 226 | NSAssert( GetEventClass( event ) == kEventClassKeyboard, @"Unknown event class" ); 227 | 228 | err = GetEventParameter( event, 229 | kEventParamDirectObject, 230 | typeEventHotKeyID, 231 | nil, 232 | sizeof(EventHotKeyID), 233 | nil, 234 | &hotKeyID ); 235 | if( err ) 236 | return err; 237 | 238 | 239 | NSAssert( hotKeyID.signature == 'PTHk', @"Invalid hot key id" ); 240 | NSAssert( hotKeyID.id != 0, @"Invalid hot key id" ); 241 | 242 | hotKey = [self _hotKeyForCarbonHotKeyID:hotKeyID]; 243 | 244 | switch( GetEventKind( event ) ) 245 | { 246 | case kEventHotKeyPressed: 247 | [self _hotKeyDown: hotKey]; 248 | break; 249 | 250 | case kEventHotKeyReleased: 251 | [self _hotKeyUp: hotKey]; 252 | break; 253 | 254 | default: 255 | NSAssert( 0, @"Unknown event kind" ); 256 | break; 257 | } 258 | 259 | return noErr; 260 | } 261 | 262 | static OSStatus hotKeyEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void* refCon ) 263 | { 264 | return [[PTHotKeyCenter sharedCenter] sendCarbonEvent: inEvent]; 265 | } 266 | 267 | @end 268 | -------------------------------------------------------------------------------- /NAKL/ShortcutRecorder/SRCommon.h: -------------------------------------------------------------------------------- 1 | // 2 | // SRCommon.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import 15 | #import 16 | #import 17 | 18 | #pragma mark Dummy class 19 | 20 | @interface SRDummyClass : NSObject {} @end 21 | 22 | #pragma mark - 23 | #pragma mark Typedefs 24 | 25 | typedef struct _KeyCombo { 26 | NSUInteger flags; // 0 for no flags 27 | NSInteger code; // -1 for no code 28 | } KeyCombo; 29 | 30 | #pragma mark - 31 | #pragma mark Enums 32 | 33 | // Unicode values of some keyboard glyphs 34 | enum { 35 | KeyboardTabRightGlyph = 0x21E5, 36 | KeyboardTabLeftGlyph = 0x21E4, 37 | KeyboardCommandGlyph = kCommandUnicode, 38 | KeyboardOptionGlyph = kOptionUnicode, 39 | KeyboardShiftGlyph = kShiftUnicode, 40 | KeyboardControlGlyph = kControlUnicode, 41 | KeyboardReturnGlyph = 0x2305, 42 | KeyboardReturnR2LGlyph = 0x21A9, 43 | KeyboardDeleteLeftGlyph = 0x232B, 44 | KeyboardDeleteRightGlyph = 0x2326, 45 | KeyboardPadClearGlyph = 0x2327, 46 | KeyboardLeftArrowGlyph = 0x2190, 47 | KeyboardRightArrowGlyph = 0x2192, 48 | KeyboardUpArrowGlyph = 0x2191, 49 | KeyboardDownArrowGlyph = 0x2193, 50 | KeyboardPageDownGlyph = 0x21DF, 51 | KeyboardPageUpGlyph = 0x21DE, 52 | KeyboardNorthwestArrowGlyph = 0x2196, 53 | KeyboardSoutheastArrowGlyph = 0x2198, 54 | KeyboardEscapeGlyph = 0x238B, 55 | KeyboardHelpGlyph = 0x003F, 56 | KeyboardUpArrowheadGlyph = 0x2303, 57 | }; 58 | 59 | // Special keys 60 | enum { 61 | kSRKeysF1 = 122, 62 | kSRKeysF2 = 120, 63 | kSRKeysF3 = 99, 64 | kSRKeysF4 = 118, 65 | kSRKeysF5 = 96, 66 | kSRKeysF6 = 97, 67 | kSRKeysF7 = 98, 68 | kSRKeysF8 = 100, 69 | kSRKeysF9 = 101, 70 | kSRKeysF10 = 109, 71 | kSRKeysF11 = 103, 72 | kSRKeysF12 = 111, 73 | kSRKeysF13 = 105, 74 | kSRKeysF14 = 107, 75 | kSRKeysF15 = 113, 76 | kSRKeysF16 = 106, 77 | kSRKeysF17 = 64, 78 | kSRKeysF18 = 79, 79 | kSRKeysF19 = 80, 80 | kSRKeysSpace = 49, 81 | kSRKeysDeleteLeft = 51, 82 | kSRKeysDeleteRight = 117, 83 | kSRKeysPadClear = 71, 84 | kSRKeysLeftArrow = 123, 85 | kSRKeysRightArrow = 124, 86 | kSRKeysUpArrow = 126, 87 | kSRKeysDownArrow = 125, 88 | kSRKeysSoutheastArrow = 119, 89 | kSRKeysNorthwestArrow = 115, 90 | kSRKeysEscape = 53, 91 | kSRKeysPageDown = 121, 92 | kSRKeysPageUp = 116, 93 | kSRKeysReturnR2L = 36, 94 | kSRKeysReturn = 76, 95 | kSRKeysTabRight = 48, 96 | kSRKeysHelp = 114 97 | }; 98 | 99 | #pragma mark - 100 | #pragma mark Macros 101 | 102 | // Localization macros, for use in any bundle 103 | #define SRLoc(key) SRLocalizedString(key, nil) 104 | #define SRLocalizedString(key, comment) NSLocalizedStringFromTableInBundle(key, @"ShortcutRecorder", [NSBundle bundleForClass: [SRDummyClass class]], comment) 105 | 106 | // Image macros, for use in any bundle 107 | //#define SRImage(name) [[[NSImage alloc] initWithContentsOfFile: [[NSBundle bundleForClass: [self class]] pathForImageResource: name]] autorelease] 108 | #define SRResIndImage(name) [SRSharedImageProvider supportingImageWithName:name] 109 | #define SRImage(name) SRResIndImage(name) 110 | 111 | //#define SRCommonWriteDebugImagery 112 | 113 | // Macros for glyps 114 | #define SRInt(x) [NSNumber numberWithInteger:x] 115 | #define SRChar(x) [NSString stringWithFormat: @"%C", x] 116 | 117 | // Some default values 118 | #define ShortcutRecorderEmptyFlags 0 119 | #define ShortcutRecorderAllFlags ShortcutRecorderEmptyFlags | (NSCommandKeyMask | NSAlternateKeyMask | NSControlKeyMask | NSShiftKeyMask | NSFunctionKeyMask) 120 | #define ShortcutRecorderEmptyCode -1 121 | 122 | // These keys will cancel the recoding mode if not pressed with any modifier 123 | #define ShortcutRecorderEscapeKey 53 124 | #define ShortcutRecorderBackspaceKey 51 125 | #define ShortcutRecorderDeleteKey 117 126 | 127 | #pragma mark - 128 | #pragma mark Getting a string of the key combination 129 | 130 | // 131 | // ################### +- Returns string from keyCode like NSEvent's -characters 132 | // # EXPLANATORY # | +- Returns string from keyCode like NSEvent's -charactersUsingModifiers 133 | // # CHART # | | +- Returns fully readable and localized name of modifier (if modifier given) 134 | // ################### | | | +- Returns glyph of modifier (if modifier given) 135 | // SRString... X - - X 136 | // SRReadableString... X - X - 137 | // SRCharacter... - X - - 138 | // 139 | NSString * SRStringForKeyCode( NSInteger keyCode ); 140 | NSString * SRStringForCarbonModifierFlags( NSUInteger flags ); 141 | NSString * SRStringForCarbonModifierFlagsAndKeyCode( NSUInteger flags, NSInteger keyCode ); 142 | NSString * SRStringForCocoaModifierFlags( NSUInteger flags ); 143 | NSString * SRStringForCocoaModifierFlagsAndKeyCode( NSUInteger flags, NSInteger keyCode ); 144 | NSString * SRReadableStringForCarbonModifierFlagsAndKeyCode( NSUInteger flags, NSInteger keyCode ); 145 | NSString * SRReadableStringForCocoaModifierFlagsAndKeyCode( NSUInteger flags, NSInteger keyCode ); 146 | NSString *SRCharacterForKeyCodeAndCarbonFlags(NSInteger keyCode, NSUInteger carbonFlags); 147 | NSString *SRCharacterForKeyCodeAndCocoaFlags(NSInteger keyCode, NSUInteger cocoaFlags); 148 | 149 | #pragma mark Converting between Cocoa and Carbon modifier flags 150 | 151 | NSUInteger SRCarbonToCocoaFlags( NSUInteger carbonFlags ); 152 | NSUInteger SRCocoaToCarbonFlags( NSUInteger cocoaFlags ); 153 | 154 | #pragma mark - 155 | #pragma mark Animation pace function 156 | 157 | CGFloat SRAnimationEaseInOut(CGFloat t); 158 | 159 | #pragma mark - 160 | #pragma mark Inlines 161 | 162 | FOUNDATION_STATIC_INLINE KeyCombo SRMakeKeyCombo(NSInteger code, NSUInteger flags) { 163 | KeyCombo kc; 164 | kc.code = code; 165 | kc.flags = flags; 166 | return kc; 167 | } 168 | 169 | FOUNDATION_STATIC_INLINE BOOL SRIsSpecialKey(NSInteger keyCode) { 170 | return (keyCode == kSRKeysF1 || keyCode == kSRKeysF2 || keyCode == kSRKeysF3 || keyCode == kSRKeysF4 || keyCode == kSRKeysF5 || keyCode == kSRKeysF6 || keyCode == kSRKeysF7 || keyCode == kSRKeysF8 || keyCode == kSRKeysF9 || keyCode == kSRKeysF10 || keyCode == kSRKeysF11 || keyCode == kSRKeysF12 || keyCode == kSRKeysF13 || keyCode == kSRKeysF14 || keyCode == kSRKeysF15 || keyCode == kSRKeysF16 || keyCode == kSRKeysSpace || keyCode == kSRKeysDeleteLeft || keyCode == kSRKeysDeleteRight || keyCode == kSRKeysPadClear || keyCode == kSRKeysLeftArrow || keyCode == kSRKeysRightArrow || keyCode == kSRKeysUpArrow || keyCode == kSRKeysDownArrow || keyCode == kSRKeysSoutheastArrow || keyCode == kSRKeysNorthwestArrow || keyCode == kSRKeysEscape || keyCode == kSRKeysPageDown || keyCode == kSRKeysPageUp || keyCode == kSRKeysReturnR2L || keyCode == kSRKeysReturn || keyCode == kSRKeysTabRight || keyCode == kSRKeysHelp); 171 | } 172 | 173 | #pragma mark - 174 | #pragma mark Additions 175 | 176 | @interface NSAlert( SRAdditions ) 177 | + (NSAlert *) alertWithNonRecoverableError:(NSError *)error; 178 | @end 179 | 180 | #pragma mark - 181 | #pragma mark Image provider 182 | 183 | @interface SRSharedImageProvider : NSObject 184 | + (NSImage *)supportingImageWithName:(NSString *)name; 185 | @end 186 | -------------------------------------------------------------------------------- /NAKL/ShortcutRecorder/SRKeyCodeTransformer.m: -------------------------------------------------------------------------------- 1 | // 2 | // SRKeyCodeTransformer.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import "SRKeyCodeTransformer.h" 15 | #import 16 | #import 17 | #import "SRCommon.h" 18 | 19 | static NSMutableDictionary *stringToKeyCodeDict = nil; 20 | static NSDictionary *keyCodeToStringDict = nil; 21 | static NSArray *padKeysArray = nil; 22 | 23 | @interface SRKeyCodeTransformer( Private ) 24 | + (void) regenerateStringToKeyCodeMapping; 25 | @end 26 | 27 | #pragma mark - 28 | 29 | @implementation SRKeyCodeTransformer 30 | 31 | //---------------------------------------------------------- 32 | // initialize 33 | //---------------------------------------------------------- 34 | + (void) initialize; 35 | { 36 | if ( self != [SRKeyCodeTransformer class] ) 37 | return; 38 | 39 | // Some keys need a special glyph 40 | keyCodeToStringDict = [[NSDictionary alloc] initWithObjectsAndKeys: 41 | @"F1", SRInt(122), 42 | @"F2", SRInt(120), 43 | @"F3", SRInt(99), 44 | @"F4", SRInt(118), 45 | @"F5", SRInt(96), 46 | @"F6", SRInt(97), 47 | @"F7", SRInt(98), 48 | @"F8", SRInt(100), 49 | @"F9", SRInt(101), 50 | @"F10", SRInt(109), 51 | @"F11", SRInt(103), 52 | @"F12", SRInt(111), 53 | @"F13", SRInt(105), 54 | @"F14", SRInt(107), 55 | @"F15", SRInt(113), 56 | @"F16", SRInt(106), 57 | @"F17", SRInt(64), 58 | @"F18", SRInt(79), 59 | @"F19", SRInt(80), 60 | SRLoc(@"Space"), SRInt(49), 61 | SRChar(KeyboardDeleteLeftGlyph), SRInt(51), 62 | SRChar(KeyboardDeleteRightGlyph), SRInt(117), 63 | SRChar(KeyboardPadClearGlyph), SRInt(71), 64 | SRChar(KeyboardLeftArrowGlyph), SRInt(123), 65 | SRChar(KeyboardRightArrowGlyph), SRInt(124), 66 | SRChar(KeyboardUpArrowGlyph), SRInt(126), 67 | SRChar(KeyboardDownArrowGlyph), SRInt(125), 68 | SRChar(KeyboardSoutheastArrowGlyph), SRInt(119), 69 | SRChar(KeyboardNorthwestArrowGlyph), SRInt(115), 70 | SRChar(KeyboardEscapeGlyph), SRInt(53), 71 | SRChar(KeyboardPageDownGlyph), SRInt(121), 72 | SRChar(KeyboardPageUpGlyph), SRInt(116), 73 | SRChar(KeyboardReturnR2LGlyph), SRInt(36), 74 | SRChar(KeyboardReturnGlyph), SRInt(76), 75 | SRChar(KeyboardTabRightGlyph), SRInt(48), 76 | SRChar(KeyboardHelpGlyph), SRInt(114), 77 | nil]; 78 | 79 | // We want to identify if the key was pressed on the numpad 80 | padKeysArray = [[NSArray alloc] initWithObjects: 81 | SRInt(65), // , 82 | SRInt(67), // * 83 | SRInt(69), // + 84 | SRInt(75), // / 85 | SRInt(78), // - 86 | SRInt(81), // = 87 | SRInt(82), // 0 88 | SRInt(83), // 1 89 | SRInt(84), // 2 90 | SRInt(85), // 3 91 | SRInt(86), // 4 92 | SRInt(87), // 5 93 | SRInt(88), // 6 94 | SRInt(89), // 7 95 | SRInt(91), // 8 96 | SRInt(92), // 9 97 | nil]; 98 | 99 | // generate the string to keycode mapping dict... 100 | stringToKeyCodeDict = [[NSMutableDictionary alloc] init]; 101 | [self regenerateStringToKeyCodeMapping]; 102 | 103 | [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(regenerateStringToKeyCodeMapping) name:(NSString*)kTISNotifySelectedKeyboardInputSourceChanged object:nil]; 104 | } 105 | 106 | //---------------------------------------------------------- 107 | // allowsReverseTransformation 108 | //---------------------------------------------------------- 109 | + (BOOL) allowsReverseTransformation 110 | { 111 | return YES; 112 | } 113 | 114 | //---------------------------------------------------------- 115 | // transformedValueClass 116 | //---------------------------------------------------------- 117 | + (Class) transformedValueClass; 118 | { 119 | return [NSString class]; 120 | } 121 | 122 | 123 | //---------------------------------------------------------- 124 | // init 125 | //---------------------------------------------------------- 126 | - (id)init 127 | { 128 | if((self = [super init])) 129 | { 130 | } 131 | return self; 132 | } 133 | 134 | //---------------------------------------------------------- 135 | // dealloc 136 | //---------------------------------------------------------- 137 | - (void)dealloc 138 | { 139 | [super dealloc]; 140 | } 141 | 142 | //---------------------------------------------------------- 143 | // transformedValue: 144 | //---------------------------------------------------------- 145 | - (id) transformedValue:(id)value 146 | { 147 | if ( ![value isKindOfClass:[NSNumber class]] ) 148 | return nil; 149 | 150 | // Can be -1 when empty 151 | NSInteger keyCode = [value shortValue]; 152 | if ( keyCode < 0 ) return nil; 153 | 154 | // We have some special gylphs for some special keys... 155 | NSString *unmappedString = [keyCodeToStringDict objectForKey: SRInt( keyCode )]; 156 | if ( unmappedString != nil ) return unmappedString; 157 | 158 | BOOL isPadKey = [padKeysArray containsObject: SRInt( keyCode )]; 159 | 160 | OSStatus err; 161 | TISInputSourceRef tisSource = TISCopyCurrentKeyboardInputSource(); 162 | if(!tisSource) return nil; 163 | 164 | CFDataRef layoutData; 165 | UInt32 keysDown = 0; 166 | layoutData = (CFDataRef)TISGetInputSourceProperty(tisSource, kTISPropertyUnicodeKeyLayoutData); 167 | 168 | CFRelease(tisSource); 169 | 170 | // For non-unicode layouts such as Chinese, Japanese, and Korean, get the ASCII capable layout 171 | if(!layoutData) { 172 | tisSource = TISCopyCurrentASCIICapableKeyboardLayoutInputSource(); 173 | layoutData = (CFDataRef)TISGetInputSourceProperty(tisSource, kTISPropertyUnicodeKeyLayoutData); 174 | CFRelease(tisSource); 175 | } 176 | 177 | if (!layoutData) return nil; 178 | 179 | const UCKeyboardLayout *keyLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData); 180 | 181 | UniCharCount length = 4, realLength; 182 | UniChar chars[4]; 183 | 184 | err = UCKeyTranslate( keyLayout, 185 | keyCode, 186 | kUCKeyActionDisplay, 187 | 0, 188 | LMGetKbdType(), 189 | kUCKeyTranslateNoDeadKeysBit, 190 | &keysDown, 191 | length, 192 | &realLength, 193 | chars); 194 | 195 | if ( err != noErr ) return nil; 196 | 197 | NSString *keyString = [[NSString stringWithCharacters:chars length:1] uppercaseString]; 198 | 199 | return ( isPadKey ? [NSString stringWithFormat: SRLoc(@"Pad %@"), keyString] : keyString ); 200 | } 201 | 202 | //---------------------------------------------------------- 203 | // reverseTransformedValue: 204 | //---------------------------------------------------------- 205 | - (id) reverseTransformedValue:(id)value 206 | { 207 | if ( ![value isKindOfClass:[NSString class]] ) 208 | return nil; 209 | 210 | // try and retrieve a mapped keycode from the reverse mapping dict... 211 | return [stringToKeyCodeDict objectForKey:value]; 212 | } 213 | 214 | @end 215 | 216 | #pragma mark - 217 | 218 | @implementation SRKeyCodeTransformer( Private ) 219 | 220 | //---------------------------------------------------------- 221 | // regenerateStringToKeyCodeMapping: 222 | //---------------------------------------------------------- 223 | + (void) regenerateStringToKeyCodeMapping; 224 | { 225 | SRKeyCodeTransformer *transformer = [[[self alloc] init] autorelease]; 226 | [stringToKeyCodeDict removeAllObjects]; 227 | 228 | // loop over every keycode (0 - 127) finding its current string mapping... 229 | NSUInteger i; 230 | for ( i = 0U; i < 128U; i++ ) 231 | { 232 | NSNumber *keyCode = [NSNumber numberWithUnsignedInteger:i]; 233 | NSString *string = [transformer transformedValue:keyCode]; 234 | if ( ( string ) && ( [string length] ) ) 235 | { 236 | [stringToKeyCodeDict setObject:keyCode forKey:string]; 237 | } 238 | } 239 | } 240 | 241 | @end 242 | -------------------------------------------------------------------------------- /NAKL/ShortcutRecorder/SRValidator.m: -------------------------------------------------------------------------------- 1 | // 2 | // SRValidator.h 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2011 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | // Andy Kim 14 | 15 | #import "SRValidator.h" 16 | #import "SRCommon.h" 17 | 18 | @implementation SRValidator 19 | 20 | //---------------------------------------------------------- 21 | // iinitWithDelegate: 22 | //---------------------------------------------------------- 23 | - (id) initWithDelegate:(id)theDelegate; 24 | { 25 | self = [super init]; 26 | if ( !self ) 27 | return nil; 28 | 29 | [self setDelegate:theDelegate]; 30 | 31 | return self; 32 | } 33 | 34 | //---------------------------------------------------------- 35 | // isKeyCode:andFlagsTaken:error: 36 | //---------------------------------------------------------- 37 | - (BOOL) isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags error:(NSError **)error; 38 | { 39 | // if we have a delegate, it goes first... 40 | if ( delegate ) 41 | { 42 | NSString *delegateReason = nil; 43 | if ( [delegate shortcutValidator:self 44 | isKeyCode:keyCode 45 | andFlagsTaken:SRCarbonToCocoaFlags( flags ) 46 | reason:&delegateReason]) 47 | { 48 | if ( error ) 49 | { 50 | NSString *description = [NSString stringWithFormat: 51 | SRLoc(@"The key combination %@ can't be used!"), 52 | SRStringForCarbonModifierFlagsAndKeyCode( flags, keyCode )]; 53 | NSString *recoverySuggestion = [NSString stringWithFormat: 54 | SRLoc(@"The key combination \"%@\" can't be used because %@."), 55 | SRReadableStringForCarbonModifierFlagsAndKeyCode( flags, keyCode ), 56 | ( delegateReason && [delegateReason length] ) ? delegateReason : @"it's already used"]; 57 | NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: 58 | description, NSLocalizedDescriptionKey, 59 | recoverySuggestion, NSLocalizedRecoverySuggestionErrorKey, 60 | [NSArray arrayWithObject:@"OK"], NSLocalizedRecoveryOptionsErrorKey, // Is this needed? Shouldn't it show 'OK' by default? -AK 61 | nil]; 62 | *error = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:userInfo]; 63 | } 64 | return YES; 65 | } 66 | } 67 | 68 | // then our implementation... 69 | CFArrayRef tempArray = NULL; 70 | OSStatus err = noErr; 71 | 72 | // get global hot keys... 73 | err = CopySymbolicHotKeys( &tempArray ); 74 | 75 | if ( err != noErr ) return YES; 76 | 77 | // Not copying the array like this results in a leak on according to the Leaks Instrument 78 | NSArray *globalHotKeys = [NSArray arrayWithArray:(NSArray *)tempArray]; 79 | 80 | if ( tempArray ) CFRelease(tempArray); 81 | 82 | NSEnumerator *globalHotKeysEnumerator = [globalHotKeys objectEnumerator]; 83 | NSDictionary *globalHotKeyInfoDictionary; 84 | int32_t globalHotKeyFlags; 85 | NSInteger globalHotKeyCharCode; 86 | BOOL globalCommandMod = NO, globalOptionMod = NO, globalShiftMod = NO, globalCtrlMod = NO; 87 | BOOL localCommandMod = NO, localOptionMod = NO, localShiftMod = NO, localCtrlMod = NO; 88 | 89 | // Prepare local carbon comparison flags 90 | if ( flags & cmdKey ) localCommandMod = YES; 91 | if ( flags & optionKey ) localOptionMod = YES; 92 | if ( flags & shiftKey ) localShiftMod = YES; 93 | if ( flags & controlKey ) localCtrlMod = YES; 94 | 95 | while (( globalHotKeyInfoDictionary = [globalHotKeysEnumerator nextObject] )) 96 | { 97 | // Only check if global hotkey is enabled 98 | if ( (CFBooleanRef)[globalHotKeyInfoDictionary objectForKey:(NSString *)kHISymbolicHotKeyEnabled] != kCFBooleanTrue ) 99 | continue; 100 | 101 | globalCommandMod = NO; 102 | globalOptionMod = NO; 103 | globalShiftMod = NO; 104 | globalCtrlMod = NO; 105 | 106 | globalHotKeyCharCode = [(NSNumber *)[globalHotKeyInfoDictionary objectForKey:(NSString *)kHISymbolicHotKeyCode] shortValue]; 107 | 108 | CFNumberGetValue((CFNumberRef)[globalHotKeyInfoDictionary objectForKey: (NSString *)kHISymbolicHotKeyModifiers],kCFNumberSInt32Type,&globalHotKeyFlags); 109 | 110 | if ( globalHotKeyFlags & cmdKey ) globalCommandMod = YES; 111 | if ( globalHotKeyFlags & optionKey ) globalOptionMod = YES; 112 | if ( globalHotKeyFlags & shiftKey) globalShiftMod = YES; 113 | if ( globalHotKeyFlags & controlKey ) globalCtrlMod = YES; 114 | 115 | NSString *localKeyString = SRStringForKeyCode( keyCode ); 116 | if (![localKeyString length]) return YES; 117 | 118 | 119 | // compare unichar value and modifier flags 120 | if ( ( globalHotKeyCharCode == keyCode ) 121 | && ( globalCommandMod == localCommandMod ) 122 | && ( globalOptionMod == localOptionMod ) 123 | && ( globalShiftMod == localShiftMod ) 124 | && ( globalCtrlMod == localCtrlMod ) ) 125 | { 126 | if ( error ) 127 | { 128 | NSString *description = [NSString stringWithFormat: 129 | SRLoc(@"The key combination %@ can't be used!"), 130 | SRStringForCarbonModifierFlagsAndKeyCode( flags, keyCode )]; 131 | NSString *recoverySuggestion = [NSString stringWithFormat: 132 | SRLoc(@"The key combination \"%@\" can't be used because it's already used by a system-wide keyboard shortcut. (If you really want to use this key combination, most shortcuts can be changed in the Keyboard & Mouse panel in System Preferences.)"), 133 | SRReadableStringForCarbonModifierFlagsAndKeyCode( flags, keyCode )]; 134 | NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: 135 | description, NSLocalizedDescriptionKey, 136 | recoverySuggestion, NSLocalizedRecoverySuggestionErrorKey, 137 | [NSArray arrayWithObject:@"OK"], NSLocalizedRecoveryOptionsErrorKey, 138 | nil]; 139 | *error = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:userInfo]; 140 | } 141 | return YES; 142 | } 143 | } 144 | 145 | // Check menus too 146 | return [self isKeyCode:keyCode andFlags:flags takenInMenu:[NSApp mainMenu] error:error]; 147 | } 148 | 149 | //---------------------------------------------------------- 150 | // isKeyCode:andFlags:takenInMenu:error: 151 | //---------------------------------------------------------- 152 | - (BOOL) isKeyCode:(NSInteger)keyCode andFlags:(NSUInteger)flags takenInMenu:(NSMenu *)menu error:(NSError **)error; 153 | { 154 | NSArray *menuItemsArray = [menu itemArray]; 155 | NSEnumerator *menuItemsEnumerator = [menuItemsArray objectEnumerator]; 156 | NSMenuItem *menuItem; 157 | NSUInteger menuItemModifierFlags; 158 | NSString *menuItemKeyEquivalent; 159 | 160 | BOOL menuItemCommandMod = NO, menuItemOptionMod = NO, menuItemShiftMod = NO, menuItemCtrlMod = NO; 161 | BOOL localCommandMod = NO, localOptionMod = NO, localShiftMod = NO, localCtrlMod = NO; 162 | 163 | // Prepare local carbon comparison flags 164 | if ( flags & cmdKey ) localCommandMod = YES; 165 | if ( flags & optionKey ) localOptionMod = YES; 166 | if ( flags & shiftKey ) localShiftMod = YES; 167 | if ( flags & controlKey ) localCtrlMod = YES; 168 | 169 | while (( menuItem = [menuItemsEnumerator nextObject] )) 170 | { 171 | // rescurse into all submenus... 172 | if ( [menuItem hasSubmenu] ) 173 | { 174 | if ( [self isKeyCode:keyCode andFlags:flags takenInMenu:[menuItem submenu] error:error] ) 175 | { 176 | return YES; 177 | } 178 | } 179 | 180 | if ( ( menuItemKeyEquivalent = [menuItem keyEquivalent] ) 181 | && ( ![menuItemKeyEquivalent isEqualToString: @""] ) ) 182 | { 183 | menuItemCommandMod = NO; 184 | menuItemOptionMod = NO; 185 | menuItemShiftMod = NO; 186 | menuItemCtrlMod = NO; 187 | 188 | menuItemModifierFlags = [menuItem keyEquivalentModifierMask]; 189 | 190 | if ( menuItemModifierFlags & NSCommandKeyMask ) menuItemCommandMod = YES; 191 | if ( menuItemModifierFlags & NSAlternateKeyMask ) menuItemOptionMod = YES; 192 | if ( menuItemModifierFlags & NSShiftKeyMask ) menuItemShiftMod = YES; 193 | if ( menuItemModifierFlags & NSControlKeyMask ) menuItemCtrlMod = YES; 194 | 195 | NSString *localKeyString = SRStringForKeyCode( keyCode ); 196 | 197 | // Compare translated keyCode and modifier flags 198 | if ( ( [[menuItemKeyEquivalent uppercaseString] isEqualToString: localKeyString] ) 199 | && ( menuItemCommandMod == localCommandMod ) 200 | && ( menuItemOptionMod == localOptionMod ) 201 | && ( menuItemShiftMod == localShiftMod ) 202 | && ( menuItemCtrlMod == localCtrlMod ) ) 203 | { 204 | if ( error ) 205 | { 206 | NSString *description = [NSString stringWithFormat: 207 | SRLoc(@"The key combination %@ can't be used!"), 208 | SRStringForCarbonModifierFlagsAndKeyCode( flags, keyCode )]; 209 | NSString *recoverySuggestion = [NSString stringWithFormat: 210 | SRLoc(@"The key combination \"%@\" can't be used because it's already used by the menu item \"%@\"."), 211 | SRReadableStringForCocoaModifierFlagsAndKeyCode( menuItemModifierFlags, keyCode ), 212 | [menuItem title]]; 213 | NSDictionary *userInfo = [NSDictionary dictionaryWithObjectsAndKeys: 214 | description, NSLocalizedDescriptionKey, 215 | recoverySuggestion, NSLocalizedRecoverySuggestionErrorKey, 216 | [NSArray arrayWithObject:@"OK"], NSLocalizedRecoveryOptionsErrorKey, 217 | nil]; 218 | *error = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:userInfo]; 219 | } 220 | return YES; 221 | } 222 | } 223 | } 224 | return NO; 225 | } 226 | 227 | #pragma mark - 228 | #pragma mark accessors 229 | 230 | //---------------------------------------------------------- 231 | // delegate 232 | //---------------------------------------------------------- 233 | - (id) delegate 234 | { 235 | return delegate; 236 | } 237 | 238 | - (void) setDelegate: (id) theDelegate 239 | { 240 | delegate = theDelegate; // Standard delegate pattern does not retain the delegate 241 | } 242 | 243 | @end 244 | 245 | #pragma mark - 246 | #pragma mark default delegate implementation 247 | 248 | @implementation NSObject( SRValidation ) 249 | 250 | //---------------------------------------------------------- 251 | // shortcutValidator:isKeyCode:andFlagsTaken:reason: 252 | //---------------------------------------------------------- 253 | - (BOOL) shortcutValidator:(SRValidator *)validator isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags reason:(NSString **)aReason; 254 | { 255 | return NO; 256 | } 257 | 258 | @end 259 | -------------------------------------------------------------------------------- /NAKL/ShortcutRecorder/SRRecorderControl.m: -------------------------------------------------------------------------------- 1 | // 2 | // SRRecorderControl.m 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2007 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | 14 | #import "SRRecorderControl.h" 15 | #import "SRCommon.h" 16 | 17 | #define SRCell (SRRecorderCell *)[self cell] 18 | 19 | @interface SRRecorderControl (Private) 20 | - (void)resetTrackingRects; 21 | @end 22 | 23 | @implementation SRRecorderControl 24 | 25 | + (void)initialize 26 | { 27 | if (self == [SRRecorderControl class]) 28 | { 29 | [self setCellClass: [SRRecorderCell class]]; 30 | } 31 | } 32 | 33 | + (Class)cellClass 34 | { 35 | return [SRRecorderCell class]; 36 | } 37 | 38 | - (id)initWithFrame:(NSRect)frameRect 39 | { 40 | self = [super initWithFrame: frameRect]; 41 | 42 | [SRCell setDelegate: self]; 43 | 44 | return self; 45 | } 46 | 47 | - (id)initWithCoder:(NSCoder *)aDecoder 48 | { 49 | self = [super initWithCoder: aDecoder]; 50 | 51 | [SRCell setDelegate: self]; 52 | 53 | return self; 54 | } 55 | 56 | - (void)encodeWithCoder:(NSCoder *)aCoder 57 | { 58 | [super encodeWithCoder: aCoder]; 59 | } 60 | 61 | - (void)dealloc 62 | { 63 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 64 | [super dealloc]; 65 | } 66 | 67 | #pragma mark *** Cell Behavior *** 68 | 69 | // We need keyboard access 70 | - (BOOL)acceptsFirstResponder 71 | { 72 | return YES; 73 | } 74 | 75 | // Allow the control to be activated with the first click on it even if it's window isn't the key window 76 | - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent 77 | { 78 | return YES; 79 | } 80 | 81 | - (BOOL) becomeFirstResponder 82 | { 83 | BOOL okToChange = [SRCell becomeFirstResponder]; 84 | if (okToChange) [super setKeyboardFocusRingNeedsDisplayInRect:[self bounds]]; 85 | return okToChange; 86 | } 87 | 88 | - (BOOL) resignFirstResponder 89 | { 90 | BOOL okToChange = [SRCell resignFirstResponder]; 91 | if (okToChange) [super setKeyboardFocusRingNeedsDisplayInRect:[self bounds]]; 92 | return okToChange; 93 | } 94 | 95 | #pragma mark *** Aesthetics *** 96 | - (BOOL)animates { 97 | return [SRCell animates]; 98 | } 99 | 100 | - (void)setAnimates:(BOOL)an { 101 | [SRCell setAnimates:an]; 102 | } 103 | 104 | - (SRRecorderStyle)style { 105 | return [SRCell style]; 106 | } 107 | 108 | - (void)setStyle:(SRRecorderStyle)nStyle { 109 | [SRCell setStyle:nStyle]; 110 | } 111 | 112 | #pragma mark *** Interface Stuff *** 113 | 114 | 115 | // If the control is set to be resizeable in width, this will make sure that the tracking rects are always updated 116 | - (void)viewDidMoveToWindow 117 | { 118 | NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 119 | 120 | if ([self window]) 121 | { 122 | [center removeObserver: self]; 123 | [center addObserver:self selector:@selector(viewFrameDidChange:) name:NSViewFrameDidChangeNotification object:self]; 124 | [self resetTrackingRects]; 125 | } 126 | } 127 | 128 | - (void)viewFrameDidChange:(NSNotification *)aNotification 129 | { 130 | [self resetTrackingRects]; 131 | } 132 | 133 | // Prevent from being too small 134 | - (void)setFrameSize:(NSSize)newSize 135 | { 136 | NSSize correctedSize = newSize; 137 | correctedSize.height = SRMaxHeight; 138 | if (correctedSize.width < SRMinWidth) correctedSize.width = SRMinWidth; 139 | 140 | [super setFrameSize: correctedSize]; 141 | } 142 | 143 | - (void)setFrame:(NSRect)frameRect 144 | { 145 | NSRect correctedFrarme = frameRect; 146 | correctedFrarme.size.height = SRMaxHeight; 147 | if (correctedFrarme.size.width < SRMinWidth) correctedFrarme.size.width = SRMinWidth; 148 | 149 | [super setFrame: correctedFrarme]; 150 | } 151 | 152 | - (NSString *)keyChars { 153 | return [SRCell keyChars]; 154 | } 155 | 156 | - (NSString *)keyCharsIgnoringModifiers { 157 | return [SRCell keyCharsIgnoringModifiers]; 158 | } 159 | 160 | #pragma mark *** Key Interception *** 161 | 162 | // Like most NSControls, pass things on to the cell 163 | - (BOOL)performKeyEquivalent:(NSEvent *)theEvent 164 | { 165 | // Only if we're key, please. Otherwise hitting Space after having 166 | // tabbed past SRRecorderControl will put you into recording mode. 167 | if (([[[self window] firstResponder] isEqualTo:self])) { 168 | if ([SRCell performKeyEquivalent:theEvent]) return YES; 169 | } 170 | 171 | return [super performKeyEquivalent: theEvent]; 172 | } 173 | 174 | - (void)flagsChanged:(NSEvent *)theEvent 175 | { 176 | [SRCell flagsChanged:theEvent]; 177 | } 178 | 179 | - (void)keyDown:(NSEvent *)theEvent 180 | { 181 | if ( [SRCell performKeyEquivalent: theEvent] ) 182 | return; 183 | 184 | [super keyDown:theEvent]; 185 | } 186 | 187 | #pragma mark *** Key Combination Control *** 188 | 189 | - (NSUInteger)allowedFlags 190 | { 191 | return [SRCell allowedFlags]; 192 | } 193 | 194 | - (void)setAllowedFlags:(NSUInteger)flags 195 | { 196 | [SRCell setAllowedFlags: flags]; 197 | } 198 | 199 | - (BOOL)allowsKeyOnly { 200 | return [SRCell allowsKeyOnly]; 201 | } 202 | 203 | - (void)setAllowsKeyOnly:(BOOL)nAllowsKeyOnly { 204 | [self setAllowsKeyOnly:nAllowsKeyOnly escapeKeysRecord:NO]; 205 | } 206 | 207 | - (void)setAllowsKeyOnly:(BOOL)nAllowsKeyOnly escapeKeysRecord:(BOOL)nEscapeKeysRecord { 208 | [SRCell setAllowsKeyOnly:nAllowsKeyOnly escapeKeysRecord:nEscapeKeysRecord]; 209 | } 210 | 211 | - (BOOL)escapeKeysRecord { 212 | return [SRCell escapeKeysRecord]; 213 | } 214 | 215 | - (void)setEscapeKeysRecord:(BOOL)nEscapeKeysRecord { 216 | [SRCell setEscapeKeysRecord:nEscapeKeysRecord]; 217 | } 218 | 219 | - (BOOL)canCaptureGlobalHotKeys 220 | { 221 | return [[self cell] canCaptureGlobalHotKeys]; 222 | } 223 | 224 | - (void)setCanCaptureGlobalHotKeys:(BOOL)inState 225 | { 226 | [[self cell] setCanCaptureGlobalHotKeys:inState]; 227 | } 228 | 229 | - (NSUInteger)requiredFlags 230 | { 231 | return [SRCell requiredFlags]; 232 | } 233 | 234 | - (void)setRequiredFlags:(NSUInteger)flags 235 | { 236 | [SRCell setRequiredFlags: flags]; 237 | } 238 | 239 | - (KeyCombo)keyCombo 240 | { 241 | return [SRCell keyCombo]; 242 | } 243 | 244 | - (void)setKeyCombo:(KeyCombo)aKeyCombo 245 | { 246 | [SRCell setKeyCombo: aKeyCombo]; 247 | } 248 | 249 | #pragma mark *** Binding Methods *** 250 | 251 | - (NSDictionary *)objectValue 252 | { 253 | KeyCombo keyCombo = [self keyCombo]; 254 | if (keyCombo.code == ShortcutRecorderEmptyCode || keyCombo.flags == ShortcutRecorderEmptyFlags) 255 | return nil; 256 | 257 | return [NSDictionary dictionaryWithObjectsAndKeys: 258 | [self keyCharsIgnoringModifiers], @"characters", 259 | [NSNumber numberWithInteger:keyCombo.code], @"keyCode", 260 | [NSNumber numberWithUnsignedInteger:keyCombo.flags], @"modifierFlags", 261 | nil]; 262 | } 263 | 264 | - (void)setObjectValue:(NSDictionary *)shortcut 265 | { 266 | KeyCombo keyCombo = SRMakeKeyCombo(ShortcutRecorderEmptyCode, ShortcutRecorderEmptyFlags); 267 | if (shortcut != nil && [shortcut isKindOfClass:[NSDictionary class]]) { 268 | NSNumber *keyCode = [shortcut objectForKey:@"keyCode"]; 269 | NSNumber *modifierFlags = [shortcut objectForKey:@"modifierFlags"]; 270 | if ([keyCode isKindOfClass:[NSNumber class]] && [modifierFlags isKindOfClass:[NSNumber class]]) { 271 | keyCombo.code = [keyCode integerValue]; 272 | keyCombo.flags = [modifierFlags unsignedIntegerValue]; 273 | } 274 | } 275 | 276 | [self setKeyCombo: keyCombo]; 277 | } 278 | 279 | - (Class)valueClassForBinding:(NSString *)binding 280 | { 281 | if ([binding isEqualToString:@"value"]) 282 | return [NSDictionary class]; 283 | 284 | return [super valueClassForBinding:binding]; 285 | } 286 | 287 | #pragma mark *** Autosave Control *** 288 | 289 | - (NSString *)autosaveName 290 | { 291 | return [SRCell autosaveName]; 292 | } 293 | 294 | - (void)setAutosaveName:(NSString *)aName 295 | { 296 | [SRCell setAutosaveName: aName]; 297 | } 298 | 299 | #pragma mark - 300 | 301 | - (NSString *)keyComboString 302 | { 303 | return [SRCell keyComboString]; 304 | } 305 | 306 | #pragma mark *** Conversion Methods *** 307 | 308 | - (NSUInteger)cocoaToCarbonFlags:(NSUInteger)cocoaFlags 309 | { 310 | return SRCocoaToCarbonFlags( cocoaFlags ); 311 | } 312 | 313 | - (NSUInteger)carbonToCocoaFlags:(NSUInteger)carbonFlags; 314 | { 315 | return SRCarbonToCocoaFlags( carbonFlags ); 316 | } 317 | 318 | #pragma mark *** Delegate *** 319 | 320 | // Only the delegate will be handled by the control 321 | - (id)delegate 322 | { 323 | return delegate; 324 | } 325 | 326 | - (void)setDelegate:(id)aDelegate 327 | { 328 | delegate = aDelegate; 329 | } 330 | 331 | #pragma mark *** Delegate pass-through *** 332 | 333 | - (BOOL)shortcutRecorderCell:(SRRecorderCell *)aRecorderCell isKeyCode:(NSInteger)keyCode andFlagsTaken:(NSUInteger)flags reason:(NSString **)aReason 334 | { 335 | if (delegate != nil && [delegate respondsToSelector: @selector(shortcutRecorder:isKeyCode:andFlagsTaken:reason:)]) 336 | return [delegate shortcutRecorder:self isKeyCode:keyCode andFlagsTaken:flags reason:aReason]; 337 | else 338 | return NO; 339 | } 340 | 341 | #define NilOrNull(o) ((o) == nil || (id)(o) == [NSNull null]) 342 | 343 | - (void)shortcutRecorderCell:(SRRecorderCell *)aRecorderCell keyComboDidChange:(KeyCombo)newKeyCombo 344 | { 345 | if (delegate != nil && [delegate respondsToSelector: @selector(shortcutRecorder:keyComboDidChange:)]) 346 | [delegate shortcutRecorder:self keyComboDidChange:newKeyCombo]; 347 | 348 | // propagate view changes to binding (see http://www.tomdalling.com/cocoa/implementing-your-own-cocoa-bindings) 349 | NSDictionary *bindingInfo = [self infoForBinding:@"value"]; 350 | if (!bindingInfo) 351 | return; 352 | 353 | // apply the value transformer, if one has been set 354 | NSDictionary *value = [self objectValue]; 355 | NSDictionary *bindingOptions = [bindingInfo objectForKey:NSOptionsKey]; 356 | if (bindingOptions != nil) { 357 | NSValueTransformer *transformer = [bindingOptions valueForKey:NSValueTransformerBindingOption]; 358 | if (NilOrNull(transformer)) { 359 | NSString *transformerName = [bindingOptions valueForKey:NSValueTransformerNameBindingOption]; 360 | if (!NilOrNull(transformerName)) 361 | transformer = [NSValueTransformer valueTransformerForName:transformerName]; 362 | } 363 | 364 | if (!NilOrNull(transformer)) { 365 | if ([[transformer class] allowsReverseTransformation]) 366 | value = [transformer reverseTransformedValue:value]; 367 | else 368 | NSLog(@"WARNING: value has value transformer, but it doesn't allow reverse transformations in %s", __PRETTY_FUNCTION__); 369 | } 370 | } 371 | 372 | id boundObject = [bindingInfo objectForKey:NSObservedObjectKey]; 373 | if (NilOrNull(boundObject)) { 374 | NSLog(@"ERROR: NSObservedObjectKey was nil for value binding in %s", __PRETTY_FUNCTION__); 375 | return; 376 | } 377 | 378 | NSString *boundKeyPath = [bindingInfo objectForKey:NSObservedKeyPathKey]; 379 | if (NilOrNull(boundKeyPath)) { 380 | NSLog(@"ERROR: NSObservedKeyPathKey was nil for value binding in %s", __PRETTY_FUNCTION__); 381 | return; 382 | } 383 | 384 | [boundObject setValue:value forKeyPath:boundKeyPath]; 385 | } 386 | 387 | @end 388 | 389 | @implementation SRRecorderControl (Private) 390 | 391 | - (void)resetTrackingRects 392 | { 393 | [SRCell resetTrackingRects]; 394 | } 395 | 396 | @end 397 | -------------------------------------------------------------------------------- /NAKL/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Copyright (c) 2012 Huy Phan 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | #import 20 | #import "AppDelegate.h" 21 | 22 | @implementation AppDelegate 23 | 24 | @synthesize window = _window; 25 | @synthesize preferencesController; 26 | @synthesize eventTap; 27 | 28 | uint64_t controlKeys = kCGEventFlagMaskCommand | kCGEventFlagMaskAlternate | kCGEventFlagMaskControl | kCGEventFlagMaskSecondaryFn | kCGEventFlagMaskHelp; 29 | 30 | static char *separators[] = { 31 | "", // VKM_OFF 32 | "!@#$%&)|\\-{}[]:\";<>,/'`~?.^*(+=", // VKM_VNI 33 | "!@#$%&)|\\-:\";<>,/'`~?.^*(+=" // VKM_TELEX 34 | }; 35 | 36 | KeyboardHandler *kbHandler; 37 | 38 | static char rk = 0; 39 | bool dirty; 40 | static bool frontmostAppApiCompatible = false; 41 | 42 | #pragma mark Initialization 43 | 44 | + (void)initialize 45 | { 46 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 47 | NSMutableDictionary *appDefs = [NSMutableDictionary dictionary]; 48 | [appDefs setObject:[NSNumber numberWithInt:1] forKey:NAKL_KEYBOARD_METHOD]; 49 | [defaults registerDefaults:appDefs]; 50 | 51 | if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_7) { 52 | frontmostAppApiCompatible = true; 53 | } 54 | 55 | BOOL accessibilityEnabled = YES; 56 | 57 | if (AXIsProcessTrustedWithOptions != NULL) { 58 | NSDictionary *options = @{(id) kAXTrustedCheckOptionPrompt: @NO}; 59 | accessibilityEnabled = AXIsProcessTrustedWithOptions((CFDictionaryRef)options); 60 | } else { 61 | accessibilityEnabled = AXAPIEnabled(); 62 | } 63 | 64 | if (!accessibilityEnabled) { 65 | NSString* path = [[NSBundle mainBundle] pathForResource:@"EnableAssistiveDevices" ofType:@"scpt"]; 66 | if (path != nil) 67 | { 68 | NSURL* url = [NSURL fileURLWithPath:path]; 69 | if (url != nil) 70 | { 71 | NSDictionary* errors = [NSDictionary dictionary]; 72 | NSAppleScript* appleScript = [[NSAppleScript alloc] initWithContentsOfURL:url error:&errors]; 73 | if (appleScript != nil) 74 | { 75 | [appleScript executeAndReturnError:nil]; 76 | [appleScript release]; 77 | } else { 78 | 79 | } 80 | } 81 | } else { 82 | NSLog(@"Can't find EnableAssistiveDevices.scpt script"); 83 | } 84 | } 85 | } 86 | 87 | - (void)applicationWillFinishLaunching:(NSNotification *)aNotification 88 | { 89 | preferencesController = [[PreferencesController alloc] init]; 90 | 91 | [AppData loadUserPrefs]; 92 | [AppData loadHotKeys]; 93 | [AppData loadShortcuts]; 94 | [AppData loadExcludedApps]; 95 | 96 | int method = (int)[[AppData sharedAppData].userPrefs integerForKey:NAKL_KEYBOARD_METHOD]; 97 | for (id object in [statusMenu itemArray]) { 98 | [(NSMenuItem*) object setState:((NSMenuItem*) object).tag == method]; 99 | } 100 | 101 | kbHandler = [[KeyboardHandler alloc] init]; 102 | kbHandler.kbMethod = method; 103 | [self performSelectorInBackground:@selector(eventLoop) withObject:nil]; 104 | 105 | [self updateStatusItem]; 106 | } 107 | 108 | -(void)awakeFromNib { 109 | [super awakeFromNib]; 110 | statusItem = [[[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength] retain]; 111 | [statusItem setMenu:statusMenu]; 112 | [statusItem setAction:@selector(menuItemClicked)]; 113 | [statusItem setHighlightMode: YES]; 114 | 115 | 116 | NSSize imageSize; 117 | imageSize.width = 16; 118 | imageSize.height = 16; 119 | 120 | NSBundle *bundle = [NSBundle mainBundle]; 121 | viStatusImage = [[NSImage alloc] initWithContentsOfFile: [bundle pathForResource: @"icon24" ofType: @"png"]]; 122 | [viStatusImage setSize:imageSize]; 123 | 124 | enStatusImage = [[NSImage alloc] initWithContentsOfFile: [bundle pathForResource: @"icon_blue_24" ofType: @"png"]]; 125 | [enStatusImage setSize:imageSize]; 126 | } 127 | 128 | #pragma mark Keyboard Handler 129 | 130 | CGEventRef KeyHandler(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) 131 | { 132 | UniCharCount actualStringLength; 133 | UniCharCount maxStringLength = 1; 134 | UniChar chars[3]; 135 | UniChar *x; 136 | long i; 137 | NSString *activeAppBundleId; 138 | 139 | if (frontmostAppApiCompatible) { 140 | NSRunningApplication *activeApp = [[NSWorkspace sharedWorkspace] frontmostApplication]; 141 | activeAppBundleId = [activeApp bundleIdentifier]; 142 | } else { 143 | NSDictionary *activeApp = [[NSWorkspace sharedWorkspace] activeApplication]; 144 | activeAppBundleId = [activeApp objectForKey:@"NSApplicationBundleIdentifier"]; 145 | } 146 | 147 | uint64_t flag = CGEventGetFlags(event); 148 | 149 | if (flag & NAKL_MAGIC_NUMBER) { 150 | return event; 151 | } 152 | 153 | if ([[AppData sharedAppData].excludedApps objectForKey:activeAppBundleId]) { 154 | return event; 155 | } 156 | 157 | CGEventKeyboardGetUnicodeString(event, maxStringLength, &actualStringLength, chars); 158 | UniChar key = chars[0]; 159 | 160 | switch (type) { 161 | case kCGEventKeyUp: 162 | if (rk == key) { 163 | chars[0] = XK_BackSpace; 164 | CGEventKeyboardSetUnicodeString(event, actualStringLength, chars); 165 | rk = 0; 166 | } 167 | break; 168 | 169 | case kCGEventTapDisabledByTimeout: 170 | CGEventTapEnable(((AppDelegate*) refcon).eventTap , TRUE); 171 | break; 172 | 173 | case kCGEventKeyDown: 174 | { 175 | ushort keycode = CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode); 176 | 177 | if (flag & (controlKeys)) { 178 | bool validShortcut = false; 179 | if (((flag & controlKeys) == [AppData sharedAppData].toggleCombo.flags) && (keycode == [AppData sharedAppData].toggleCombo.code) ) 180 | { 181 | if (kbHandler.kbMethod == VKM_OFF) { 182 | kbHandler.kbMethod = (int)[[AppData sharedAppData].userPrefs integerForKey:NAKL_KEYBOARD_METHOD]; 183 | } else { 184 | kbHandler.kbMethod = VKM_OFF; 185 | } 186 | 187 | [((AppDelegate*) refcon) updateCheckedItem]; 188 | [((AppDelegate*) refcon) updateStatusItem]; 189 | validShortcut = true; 190 | } 191 | 192 | if (((flag & controlKeys) == [AppData sharedAppData].switchMethodCombo.flags) && (keycode == [AppData sharedAppData].switchMethodCombo.code) ){ 193 | if (kbHandler.kbMethod == VKM_VNI) { 194 | kbHandler.kbMethod = VKM_TELEX; 195 | } else if (kbHandler.kbMethod == VKM_TELEX) { 196 | kbHandler.kbMethod = VKM_VNI; 197 | } 198 | 199 | if (kbHandler.kbMethod != VKM_OFF) { 200 | [[AppData sharedAppData].userPrefs setValue:[NSNumber numberWithInt:kbHandler.kbMethod] forKey:NAKL_KEYBOARD_METHOD]; 201 | [((AppDelegate*) refcon) updateCheckedItem]; 202 | [((AppDelegate*) refcon) updateStatusItem]; 203 | } 204 | validShortcut = true; 205 | } 206 | 207 | [kbHandler clearBuffer]; 208 | 209 | if (validShortcut) return NULL; 210 | 211 | break; 212 | } 213 | 214 | /* TODO: Use keycode instead of value of character */ 215 | switch (keycode) { 216 | case KC_Return: 217 | case KC_Return_Num: 218 | case KC_Home: 219 | case KC_Left: 220 | case KC_Up: 221 | case KC_Right: 222 | case KC_Down: 223 | case KC_End: 224 | case KC_Tab: 225 | case KC_BackSpace: 226 | case KC_Delete: 227 | case KC_Page_Up: 228 | case KC_Page_Down: 229 | [kbHandler clearBuffer]; 230 | break; 231 | 232 | default: 233 | 234 | if (kbHandler.kbMethod == VKM_OFF) { 235 | break; 236 | } 237 | 238 | char *sp = strchr(separators[kbHandler.kbMethod], key); 239 | if (sp) { 240 | [kbHandler clearBuffer]; 241 | break; 242 | } 243 | 244 | switch([kbHandler addKey:key]) { 245 | case -1: 246 | 247 | break; 248 | 249 | default: 250 | { 251 | x = kbHandler.kbBuffer+BACKSPACE_BUFFER-kbHandler.kbPLength; 252 | for (i = 0;i 3 | * This file is part of NAKL project. 4 | * 5 | * NAKL is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * NAKL is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with NAKL. If not, see . 17 | ******************************************************************************/ 18 | 19 | 20 | #import "KeyboardHandler.h" 21 | #import "utf.h" 22 | #import "AppData.h" 23 | #import "keymap.h" 24 | 25 | @implementation KeyboardHandler 26 | 27 | #define chr_A 'A' 28 | #define chr_a 'a' 29 | #define chr_D 'D' 30 | #define chr_d 'd' 31 | #define chr_U 'U' 32 | #define chr_u 'u' 33 | #define chr_G 'G' 34 | #define chr_g 'g' 35 | #define chr_Q 'Q' 36 | #define chr_q 'q' 37 | 38 | #define LookupChar(t, c) for( ; *t && *t!=c; t++ ) 39 | 40 | const char *vowels = "AIUEOYaiueoy"; 41 | const char *consonants = "BCDFGHJKLMNPQRSTVWXZbcdfghjklmnpqrstvwxz"; 42 | 43 | @synthesize kbBuffer; 44 | @synthesize kbBLength; 45 | @synthesize kbPLength; 46 | @synthesize kbMethod; 47 | @synthesize vowelsMap; 48 | 49 | //UniChar kbBuffer[256]; 50 | UniChar backup[WORDSIZE]; 51 | UniChar word[WORDSIZE], *pw; 52 | 53 | int kbOff; 54 | int count; 55 | 56 | int vp = -1; 57 | int vpc = 0; 58 | int vps[WORDSIZE]; 59 | char lvs[WORDSIZE]; 60 | int tempoff = 0; 61 | bool hasVowel = false; 62 | bool hasSpaceBar = false; 63 | 64 | -(id)init 65 | { 66 | if (self = [super init]) { 67 | for (int i=0;i0; count--, w++ ) { 155 | *s++ = *w; 156 | } 157 | *s = 0; 158 | 159 | self.kbBLength = s - _kbBuffer - BACKSPACE_BUFFER; 160 | } 161 | 162 | - (int) uiGroup: (ushort) u 163 | { 164 | static ushort UI[] = { 165 | utf_U, utf_U1, utf_U2, utf_U3, utf_U4, utf_U5, 166 | utf_u, utf_u1, utf_u2, utf_u3, utf_u4, utf_u5, 167 | utf_U7, utf_U71, utf_U72, utf_U73, utf_U74, utf_U75, 168 | utf_u7, utf_u71, utf_u72, utf_u73, utf_u74, utf_u75, 169 | utf_I, utf_I1, utf_I2, utf_I3, utf_I4, utf_I5, 170 | utf_i, utf_i1, utf_i2, utf_i3, utf_i4, utf_i5, 0 171 | }; 172 | register ushort *ui = UI; 173 | while( *ui ) { 174 | if( u==*ui++ ) { 175 | return ui - UI; 176 | } 177 | } 178 | return 0; 179 | } 180 | 181 | - (int) utfVnCmp :(ushort)u1 :(ushort) u2 182 | { 183 | static ushort V[] = { 184 | utf_a, utf_A, utf_a1, utf_A1, utf_a2, utf_A2, 185 | utf_a3, utf_A3, utf_a4, utf_A4, utf_a5, utf_A5, 186 | utf_a6, utf_A6, utf_a61, utf_A61, utf_a62, utf_A62, 187 | utf_a63, utf_A63, utf_a64, utf_A64, utf_a65, utf_A65, 188 | utf_a8, utf_A8, utf_a81, utf_A81, utf_a82, utf_A82, 189 | utf_a83, utf_A83, utf_a84, utf_A84, utf_a85, utf_A85, 190 | utf_e, utf_E, utf_e1, utf_E1, utf_e2, utf_E2, 191 | utf_e3, utf_E3, utf_e4, utf_E4, utf_e5, utf_E5, 192 | utf_e6, utf_E6, utf_e61, utf_E61, utf_e62, utf_E62, 193 | utf_e63, utf_E63, utf_e64, utf_E64, utf_e65, utf_E65, 194 | utf_o, utf_O, utf_o1, utf_O1, utf_o2, utf_O2, 195 | utf_o3, utf_O3, utf_o4, utf_O4, utf_o5, utf_O5, 196 | utf_o6, utf_O6, utf_o61, utf_O61, utf_o62, utf_O62, 197 | utf_o63, utf_O63, utf_o64, utf_O64, utf_o65, utf_O65, 198 | utf_o7, utf_O7, utf_o71, utf_O71, utf_o72, utf_O72, 199 | utf_o73, utf_O73, utf_o74, utf_O74, utf_o75, utf_O75, 200 | utf_y, utf_Y, utf_y1, utf_Y1, utf_y2, utf_Y2, 201 | utf_y3, utf_Y3, utf_y4, utf_Y4, utf_y5, utf_Y5, 202 | utf_u, utf_U, utf_u1, utf_U1, utf_u2, utf_U2, 203 | utf_u3, utf_U3, utf_u4, utf_U4, utf_u5, utf_U5, 204 | utf_u7, utf_U7, utf_u71, utf_U71, utf_u72, utf_U72, 205 | utf_u73, utf_U73, utf_u74, utf_U74, utf_u75, utf_U75, 206 | utf_i, utf_I, utf_i1, utf_I1, utf_i2, utf_I2, 207 | utf_i3, utf_I3, utf_i4, utf_I4, utf_i5, utf_I5, 208 | utf_d9, utf_D9, 0 209 | }; 210 | register int i = -1, j = -1; 211 | register ushort *v = V; 212 | 213 | LookupChar(v, u1); 214 | 215 | if( *v ) { 216 | i = v - V; 217 | } 218 | v = V; 219 | LookupChar(v, u2); 220 | 221 | if( *v ) { 222 | j = v - V; 223 | } 224 | 225 | return i-j; 226 | } 227 | 228 | //---------------------------------------------------------------------------- 229 | // Clear internal buffer & Speller status 230 | //---------------------------------------------------------------------------- 231 | - (void) clearBuffer 232 | { 233 | tempoff = 0; 234 | count = 0; 235 | *word = 0; 236 | hasVowel = NO; 237 | hasSpaceBar = NO; 238 | // Speller.Clear(); 239 | } 240 | 241 | - (void) updateBuffer 242 | { 243 | return; 244 | } 245 | 246 | - (void) shiftBuffer 247 | { 248 | kbOff = 0; 249 | word[0] = word[count-1]; 250 | count = 1; 251 | } 252 | 253 | - (void) append :(ushort)lastkey :(UniChar)key 254 | { 255 | static char *spchk = "AIUEOYaiueoy|BDFJKLQSVWXZbdfjklqsvwxz|'`~?.^*+="; 256 | static char *vwchk = "|ia|ua|oa|ai|ui|oi|au|iu|eu|ie|ue|oe|ye|ao|uo|eo|ay|uy|uu|ou|io|"; 257 | char *sp = strchr(spchk, (char) key); 258 | int kp = sp ? (sp - spchk) : -1; 259 | 260 | if( !count ) { 261 | if( kp>=0 && kp<12 ) { 262 | vpc = 1; 263 | vps[vp = 0] = -1; 264 | lvs[0] = key; 265 | } else { 266 | if( kp==12 || kp>37 ) { 267 | return; 268 | } else { 269 | vp = -1; 270 | vpc = 0; 271 | } 272 | } 273 | } 274 | else { 275 | if( kp==12 || kp>37 ) { 276 | [self clearBuffer]; 277 | return; 278 | } 279 | else 280 | if( kp>12 ) // b, d, f,... 281 | tempoff = count; 282 | else 283 | if( kp>=0 ) { // vowels 284 | if (!hasVowel) { 285 | hasVowel = YES; 286 | } else { 287 | char *lsp = strchr(spchk, (char) lastkey); 288 | int lkp = sp ? (lsp - spchk) : -1; 289 | if ( (lastkey < 127) && (lkp > 12) && (lkp < 37) ) { 290 | tempoff = count; 291 | } 292 | } 293 | if( vp<0 ) { 294 | vps[vpc++] = vp; 295 | vp = count; 296 | lvs[0] = key; 297 | } 298 | else 299 | if( count-vp>1 ) 300 | tempoff = count; 301 | else { 302 | #define lower(c) ((c) <= 'Z' ? (c) + 'a' - 'A' : c) 303 | static char w[5] = { '|', 0, 0, '|', 0 }; 304 | w[1] = lower(lvs[vpc-1]); 305 | w[2] = lower(key); 306 | if( !strstr(vwchk, w) ) 307 | tempoff = count; 308 | else { 309 | lvs[vpc] = key; 310 | vps[vpc++] = vp; 311 | vp = count; 312 | } 313 | #undef lower 314 | } 315 | } 316 | else 317 | switch( key ) { 318 | case 'h': 319 | case 'H': // [cgknpt]h 320 | if( lastkey>127 || !strchr("CGKNPTcgknpt", lastkey) ) 321 | tempoff = count; 322 | break; 323 | case 'g': 324 | case 'G': // [n]g 325 | if( lastkey!='n' && lastkey!='N' ) 326 | tempoff = count; 327 | break; 328 | case 'r': 329 | case 'R': // [t]r 330 | if( lastkey!='t' && lastkey!='T' ) 331 | tempoff = count; 332 | break; 333 | default: 334 | if( strchr(consonants, lastkey) ) 335 | tempoff = count; 336 | break; 337 | } 338 | } 339 | word[count++] = (ushort)key; 340 | } 341 | 342 | - (bool) isValidModifier :(UniChar)c :(char)key 343 | { 344 | char *m = modifierKeys[self.kbMethod - 1]; 345 | if ( (65<=key) && (key<=90)) { 346 | key += 32; 347 | } 348 | char* p; 349 | if ( (p = strchr(m, key)) == NULL) { 350 | return NULL; 351 | } 352 | 353 | for (NSString* s in vowelsMap) { 354 | NSString *cString = [NSString stringWithCharacters:&c length:1]; 355 | if ([s rangeOfString:cString].location != NSNotFound) { 356 | ushort v = modifiersMap[self.kbMethod - 1][strchr(modifiedChars,[(NSString*) s characterAtIndex:0]) - modifiedChars]; 357 | return 1L&(v>>(p-m)); 358 | } 359 | } 360 | 361 | return NO; 362 | } 363 | 364 | - (int) checkShortcut 365 | { 366 | NSString *lastWord = [NSString stringWithCharacters:word length:count]; 367 | NSString* text = [[AppData sharedAppData].shortcutDictionary objectForKey:lastWord]; 368 | if (text != nil) { 369 | int i=0; 370 | for (;i= 0) && ![self isValidModifier:word[i]:key] ) { 427 | i--; 428 | } 429 | 430 | if( i < 0 ) { 431 | [self append:c:key]; 432 | return -1; 433 | } 434 | 435 | /* If there's other character that can match with current key, we modify it first */ 436 | while ( (i-1 >= 0) && 437 | (strchr(vowels, word[i-1]) || (word[i-1] > 0x80) ) 438 | && ([self utfVnCmp:word[i-1]:word[i]] < 0) 439 | && [self isValidModifier:word[i-1]:key] 440 | ) { 441 | i--; 442 | } 443 | 444 | if( i == count-1 && i-1 >= 0 && (j = [self uiGroup:word[i-1]]) > 0 ) { 445 | switch( word[i] ) { 446 | case chr_a: 447 | case chr_A: 448 | 449 | if (( i-2 < 0 || ( 450 | ( 451 | (j < 24 && word[i-2] != chr_q && word[i-2] != chr_Q) || 452 | (j > 24 && word[i-2] != chr_g && word[i-2] != chr_G) 453 | ) 454 | ) 455 | ) && [self isValidModifier:word[i-1]:key] ) 456 | i = i - 1; 457 | break; 458 | case chr_u: 459 | case chr_U: 460 | if( i-2 < 0 || (word[i-2] != chr_g && word[i-2] != chr_G) ) 461 | i = i - 1; 462 | break; 463 | } 464 | } 465 | 466 | /* Try to prevent modifying long words (probably when typing foreign language) 467 | TODO: this code is *hacky*, it needs to be replaced by a proper spellcheck. 468 | */ 469 | if (p - i >= BACKSPACE_BUFFER) { 470 | [self append:c:key]; 471 | return -1; 472 | } 473 | 474 | c = word[p = i]; 475 | 476 | for( i = 0; (cc = v[i].c) != 0 && c != cc; i++ ); 477 | 478 | if( !cc ) { 479 | [self append:c:key]; 480 | return -1; 481 | } 482 | 483 | kbPLength = count - p; 484 | if( !v[i].r2 ) { 485 | word[ p ] = v[i].r1; 486 | backup[ p ] = c; 487 | } else { 488 | word[ tempoff = count++ ] = (ushort)key; 489 | word[ p ] = backup[ p ]; 490 | } 491 | 492 | [self mapToCharset:&word[p]:count-p]; 493 | return p; 494 | } 495 | 496 | - (void) dealloc { 497 | [super dealloc]; 498 | } 499 | 500 | @end 501 | -------------------------------------------------------------------------------- /NAKL/ShortcutRecorder/SRCommon.m: -------------------------------------------------------------------------------- 1 | // 2 | // SRCommon.m 3 | // ShortcutRecorder 4 | // 5 | // Copyright 2006-2011 Contributors. All rights reserved. 6 | // 7 | // License: BSD 8 | // 9 | // Contributors: 10 | // David Dauer 11 | // Jesper 12 | // Jamie Kirkpatrick 13 | // Andy Kim 14 | 15 | #import "SRCommon.h" 16 | #import "SRKeyCodeTransformer.h" 17 | 18 | #include 19 | 20 | //#define SRCommon_PotentiallyUsefulDebugInfo 21 | 22 | #ifdef SRCommon_PotentiallyUsefulDebugInfo 23 | #warning 64BIT: Check formatting arguments 24 | #define PUDNSLog(X,...) NSLog(X,##__VA_ARGS__) 25 | #else 26 | #define PUDNSLog(X,...) { ; } 27 | #endif 28 | 29 | #pragma mark - 30 | #pragma mark dummy class 31 | 32 | @implementation SRDummyClass @end 33 | 34 | #pragma mark - 35 | 36 | //---------------------------------------------------------- 37 | // SRStringForKeyCode() 38 | //---------------------------------------------------------- 39 | NSString * SRStringForKeyCode( NSInteger keyCode ) 40 | { 41 | static SRKeyCodeTransformer *keyCodeTransformer = nil; 42 | if ( !keyCodeTransformer ) 43 | keyCodeTransformer = [[SRKeyCodeTransformer alloc] init]; 44 | return [keyCodeTransformer transformedValue:[NSNumber numberWithShort:keyCode]]; 45 | } 46 | 47 | //---------------------------------------------------------- 48 | // SRStringForCarbonModifierFlags() 49 | //---------------------------------------------------------- 50 | NSString * SRStringForCarbonModifierFlags( NSUInteger flags ) 51 | { 52 | NSString *modifierFlagsString = [NSString stringWithFormat:@"%@%@%@%@", 53 | ( flags & controlKey ? [NSString stringWithFormat:@"%C", KeyboardControlGlyph] : @"" ), 54 | ( flags & optionKey ? [NSString stringWithFormat:@"%C", KeyboardOptionGlyph] : @"" ), 55 | ( flags & shiftKey ? [NSString stringWithFormat:@"%C", KeyboardShiftGlyph] : @"" ), 56 | ( flags & cmdKey ? [NSString stringWithFormat:@"%C", KeyboardCommandGlyph] : @"" )]; 57 | return modifierFlagsString; 58 | } 59 | 60 | //---------------------------------------------------------- 61 | // SRStringForCarbonModifierFlagsAndKeyCode() 62 | //---------------------------------------------------------- 63 | NSString * SRStringForCarbonModifierFlagsAndKeyCode( NSUInteger flags, NSInteger keyCode ) 64 | { 65 | return [NSString stringWithFormat: @"%@%@", 66 | SRStringForCarbonModifierFlags( flags ), 67 | SRStringForKeyCode( keyCode )]; 68 | } 69 | 70 | //---------------------------------------------------------- 71 | // SRStringForCocoaModifierFlags() 72 | //---------------------------------------------------------- 73 | NSString * SRStringForCocoaModifierFlags( NSUInteger flags ) 74 | { 75 | NSString *modifierFlagsString = [NSString stringWithFormat:@"%@%@%@%@", 76 | ( flags & NSControlKeyMask ? [NSString stringWithFormat:@"%C", KeyboardControlGlyph] : @"" ), 77 | ( flags & NSAlternateKeyMask ? [NSString stringWithFormat:@"%C", KeyboardOptionGlyph] : @"" ), 78 | ( flags & NSShiftKeyMask ? [NSString stringWithFormat:@"%C", KeyboardShiftGlyph] : @"" ), 79 | ( flags & NSCommandKeyMask ? [NSString stringWithFormat:@"%C", KeyboardCommandGlyph] : @"" )]; 80 | 81 | return modifierFlagsString; 82 | } 83 | 84 | //---------------------------------------------------------- 85 | // SRStringForCocoaModifierFlagsAndKeyCode() 86 | //---------------------------------------------------------- 87 | NSString * SRStringForCocoaModifierFlagsAndKeyCode( NSUInteger flags, NSInteger keyCode ) 88 | { 89 | return [NSString stringWithFormat: @"%@%@", 90 | SRStringForCocoaModifierFlags( flags ), 91 | SRStringForKeyCode( keyCode )]; 92 | } 93 | 94 | //---------------------------------------------------------- 95 | // SRReadableStringForCarbonModifierFlagsAndKeyCode() 96 | //---------------------------------------------------------- 97 | NSString * SRReadableStringForCarbonModifierFlagsAndKeyCode( NSUInteger flags, NSInteger keyCode ) 98 | { 99 | NSString *readableString = [NSString stringWithFormat:@"%@%@%@%@%@", 100 | ( flags & cmdKey ? SRLoc(@"Command + ") : @""), 101 | ( flags & optionKey ? SRLoc(@"Option + ") : @""), 102 | ( flags & controlKey ? SRLoc(@"Control + ") : @""), 103 | ( flags & shiftKey ? SRLoc(@"Shift + ") : @""), 104 | SRStringForKeyCode( keyCode )]; 105 | return readableString; 106 | } 107 | 108 | //---------------------------------------------------------- 109 | // SRReadableStringForCocoaModifierFlagsAndKeyCode() 110 | //---------------------------------------------------------- 111 | NSString * SRReadableStringForCocoaModifierFlagsAndKeyCode( NSUInteger flags, NSInteger keyCode ) 112 | { 113 | NSString *readableString = [NSString stringWithFormat:@"%@%@%@%@%@", 114 | (flags & NSCommandKeyMask ? SRLoc(@"Command + ") : @""), 115 | (flags & NSAlternateKeyMask ? SRLoc(@"Option + ") : @""), 116 | (flags & NSControlKeyMask ? SRLoc(@"Control + ") : @""), 117 | (flags & NSShiftKeyMask ? SRLoc(@"Shift + ") : @""), 118 | SRStringForKeyCode( keyCode )]; 119 | return readableString; 120 | } 121 | 122 | //---------------------------------------------------------- 123 | // SRCarbonToCocoaFlags() 124 | //---------------------------------------------------------- 125 | NSUInteger SRCarbonToCocoaFlags( NSUInteger carbonFlags ) 126 | { 127 | NSUInteger cocoaFlags = ShortcutRecorderEmptyFlags; 128 | 129 | if (carbonFlags & cmdKey) cocoaFlags |= NSCommandKeyMask; 130 | if (carbonFlags & optionKey) cocoaFlags |= NSAlternateKeyMask; 131 | if (carbonFlags & controlKey) cocoaFlags |= NSControlKeyMask; 132 | if (carbonFlags & shiftKey) cocoaFlags |= NSShiftKeyMask; 133 | if (carbonFlags & NSFunctionKeyMask) cocoaFlags += NSFunctionKeyMask; 134 | 135 | return cocoaFlags; 136 | } 137 | 138 | //---------------------------------------------------------- 139 | // SRCocoaToCarbonFlags() 140 | //---------------------------------------------------------- 141 | NSUInteger SRCocoaToCarbonFlags( NSUInteger cocoaFlags ) 142 | { 143 | NSUInteger carbonFlags = ShortcutRecorderEmptyFlags; 144 | 145 | if (cocoaFlags & NSCommandKeyMask) carbonFlags |= cmdKey; 146 | if (cocoaFlags & NSAlternateKeyMask) carbonFlags |= optionKey; 147 | if (cocoaFlags & NSControlKeyMask) carbonFlags |= controlKey; 148 | if (cocoaFlags & NSShiftKeyMask) carbonFlags |= shiftKey; 149 | if (cocoaFlags & NSFunctionKeyMask) carbonFlags |= NSFunctionKeyMask; 150 | 151 | return carbonFlags; 152 | } 153 | 154 | //---------------------------------------------------------- 155 | // SRCharacterForKeyCodeAndCarbonFlags() 156 | //---------------------------------------------------------- 157 | NSString *SRCharacterForKeyCodeAndCarbonFlags(NSInteger keyCode, NSUInteger carbonFlags) { 158 | return SRCharacterForKeyCodeAndCocoaFlags(keyCode, SRCarbonToCocoaFlags(carbonFlags)); 159 | } 160 | 161 | //---------------------------------------------------------- 162 | // SRCharacterForKeyCodeAndCocoaFlags() 163 | //---------------------------------------------------------- 164 | NSString *SRCharacterForKeyCodeAndCocoaFlags(NSInteger keyCode, NSUInteger cocoaFlags) { 165 | 166 | PUDNSLog(@"SRCharacterForKeyCodeAndCocoaFlags, keyCode: %hi, cocoaFlags: %u", 167 | keyCode, cocoaFlags); 168 | 169 | // Fall back to string based on key code: 170 | #define FailWithNaiveString SRStringForKeyCode(keyCode) 171 | 172 | UInt32 deadKeyState; 173 | OSStatus err = noErr; 174 | CFLocaleRef locale = CFLocaleCopyCurrent(); 175 | [(id)CFMakeCollectable(locale) autorelease]; // Autorelease here so that it gets released no matter what 176 | 177 | TISInputSourceRef tisSource = TISCopyCurrentKeyboardInputSource(); 178 | if(!tisSource) 179 | return FailWithNaiveString; 180 | 181 | CFDataRef layoutData = (CFDataRef)TISGetInputSourceProperty(tisSource, kTISPropertyUnicodeKeyLayoutData); 182 | if (!layoutData) 183 | return FailWithNaiveString; 184 | 185 | const UCKeyboardLayout *keyLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData); 186 | if (!keyLayout) 187 | return FailWithNaiveString; 188 | 189 | EventModifiers modifiers = 0; 190 | if (cocoaFlags & NSAlternateKeyMask) modifiers |= optionKey; 191 | if (cocoaFlags & NSShiftKeyMask) modifiers |= shiftKey; 192 | UniCharCount maxStringLength = 4, actualStringLength; 193 | UniChar unicodeString[4]; 194 | err = UCKeyTranslate( keyLayout, (UInt16)keyCode, kUCKeyActionDisplay, modifiers, LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &deadKeyState, maxStringLength, &actualStringLength, unicodeString ); 195 | if(err != noErr) 196 | return FailWithNaiveString; 197 | 198 | CFStringRef temp = CFStringCreateWithCharacters(kCFAllocatorDefault, unicodeString, 1); 199 | CFMutableStringRef mutableTemp = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, temp); 200 | 201 | CFStringCapitalize(mutableTemp, locale); 202 | 203 | NSString *resultString = [NSString stringWithString:(NSString *)mutableTemp]; 204 | 205 | if (temp) CFRelease(temp); 206 | if (mutableTemp) CFRelease(mutableTemp); 207 | 208 | PUDNSLog(@"character: -%@-", (NSString *)resultString); 209 | 210 | return resultString; 211 | } 212 | 213 | #pragma mark Animation Easing 214 | 215 | #define CG_M_PI (CGFloat)M_PI 216 | #define CG_M_PI_2 (CGFloat)M_PI_2 217 | 218 | #ifdef __LP64__ 219 | #define CGSin(x) sin(x) 220 | #else 221 | #define CGSin(x) sinf(x) 222 | #endif 223 | 224 | // From: http://developer.apple.com/samplecode/AnimatedSlider/ as "easeFunction" 225 | CGFloat SRAnimationEaseInOut(CGFloat t) { 226 | // This function implements a sinusoidal ease-in/ease-out for t = 0 to 1.0. T is scaled to represent the interval of one full period of the sine function, and transposed to lie above the X axis. 227 | CGFloat x = (CGSin((t * CG_M_PI) - CG_M_PI_2) + 1.0f ) / 2.0f; 228 | // NSLog(@"SRAnimationEaseInOut: %f. a: %f, b: %f, c: %f, d: %f, e: %f", t, (t * M_PI), ((t * M_PI) - M_PI_2), sin((t * M_PI) - M_PI_2), (sin((t * M_PI) - M_PI_2) + 1.0), x); 229 | return x; 230 | } 231 | 232 | 233 | #pragma mark - 234 | #pragma mark additions 235 | 236 | @implementation NSAlert( SRAdditions ) 237 | 238 | //---------------------------------------------------------- 239 | // + alertWithNonRecoverableError: 240 | //---------------------------------------------------------- 241 | + (NSAlert *) alertWithNonRecoverableError:(NSError *)error; 242 | { 243 | NSString *reason = [error localizedRecoverySuggestion]; 244 | return [self alertWithMessageText:[error localizedDescription] 245 | defaultButton:[[error localizedRecoveryOptions] objectAtIndex:0U] 246 | alternateButton:nil 247 | otherButton:nil 248 | informativeTextWithFormat:(reason ? reason : @"")]; 249 | } 250 | 251 | @end 252 | 253 | static NSMutableDictionary *SRSharedImageCache = nil; 254 | 255 | @interface SRSharedImageProvider (Private) 256 | + (void)_drawSRSnapback:(id)anNSCustomImageRep; 257 | + (NSValue *)_sizeSRSnapback; 258 | + (void)_drawSRRemoveShortcut:(id)anNSCustomImageRep; 259 | + (NSValue *)_sizeSRRemoveShortcut; 260 | + (void)_drawSRRemoveShortcutRollover:(id)anNSCustomImageRep; 261 | + (NSValue *)_sizeSRRemoveShortcutRollover; 262 | + (void)_drawSRRemoveShortcutPressed:(id)anNSCustomImageRep; 263 | + (NSValue *)_sizeSRRemoveShortcutPressed; 264 | 265 | + (void)_drawARemoveShortcutBoxUsingRep:(id)anNSCustomImageRep opacity:(CGFloat)opacity; 266 | @end 267 | 268 | @implementation SRSharedImageProvider 269 | + (NSImage *)supportingImageWithName:(NSString *)name { 270 | // NSLog(@"supportingImageWithName: %@", name); 271 | if (nil == SRSharedImageCache) { 272 | SRSharedImageCache = [[NSMutableDictionary dictionary] retain]; 273 | // NSLog(@"inited cache"); 274 | } 275 | NSImage *cachedImage = nil; 276 | if (nil != (cachedImage = [SRSharedImageCache objectForKey:name])) { 277 | // NSLog(@"returned cached image: %@", cachedImage); 278 | return cachedImage; 279 | } 280 | 281 | // NSLog(@"constructing image"); 282 | NSSize size; 283 | NSValue *sizeValue = [self performSelector:NSSelectorFromString([NSString stringWithFormat:@"_size%@", name])]; 284 | size = [sizeValue sizeValue]; 285 | // NSLog(@"size: %@", NSStringFromSize(size)); 286 | 287 | NSCustomImageRep *customImageRep = [[NSCustomImageRep alloc] initWithDrawSelector:NSSelectorFromString([NSString stringWithFormat:@"_draw%@:", name]) delegate:self]; 288 | [customImageRep setSize:size]; 289 | // NSLog(@"created customImageRep: %@", customImageRep); 290 | NSImage *returnImage = [[NSImage alloc] initWithSize:size]; 291 | [returnImage addRepresentation:customImageRep]; 292 | [customImageRep release]; 293 | [returnImage setScalesWhenResized:YES]; 294 | [SRSharedImageCache setObject:returnImage forKey:name]; 295 | 296 | #ifdef SRCommonWriteDebugImagery 297 | 298 | NSData *tiff = [returnImage TIFFRepresentation]; 299 | [tiff writeToURL:[NSURL fileURLWithPath:[[NSString stringWithFormat:@"~/Desktop/m_%@.tiff", name] stringByExpandingTildeInPath]] atomically:YES]; 300 | 301 | NSSize sizeQDRPL = NSMakeSize(size.width*4.0,size.height*4.0); 302 | 303 | // sizeQDRPL = NSMakeSize(70.0,70.0); 304 | NSCustomImageRep *customImageRepQDRPL = [[NSCustomImageRep alloc] initWithDrawSelector:NSSelectorFromString([NSString stringWithFormat:@"_draw%@:", name]) delegate:self]; 305 | [customImageRepQDRPL setSize:sizeQDRPL]; 306 | // NSLog(@"created customImageRepQDRPL: %@", customImageRepQDRPL); 307 | NSImage *returnImageQDRPL = [[NSImage alloc] initWithSize:sizeQDRPL]; 308 | [returnImageQDRPL addRepresentation:customImageRepQDRPL]; 309 | [customImageRepQDRPL release]; 310 | [returnImageQDRPL setScalesWhenResized:YES]; 311 | [returnImageQDRPL setFlipped:YES]; 312 | NSData *tiffQDRPL = [returnImageQDRPL TIFFRepresentation]; 313 | [tiffQDRPL writeToURL:[NSURL fileURLWithPath:[[NSString stringWithFormat:@"~/Desktop/m_QDRPL_%@.tiff", name] stringByExpandingTildeInPath]] atomically:YES]; 314 | 315 | #endif 316 | 317 | // NSLog(@"returned image: %@", returnImage); 318 | return [returnImage autorelease]; 319 | } 320 | @end 321 | 322 | @implementation SRSharedImageProvider (Private) 323 | 324 | #define MakeRelativePoint(x,y) NSMakePoint(x*hScale, y*vScale) 325 | 326 | + (NSValue *)_sizeSRSnapback { 327 | return [NSValue valueWithSize:NSMakeSize(14.0f,14.0f)]; 328 | } 329 | + (void)_drawSRSnapback:(id)anNSCustomImageRep { 330 | 331 | // NSLog(@"drawSRSnapback using: %@", anNSCustomImageRep); 332 | 333 | NSCustomImageRep *rep = anNSCustomImageRep; 334 | NSSize size = [rep size]; 335 | [[NSColor whiteColor] setFill]; 336 | CGFloat hScale = (size.width/1.0f); 337 | CGFloat vScale = (size.height/1.0f); 338 | 339 | NSBezierPath *bp = [[NSBezierPath alloc] init]; 340 | [bp setLineWidth:hScale]; 341 | 342 | [bp moveToPoint:MakeRelativePoint(0.0489685f, 0.6181513f)]; 343 | [bp lineToPoint:MakeRelativePoint(0.4085750f, 0.9469318f)]; 344 | [bp lineToPoint:MakeRelativePoint(0.4085750f, 0.7226146f)]; 345 | [bp curveToPoint:MakeRelativePoint(0.8508247f, 0.4836237f) controlPoint1:MakeRelativePoint(0.4085750f, 0.7226146f) controlPoint2:MakeRelativePoint(0.8371143f, 0.7491841f)]; 346 | [bp curveToPoint:MakeRelativePoint(0.5507195f, 0.0530682f) controlPoint1:MakeRelativePoint(0.8677834f, 0.1545071f) controlPoint2:MakeRelativePoint(0.5507195f, 0.0530682f)]; 347 | [bp curveToPoint:MakeRelativePoint(0.7421721f, 0.3391942f) controlPoint1:MakeRelativePoint(0.5507195f, 0.0530682f) controlPoint2:MakeRelativePoint(0.7458685f, 0.1913146f)]; 348 | [bp curveToPoint:MakeRelativePoint(0.4085750f, 0.5154130f) controlPoint1:MakeRelativePoint(0.7383412f, 0.4930328f) controlPoint2:MakeRelativePoint(0.4085750f, 0.5154130f)]; 349 | [bp lineToPoint:MakeRelativePoint(0.4085750f, 0.2654000f)]; 350 | 351 | NSAffineTransform *flip = [[NSAffineTransform alloc] init]; 352 | // [flip translateXBy:0.95f yBy:-1.0f]; 353 | [flip scaleXBy:0.9f yBy:1.0f]; 354 | [flip translateXBy:0.5f yBy:-0.5f]; 355 | 356 | [bp transformUsingAffineTransform:flip]; 357 | 358 | NSShadow *sh = [[NSShadow alloc] init]; 359 | [sh setShadowColor:[[NSColor blackColor] colorWithAlphaComponent:0.45f]]; 360 | [sh setShadowBlurRadius:1.0f]; 361 | [sh setShadowOffset:NSMakeSize(0.0f,-1.0f)]; 362 | [sh set]; 363 | 364 | [bp fill]; 365 | 366 | [bp release]; 367 | [flip release]; 368 | [sh release]; 369 | } 370 | 371 | + (NSValue *)_sizeSRRemoveShortcut { 372 | return [NSValue valueWithSize:NSMakeSize(14.0f,14.0f)]; 373 | } 374 | + (NSValue *)_sizeSRRemoveShortcutRollover { return [self _sizeSRRemoveShortcut]; } 375 | + (NSValue *)_sizeSRRemoveShortcutPressed { return [self _sizeSRRemoveShortcut]; } 376 | + (void)_drawARemoveShortcutBoxUsingRep:(id)anNSCustomImageRep opacity:(CGFloat)opacity { 377 | 378 | // NSLog(@"drawARemoveShortcutBoxUsingRep: %@ opacity: %f", anNSCustomImageRep, opacity); 379 | 380 | NSCustomImageRep *rep = anNSCustomImageRep; 381 | NSSize size = [rep size]; 382 | [[NSColor colorWithCalibratedWhite:0.0f alpha:1.0f-opacity] setFill]; 383 | CGFloat hScale = (size.width/14.0f); 384 | CGFloat vScale = (size.height/14.0f); 385 | 386 | [[NSBezierPath bezierPathWithOvalInRect:NSMakeRect(0.0f,0.0f,size.width,size.height)] fill]; 387 | 388 | [[NSColor whiteColor] setStroke]; 389 | 390 | NSBezierPath *cross = [[NSBezierPath alloc] init]; 391 | [cross setLineWidth:hScale*1.2f]; 392 | 393 | [cross moveToPoint:MakeRelativePoint(4.0f,4.0f)]; 394 | [cross lineToPoint:MakeRelativePoint(10.0f,10.0f)]; 395 | [cross moveToPoint:MakeRelativePoint(10.0f,4.0f)]; 396 | [cross lineToPoint:MakeRelativePoint(4.0f,10.0f)]; 397 | 398 | [cross stroke]; 399 | [cross release]; 400 | } 401 | + (void)_drawSRRemoveShortcut:(id)anNSCustomImageRep { 402 | 403 | // NSLog(@"drawSRRemoveShortcut using: %@", anNSCustomImageRep); 404 | 405 | [self _drawARemoveShortcutBoxUsingRep:anNSCustomImageRep opacity:0.75f]; 406 | } 407 | + (void)_drawSRRemoveShortcutRollover:(id)anNSCustomImageRep { 408 | 409 | // NSLog(@"drawSRRemoveShortcutRollover using: %@", anNSCustomImageRep); 410 | 411 | [self _drawARemoveShortcutBoxUsingRep:anNSCustomImageRep opacity:0.65f]; 412 | } 413 | + (void)_drawSRRemoveShortcutPressed:(id)anNSCustomImageRep { 414 | 415 | // NSLog(@"drawSRRemoveShortcutPressed using: %@", anNSCustomImageRep); 416 | 417 | [self _drawARemoveShortcutBoxUsingRep:anNSCustomImageRep opacity:0.55f]; 418 | } 419 | @end 420 | -------------------------------------------------------------------------------- /NAKL.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2AC205CD1ECE60F4002016FB /* ExcludedAppsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2AC205CC1ECE60F4002016FB /* ExcludedAppsTableViewController.m */; }; 11 | 51151930157FA071003D3BB4 /* NSFileManager+DirectoryLocations.m in Sources */ = {isa = PBXBuildFile; fileRef = 5115192F157FA071003D3BB4 /* NSFileManager+DirectoryLocations.m */; }; 12 | 512C87BE181AE049008E8A65 /* EnableAssistiveDevices.scpt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 512C87BD181AE049008E8A65 /* EnableAssistiveDevices.scpt */; }; 13 | 51471007158B1BD000FFB252 /* icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 51471006158B1BD000FFB252 /* icon.png */; }; 14 | 5147100B158B1F4D00FFB252 /* icon24.png in Resources */ = {isa = PBXBuildFile; fileRef = 5147100A158B1F4D00FFB252 /* icon24.png */; }; 15 | 51471011158B2B6200FFB252 /* NAKL.icns in Resources */ = {isa = PBXBuildFile; fileRef = 51471010158B2B6200FFB252 /* NAKL.icns */; }; 16 | 51471013158B2C2000FFB252 /* icon_blue_24.png in Resources */ = {isa = PBXBuildFile; fileRef = 51471012158B2C2000FFB252 /* icon_blue_24.png */; }; 17 | 5147E45A15791D5A00932040 /* ShortcutTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5147E45915791D5A00932040 /* ShortcutTableViewController.m */; }; 18 | 5158BDB21568111A00EEBAD6 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5158BDB11568111A00EEBAD6 /* Cocoa.framework */; }; 19 | 5158BDBC1568111A00EEBAD6 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5158BDBA1568111A00EEBAD6 /* InfoPlist.strings */; }; 20 | 5158BDBE1568111A00EEBAD6 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5158BDBD1568111A00EEBAD6 /* main.m */; }; 21 | 5158BDC51568111A00EEBAD6 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5158BDC41568111A00EEBAD6 /* AppDelegate.m */; }; 22 | 5158BDC81568111A00EEBAD6 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5158BDC61568111A00EEBAD6 /* MainMenu.xib */; }; 23 | 5158BDEF1568CB1800EEBAD6 /* KeyboardHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 5158BDEE1568CB1800EEBAD6 /* KeyboardHandler.m */; }; 24 | 5189A8DF1570CA5100327B99 /* PreferencesController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5189A8DE1570CA5100327B99 /* PreferencesController.m */; }; 25 | 5189A8F41570CEE400327B99 /* ShortcutRecorder.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5189A8F21570CEE400327B99 /* ShortcutRecorder.strings */; }; 26 | 5189A8F61570D81800327B99 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5189A8F51570D81800327B99 /* Carbon.framework */; }; 27 | 5189A9061570ECB800327B99 /* SRCommon.m in Sources */ = {isa = PBXBuildFile; fileRef = 5189A8FD1570ECB800327B99 /* SRCommon.m */; }; 28 | 5189A9071570ECB800327B99 /* SRKeyCodeTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = 5189A8FF1570ECB800327B99 /* SRKeyCodeTransformer.m */; }; 29 | 5189A9081570ECB800327B99 /* SRRecorderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 5189A9011570ECB800327B99 /* SRRecorderCell.m */; }; 30 | 5189A9091570ECB800327B99 /* SRRecorderControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5189A9031570ECB800327B99 /* SRRecorderControl.m */; }; 31 | 5189A90A1570ECB800327B99 /* SRValidator.m in Sources */ = {isa = PBXBuildFile; fileRef = 5189A9051570ECB800327B99 /* SRValidator.m */; }; 32 | 5189A91415711B7F00327B99 /* PTHotKey.m in Sources */ = {isa = PBXBuildFile; fileRef = 5189A90D15711B7F00327B99 /* PTHotKey.m */; }; 33 | 5189A91515711B7F00327B99 /* PTHotKeyCenter.m in Sources */ = {isa = PBXBuildFile; fileRef = 5189A90F15711B7F00327B99 /* PTHotKeyCenter.m */; }; 34 | 5189A91615711B7F00327B99 /* PTKeyCodeTranslator.m in Sources */ = {isa = PBXBuildFile; fileRef = 5189A91115711B7F00327B99 /* PTKeyCodeTranslator.m */; }; 35 | 5189A91715711B7F00327B99 /* PTKeyCombo.m in Sources */ = {isa = PBXBuildFile; fileRef = 5189A91315711B7F00327B99 /* PTKeyCombo.m */; }; 36 | 5189A9221571CC2200327B99 /* AppData.m in Sources */ = {isa = PBXBuildFile; fileRef = 5189A9211571CC2200327B99 /* AppData.m */; }; 37 | 519D090B1946B2E5000722E7 /* Images-2.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 519D090A1946B2E5000722E7 /* Images-2.xcassets */; }; 38 | 51E7BA941589CB50003A6F3F /* Preferences.xib in Resources */ = {isa = PBXBuildFile; fileRef = 51E7BA961589CB50003A6F3F /* Preferences.xib */; }; 39 | 51F8A4DC1577D41900D42909 /* ShortcutSetting.m in Sources */ = {isa = PBXBuildFile; fileRef = 51F8A4DB1577D41900D42909 /* ShortcutSetting.m */; }; 40 | /* End PBXBuildFile section */ 41 | 42 | /* Begin PBXCopyFilesBuildPhase section */ 43 | 512C87BC181ADFC0008E8A65 /* CopyFiles */ = { 44 | isa = PBXCopyFilesBuildPhase; 45 | buildActionMask = 2147483647; 46 | dstPath = ""; 47 | dstSubfolderSpec = 7; 48 | files = ( 49 | 512C87BE181AE049008E8A65 /* EnableAssistiveDevices.scpt in CopyFiles */, 50 | ); 51 | runOnlyForDeploymentPostprocessing = 0; 52 | }; 53 | /* End PBXCopyFilesBuildPhase section */ 54 | 55 | /* Begin PBXFileReference section */ 56 | 2AC205CB1ECE60F4002016FB /* ExcludedAppsTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExcludedAppsTableViewController.h; sourceTree = ""; }; 57 | 2AC205CC1ECE60F4002016FB /* ExcludedAppsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ExcludedAppsTableViewController.m; sourceTree = ""; }; 58 | 5115192E157FA071003D3BB4 /* NSFileManager+DirectoryLocations.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSFileManager+DirectoryLocations.h"; sourceTree = ""; }; 59 | 5115192F157FA071003D3BB4 /* NSFileManager+DirectoryLocations.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSFileManager+DirectoryLocations.m"; sourceTree = ""; }; 60 | 512C87BD181AE049008E8A65 /* EnableAssistiveDevices.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; name = EnableAssistiveDevices.scpt; path = scripts/EnableAssistiveDevices.scpt; sourceTree = ""; }; 61 | 51471006158B1BD000FFB252 /* icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon.png; sourceTree = ""; }; 62 | 5147100A158B1F4D00FFB252 /* icon24.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon24.png; sourceTree = ""; }; 63 | 51471010158B2B6200FFB252 /* NAKL.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = NAKL.icns; sourceTree = ""; }; 64 | 51471012158B2C2000FFB252 /* icon_blue_24.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = icon_blue_24.png; sourceTree = ""; }; 65 | 5147E45815791D5A00932040 /* ShortcutTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShortcutTableViewController.h; sourceTree = ""; }; 66 | 5147E45915791D5A00932040 /* ShortcutTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShortcutTableViewController.m; sourceTree = ""; }; 67 | 5158BDAD1568111A00EEBAD6 /* NAKL.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = NAKL.app; sourceTree = BUILT_PRODUCTS_DIR; }; 68 | 5158BDB11568111A00EEBAD6 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; }; 69 | 5158BDB41568111A00EEBAD6 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 70 | 5158BDB51568111A00EEBAD6 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 71 | 5158BDB61568111A00EEBAD6 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 72 | 5158BDBB1568111A00EEBAD6 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 73 | 5158BDBD1568111A00EEBAD6 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 74 | 5158BDBF1568111A00EEBAD6 /* NAKL-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NAKL-Prefix.pch"; sourceTree = ""; }; 75 | 5158BDC31568111A00EEBAD6 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 76 | 5158BDC41568111A00EEBAD6 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 77 | 5158BDC71568111A00EEBAD6 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainMenu.xib; sourceTree = ""; }; 78 | 5158BDE51568A6EB00EEBAD6 /* utf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = utf.h; sourceTree = ""; }; 79 | 5158BDEC1568A78800EEBAD6 /* keymap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = keymap.h; sourceTree = ""; }; 80 | 5158BDED1568CB1800EEBAD6 /* KeyboardHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyboardHandler.h; sourceTree = ""; }; 81 | 5158BDEE1568CB1800EEBAD6 /* KeyboardHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KeyboardHandler.m; sourceTree = ""; }; 82 | 516BEA5D15726A7B0085B4BA /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = en; path = "en.lproj/NAKL-Info.plist"; sourceTree = ""; }; 83 | 5189A8DC1570C31100327B99 /* telex-standard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "telex-standard.h"; sourceTree = ""; }; 84 | 5189A8DD1570CA5100327B99 /* PreferencesController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PreferencesController.h; sourceTree = ""; }; 85 | 5189A8DE1570CA5100327B99 /* PreferencesController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PreferencesController.m; sourceTree = ""; }; 86 | 5189A8F31570CEE400327B99 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/ShortcutRecorder.strings; sourceTree = ""; }; 87 | 5189A8F51570D81800327B99 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = System/Library/Frameworks/Carbon.framework; sourceTree = SDKROOT; }; 88 | 5189A8FC1570ECB800327B99 /* SRCommon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRCommon.h; path = ShortcutRecorder/SRCommon.h; sourceTree = ""; }; 89 | 5189A8FD1570ECB800327B99 /* SRCommon.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRCommon.m; path = ShortcutRecorder/SRCommon.m; sourceTree = ""; }; 90 | 5189A8FE1570ECB800327B99 /* SRKeyCodeTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRKeyCodeTransformer.h; path = ShortcutRecorder/SRKeyCodeTransformer.h; sourceTree = ""; }; 91 | 5189A8FF1570ECB800327B99 /* SRKeyCodeTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRKeyCodeTransformer.m; path = ShortcutRecorder/SRKeyCodeTransformer.m; sourceTree = ""; }; 92 | 5189A9001570ECB800327B99 /* SRRecorderCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRRecorderCell.h; path = ShortcutRecorder/SRRecorderCell.h; sourceTree = ""; }; 93 | 5189A9011570ECB800327B99 /* SRRecorderCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRRecorderCell.m; path = ShortcutRecorder/SRRecorderCell.m; sourceTree = ""; }; 94 | 5189A9021570ECB800327B99 /* SRRecorderControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRRecorderControl.h; path = ShortcutRecorder/SRRecorderControl.h; sourceTree = ""; }; 95 | 5189A9031570ECB800327B99 /* SRRecorderControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRRecorderControl.m; path = ShortcutRecorder/SRRecorderControl.m; sourceTree = ""; }; 96 | 5189A9041570ECB800327B99 /* SRValidator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SRValidator.h; path = ShortcutRecorder/SRValidator.h; sourceTree = ""; }; 97 | 5189A9051570ECB800327B99 /* SRValidator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SRValidator.m; path = ShortcutRecorder/SRValidator.m; sourceTree = ""; }; 98 | 5189A90C15711B7F00327B99 /* PTHotKey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PTHotKey.h; path = HotKey/PTHotKey.h; sourceTree = ""; }; 99 | 5189A90D15711B7F00327B99 /* PTHotKey.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PTHotKey.m; path = HotKey/PTHotKey.m; sourceTree = ""; }; 100 | 5189A90E15711B7F00327B99 /* PTHotKeyCenter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PTHotKeyCenter.h; path = HotKey/PTHotKeyCenter.h; sourceTree = ""; }; 101 | 5189A90F15711B7F00327B99 /* PTHotKeyCenter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PTHotKeyCenter.m; path = HotKey/PTHotKeyCenter.m; sourceTree = ""; }; 102 | 5189A91015711B7F00327B99 /* PTKeyCodeTranslator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PTKeyCodeTranslator.h; path = HotKey/PTKeyCodeTranslator.h; sourceTree = ""; }; 103 | 5189A91115711B7F00327B99 /* PTKeyCodeTranslator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PTKeyCodeTranslator.m; path = HotKey/PTKeyCodeTranslator.m; sourceTree = ""; }; 104 | 5189A91215711B7F00327B99 /* PTKeyCombo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PTKeyCombo.h; path = HotKey/PTKeyCombo.h; sourceTree = ""; }; 105 | 5189A91315711B7F00327B99 /* PTKeyCombo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PTKeyCombo.m; path = HotKey/PTKeyCombo.m; sourceTree = ""; }; 106 | 5189A9201571CC2200327B99 /* AppData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppData.h; sourceTree = ""; }; 107 | 5189A9211571CC2200327B99 /* AppData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppData.m; sourceTree = ""; }; 108 | 5189A9231571CD6D00327B99 /* CWLSynthesizeSingleton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CWLSynthesizeSingleton.h; sourceTree = ""; }; 109 | 519D0909194641E4000722E7 /* NAKL.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = NAKL.entitlements; sourceTree = ""; }; 110 | 519D090A1946B2E5000722E7 /* Images-2.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Images-2.xcassets"; sourceTree = ""; }; 111 | 51E7BA951589CB50003A6F3F /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/Preferences.xib; sourceTree = ""; }; 112 | 51F8A4DA1577D41900D42909 /* ShortcutSetting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ShortcutSetting.h; sourceTree = ""; }; 113 | 51F8A4DB1577D41900D42909 /* ShortcutSetting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ShortcutSetting.m; sourceTree = ""; }; 114 | /* End PBXFileReference section */ 115 | 116 | /* Begin PBXFrameworksBuildPhase section */ 117 | 5158BDAA1568111A00EEBAD6 /* Frameworks */ = { 118 | isa = PBXFrameworksBuildPhase; 119 | buildActionMask = 2147483647; 120 | files = ( 121 | 5189A8F61570D81800327B99 /* Carbon.framework in Frameworks */, 122 | 5158BDB21568111A00EEBAD6 /* Cocoa.framework in Frameworks */, 123 | ); 124 | runOnlyForDeploymentPostprocessing = 0; 125 | }; 126 | /* End PBXFrameworksBuildPhase section */ 127 | 128 | /* Begin PBXGroup section */ 129 | 5115192D157FA037003D3BB4 /* Utils */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 5115192E157FA071003D3BB4 /* NSFileManager+DirectoryLocations.h */, 133 | 5115192F157FA071003D3BB4 /* NSFileManager+DirectoryLocations.m */, 134 | ); 135 | name = Utils; 136 | sourceTree = ""; 137 | }; 138 | 5158BDA21568111A00EEBAD6 = { 139 | isa = PBXGroup; 140 | children = ( 141 | 512C87BD181AE049008E8A65 /* EnableAssistiveDevices.scpt */, 142 | 5158BDB71568111A00EEBAD6 /* NAKL */, 143 | 5158BDB01568111A00EEBAD6 /* Frameworks */, 144 | 5158BDAE1568111A00EEBAD6 /* Products */, 145 | ); 146 | sourceTree = ""; 147 | }; 148 | 5158BDAE1568111A00EEBAD6 /* Products */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 5158BDAD1568111A00EEBAD6 /* NAKL.app */, 152 | ); 153 | name = Products; 154 | sourceTree = ""; 155 | }; 156 | 5158BDB01568111A00EEBAD6 /* Frameworks */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 5189A8F51570D81800327B99 /* Carbon.framework */, 160 | 5158BDB11568111A00EEBAD6 /* Cocoa.framework */, 161 | 5158BDB31568111A00EEBAD6 /* Other Frameworks */, 162 | ); 163 | name = Frameworks; 164 | sourceTree = ""; 165 | }; 166 | 5158BDB31568111A00EEBAD6 /* Other Frameworks */ = { 167 | isa = PBXGroup; 168 | children = ( 169 | 5158BDB41568111A00EEBAD6 /* AppKit.framework */, 170 | 5158BDB51568111A00EEBAD6 /* CoreData.framework */, 171 | 5158BDB61568111A00EEBAD6 /* Foundation.framework */, 172 | ); 173 | name = "Other Frameworks"; 174 | sourceTree = ""; 175 | }; 176 | 5158BDB71568111A00EEBAD6 /* NAKL */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | 519D0909194641E4000722E7 /* NAKL.entitlements */, 180 | 5115192D157FA037003D3BB4 /* Utils */, 181 | 51F8A4DF1578FDD200D42909 /* Resources */, 182 | 51F8A4DE1578FDBE00D42909 /* Classes */, 183 | 5189A90B15711B5600327B99 /* HotKey */, 184 | 5189A8FB1570EC9900327B99 /* ShortcutRecorder */, 185 | 519D090A1946B2E5000722E7 /* Images-2.xcassets */, 186 | 5158BDB81568111A00EEBAD6 /* Supporting Files */, 187 | ); 188 | path = NAKL; 189 | sourceTree = ""; 190 | }; 191 | 5158BDB81568111A00EEBAD6 /* Supporting Files */ = { 192 | isa = PBXGroup; 193 | children = ( 194 | 5189A8F21570CEE400327B99 /* ShortcutRecorder.strings */, 195 | 516BEA5E15726A7B0085B4BA /* NAKL-Info.plist */, 196 | 5158BDBA1568111A00EEBAD6 /* InfoPlist.strings */, 197 | 5158BDBD1568111A00EEBAD6 /* main.m */, 198 | 5158BDBF1568111A00EEBAD6 /* NAKL-Prefix.pch */, 199 | ); 200 | name = "Supporting Files"; 201 | sourceTree = ""; 202 | }; 203 | 5189A8FB1570EC9900327B99 /* ShortcutRecorder */ = { 204 | isa = PBXGroup; 205 | children = ( 206 | 5189A8FC1570ECB800327B99 /* SRCommon.h */, 207 | 5189A8FD1570ECB800327B99 /* SRCommon.m */, 208 | 5189A8FE1570ECB800327B99 /* SRKeyCodeTransformer.h */, 209 | 5189A8FF1570ECB800327B99 /* SRKeyCodeTransformer.m */, 210 | 5189A9001570ECB800327B99 /* SRRecorderCell.h */, 211 | 5189A9011570ECB800327B99 /* SRRecorderCell.m */, 212 | 5189A9021570ECB800327B99 /* SRRecorderControl.h */, 213 | 5189A9031570ECB800327B99 /* SRRecorderControl.m */, 214 | 5189A9041570ECB800327B99 /* SRValidator.h */, 215 | 5189A9051570ECB800327B99 /* SRValidator.m */, 216 | ); 217 | name = ShortcutRecorder; 218 | sourceTree = ""; 219 | }; 220 | 5189A90B15711B5600327B99 /* HotKey */ = { 221 | isa = PBXGroup; 222 | children = ( 223 | 5189A90C15711B7F00327B99 /* PTHotKey.h */, 224 | 5189A90D15711B7F00327B99 /* PTHotKey.m */, 225 | 5189A90E15711B7F00327B99 /* PTHotKeyCenter.h */, 226 | 5189A90F15711B7F00327B99 /* PTHotKeyCenter.m */, 227 | 5189A91015711B7F00327B99 /* PTKeyCodeTranslator.h */, 228 | 5189A91115711B7F00327B99 /* PTKeyCodeTranslator.m */, 229 | 5189A91215711B7F00327B99 /* PTKeyCombo.h */, 230 | 5189A91315711B7F00327B99 /* PTKeyCombo.m */, 231 | ); 232 | name = HotKey; 233 | sourceTree = ""; 234 | }; 235 | 51F8A4DE1578FDBE00D42909 /* Classes */ = { 236 | isa = PBXGroup; 237 | children = ( 238 | 5189A9201571CC2200327B99 /* AppData.h */, 239 | 5189A9211571CC2200327B99 /* AppData.m */, 240 | 5158BDC31568111A00EEBAD6 /* AppDelegate.h */, 241 | 5158BDC41568111A00EEBAD6 /* AppDelegate.m */, 242 | 5189A9231571CD6D00327B99 /* CWLSynthesizeSingleton.h */, 243 | 5158BDED1568CB1800EEBAD6 /* KeyboardHandler.h */, 244 | 5158BDEE1568CB1800EEBAD6 /* KeyboardHandler.m */, 245 | 5158BDEC1568A78800EEBAD6 /* keymap.h */, 246 | 5189A8DD1570CA5100327B99 /* PreferencesController.h */, 247 | 5189A8DE1570CA5100327B99 /* PreferencesController.m */, 248 | 51F8A4DA1577D41900D42909 /* ShortcutSetting.h */, 249 | 51F8A4DB1577D41900D42909 /* ShortcutSetting.m */, 250 | 5189A8DC1570C31100327B99 /* telex-standard.h */, 251 | 5158BDE51568A6EB00EEBAD6 /* utf.h */, 252 | 5147E45815791D5A00932040 /* ShortcutTableViewController.h */, 253 | 5147E45915791D5A00932040 /* ShortcutTableViewController.m */, 254 | 2AC205CB1ECE60F4002016FB /* ExcludedAppsTableViewController.h */, 255 | 2AC205CC1ECE60F4002016FB /* ExcludedAppsTableViewController.m */, 256 | ); 257 | name = Classes; 258 | sourceTree = ""; 259 | }; 260 | 51F8A4DF1578FDD200D42909 /* Resources */ = { 261 | isa = PBXGroup; 262 | children = ( 263 | 51471012158B2C2000FFB252 /* icon_blue_24.png */, 264 | 51471010158B2B6200FFB252 /* NAKL.icns */, 265 | 51471006158B1BD000FFB252 /* icon.png */, 266 | 5147100A158B1F4D00FFB252 /* icon24.png */, 267 | 5158BDC61568111A00EEBAD6 /* MainMenu.xib */, 268 | 51E7BA961589CB50003A6F3F /* Preferences.xib */, 269 | ); 270 | name = Resources; 271 | sourceTree = ""; 272 | }; 273 | /* End PBXGroup section */ 274 | 275 | /* Begin PBXNativeTarget section */ 276 | 5158BDAC1568111A00EEBAD6 /* NAKL */ = { 277 | isa = PBXNativeTarget; 278 | buildConfigurationList = 5158BDCB1568111A00EEBAD6 /* Build configuration list for PBXNativeTarget "NAKL" */; 279 | buildPhases = ( 280 | 5158BDA91568111A00EEBAD6 /* Sources */, 281 | 5158BDAA1568111A00EEBAD6 /* Frameworks */, 282 | 5158BDAB1568111A00EEBAD6 /* Resources */, 283 | 512C87BB181ADBF2008E8A65 /* ShellScript */, 284 | 512C87BC181ADFC0008E8A65 /* CopyFiles */, 285 | ); 286 | buildRules = ( 287 | ); 288 | dependencies = ( 289 | ); 290 | name = NAKL; 291 | productName = NAKL; 292 | productReference = 5158BDAD1568111A00EEBAD6 /* NAKL.app */; 293 | productType = "com.apple.product-type.application"; 294 | }; 295 | /* End PBXNativeTarget section */ 296 | 297 | /* Begin PBXProject section */ 298 | 5158BDA41568111A00EEBAD6 /* Project object */ = { 299 | isa = PBXProject; 300 | attributes = { 301 | LastUpgradeCheck = 0460; 302 | TargetAttributes = { 303 | 5158BDAC1568111A00EEBAD6 = { 304 | SystemCapabilities = { 305 | com.apple.Sandbox = { 306 | enabled = 0; 307 | }; 308 | }; 309 | }; 310 | }; 311 | }; 312 | buildConfigurationList = 5158BDA71568111A00EEBAD6 /* Build configuration list for PBXProject "NAKL" */; 313 | compatibilityVersion = "Xcode 3.2"; 314 | developmentRegion = English; 315 | hasScannedForEncodings = 0; 316 | knownRegions = ( 317 | en, 318 | vi, 319 | ); 320 | mainGroup = 5158BDA21568111A00EEBAD6; 321 | productRefGroup = 5158BDAE1568111A00EEBAD6 /* Products */; 322 | projectDirPath = ""; 323 | projectRoot = ""; 324 | targets = ( 325 | 5158BDAC1568111A00EEBAD6 /* NAKL */, 326 | ); 327 | }; 328 | /* End PBXProject section */ 329 | 330 | /* Begin PBXResourcesBuildPhase section */ 331 | 5158BDAB1568111A00EEBAD6 /* Resources */ = { 332 | isa = PBXResourcesBuildPhase; 333 | buildActionMask = 2147483647; 334 | files = ( 335 | 519D090B1946B2E5000722E7 /* Images-2.xcassets in Resources */, 336 | 5158BDBC1568111A00EEBAD6 /* InfoPlist.strings in Resources */, 337 | 5158BDC81568111A00EEBAD6 /* MainMenu.xib in Resources */, 338 | 51E7BA941589CB50003A6F3F /* Preferences.xib in Resources */, 339 | 5189A8F41570CEE400327B99 /* ShortcutRecorder.strings in Resources */, 340 | 51471007158B1BD000FFB252 /* icon.png in Resources */, 341 | 5147100B158B1F4D00FFB252 /* icon24.png in Resources */, 342 | 51471011158B2B6200FFB252 /* NAKL.icns in Resources */, 343 | 51471013158B2C2000FFB252 /* icon_blue_24.png in Resources */, 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | }; 347 | /* End PBXResourcesBuildPhase section */ 348 | 349 | /* Begin PBXShellScriptBuildPhase section */ 350 | 512C87BB181ADBF2008E8A65 /* ShellScript */ = { 351 | isa = PBXShellScriptBuildPhase; 352 | buildActionMask = 2147483647; 353 | files = ( 354 | ); 355 | inputPaths = ( 356 | ); 357 | outputPaths = ( 358 | ); 359 | runOnlyForDeploymentPostprocessing = 0; 360 | shellPath = /bin/sh; 361 | shellScript = "osacompile -d -o scripts/EnableAssistiveDevices.scpt scripts/EnableAssistiveDevices.applescript"; 362 | }; 363 | /* End PBXShellScriptBuildPhase section */ 364 | 365 | /* Begin PBXSourcesBuildPhase section */ 366 | 5158BDA91568111A00EEBAD6 /* Sources */ = { 367 | isa = PBXSourcesBuildPhase; 368 | buildActionMask = 2147483647; 369 | files = ( 370 | 5158BDBE1568111A00EEBAD6 /* main.m in Sources */, 371 | 2AC205CD1ECE60F4002016FB /* ExcludedAppsTableViewController.m in Sources */, 372 | 5158BDC51568111A00EEBAD6 /* AppDelegate.m in Sources */, 373 | 5158BDEF1568CB1800EEBAD6 /* KeyboardHandler.m in Sources */, 374 | 5189A8DF1570CA5100327B99 /* PreferencesController.m in Sources */, 375 | 5189A9061570ECB800327B99 /* SRCommon.m in Sources */, 376 | 5189A9071570ECB800327B99 /* SRKeyCodeTransformer.m in Sources */, 377 | 5189A9081570ECB800327B99 /* SRRecorderCell.m in Sources */, 378 | 5189A9091570ECB800327B99 /* SRRecorderControl.m in Sources */, 379 | 5189A90A1570ECB800327B99 /* SRValidator.m in Sources */, 380 | 5189A91415711B7F00327B99 /* PTHotKey.m in Sources */, 381 | 5189A91515711B7F00327B99 /* PTHotKeyCenter.m in Sources */, 382 | 5189A91615711B7F00327B99 /* PTKeyCodeTranslator.m in Sources */, 383 | 5189A91715711B7F00327B99 /* PTKeyCombo.m in Sources */, 384 | 5189A9221571CC2200327B99 /* AppData.m in Sources */, 385 | 51F8A4DC1577D41900D42909 /* ShortcutSetting.m in Sources */, 386 | 5147E45A15791D5A00932040 /* ShortcutTableViewController.m in Sources */, 387 | 51151930157FA071003D3BB4 /* NSFileManager+DirectoryLocations.m in Sources */, 388 | ); 389 | runOnlyForDeploymentPostprocessing = 0; 390 | }; 391 | /* End PBXSourcesBuildPhase section */ 392 | 393 | /* Begin PBXVariantGroup section */ 394 | 5158BDBA1568111A00EEBAD6 /* InfoPlist.strings */ = { 395 | isa = PBXVariantGroup; 396 | children = ( 397 | 5158BDBB1568111A00EEBAD6 /* en */, 398 | ); 399 | name = InfoPlist.strings; 400 | sourceTree = ""; 401 | }; 402 | 5158BDC61568111A00EEBAD6 /* MainMenu.xib */ = { 403 | isa = PBXVariantGroup; 404 | children = ( 405 | 5158BDC71568111A00EEBAD6 /* en */, 406 | ); 407 | name = MainMenu.xib; 408 | sourceTree = ""; 409 | }; 410 | 516BEA5E15726A7B0085B4BA /* NAKL-Info.plist */ = { 411 | isa = PBXVariantGroup; 412 | children = ( 413 | 516BEA5D15726A7B0085B4BA /* en */, 414 | ); 415 | name = "NAKL-Info.plist"; 416 | sourceTree = ""; 417 | }; 418 | 5189A8F21570CEE400327B99 /* ShortcutRecorder.strings */ = { 419 | isa = PBXVariantGroup; 420 | children = ( 421 | 5189A8F31570CEE400327B99 /* en */, 422 | ); 423 | name = ShortcutRecorder.strings; 424 | sourceTree = ""; 425 | }; 426 | 51E7BA961589CB50003A6F3F /* Preferences.xib */ = { 427 | isa = PBXVariantGroup; 428 | children = ( 429 | 51E7BA951589CB50003A6F3F /* en */, 430 | ); 431 | name = Preferences.xib; 432 | sourceTree = ""; 433 | }; 434 | /* End PBXVariantGroup section */ 435 | 436 | /* Begin XCBuildConfiguration section */ 437 | 5158BDC91568111A00EEBAD6 /* Debug */ = { 438 | isa = XCBuildConfiguration; 439 | buildSettings = { 440 | ALWAYS_SEARCH_USER_PATHS = NO; 441 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 442 | CLANG_ENABLE_OBJC_ARC = YES; 443 | CLANG_WARN_CONSTANT_CONVERSION = YES; 444 | CLANG_WARN_ENUM_CONVERSION = YES; 445 | CLANG_WARN_INT_CONVERSION = YES; 446 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 447 | COPY_PHASE_STRIP = NO; 448 | GCC_C_LANGUAGE_STANDARD = gnu99; 449 | GCC_DYNAMIC_NO_PIC = NO; 450 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 451 | GCC_OPTIMIZATION_LEVEL = 0; 452 | GCC_PREPROCESSOR_DEFINITIONS = ( 453 | "DEBUG=1", 454 | "$(inherited)", 455 | ); 456 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 457 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 458 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 459 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 460 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 461 | GCC_WARN_UNUSED_VARIABLE = YES; 462 | MACOSX_DEPLOYMENT_TARGET = 10.5; 463 | ONLY_ACTIVE_ARCH = YES; 464 | SDKROOT = macosx; 465 | }; 466 | name = Debug; 467 | }; 468 | 5158BDCA1568111A00EEBAD6 /* Release */ = { 469 | isa = XCBuildConfiguration; 470 | buildSettings = { 471 | ALWAYS_SEARCH_USER_PATHS = NO; 472 | ARCHS = "$(ARCHS_STANDARD_64_BIT)"; 473 | CLANG_ENABLE_OBJC_ARC = YES; 474 | CLANG_WARN_CONSTANT_CONVERSION = YES; 475 | CLANG_WARN_ENUM_CONVERSION = YES; 476 | CLANG_WARN_INT_CONVERSION = YES; 477 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 478 | COPY_PHASE_STRIP = YES; 479 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 480 | GCC_C_LANGUAGE_STANDARD = gnu99; 481 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 482 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 483 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 484 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 485 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 486 | GCC_WARN_UNUSED_VARIABLE = YES; 487 | MACOSX_DEPLOYMENT_TARGET = 10.5; 488 | SDKROOT = macosx; 489 | }; 490 | name = Release; 491 | }; 492 | 5158BDCC1568111A00EEBAD6 /* Debug */ = { 493 | isa = XCBuildConfiguration; 494 | buildSettings = { 495 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 496 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 497 | CLANG_ENABLE_OBJC_ARC = NO; 498 | CODE_SIGN_IDENTITY = "-"; 499 | COMBINE_HIDPI_IMAGES = YES; 500 | CURRENT_PROJECT_VERSION = 40; 501 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 502 | GCC_PREFIX_HEADER = "NAKL/NAKL-Prefix.pch"; 503 | INFOPLIST_FILE = "NAKL/NAKL-Info.plist"; 504 | MACOSX_DEPLOYMENT_TARGET = 10.5; 505 | PRODUCT_NAME = NAKL; 506 | VERSIONING_SYSTEM = "apple-generic"; 507 | WRAPPER_EXTENSION = app; 508 | }; 509 | name = Debug; 510 | }; 511 | 5158BDCD1568111A00EEBAD6 /* Release */ = { 512 | isa = XCBuildConfiguration; 513 | buildSettings = { 514 | ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; 515 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 516 | CLANG_ENABLE_OBJC_ARC = NO; 517 | CODE_SIGN_IDENTITY = "-"; 518 | COMBINE_HIDPI_IMAGES = YES; 519 | CURRENT_PROJECT_VERSION = 40; 520 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 521 | GCC_PREFIX_HEADER = "NAKL/NAKL-Prefix.pch"; 522 | INFOPLIST_FILE = "NAKL/NAKL-Info.plist"; 523 | MACOSX_DEPLOYMENT_TARGET = 10.5; 524 | PRODUCT_NAME = NAKL; 525 | VERSIONING_SYSTEM = "apple-generic"; 526 | WRAPPER_EXTENSION = app; 527 | }; 528 | name = Release; 529 | }; 530 | /* End XCBuildConfiguration section */ 531 | 532 | /* Begin XCConfigurationList section */ 533 | 5158BDA71568111A00EEBAD6 /* Build configuration list for PBXProject "NAKL" */ = { 534 | isa = XCConfigurationList; 535 | buildConfigurations = ( 536 | 5158BDC91568111A00EEBAD6 /* Debug */, 537 | 5158BDCA1568111A00EEBAD6 /* Release */, 538 | ); 539 | defaultConfigurationIsVisible = 0; 540 | defaultConfigurationName = Release; 541 | }; 542 | 5158BDCB1568111A00EEBAD6 /* Build configuration list for PBXNativeTarget "NAKL" */ = { 543 | isa = XCConfigurationList; 544 | buildConfigurations = ( 545 | 5158BDCC1568111A00EEBAD6 /* Debug */, 546 | 5158BDCD1568111A00EEBAD6 /* Release */, 547 | ); 548 | defaultConfigurationIsVisible = 0; 549 | defaultConfigurationName = Release; 550 | }; 551 | /* End XCConfigurationList section */ 552 | }; 553 | rootObject = 5158BDA41568111A00EEBAD6 /* Project object */; 554 | } 555 | --------------------------------------------------------------------------------