Browse Source

Adding latest files.

pull/92/head
Abhishek Banthia 5 years ago
parent
commit
90655a653e
  1. 8
      .gitignore
  2. 8
      .travis.yml
  3. BIN
      Archive/Clocker-1-Scaled.png
  4. BIN
      Archive/Clocker-1.png
  5. BIN
      Archive/Clocker-2-Scaled.png
  6. BIN
      Archive/Clocker-2.png
  7. BIN
      Archive/Clocker-3-Scaled.png
  8. BIN
      Archive/Clocker-3.png
  9. BIN
      Archive/Clocker-4-Scaled.png
  10. BIN
      Archive/Clocker-4.png
  11. BIN
      Archive/Icon.png
  12. 294
      Clocker/AppDelegate.swift
  13. 14
      Clocker/Clocker-Bridging-Header.h
  14. 1924
      Clocker/Clocker.xcodeproj/project.pbxproj
  15. 7
      Clocker/Clocker.xcodeproj/project.xcworkspace/contents.xcworkspacedata
  16. 30
      Clocker/Clocker.xcodeproj/project.xcworkspace/xcshareddata/Clocker.xcscmblueprint
  17. 8
      Clocker/Clocker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
  18. 8
      Clocker/Clocker.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
  19. 18
      Clocker/Clocker.xcodeproj/project.xcworkspace/xcuserdata/abhishek_banthia.xcuserdatad/WorkspaceSettings.xcsettings
  20. 5
      Clocker/Clocker.xcodeproj/project.xcworkspace/xcuserdata/abhishekbanthia.xcuserdatad/IDEFindNavigatorScopes.plist
  21. 5
      Clocker/Clocker.xcodeproj/project.xcworkspace/xcuserdata/ban.xcuserdatad/IDEFindNavigatorScopes.plist
  22. 8
      Clocker/Clocker.xcodeproj/xcshareddata/IDETemplateMacros.plist
  23. 135
      Clocker/Clocker.xcodeproj/xcshareddata/xcschemes/Clocker.xcscheme
  24. 101
      Clocker/Clocker.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme
  25. 152
      Clocker/Clocker.xcodeproj/xcuserdata/abhishek_banthia.xcuserdatad/xcschemes/Clocker.xcscheme
  26. 91
      Clocker/Clocker.xcodeproj/xcuserdata/abhishek_banthia.xcuserdatad/xcschemes/ClockerHelper.xcscheme
  27. 47
      Clocker/Clocker.xcodeproj/xcuserdata/abhishek_banthia.xcuserdatad/xcschemes/xcschememanagement.plist
  28. 17
      Clocker/Clocker.xcodeproj/xcuserdata/abhishekbanthia.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
  29. 101
      Clocker/Clocker.xcodeproj/xcuserdata/abhishekbanthia.xcuserdatad/xcschemes/ClockerHelper.xcscheme
  30. 47
      Clocker/Clocker.xcodeproj/xcuserdata/abhishekbanthia.xcuserdatad/xcschemes/xcschememanagement.plist
  31. 32
      Clocker/Clocker.xcodeproj/xcuserdata/ban.xcuserdatad/xcschemes/xcschememanagement.plist
  32. 65
      Clocker/Clocker/Clocker-Info.plist
  33. 9
      Clocker/Clocker/Clocker-Prefix.pch
  34. 16
      Clocker/Clocker/Clocker.entitlements
  35. BIN
      Clocker/Clocker/Images/ClockHands.gif
  36. BIN
      Clocker/Clocker/Images/ClockerIcon-16.png
  37. BIN
      Clocker/Clocker/Images/ClockerIcon-256.png
  38. BIN
      Clocker/Clocker/Images/FB-FindUsonFacebook-online-144.png
  39. BIN
      Clocker/Clocker/Images/MacAppStore.png
  40. BIN
      Clocker/Clocker/Images/MenuBar.png
  41. BIN
      Clocker/Clocker/Images/PowerIcon 2.png
  42. BIN
      Clocker/Clocker/Images/PowerIcon-White.png
  43. BIN
      Clocker/Clocker/Images/PowerIcon.png
  44. BIN
      Clocker/Clocker/Images/Settings-White.png
  45. BIN
      Clocker/Clocker/Images/Status.png
  46. BIN
      Clocker/Clocker/Images/Status@2x.png
  47. BIN
      Clocker/Clocker/Images/StatusHighlighted.png
  48. BIN
      Clocker/Clocker/Images/StatusHighlighted@2x.png
  49. BIN
      Clocker/Clocker/Images/Sunrise-512x512.png
  50. BIN
      Clocker/Clocker/Images/Untitled.png
  51. BIN
      Clocker/Clocker/Images/White Sunset.png
  52. BIN
      Clocker/Clocker/Images/WhiteButton.png
  53. BIN
      Clocker/Clocker/Images/WhiteSunrise.png
  54. BIN
      Clocker/Clocker/Images/aboutTemplate.png
  55. BIN
      Clocker/Clocker/Images/index.png
  56. BIN
      Clocker/Clocker/Images/sunset-512.png
  57. 119
      Clocker/Clocker/LocationController.swift
  58. 361
      Clocker/Clocker/MainMenu.xib
  59. 18
      Clocker/Clocker/ShortcutRecorder-master/.gitignore
  60. 31
      Clocker/Clocker/ShortcutRecorder-master/LICENSE.md
  61. 22
      Clocker/Clocker/ShortcutRecorder-master/Library/Info.plist
  62. 5
      Clocker/Clocker/ShortcutRecorder-master/Library/Prefix.pch
  63. 116
      Clocker/Clocker/ShortcutRecorder-master/Library/SRCommon.h
  64. 175
      Clocker/Clocker/ShortcutRecorder-master/Library/SRCommon.m
  65. 139
      Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyCodeTransformer.h
  66. 357
      Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyCodeTransformer.m
  67. 21
      Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyEquivalentModifierMaskTransformer.h
  68. 44
      Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyEquivalentModifierMaskTransformer.m
  69. 21
      Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyEquivalentTransformer.h
  70. 53
      Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyEquivalentTransformer.m
  71. 37
      Clocker/Clocker/ShortcutRecorder-master/Library/SRModifierFlagsTransformer.h
  72. 108
      Clocker/Clocker/ShortcutRecorder-master/Library/SRModifierFlagsTransformer.m
  73. 436
      Clocker/Clocker/ShortcutRecorder-master/Library/SRRecorderControl.h
  74. 1407
      Clocker/Clocker/ShortcutRecorder-master/Library/SRRecorderControl.m
  75. 131
      Clocker/Clocker/ShortcutRecorder-master/Library/SRValidator.h
  76. 233
      Clocker/Clocker/ShortcutRecorder-master/Library/SRValidator.m
  77. 54
      Clocker/Clocker/ShortcutRecorder-master/Library/ShortcutRecorder.h
  78. 22
      Clocker/Clocker/ShortcutRecorder-master/PTHotKey/Info.plist
  79. 31
      Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKey+ShortcutRecorder.h
  80. 53
      Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKey+ShortcutRecorder.m
  81. 60
      Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKey.h
  82. 156
      Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKey.m
  83. 44
      Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKeyCenter.h
  84. 334
      Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKeyCenter.m
  85. 26
      Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTKeyCodeTranslator.h
  86. 71
      Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTKeyCodeTranslator.m
  87. 38
      Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTKeyCombo.h
  88. 127
      Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTKeyCombo.m
  89. 112
      Clocker/Clocker/ShortcutRecorder-master/README.md
  90. 40
      Clocker/Clocker/ShortcutRecorder-master/Resources/LICENSE.txt
  91. BIN
      Clocker/Clocker/ShortcutRecorder-master/Resources/ShorcutRecorder Yosemite.sketch
  92. BIN
      Clocker/Clocker/ShortcutRecorder-master/Resources/ca.lproj/ShortcutRecorder.strings
  93. BIN
      Clocker/Clocker/ShortcutRecorder-master/Resources/cs.lproj/ShortcutRecorder.strings
  94. BIN
      Clocker/Clocker/ShortcutRecorder-master/Resources/de.lproj/ShortcutRecorder.strings
  95. BIN
      Clocker/Clocker/ShortcutRecorder-master/Resources/el.lproj/ShortcutRecorder.strings
  96. BIN
      Clocker/Clocker/ShortcutRecorder-master/Resources/en.lproj/ShortcutRecorder.strings
  97. BIN
      Clocker/Clocker/ShortcutRecorder-master/Resources/es-MX.lproj/ShortcutRecorder.strings
  98. BIN
      Clocker/Clocker/ShortcutRecorder-master/Resources/es.lproj/ShortcutRecorder.strings
  99. BIN
      Clocker/Clocker/ShortcutRecorder-master/Resources/fr.lproj/ShortcutRecorder.strings
  100. BIN
      Clocker/Clocker/ShortcutRecorder-master/Resources/it.lproj/ShortcutRecorder.strings
  101. Some files were not shown because too many files have changed in this diff Show More

8
.gitignore vendored

@ -0,0 +1,8 @@
*.xcuserstate
.DS_Store
.DS_Store
Clocker/Clocker.xcodeproj/project.xcworkspace/xcuserdata/abhishek_banthia.xcuserdatad/UserInterfaceState.xcuserstate
Clocker/Clocker.xcodeproj/xcuserdata/abhishek_banthia.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
*.xcuserstate
.DS_Store

8
.travis.yml

@ -0,0 +1,8 @@
os: osx
language: swift
xcode_project: Clocker.xcodeproj # path to your xcodeproj folder
osx_image: xcode10.2
script:
- set -o pipefail
- xcodebuild -project Clocker/Clocker.xcodeproj -scheme Clocker build analyze | xcpretty
- xcodebuild -project Clocker/Clocker.xcodeproj -scheme Tests test-without-building | xcpretty

BIN
Archive/Clocker-1-Scaled.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

BIN
Archive/Clocker-1.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

BIN
Archive/Clocker-2-Scaled.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 272 KiB

BIN
Archive/Clocker-2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1022 KiB

BIN
Archive/Clocker-3-Scaled.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 481 KiB

BIN
Archive/Clocker-3.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 711 KiB

BIN
Archive/Clocker-4-Scaled.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

BIN
Archive/Clocker-4.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 812 KiB

BIN
Archive/Icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

294
Clocker/AppDelegate.swift

@ -0,0 +1,294 @@
// Copyright © 2015 Abhishek Banthia
import Cocoa
open class AppDelegate : NSObject, NSApplicationDelegate {
lazy private var floatingWindow: FloatingWindowController = FloatingWindowController.shared()
lazy private var panelController: PanelController = PanelController.shared()
private var statusBarHandler: StatusItemHandler!
deinit {
panelController.removeObserver(self, forKeyPath: "hasActivePanel")
}
private var kContextActivePanel = 0
open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &kContextActivePanel {
statusBarHandler.setHasActiveIcon(panelController.hasActivePanelGetter())
} else if let path = keyPath, path == "values.globalPing" {
let hotKeyCenter = PTHotKeyCenter.shared()
// Unregister old hot key
let oldHotKey = hotKeyCenter?.hotKey(withIdentifier: path)
hotKeyCenter?.unregisterHotKey(oldHotKey)
// We don't register unless there's a valid key combination
guard let newObject = object as? NSObject, let newShortcut = newObject.value(forKeyPath: path) as? [AnyHashable: Any] else {
return
}
// Register new key
let newHotKey: PTHotKey = PTHotKey(identifier: keyPath,
keyCombo: newShortcut,
target: self,
action: #selector(ping(_:)))
hotKeyCenter?.register(newHotKey)
}
}
public func applicationWillFinishLaunching(_ notification: Notification) {
iVersion.sharedInstance().useAllAvailableLanguages = true
iVersion.sharedInstance().verboseLogging = false
}
public func applicationDidFinishLaunching(_ notification: Notification) {
// Initializing the event store takes really long
EventCenter.sharedCenter()
AppDefaults.initialize()
// Check if we can show the onboarding flow!
showOnboardingFlow()
// Ratings Controller initialization
RateController.applicationDidLaunch(UserDefaults.standard)
#if RELEASE
Crashlytics.sharedInstance().debugMode = true
Fabric.with([Crashlytics.self])
checkIfRunFromApplicationsFolder()
#endif
}
public func applicationDockMenu(_ sender: NSApplication) -> NSMenu? {
let menu = NSMenu(title: "Quick Access")
Logger.log(object: ["Dock Menu Triggered": "YES"], for: "Dock Menu Triggered")
let toggleMenuItem = NSMenuItem(title: "Toggle Panel", action: #selector(AppDelegate.togglePanel(_:)), keyEquivalent: "")
let openPreferences = NSMenuItem(title: "Preferences", action: #selector(AppDelegate.openPreferencesWindow), keyEquivalent: ",")
[toggleMenuItem, openPreferences].forEach {
$0.isEnabled = true
menu.addItem($0)
}
return menu
}
@objc private func openPreferencesWindow() {
let displayMode = UserDefaults.standard.integer(forKey: CLShowAppInForeground)
if displayMode == 1 {
let floatingWindow = FloatingWindowController.shared()
floatingWindow.openPreferences(NSButton())
} else {
let panelController = PanelController.shared()
panelController.openPreferences(NSButton())
}
}
private lazy var controller: OnboardingController? = {
let s = NSStoryboard(name: NSStoryboard.Name("Onboarding"), bundle: nil)
return s.instantiateController(withIdentifier: NSStoryboard.SceneIdentifier("onboardingFlow")) as? OnboardingController
}()
private func showOnboardingFlow() {
let shouldLaunchOnboarding = (DataStore.shared().retrieve(key: CLShowOnboardingFlow) == nil && DataStore.shared().timezones().isEmpty) || (ProcessInfo.processInfo.arguments.contains(CLOnboaringTestsLaunchArgument))
shouldLaunchOnboarding ? controller?.launch() : continueUsually()
}
func continueUsually() {
// Check if another instance of the app is already running. If so, then stop this one.
checkIfAppIsAlreadyOpen()
// Make sure the old models are not used anymore
TimezoneData.convert()
// Install the menubar item!
statusBarHandler = StatusItemHandler()
if UserDefaults.standard.object(forKey: CLInstallHomeIndicatorObject) == nil {
fetchLocalTimezone()
UserDefaults.standard.set(1, forKey: CLInstallHomeIndicatorObject)
}
if ProcessInfo.processInfo.arguments.contains(CLUITestingLaunchArgument) {
RateController.setPreviewMode(true)
}
UserDefaults.standard.register(defaults: ["NSApplicationCrashOnExceptions": true])
assignShortcut()
panelController.addObserver(self,
forKeyPath: "hasActivePanel",
options: [.new],
context: &kContextActivePanel)
let defaults = UserDefaults.standard
setActivationPolicy()
// Set the display mode default as panel!
if let displayMode = defaults.object(forKey: CLShowAppInForeground) as? NSNumber, displayMode.intValue == 1 {
showFloatingWindow()
} else if let displayMode = defaults.object(forKey: CLShowAppInForeground) as? Int, displayMode == 1 {
showFloatingWindow()
}
}
// Should we have a dock icon or just stay in the menubar?
private func setActivationPolicy() {
let defaults = UserDefaults.standard
let activationPolicy: NSApplication.ActivationPolicy = defaults.integer(forKey: CLAppDislayOptions) == 0 ? .accessory : .regular
NSApp.setActivationPolicy(activationPolicy)
}
private func checkIfAppIsAlreadyOpen() {
guard let bundleID = Bundle.main.bundleIdentifier else {
return
}
let apps = NSRunningApplication.runningApplications(withBundleIdentifier: bundleID)
if apps.count > 1 {
let currentApplication = NSRunningApplication.current
for app in apps where app != currentApplication {
app.terminate()
}
}
}
private func showAppAlreadyOpenMessage() {
showAlert(message: "An instance of Clocker is already open 😅",
informativeText: "This instance of Clocker will terminate now.",
buttonTitle: "Close")
}
private func showAlert(message: String, informativeText: String, buttonTitle: String) {
NSApplication.shared.activate(ignoringOtherApps: true)
let alert = NSAlert()
alert.messageText = message
alert.informativeText = informativeText
alert.addButton(withTitle: buttonTitle)
alert.runModal()
}
private func fetchLocalTimezone() {
let identifier = TimeZone.autoupdatingCurrent.identifier
let currentTimezone = TimezoneData()
currentTimezone.timezoneID = identifier
currentTimezone.setLabel(identifier)
currentTimezone.formattedAddress = identifier
currentTimezone.isSystemTimezone = true
currentTimezone.placeID = "Home"
let operations = TimezoneDataOperations(with: currentTimezone)
operations.saveObject(at: 0)
// Retrieve Location
// retrieveLatestLocation()
}
@IBAction func ping(_ sender: Any) {
togglePanel(sender)
}
private func retrieveLatestLocation() {
let locationController = LocationController.sharedController()
locationController.determineAndRequestLocationAuthorization()
}
private func showFloatingWindow() {
// Display the Floating Window!
floatingWindow.showWindow(nil)
floatingWindow.updateTableContent()
floatingWindow.startWindowTimer()
NSApp.activate(ignoringOtherApps: true)
}
private func assignShortcut() {
NSUserDefaultsController.shared.addObserver(self,
forKeyPath: "values.globalPing",
options: [.initial, .new],
context: nil)
}
private func checkIfRunFromApplicationsFolder() {
if let shortCircuit = UserDefaults.standard.object(forKey: "AllowOutsideApplicationsFolder") as? Bool, shortCircuit == true {
return
}
let bundlePath = Bundle.main.bundlePath
let applicationDirectory = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.applicationDirectory,
FileManager.SearchPathDomainMask.localDomainMask,
true)
for appDir in applicationDirectory {
if bundlePath.hasPrefix(appDir) {
return
}
}
// Clocker is installed out of Applications directory
// This breaks start at login! Time to show an alert and terminate
showAlert(message: "Move Clocker to the Applications folder",
informativeText: "Clocker must be run from the Applications folder in order to work properly.\n\nPlease quit Clocker, move it to the Applications folder, and relaunch. Current folder: \(applicationDirectory)",
buttonTitle: "Quit")
// Terminate
NSApp.terminate(nil)
}
@IBAction open func togglePanel(_ sender: Any) {
let displayMode = UserDefaults.standard.integer(forKey: CLShowAppInForeground)
if displayMode == 1 {
floatingWindow.showWindow(nil)
floatingWindow.updateTableContent()
floatingWindow.startWindowTimer()
} else {
panelController.showWindow(nil)
panelController.setActivePanel(newValue: !panelController.hasActivePanelGetter())
}
NSApp.activate(ignoringOtherApps: true)
}
open func setupFloatingWindow() {
showFloatingWindow()
}
open func closeFloatingWindow() {
floatingWindow.window?.close()
}
func statusItemForPanel() -> StatusItemHandler {
return statusBarHandler
}
open func setPanelDefaults() {
panelController.updateDefaultPreferences()
}
open func setupMenubarTimer() {
statusBarHandler.setupStatusItem()
}
open func invalidateMenubarTimer(_ showIcon: Bool) {
statusBarHandler.invalidateTimer(showIcon: showIcon, isSyncing: true)
}
}

14
Clocker/Clocker-Bridging-Header.h

@ -0,0 +1,14 @@
//
// Clocker-Bridging-Header.h
// Clocker
//
// Created by Banthia, Abhishek on 12/22/17.
//
#import "CLTimezoneData.h"
#import "iVersion.h"
#import <ShortcutRecorder/ShortcutRecorder.h>
#import <PTHotKey/PTHotKeyCenter.h>
#import <PTHotKey/PTHotKey+ShortcutRecorder.h>
#import <Fabric/Fabric.h>
#import <Crashlytics/Crashlytics.h>

1924
Clocker/Clocker.xcodeproj/project.pbxproj

File diff suppressed because it is too large Load Diff

7
Clocker/Clocker.xcodeproj/project.xcworkspace/contents.xcworkspacedata generated

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:/Users/abhishekbanthia/Downloads/Popup-master/Clocker.xcodeproj">
</FileRef>
</Workspace>

30
Clocker/Clocker.xcodeproj/project.xcworkspace/xcshareddata/Clocker.xcscmblueprint

@ -0,0 +1,30 @@
{
"DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "79BC31FA35C73FAE9D63749994DC7D1D9E35A66B",
"DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
},
"DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
"79BC31FA35C73FAE9D63749994DC7D1D9E35A66B" : 0,
"F2FE0AAE95F0B87896F2BEE0B176D4FC32D691A3" : 0
},
"DVTSourceControlWorkspaceBlueprintIdentifierKey" : "FE3C46F0-59C9-4F38-8281-63F46BD16224",
"DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
"79BC31FA35C73FAE9D63749994DC7D1D9E35A66B" : "Clocker\/",
"F2FE0AAE95F0B87896F2BEE0B176D4FC32D691A3" : "Clocker\/Clocker\/pop\/"
},
"DVTSourceControlWorkspaceBlueprintNameKey" : "Clocker",
"DVTSourceControlWorkspaceBlueprintVersion" : 204,
"DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Clocker.xcodeproj",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/Abhishaker17\/Clocker.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "79BC31FA35C73FAE9D63749994DC7D1D9E35A66B"
},
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/facebook\/pop.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "F2FE0AAE95F0B87896F2BEE0B176D4FC32D691A3"
}
]
}

8
Clocker/Clocker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

8
Clocker/Clocker.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildSystemType</key>
<string>Latest</string>
</dict>
</plist>

18
Clocker/Clocker.xcodeproj/project.xcworkspace/xcuserdata/abhishek_banthia.xcuserdatad/WorkspaceSettings.xcsettings

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildLocationStyle</key>
<string>UseAppPreferences</string>
<key>CustomBuildLocationType</key>
<string>RelativeToDerivedData</string>
<key>DerivedDataLocationStyle</key>
<string>Default</string>
<key>EnabledFullIndexStoreVisibility</key>
<false/>
<key>IssueFilterStyle</key>
<string>ShowActiveSchemeOnly</string>
<key>LiveSourceIssuesEnabled</key>
<true/>
</dict>
</plist>

5
Clocker/Clocker.xcodeproj/project.xcworkspace/xcuserdata/abhishekbanthia.xcuserdatad/IDEFindNavigatorScopes.plist

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array/>
</plist>

5
Clocker/Clocker.xcodeproj/project.xcworkspace/xcuserdata/ban.xcuserdatad/IDEFindNavigatorScopes.plist

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array/>
</plist>

8
Clocker/Clocker.xcodeproj/xcshareddata/IDETemplateMacros.plist

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>FILEHEADER</key>
<string> Copyright © 2015 Abhishek Banthia</string>
</dict>
</plist>

135
Clocker/Clocker.xcodeproj/xcshareddata/xcschemes/Clocker.xcscheme

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
codeCoverageEnabled = "YES"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9AC5EE2C1EDA17E400B4CE7B"
BuildableName = "ClockerTests.xctest"
BlueprintName = "ClockerTests"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C2BFE3E22049F82300825BE5"
BuildableName = "ClockerUITests.xctest"
BlueprintName = "ClockerUITests"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C20839C621515C1E00C86589"
BuildableName = "ClockerUnitTests.xctest"
BlueprintName = "ClockerUnitTests"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
region = "PH"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES"
showNonLocalizedStrings = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<EnvironmentVariables>
<EnvironmentVariable
key = "OS_ACTIVITY_MODE"
value = "disable"
isEnabled = "NO">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
</AdditionalOptions>
<LocationScenarioReference
identifier = "com.apple.dt.IDEFoundation.CurrentLocationScenarioIdentifier"
referenceType = "1">
</LocationScenarioReference>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

101
Clocker/Clocker.xcodeproj/xcshareddata/xcschemes/Tests.xcscheme

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C20839C621515C1E00C86589"
BuildableName = "ClockerUnitTests.xctest"
BlueprintName = "ClockerUnitTests"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

152
Clocker/Clocker.xcodeproj/xcuserdata/abhishek_banthia.xcuserdatad/xcschemes/Clocker.xcscheme

@ -0,0 +1,152 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
codeCoverageEnabled = "YES"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9AC5EE2C1EDA17E400B4CE7B"
BuildableName = "ClockerTests.xctest"
BlueprintName = "ClockerTests"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C2BFE3E22049F82300825BE5"
BuildableName = "ClockerUITests.xctest"
BlueprintName = "ClockerUITests"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "C25C2C7B20D18D6400BC9C81"
BuildableName = "ClockerUnitTests.xctest"
BlueprintName = "ClockerUnitTests"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
<AdditionalOption
key = "MallocStackLogging"
value = ""
isEnabled = "YES">
</AdditionalOption>
<AdditionalOption
key = "DYLD_INSERT_LIBRARIES"
value = "/usr/lib/libgmalloc.dylib"
isEnabled = "YES">
</AdditionalOption>
<AdditionalOption
key = "PrefersMallocStackLoggingLite"
value = ""
isEnabled = "YES">
</AdditionalOption>
<AdditionalOption
key = "NSZombieEnabled"
value = "YES"
isEnabled = "YES">
</AdditionalOption>
<AdditionalOption
key = "MallocGuardEdges"
value = ""
isEnabled = "YES">
</AdditionalOption>
<AdditionalOption
key = "MallocScribble"
value = ""
isEnabled = "YES">
</AdditionalOption>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DD4F7C0313C30F9F00825C6E"
BuildableName = "Clocker.app"
BlueprintName = "Clocker"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

91
Clocker/Clocker.xcodeproj/xcuserdata/abhishek_banthia.xcuserdatad/xcschemes/ClockerHelper.xcscheme

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0930"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9A7547CF1F184DC3004705EF"
BuildableName = "ClockerHelper.app"
BlueprintName = "ClockerHelper"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9A7547CF1F184DC3004705EF"
BuildableName = "ClockerHelper.app"
BlueprintName = "ClockerHelper"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9A7547CF1F184DC3004705EF"
BuildableName = "ClockerHelper.app"
BlueprintName = "ClockerHelper"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9A7547CF1F184DC3004705EF"
BuildableName = "ClockerHelper.app"
BlueprintName = "ClockerHelper"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

47
Clocker/Clocker.xcodeproj/xcuserdata/abhishek_banthia.xcuserdatad/xcschemes/xcschememanagement.plist

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Clocker.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>Clocker.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>4</integer>
</dict>
<key>ClockerHelper.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>2</integer>
</dict>
<key>ClockerUnitTest.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>6</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>9A7547CF1F184DC3004705EF</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>9AC5EE2C1EDA17E400B4CE7B</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>DD4F7C0313C30F9F00825C6E</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

17
Clocker/Clocker.xcodeproj/xcuserdata/abhishekbanthia.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
type = "1"
version = "2.0">
<Breakpoints>
<BreakpointProxy
BreakpointExtensionID = "Xcode.Breakpoint.ExceptionBreakpoint">
<BreakpointContent
shouldBeEnabled = "Yes"
ignoreCount = "0"
continueAfterRunningActions = "No"
scope = "1"
stopOnStyle = "0">
</BreakpointContent>
</BreakpointProxy>
</Breakpoints>
</Bucket>

101
Clocker/Clocker.xcodeproj/xcuserdata/abhishekbanthia.xcuserdatad/xcschemes/ClockerHelper.xcscheme

@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9A7547CF1F184DC3004705EF"
BuildableName = "ClockerHelper.app"
BlueprintName = "ClockerHelper"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9A7547AA1F1834D9004705EF"
BuildableName = "ClockerHelperTests.xctest"
BlueprintName = "ClockerHelperTests"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9A7547CF1F184DC3004705EF"
BuildableName = "ClockerHelper.app"
BlueprintName = "ClockerHelper"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9A7547CF1F184DC3004705EF"
BuildableName = "ClockerHelper.app"
BlueprintName = "ClockerHelper"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "9A7547CF1F184DC3004705EF"
BuildableName = "ClockerHelper.app"
BlueprintName = "ClockerHelper"
ReferencedContainer = "container:Clocker.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

47
Clocker/Clocker.xcodeproj/xcuserdata/abhishekbanthia.xcuserdatad/xcschemes/xcschememanagement.plist

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Clocker.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>ClockerHelper.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>3</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>9A7547951F1834D9004705EF</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>9A7547AA1F1834D9004705EF</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>9A7547CF1F184DC3004705EF</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>9AC5EE2C1EDA17E400B4CE7B</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>DD4F7C0313C30F9F00825C6E</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

32
Clocker/Clocker.xcodeproj/xcuserdata/ban.xcuserdatad/xcschemes/xcschememanagement.plist

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SchemeUserState</key>
<dict>
<key>Clocker.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>0</integer>
</dict>
<key>ClockerHelper.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>4</integer>
</dict>
<key>Tests.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>3</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>DD4F7C0313C30F9F00825C6E</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>

65
Clocker/Clocker/Clocker-Info.plist

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.6.09</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>64</string>
<key>Fabric</key>
<dict>
<key>APIKey</key>
<string>94088f95c41979e8019b67d5795f52bbbe7104d4</string>
<key>Kits</key>
<array>
<dict>
<key>KitInfo</key>
<dict/>
<key>KitName</key>
<string>Crashlytics</string>
</dict>
</array>
</dict>
<key>LSApplicationCategoryType</key>
<string>public.app-category.utilities</string>
<key>LSMinimumSystemVersion</key>
<string>${MACOSX_DEPLOYMENT_TARGET}</string>
<key>LSUIElement</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSCalendarsUsageDescription</key>
<string>Clocker can be more useful when it can display upcoming events from your calendars. You can change this setting in System Preferences › Security &amp; Privacy › Privacy</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2016, Abhishek Banthia</string>
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Clocker can be more useful when it can use your location to determine your current timezone.</string>
<key>NSLocationUsageDescription</key>
<string>Clocker can be more useful when it can use your location to determine your current timezone.</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSRemindersUsageDescription</key>
<string>Clocker can be more useful when it can set reminders for your selected timezone(s). You can change this setting in System Preferences › Security &amp; Privacy › Privacy.</string>
<key>NSSupportsAutomaticGraphicsSwitching</key>
<true/>
<key>RequestsOpenAccess</key>
<string>YES</string>
</dict>
</plist>

9
Clocker/Clocker/Clocker-Prefix.pch

@ -0,0 +1,9 @@
//
// Prefix header for all source files of the 'Clocker' target in the 'Clocker' project
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif

16
Clocker/Clocker/Clocker.entitlements

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.personal-information.calendars</key>
<true/>
<key>com.apple.security.temporary-exception.apple-events</key>
<array>
<string>com.apple.reminders</string>
</array>
</dict>
</plist>

BIN
Clocker/Clocker/Images/ClockHands.gif

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
Clocker/Clocker/Images/ClockerIcon-16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
Clocker/Clocker/Images/ClockerIcon-256.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

BIN
Clocker/Clocker/Images/FB-FindUsonFacebook-online-144.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
Clocker/Clocker/Images/MacAppStore.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
Clocker/Clocker/Images/MenuBar.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
Clocker/Clocker/Images/PowerIcon 2.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
Clocker/Clocker/Images/PowerIcon-White.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
Clocker/Clocker/Images/PowerIcon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
Clocker/Clocker/Images/Settings-White.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

BIN
Clocker/Clocker/Images/Status.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
Clocker/Clocker/Images/Status@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
Clocker/Clocker/Images/StatusHighlighted.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 389 B

BIN
Clocker/Clocker/Images/StatusHighlighted@2x.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
Clocker/Clocker/Images/Sunrise-512x512.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
Clocker/Clocker/Images/Untitled.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 249 B

BIN
Clocker/Clocker/Images/White Sunset.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
Clocker/Clocker/Images/WhiteButton.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
Clocker/Clocker/Images/WhiteSunrise.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
Clocker/Clocker/Images/aboutTemplate.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 627 B

BIN
Clocker/Clocker/Images/index.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
Clocker/Clocker/Images/sunset-512.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

119
Clocker/Clocker/LocationController.swift

@ -0,0 +1,119 @@
// Copyright © 2015 Abhishek Banthia
import Cocoa
import CoreLocation
class LocationController: NSObject {
public static let sharedInstance = LocationController()
private var locationManager: CLLocationManager = {
let l = CLLocationManager()
l.desiredAccuracy = kCLLocationAccuracyThreeKilometers
return l
}()
@objc class func sharedController() -> LocationController {
return sharedInstance
}
func authorizationStatus() -> CLAuthorizationStatus {
return CLLocationManager.authorizationStatus()
}
@objc func locationAccessNotDetermined() -> Bool {
return CLLocationManager.authorizationStatus() == .notDetermined
}
@objc func locationAccessGranted() -> Bool {
return CLLocationManager.authorizationStatus() == .authorizedAlways || CLLocationManager.authorizationStatus() == .authorized
}
@objc func locationAccessDenied() -> Bool {
return CLLocationManager.authorizationStatus() == .restricted || CLLocationManager.authorizationStatus() == .denied
}
@objc func setDelegate() {
locationManager.delegate = self
}
@objc func determineAndRequestLocationAuthorization() {
setDelegate()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
}
switch authorizationStatus() {
case .authorizedAlways:
locationManager.startUpdatingLocation()
case .notDetermined:
locationManager.startUpdatingLocation()
case .denied, .restricted:
locationManager.startUpdatingLocation()
default:
fatalError("Unexpected Authorization Status")
}
}
private func updateHomeObject(with customLabel: String, coordinates: CLLocationCoordinate2D?) {
let timezones = DataStore.shared().timezones()
var timezoneObjects: [TimezoneData] = []
for timezone in timezones {
if let model = TimezoneData.customObject(from: timezone) {
timezoneObjects.append(model)
}
}
for timezoneObject in timezoneObjects {
if timezoneObject.isSystemTimezone == true {
timezoneObject.setLabel(customLabel)
if let latlong = coordinates {
timezoneObject.longitude = latlong.longitude
timezoneObject.latitude = latlong.latitude
}
}
}
var datas: [Data] = []
for updatedObject in timezoneObjects {
let dataObject = NSKeyedArchiver.archivedData(withRootObject: updatedObject)
datas.append(dataObject)
}
DataStore.shared().setTimezones(datas)
}
}
extension LocationController: CLLocationManagerDelegate {
func locationManager(_: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard locations.count > 0, let coordinates = locations.first?.coordinate else { return }
let reverseGeoCoder = CLGeocoder()
reverseGeoCoder.reverseGeocodeLocation(locations[0]) { placemarks, _ in
guard let customLabel = placemarks?.first?.locality else { return }
self.updateHomeObject(with: customLabel, coordinates: coordinates)
self.locationManager.stopUpdatingLocation()
}
}
func locationManager(_: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .denied || status == .restricted {
updateHomeObject(with: TimeZone.autoupdatingCurrent.identifier, coordinates: nil)
locationManager.stopUpdatingLocation()
} else if status == .notDetermined || status == .authorized || status == .authorizedAlways {
locationManager.startUpdatingLocation()
}
}
func locationManager(_: CLLocationManager, didFailWithError error: Error) {
print(error)
}
}

361
Clocker/Clocker/MainMenu.xib

@ -0,0 +1,361 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14313.18" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14313.18"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="494" id="495"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<menu title="AMainMenu" systemMenu="main" id="29">
<items>
<menuItem title="Clocker" id="56">
<menu key="submenu" title="Clocker" systemMenu="apple" id="57">
<items>
<menuItem title="About Clocker" id="58">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontStandardAboutPanel:" target="-2" id="142"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="236">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Preferences…" keyEquivalent="," id="129"/>
<menuItem isSeparatorItem="YES" id="143">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Services" id="131">
<menu key="submenu" title="Services" systemMenu="services" id="130"/>
</menuItem>
<menuItem isSeparatorItem="YES" id="144">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Hide Clocker" keyEquivalent="h" id="134">
<connections>
<action selector="hide:" target="-1" id="367"/>
</connections>
</menuItem>
<menuItem title="Hide Others" keyEquivalent="h" id="145">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="hideOtherApplications:" target="-1" id="368"/>
</connections>
</menuItem>
<menuItem title="Show All" id="150">
<connections>
<action selector="unhideAllApplications:" target="-1" id="370"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="149">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Quit Clocker" keyEquivalent="q" id="136">
<connections>
<action selector="terminate:" target="-3" id="449"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="File" id="83">
<menu key="submenu" title="File" id="81">
<items>
<menuItem title="New" keyEquivalent="n" id="82">
<connections>
<action selector="newDocument:" target="-1" id="373"/>
</connections>
</menuItem>
<menuItem title="Open…" keyEquivalent="o" id="72">
<connections>
<action selector="openDocument:" target="-1" id="374"/>
</connections>
</menuItem>
<menuItem title="Open Recent" id="124">
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="125">
<items>
<menuItem title="Clear Menu" id="126">
<connections>
<action selector="clearRecentDocuments:" target="-1" id="127"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem isSeparatorItem="YES" id="79">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Close" keyEquivalent="w" id="73">
<connections>
<action selector="performClose:" target="-1" id="193"/>
</connections>
</menuItem>
<menuItem title="Save…" keyEquivalent="s" id="75">
<connections>
<action selector="saveDocument:" target="-1" id="362"/>
</connections>
</menuItem>
<menuItem title="Revert to Saved" id="112">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="revertDocumentToSaved:" target="-1" id="364"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="74">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Page Setup..." keyEquivalent="P" id="77">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="runPageLayout:" target="-1" id="87"/>
</connections>
</menuItem>
<menuItem title="Print…" keyEquivalent="p" id="78">
<connections>
<action selector="print:" target="-1" id="86"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Edit" id="217">
<menu key="submenu" title="Edit" id="205">
<items>
<menuItem title="Undo" keyEquivalent="z" id="207">
<connections>
<action selector="undo:" target="-1" id="223"/>
</connections>
</menuItem>
<menuItem title="Redo" keyEquivalent="Z" id="215">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="redo:" target="-1" id="231"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="206">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Cut" keyEquivalent="x" id="199">
<connections>
<action selector="cut:" target="-1" id="228"/>
</connections>
</menuItem>
<menuItem title="Copy" keyEquivalent="c" id="197">
<connections>
<action selector="copy:" target="-1" id="224"/>
</connections>
</menuItem>
<menuItem title="Paste" keyEquivalent="v" id="203">
<connections>
<action selector="paste:" target="-1" id="226"/>
</connections>
</menuItem>
<menuItem title="Paste and Match Style" keyEquivalent="v" id="485">
<connections>
<action selector="pasteAsPlainText:" target="-1" id="486"/>
</connections>
</menuItem>
<menuItem title="Delete" id="202">
<connections>
<action selector="delete:" target="-1" id="235"/>
</connections>
</menuItem>
<menuItem title="Select All" keyEquivalent="a" id="198">
<connections>
<action selector="selectAll:" target="-1" id="232"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="214">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Find" id="218">
<menu key="submenu" title="Find" id="220">
<items>
<menuItem title="Find…" tag="1" keyEquivalent="f" id="209">
<connections>
<action selector="performFindPanelAction:" target="-1" id="241"/>
</connections>
</menuItem>
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="534">
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
<connections>
<action selector="performFindPanelAction:" target="-1" id="535"/>
</connections>
</menuItem>
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="208">
<connections>
<action selector="performFindPanelAction:" target="-1" id="487"/>
</connections>
</menuItem>
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="213">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="performFindPanelAction:" target="-1" id="488"/>
</connections>
</menuItem>
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="221">
<connections>
<action selector="performFindPanelAction:" target="-1" id="489"/>
</connections>
</menuItem>
<menuItem title="Jump to Selection" keyEquivalent="j" id="210">
<connections>
<action selector="centerSelectionInVisibleArea:" target="-1" id="245"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Spelling and Grammar" id="216">
<menu key="submenu" title="Spelling and Grammar" id="200">
<items>
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="204">
<connections>
<action selector="showGuessPanel:" target="-1" id="230"/>
</connections>
</menuItem>
<menuItem title="Check Document Now" keyEquivalent=";" id="201">
<connections>
<action selector="checkSpelling:" target="-1" id="225"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="453"/>
<menuItem title="Check Spelling While Typing" id="219">
<connections>
<action selector="toggleContinuousSpellChecking:" target="-1" id="222"/>
</connections>
</menuItem>
<menuItem title="Check Grammar With Spelling" id="346">
<connections>
<action selector="toggleGrammarChecking:" target="-1" id="347"/>
</connections>
</menuItem>
<menuItem title="Correct Spelling Automatically" id="454">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticSpellingCorrection:" target="-1" id="456"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Substitutions" id="348">
<menu key="submenu" title="Substitutions" id="349">
<items>
<menuItem title="Show Substitutions" id="457">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="orderFrontSubstitutionsPanel:" target="-1" id="458"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="459"/>
<menuItem title="Smart Copy/Paste" tag="1" keyEquivalent="f" id="350">
<connections>
<action selector="toggleSmartInsertDelete:" target="-1" id="355"/>
</connections>
</menuItem>
<menuItem title="Smart Quotes" tag="2" keyEquivalent="g" id="351">
<connections>
<action selector="toggleAutomaticQuoteSubstitution:" target="-1" id="356"/>
</connections>
</menuItem>
<menuItem title="Smart Dashes" id="460">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticDashSubstitution:" target="-1" id="461"/>
</connections>
</menuItem>
<menuItem title="Smart Links" tag="3" keyEquivalent="G" id="354">
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
<connections>
<action selector="toggleAutomaticLinkDetection:" target="-1" id="357"/>
</connections>
</menuItem>
<menuItem title="Text Replacement" id="462">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="toggleAutomaticTextReplacement:" target="-1" id="463"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Transformations" id="450">
<modifierMask key="keyEquivalentModifierMask"/>
<menu key="submenu" title="Transformations" id="451">
<items>
<menuItem title="Make Upper Case" id="452">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="uppercaseWord:" target="-1" id="464"/>
</connections>
</menuItem>
<menuItem title="Make Lower Case" id="465">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="lowercaseWord:" target="-1" id="468"/>
</connections>
</menuItem>
<menuItem title="Capitalize" id="466">
<modifierMask key="keyEquivalentModifierMask"/>
<connections>
<action selector="capitalizeWord:" target="-1" id="467"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Speech" id="211">
<menu key="submenu" title="Speech" id="212">
<items>
<menuItem title="Start Speaking" id="196">
<connections>
<action selector="startSpeaking:" target="-1" id="233"/>
</connections>
</menuItem>
<menuItem title="Stop Speaking" id="195">
<connections>
<action selector="stopSpeaking:" target="-1" id="227"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
</menuItem>
<menuItem title="Window" id="19">
<menu key="submenu" title="Window" systemMenu="window" id="24">
<items>
<menuItem title="Minimize" keyEquivalent="m" id="23">
<connections>
<action selector="performMiniaturize:" target="-1" id="37"/>
</connections>
</menuItem>
<menuItem title="Zoom" id="239">
<connections>
<action selector="performZoom:" target="-1" id="240"/>
</connections>
</menuItem>
<menuItem isSeparatorItem="YES" id="92">
<modifierMask key="keyEquivalentModifierMask" command="YES"/>
</menuItem>
<menuItem title="Bring All to Front" id="5">
<connections>
<action selector="arrangeInFront:" target="-1" id="39"/>
</connections>
</menuItem>
</items>
</menu>
</menuItem>
</items>
</menu>
<customObject id="494" customClass="AppDelegate" customModule="Clocker" customModuleProvider="target"/>
<customObject id="420" customClass="NSFontManager"/>
</objects>
</document>

18
Clocker/Clocker/ShortcutRecorder-master/.gitignore vendored

@ -0,0 +1,18 @@
# Xcode
build/*
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
*.xcworkspace
!default.xcworkspace
xcuserdata
profile
*.moved-aside
## Ignore incredibly annoying .DS_Store files
.DS_Store

31
Clocker/Clocker/ShortcutRecorder-master/LICENSE.md

@ -0,0 +1,31 @@
# ShortcutRecorder
Copyright (c) 2006, Contributors
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the organization nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# PTHotKey
Copyright (c) 2003 Quentin D. Carnicelli.
All rights reserved.

22
Clocker/Clocker/ShortcutRecorder-master/Library/Info.plist

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>ShortcutRecorder</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>2.17</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>2.17</string>
</dict>
</plist>

5
Clocker/Clocker/ShortcutRecorder-master/Library/Prefix.pch

@ -0,0 +1,5 @@
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
#endif

116
Clocker/Clocker/ShortcutRecorder-master/Library/SRCommon.h

@ -0,0 +1,116 @@
//
// SRCommon.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Andy Kim
// Ilya Kulakov
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
/*!
Mask representing subset of Cocoa modifier flags suitable for shortcuts.
*/
static const NSEventModifierFlags SRCocoaModifierFlagsMask = NSEventModifierFlagCommand | NSEventModifierFlagOption | NSEventModifierFlagShift | NSEventModifierFlagControl;
/*!
Mask representing subset of Carbon modifier flags suitable for shortcuts.
*/
static const NSUInteger SRCarbonModifierFlagsMask = cmdKey | optionKey | shiftKey | controlKey;
/*!
Converts carbon modifier flags to cocoa.
*/
FOUNDATION_STATIC_INLINE NSEventModifierFlags SRCarbonToCocoaFlags(UInt32 aCarbonFlags)
{
NSEventModifierFlags cocoaFlags = 0;
if (aCarbonFlags & cmdKey)
cocoaFlags |= NSEventModifierFlagCommand;
if (aCarbonFlags & optionKey)
cocoaFlags |= NSEventModifierFlagOption;
if (aCarbonFlags & controlKey)
cocoaFlags |= NSEventModifierFlagControl;
if (aCarbonFlags & shiftKey)
cocoaFlags |= NSEventModifierFlagShift;
return cocoaFlags;
}
/*!
Converts cocoa modifier flags to carbon.
*/
FOUNDATION_STATIC_INLINE UInt32 SRCocoaToCarbonFlags(NSEventModifierFlags aCocoaFlags)
{
UInt32 carbonFlags = 0;
if (aCocoaFlags & NSEventModifierFlagCommand)
carbonFlags |= cmdKey;
if (aCocoaFlags & NSEventModifierFlagOption)
carbonFlags |= optionKey;
if (aCocoaFlags & NSEventModifierFlagControl)
carbonFlags |= controlKey;
if (aCocoaFlags & NSEventModifierFlagShift)
carbonFlags |= shiftKey;
return carbonFlags;
}
/*!
Return Bundle where resources can be found.
@discussion Throws NSInternalInconsistencyException if bundle cannot be found.
*/
NSBundle *SRBundle(void);
/*!
Convenient method to get localized string from the framework bundle.
*/
NSString *SRLoc(NSString *aKey);
/*!
Convenient method to get image from the framework bundle.
*/
NSImage *SRImage(NSString *anImageName);
/*!
Returns string representation of shortcut with modifier flags replaced with their localized
readable equivalents (e.g. ? -> Option).
*/
NSString *SRReadableStringForCocoaModifierFlagsAndKeyCode(NSEventModifierFlags aModifierFlags, unsigned short aKeyCode);
/*!
Returns string representation of shortcut with modifier flags replaced with their localized
readable equivalents (e.g. ? -> Option) and ASCII character for key code.
*/
NSString *SRReadableASCIIStringForCocoaModifierFlagsAndKeyCode(NSEventModifierFlags aModifierFlags, unsigned short aKeyCode);
/*!
Determines if given key code with flags is equal to key equivalent and flags
(usually taken from NSButton or NSMenu).
@discussion On Mac OS X some key combinations can have "alternates". E.g. option-A can be represented both as option-A and as Œ.
*/
BOOL SRKeyCodeWithFlagsEqualToKeyEquivalentWithFlags(unsigned short aKeyCode,
NSEventModifierFlags aKeyCodeFlags,
NSString *aKeyEquivalent,
NSEventModifierFlags aKeyEquivalentModifierFlags);

175
Clocker/Clocker/ShortcutRecorder-master/Library/SRCommon.m

@ -0,0 +1,175 @@
//
// SRCommon.m
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Andy Kim
// Ilya Kulakov
#import "SRCommon.h"
#import "SRKeyCodeTransformer.h"
NSBundle *SRBundle()
{
static dispatch_once_t onceToken;
static NSBundle *Bundle = nil;
dispatch_once(&onceToken, ^{
Bundle = [NSBundle bundleWithIdentifier:@"com.kulakov.ShortcutRecorder"];
if (!Bundle)
{
// Could be a CocoaPods framework with embedded resources bundle.
// Look up "use_frameworks!" and "resources_bundle" in CocoaPods documentation.
Bundle = [NSBundle bundleWithIdentifier:@"org.cocoapods.ShortcutRecorder"];
if (!Bundle)
{
Class c = NSClassFromString(@"SRRecorderControl");
if (c)
{
Bundle = [NSBundle bundleForClass:c];
}
}
if (Bundle)
{
Bundle = [NSBundle bundleWithPath:[Bundle pathForResource:@"ShortcutRecorder" ofType:@"bundle"]];
}
}
});
if (!Bundle)
{
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:@"Unable to find bundle with resources."
userInfo:nil];
}
else
{
return Bundle;
}
}
NSString *SRLoc(NSString *aKey)
{
return NSLocalizedStringFromTableInBundle(aKey, @"ShortcutRecorder", SRBundle(), nil);
}
NSImage *SRImage(NSString *anImageName)
{
if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_6)
return [[NSImage alloc] initByReferencingURL:[SRBundle() URLForImageResource:anImageName]];
else
return [SRBundle() imageForResource:anImageName];
}
NSString *SRReadableStringForCocoaModifierFlagsAndKeyCode(NSEventModifierFlags aModifierFlags, unsigned short aKeyCode)
{
SRKeyCodeTransformer *t = [SRKeyCodeTransformer sharedPlainTransformer];
NSString *c = [t transformedValue:@(aKeyCode)];
return [NSString stringWithFormat:@"%@%@%@%@%@",
(aModifierFlags & NSCommandKeyMask ? SRLoc(@"Command-") : @""),
(aModifierFlags & NSAlternateKeyMask ? SRLoc(@"Option-") : @""),
(aModifierFlags & NSControlKeyMask ? SRLoc(@"Control-") : @""),
(aModifierFlags & NSShiftKeyMask ? SRLoc(@"Shift-") : @""),
c];
}
NSString *SRReadableASCIIStringForCocoaModifierFlagsAndKeyCode(NSEventModifierFlags aModifierFlags, unsigned short aKeyCode)
{
SRKeyCodeTransformer *t = [SRKeyCodeTransformer sharedPlainASCIITransformer];
NSString *c = [t transformedValue:@(aKeyCode)];
return [NSString stringWithFormat:@"%@%@%@%@%@",
(aModifierFlags & NSCommandKeyMask ? SRLoc(@"Command-") : @""),
(aModifierFlags & NSAlternateKeyMask ? SRLoc(@"Option-") : @""),
(aModifierFlags & NSControlKeyMask ? SRLoc(@"Control-") : @""),
(aModifierFlags & NSShiftKeyMask ? SRLoc(@"Shift-") : @""),
c];
}
static BOOL _SRKeyCodeWithFlagsEqualToKeyEquivalentWithFlags(unsigned short aKeyCode,
NSEventModifierFlags aKeyCodeFlags,
NSString *aKeyEquivalent,
NSEventModifierFlags aKeyEquivalentModifierFlags,
SRKeyCodeTransformer *aTransformer)
{
if (!aKeyEquivalent)
return NO;
aKeyCodeFlags &= SRCocoaModifierFlagsMask;
aKeyEquivalentModifierFlags &= SRCocoaModifierFlagsMask;
if (aKeyCodeFlags == aKeyEquivalentModifierFlags)
{
NSString *keyCodeRepresentation = [aTransformer transformedValue:@(aKeyCode)
withImplicitModifierFlags:nil
explicitModifierFlags:@(aKeyCodeFlags)];
return [keyCodeRepresentation isEqual:aKeyEquivalent];
}
else if (!aKeyEquivalentModifierFlags ||
(aKeyCodeFlags & aKeyEquivalentModifierFlags) == aKeyEquivalentModifierFlags)
{
// Some key equivalent modifier flags can be implicitly set by using special unicode characters. E.g. Πinsetead of opt-a.
// However all modifier flags explictily set in key equivalent MUST be also set in key code flags.
// E.g. ctrl-Œ/ctrl-opt-a and Œ/opt-a match this condition, but cmd-Œ/ctrl-opt-a doesn't.
NSString *keyCodeRepresentation = [aTransformer transformedValue:@(aKeyCode)
withImplicitModifierFlags:nil
explicitModifierFlags:@(aKeyCodeFlags)];
if ([keyCodeRepresentation isEqual:aKeyEquivalent])
{
// Key code and key equivalent are not equal key code representation matches key equivalent, but modifier flags are not.
return NO;
}
else
{
NSEventModifierFlags possiblyImplicitFlags = aKeyCodeFlags & ~aKeyEquivalentModifierFlags;
keyCodeRepresentation = [aTransformer transformedValue:@(aKeyCode)
withImplicitModifierFlags:@(possiblyImplicitFlags)
explicitModifierFlags:@(aKeyEquivalentModifierFlags)];
return [keyCodeRepresentation isEqual:aKeyEquivalent];
}
}
else
return NO;
}
BOOL SRKeyCodeWithFlagsEqualToKeyEquivalentWithFlags(unsigned short aKeyCode,
NSEventModifierFlags aKeyCodeFlags,
NSString *aKeyEquivalent,
NSEventModifierFlags aKeyEquivalentModifierFlags)
{
BOOL isEqual = _SRKeyCodeWithFlagsEqualToKeyEquivalentWithFlags(aKeyCode,
aKeyCodeFlags,
aKeyEquivalent,
aKeyEquivalentModifierFlags,
[SRKeyCodeTransformer sharedASCIITransformer]);
if (!isEqual)
{
isEqual = _SRKeyCodeWithFlagsEqualToKeyEquivalentWithFlags(aKeyCode,
aKeyCodeFlags,
aKeyEquivalent,
aKeyEquivalentModifierFlags,
[SRKeyCodeTransformer sharedTransformer]);
}
return isEqual;
}

139
Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyCodeTransformer.h

@ -0,0 +1,139 @@
//
// SRKeyCodeTransformer.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Ilya Kulakov
// Silvio Rizzi
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
/*!
Transforms key code into unicode character or plain string.
*/
@interface SRKeyCodeTransformer : NSValueTransformer
/*!
Returns initialized key code transformer.
@param aUsesASCII Determines whether transformer uses only ASCII capable keyboard input source.
@param aUsesPlainStrings Determines whether key codes without readable glyphs (e.g. F1...F19) are transformed to
to unicode characters (NSF1FunctionKey...NSF19FunctionKey) suitable for setting key equivalents
of Cocoa controls or to plain strings (@"F1"...@"F19") suitable for drawing, logging and accessibility.
@discussion This method is the designated initializer for SRKeyCodeTransformer.
*/
- (instancetype)initWithASCIICapableKeyboardInputSource:(BOOL)aUsesASCII plainStrings:(BOOL)aUsesPlainStrings;
/*!
Determines whether transformer uses ASCII capable keyboard input source.
*/
@property (readonly) BOOL usesASCIICapableKeyboardInputSource;
/*!
Determines whether key codes without readable glyphs are transformed to unicode characters
suitable for setting keqEquivalents or to plain strings suitable for drawing, logging and accessibility.
*/
@property (readonly) BOOL usesPlainStrings;
/*!
Returns the shared transformer.
*/
+ (instancetype)sharedTransformer;
/*!
Returns the shared transformer configured to use only ASCII capable keyboard input source.
*/
+ (instancetype)sharedASCIITransformer;
/*!
Returns the shared transformer configured to transform key codes to plain strings.
*/
+ (SRKeyCodeTransformer *)sharedPlainTransformer;
/*!
Returns the shared transformer configured to use only ASCII capable keyboard input source
and to transform key codes to plain strings.
*/
+ (SRKeyCodeTransformer *)sharedPlainASCIITransformer;
/*!
Returns mapping from special key codes to unicode characters.
*/
+ (NSDictionary *)specialKeyCodesToUnicodeCharactersMapping;
/*!
Returns mapping from special key codes to plain strings.
*/
+ (NSDictionary *)specialKeyCodesToPlainStringsMapping;
/*!
Determines whether key code is special.
@param aKeyCode Key code to be checked.
*/
- (BOOL)isKeyCodeSpecial:(unsigned short)aKeyCode;
/*!
Transforms given special key code into unicode character by taking into account modifier flags.
@discussion E.g. the key code 0x30 is transformed to . But if shift is pressed, it is transformed to .
@result Unicode character or plain string. nil if not a special key code.
*/
- (NSString *)transformedSpecialKeyCode:(NSNumber *)aKeyCode withExplicitModifierFlags:(NSNumber *)aModifierFlags;
/*!
Shorcut to [self transformedValue:aValue withImplicitModifierFlags:aModifierFlags explicitModifierFlags:0]
*/
- (NSString *)transformedValue:(NSNumber *)aValue withModifierFlags:(NSNumber *)aModifierFlags;
/*!
Transfroms given key code into unicode character by taking into account modifier flags.
@param aValue An instance of NSNumber (unsigned short) that represents key code.
@param anImplicitModifierFlags An instance of NSNumber (NSEventModifierFlags) that represents implicit modifier flags like opt in å.
@param anExplicitModifierFlags An instance of NSNumber (NSEventModifierFlags) that represents explicit modifier flags like shift in shift-.
*/
- (NSString *)transformedValue:(NSNumber *)aValue withImplicitModifierFlags:(NSNumber *)anImplicitModifierFlags explicitModifierFlags:(NSNumber *)anExplicitModifierFlags;
@end
/*!
These constants represents drawable unicode characters for key codes that do not have
appropriate constants in Carbon and Cocoa.
*/
typedef NS_ENUM(unichar, SRKeyCodeGlyph)
{
SRKeyCodeGlyphTabRight = 0x21E5, // ⇥
SRKeyCodeGlyphTabLeft = 0x21E4, // ⇤
SRKeyCodeGlyphReturn = 0x2305, // ⌅
SRKeyCodeGlyphReturnR2L = 0x21A9, // ↩
SRKeyCodeGlyphDeleteLeft = 0x232B, // ⌫
SRKeyCodeGlyphDeleteRight = 0x2326, // ⌦
SRKeyCodeGlyphPadClear = 0x2327, // ⌧
SRKeyCodeGlyphLeftArrow = 0x2190, // ←
SRKeyCodeGlyphRightArrow = 0x2192, // →
SRKeyCodeGlyphUpArrow = 0x2191, // ↑
SRKeyCodeGlyphDownArrow = 0x2193, // ↓
SRKeyCodeGlyphPageDown = 0x21DF, // ⇟
SRKeyCodeGlyphPageUp = 0x21DE, // ⇞
SRKeyCodeGlyphNorthwestArrow = 0x2196, // ↖
SRKeyCodeGlyphSoutheastArrow = 0x2198, // ↘
SRKeyCodeGlyphEscape = 0x238B, // ⎋
SRKeyCodeGlyphSpace = 0x0020, // ' '
};

357
Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyCodeTransformer.m

@ -0,0 +1,357 @@
//
// SRKeyCodeTransformer.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Ilya Kulakov
// Silvio Rizzi
#import "SRKeyCodeTransformer.h"
#import "SRCommon.h"
FOUNDATION_STATIC_INLINE NSString* _SRUnicharToString(unichar aChar)
{
return [NSString stringWithFormat: @"%C", aChar];
}
@implementation SRKeyCodeTransformer
- (instancetype)initWithASCIICapableKeyboardInputSource:(BOOL)aUsesASCII plainStrings:(BOOL)aUsesPlainStrings
{
self = [super init];
if (self)
{
_usesASCIICapableKeyboardInputSource = aUsesASCII;
_usesPlainStrings = aUsesPlainStrings;
}
return self;
}
- (instancetype)init
{
return [self initWithASCIICapableKeyboardInputSource:NO plainStrings:NO];
}
#pragma mark Methods
+ (instancetype)sharedTransformer
{
static dispatch_once_t OnceToken;
static SRKeyCodeTransformer *Transformer = nil;
dispatch_once(&OnceToken, ^{
Transformer = [[self alloc] initWithASCIICapableKeyboardInputSource:NO
plainStrings:NO];
});
return Transformer;
}
+ (instancetype)sharedASCIITransformer
{
static dispatch_once_t OnceToken;
static SRKeyCodeTransformer *Transformer = nil;
dispatch_once(&OnceToken, ^{
Transformer = [[self alloc] initWithASCIICapableKeyboardInputSource:YES
plainStrings:NO];
});
return Transformer;
}
+ (instancetype)sharedPlainTransformer
{
static dispatch_once_t OnceToken;
static SRKeyCodeTransformer *Transformer = nil;
dispatch_once(&OnceToken, ^{
Transformer = [[self alloc] initWithASCIICapableKeyboardInputSource:NO
plainStrings:YES];
});
return Transformer;
}
+ (SRKeyCodeTransformer *)sharedPlainASCIITransformer
{
static dispatch_once_t OnceToken;
static SRKeyCodeTransformer *Transformer = nil;
dispatch_once(&OnceToken, ^{
Transformer = [[self alloc] initWithASCIICapableKeyboardInputSource:YES
plainStrings:YES];
});
return Transformer;
}
+ (NSDictionary *)specialKeyCodesToUnicodeCharactersMapping
{
// Most of these keys are system constans.
// Values for rest of the keys were given by setting key equivalents in IB.
static dispatch_once_t OnceToken;
static NSDictionary *Mapping = nil;
dispatch_once(&OnceToken, ^{
Mapping = @{
@(kVK_F1): _SRUnicharToString(NSF1FunctionKey),
@(kVK_F2): _SRUnicharToString(NSF2FunctionKey),
@(kVK_F3): _SRUnicharToString(NSF3FunctionKey),
@(kVK_F4): _SRUnicharToString(NSF4FunctionKey),
@(kVK_F5): _SRUnicharToString(NSF5FunctionKey),
@(kVK_F6): _SRUnicharToString(NSF6FunctionKey),
@(kVK_F7): _SRUnicharToString(NSF7FunctionKey),
@(kVK_F8): _SRUnicharToString(NSF8FunctionKey),
@(kVK_F9): _SRUnicharToString(NSF9FunctionKey),
@(kVK_F10): _SRUnicharToString(NSF10FunctionKey),
@(kVK_F11): _SRUnicharToString(NSF11FunctionKey),
@(kVK_F12): _SRUnicharToString(NSF12FunctionKey),
@(kVK_F13): _SRUnicharToString(NSF13FunctionKey),
@(kVK_F14): _SRUnicharToString(NSF14FunctionKey),
@(kVK_F15): _SRUnicharToString(NSF15FunctionKey),
@(kVK_F16): _SRUnicharToString(NSF16FunctionKey),
@(kVK_F17): _SRUnicharToString(NSF17FunctionKey),
@(kVK_F18): _SRUnicharToString(NSF18FunctionKey),
@(kVK_F19): _SRUnicharToString(NSF19FunctionKey),
@(kVK_F20): _SRUnicharToString(NSF20FunctionKey),
@(kVK_Space): _SRUnicharToString(' '),
@(kVK_Delete): _SRUnicharToString(NSBackspaceCharacter),
@(kVK_ForwardDelete): _SRUnicharToString(NSDeleteCharacter),
@(kVK_ANSI_KeypadClear): _SRUnicharToString(NSClearLineFunctionKey),
@(kVK_LeftArrow): _SRUnicharToString(NSLeftArrowFunctionKey),
@(kVK_RightArrow): _SRUnicharToString(NSRightArrowFunctionKey),
@(kVK_UpArrow): _SRUnicharToString(NSUpArrowFunctionKey),
@(kVK_DownArrow): _SRUnicharToString(NSDownArrowFunctionKey),
@(kVK_End): _SRUnicharToString(NSEndFunctionKey),
@(kVK_Home): _SRUnicharToString(NSHomeFunctionKey),
@(kVK_Escape): _SRUnicharToString('\e'),
@(kVK_PageDown): _SRUnicharToString(NSPageDownFunctionKey),
@(kVK_PageUp): _SRUnicharToString(NSPageUpFunctionKey),
@(kVK_Return): _SRUnicharToString(NSCarriageReturnCharacter),
@(kVK_ANSI_KeypadEnter): _SRUnicharToString(NSEnterCharacter),
@(kVK_Tab): _SRUnicharToString(NSTabCharacter),
@(kVK_Help): _SRUnicharToString(NSHelpFunctionKey)
};
});
return Mapping;
}
+ (NSDictionary *)specialKeyCodesToPlainStringsMapping
{
static dispatch_once_t OnceToken;
static NSDictionary *Mapping = nil;
dispatch_once(&OnceToken, ^{
Mapping = @{
@(kVK_F1): @"F1",
@(kVK_F2): @"F2",
@(kVK_F3): @"F3",
@(kVK_F4): @"F4",
@(kVK_F5): @"F5",
@(kVK_F6): @"F6",
@(kVK_F7): @"F7",
@(kVK_F8): @"F8",
@(kVK_F9): @"F9",
@(kVK_F10): @"F10",
@(kVK_F11): @"F11",
@(kVK_F12): @"F12",
@(kVK_F13): @"F13",
@(kVK_F14): @"F14",
@(kVK_F15): @"F15",
@(kVK_F16): @"F16",
@(kVK_F17): @"F17",
@(kVK_F18): @"F18",
@(kVK_F19): @"F19",
@(kVK_F20): @"F20",
@(kVK_Space): SRLoc(@"Space"),
@(kVK_Delete): _SRUnicharToString(SRKeyCodeGlyphDeleteLeft),
@(kVK_ForwardDelete): _SRUnicharToString(SRKeyCodeGlyphDeleteRight),
@(kVK_ANSI_KeypadClear): _SRUnicharToString(SRKeyCodeGlyphPadClear),
@(kVK_LeftArrow): _SRUnicharToString(SRKeyCodeGlyphLeftArrow),
@(kVK_RightArrow): _SRUnicharToString(SRKeyCodeGlyphRightArrow),
@(kVK_UpArrow): _SRUnicharToString(SRKeyCodeGlyphUpArrow),
@(kVK_DownArrow): _SRUnicharToString(SRKeyCodeGlyphDownArrow),
@(kVK_End): _SRUnicharToString(SRKeyCodeGlyphSoutheastArrow),
@(kVK_Home): _SRUnicharToString(SRKeyCodeGlyphNorthwestArrow),
@(kVK_Escape): _SRUnicharToString(SRKeyCodeGlyphEscape),
@(kVK_PageDown): _SRUnicharToString(SRKeyCodeGlyphPageDown),
@(kVK_PageUp): _SRUnicharToString(SRKeyCodeGlyphPageUp),
@(kVK_Return): _SRUnicharToString(SRKeyCodeGlyphReturnR2L),
@(kVK_ANSI_KeypadEnter): _SRUnicharToString(SRKeyCodeGlyphReturn),
@(kVK_Tab): _SRUnicharToString(SRKeyCodeGlyphTabRight),
@(kVK_Help): @"?"
};
});
return Mapping;
}
- (BOOL)isKeyCodeSpecial:(unsigned short)aKeyCode
{
switch (aKeyCode)
{
case kVK_F1:
case kVK_F2:
case kVK_F3:
case kVK_F4:
case kVK_F5:
case kVK_F6:
case kVK_F7:
case kVK_F8:
case kVK_F9:
case kVK_F10:
case kVK_F11:
case kVK_F12:
case kVK_F13:
case kVK_F14:
case kVK_F15:
case kVK_F16:
case kVK_F17:
case kVK_F18:
case kVK_F19:
case kVK_F20:
case kVK_Space:
case kVK_Delete:
case kVK_ForwardDelete:
case kVK_ANSI_KeypadClear:
case kVK_LeftArrow:
case kVK_RightArrow:
case kVK_UpArrow:
case kVK_DownArrow:
case kVK_End:
case kVK_Home:
case kVK_Escape:
case kVK_PageDown:
case kVK_PageUp:
case kVK_Return:
case kVK_ANSI_KeypadEnter:
case kVK_Tab:
case kVK_Help:
return YES;
default:
return NO;
}
}
#pragma mark NSValueTransformer
+ (BOOL)allowsReverseTransformation
{
return NO;
}
+ (Class)transformedValueClass;
{
return [NSString class];
}
- (NSString *)transformedValue:(NSNumber *)aValue
{
return [self transformedValue:aValue withModifierFlags:nil];
}
- (NSString *)transformedValue:(NSNumber *)aValue withModifierFlags:(NSNumber *)aModifierFlags
{
return [self transformedValue:aValue withImplicitModifierFlags:aModifierFlags explicitModifierFlags:nil];
}
- (NSString *)transformedValue:(NSNumber *)aValue withImplicitModifierFlags:(NSNumber *)anImplicitModifierFlags explicitModifierFlags:(NSNumber *)anExplicitModifierFlags
{
if ([anImplicitModifierFlags unsignedIntegerValue] & [anExplicitModifierFlags unsignedIntegerValue] & SRCocoaModifierFlagsMask)
{
[NSException raise:NSInvalidArgumentException format:@"anImplicitModifierFlags and anExplicitModifierFlags MUST NOT have common elements"];
}
if (![aValue isKindOfClass:[NSNumber class]])
return @"";
// Some key codes cannot be translated directly.
NSString *unmappedString = [self transformedSpecialKeyCode:aValue withExplicitModifierFlags:anExplicitModifierFlags];
if (unmappedString)
return unmappedString;
CFDataRef layoutData = NULL;
if (self.usesASCIICapableKeyboardInputSource)
{
TISInputSourceRef tisSource = TISCopyCurrentASCIICapableKeyboardLayoutInputSource();
if (!tisSource)
return @"";
layoutData = (CFDataRef)TISGetInputSourceProperty(tisSource, kTISPropertyUnicodeKeyLayoutData);
CFRelease(tisSource);
}
else
{
TISInputSourceRef tisSource = TISCopyCurrentKeyboardLayoutInputSource();
if (!tisSource)
return @"";
layoutData = (CFDataRef)TISGetInputSourceProperty(tisSource, kTISPropertyUnicodeKeyLayoutData);
CFRelease(tisSource);
// For non-unicode layouts such as Chinese, Japanese, and Korean, get the ASCII capable layout
if (!layoutData)
{
tisSource = TISCopyCurrentASCIICapableKeyboardLayoutInputSource();
if (!tisSource)
return @"";
layoutData = (CFDataRef)TISGetInputSourceProperty(tisSource, kTISPropertyUnicodeKeyLayoutData);
CFRelease(tisSource);
}
}
if (!layoutData)
return @"";
const UCKeyboardLayout *keyLayout = (const UCKeyboardLayout *)CFDataGetBytePtr(layoutData);
static const UniCharCount MaxLength = 255;
UniCharCount actualLength = 0;
UniChar chars[MaxLength] = {0};
UInt32 deadKeyState = 0;
OSStatus err = UCKeyTranslate(keyLayout,
[aValue unsignedShortValue],
kUCKeyActionDisplay,
SRCocoaToCarbonFlags([anImplicitModifierFlags unsignedIntegerValue]) >> 8,
LMGetKbdType(),
kUCKeyTranslateNoDeadKeysBit,
&deadKeyState,
sizeof(chars) / sizeof(UniChar),
&actualLength,
chars);
if (err != noErr)
return @"";
if (self.usesPlainStrings)
return [[NSString stringWithCharacters:chars length:actualLength] uppercaseString];
else
return [NSString stringWithCharacters:chars length:actualLength];
}
- (NSString *)transformedSpecialKeyCode:(NSNumber *)aKeyCode withExplicitModifierFlags:(NSNumber *)anExplicitModifierFlags
{
if ([anExplicitModifierFlags unsignedIntegerValue] & NSShiftKeyMask && [aKeyCode unsignedShortValue] == kVK_Tab)
{
if (self.usesPlainStrings)
return _SRUnicharToString(SRKeyCodeGlyphTabLeft);
else
return _SRUnicharToString(NSBackTabCharacter);
}
if (self.usesPlainStrings)
return [[self class] specialKeyCodesToPlainStringsMapping][aKeyCode];
else
return [[self class] specialKeyCodesToUnicodeCharactersMapping][aKeyCode];
}
@end

21
Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyEquivalentModifierMaskTransformer.h

@ -0,0 +1,21 @@
//
// SRKeyEquivalentModifierMaskTransformer.h
// ShortcutRecorder
//
// Copyright 2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors to this file:
// Ilya Kulakov
#import <Foundation/Foundation.h>
/*!
Transform dictionary representation of shortcut into string suitable
for -setKeyEquivalentModifierMask: of NSButton and NSMenuItem.
*/
@interface SRKeyEquivalentModifierMaskTransformer : NSValueTransformer
@end

44
Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyEquivalentModifierMaskTransformer.m

@ -0,0 +1,44 @@
//
// SRKeyEquivalentModifierMaskTransformer.m
// ShortcutRecorder
//
// Copyright 2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// Ilya Kulakov
#import "SRKeyEquivalentModifierMaskTransformer.h"
#import "SRKeyCodeTransformer.h"
#import "SRRecorderControl.h"
@implementation SRKeyEquivalentModifierMaskTransformer
#pragma mark NSValueTransformer
+ (BOOL)allowsReverseTransformation
{
return NO;
}
+ (Class)transformedValueClass
{
return [NSNumber class];
}
- (NSNumber *)transformedValue:(NSDictionary *)aValue
{
if (![aValue isKindOfClass:[NSDictionary class]])
return @(0);
NSNumber *modifierFlags = aValue[SRShortcutModifierFlagsKey];
if (![modifierFlags isKindOfClass:[NSNumber class]])
return @(0);
return modifierFlags;
}
@end

21
Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyEquivalentTransformer.h

@ -0,0 +1,21 @@
//
// SRKeyEquivalentTransformer.h
// ShortcutRecorder
//
// Copyright 2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors to this file:
// Ilya Kulakov
#import <Foundation/Foundation.h>
/*!
Transform dictionary representation of shortcut into string suitable
for -setKeyEquivalent: of NSButton and NSMenuItem.
*/
@interface SRKeyEquivalentTransformer : NSValueTransformer
@end

53
Clocker/Clocker/ShortcutRecorder-master/Library/SRKeyEquivalentTransformer.m

@ -0,0 +1,53 @@
//
// SRKeyEquivalentTransformer.m
// ShortcutRecorder
//
// Copyright 2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// Ilya Kulakov
#import "SRKeyEquivalentTransformer.h"
#import "SRKeyCodeTransformer.h"
#import "SRRecorderControl.h"
@implementation SRKeyEquivalentTransformer
#pragma mark NSValueTransformer
+ (BOOL)allowsReverseTransformation
{
return NO;
}
+ (Class)transformedValueClass
{
return [NSString class];
}
- (NSString *)transformedValue:(NSDictionary *)aValue
{
if (![aValue isKindOfClass:[NSDictionary class]])
return @"";
NSNumber *keyCode = aValue[SRShortcutKeyCode];
if (![keyCode isKindOfClass:[NSNumber class]])
return @"";
NSNumber *modifierFlags = aValue[SRShortcutModifierFlagsKey];
if (![modifierFlags isKindOfClass:[NSNumber class]])
modifierFlags = @(0);
SRKeyCodeTransformer *t = [SRKeyCodeTransformer sharedASCIITransformer];
return [t transformedValue:keyCode
withImplicitModifierFlags:nil
explicitModifierFlags:modifierFlags];
}
@end

37
Clocker/Clocker/ShortcutRecorder-master/Library/SRModifierFlagsTransformer.h

@ -0,0 +1,37 @@
//
// SRModifierFlagsTransformer.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// Ilya Kulakov
#import <Cocoa/Cocoa.h>
/*!
Transforms mask of Cocoa modifier flags to string of unicode characters.
*/
@interface SRModifierFlagsTransformer : NSValueTransformer
- (instancetype)initWithPlainStrings:(BOOL)aUsesPlainStrings;
/*!
Determines whether modifier flags are transformed to unicode characters or to plain strings.
*/
@property (readonly) BOOL usesPlainStrings;
/*!
Returns the shared transformer.
*/
+ (instancetype)sharedTransformer;
/*!
Returns the shared plain transformer.
*/
+ (instancetype)sharedPlainTransformer;
@end

108
Clocker/Clocker/ShortcutRecorder-master/Library/SRModifierFlagsTransformer.m

@ -0,0 +1,108 @@
//
// SRModifierFlagsTransformer.m
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// Ilya Kulakov
#import "SRModifierFlagsTransformer.h"
#import "SRCommon.h"
@implementation SRModifierFlagsTransformer
- (instancetype)initWithPlainStrings:(BOOL)aUsesPlainStrings
{
self = [super init];
if (self)
{
_usesPlainStrings = aUsesPlainStrings;
}
return self;
}
- (instancetype)init
{
return [self initWithPlainStrings:NO];
}
#pragma mark Methods
+ (instancetype)sharedTransformer
{
static dispatch_once_t OnceToken;
static SRModifierFlagsTransformer *Transformer = nil;
dispatch_once(&OnceToken, ^{
Transformer = [[self alloc] initWithPlainStrings:NO];
});
return Transformer;
}
+ (instancetype)sharedPlainTransformer
{
static dispatch_once_t OnceToken;
static SRModifierFlagsTransformer *Transformer = nil;
dispatch_once(&OnceToken, ^{
Transformer = [[self alloc] initWithPlainStrings:YES];
});
return Transformer;
}
#pragma mark NSValueTransformer
+ (Class)transformedValueClass
{
return [NSString class];
}
+ (BOOL)allowsReverseTransformation
{
return NO;
}
- (NSString *)transformedValue:(NSNumber *)aValue
{
if (![aValue isKindOfClass:[NSNumber class]])
return nil;
else if (self.usesPlainStrings)
{
NSEventModifierFlags modifierFlags = [aValue unsignedIntegerValue];
NSMutableString *s = [NSMutableString string];
if (modifierFlags & NSControlKeyMask)
[s appendString:SRLoc(@"Control-")];
if (modifierFlags & NSAlternateKeyMask)
[s appendString:SRLoc(@"Option-")];
if (modifierFlags & NSShiftKeyMask)
[s appendString:SRLoc(@"Shift-")];
if (modifierFlags & NSCommandKeyMask)
[s appendString:SRLoc(@"Command-")];
if (s.length > 0)
[s deleteCharactersInRange:NSMakeRange(s.length - 1, 1)];
return s;
}
else
{
NSEventModifierFlags f = [aValue unsignedIntegerValue];
return [NSString stringWithFormat:@"%@%@%@%@",
(f & NSControlKeyMask ? @"⌃" : @""),
(f & NSAlternateKeyMask ? @"⌥" : @""),
(f & NSShiftKeyMask ? @"⇧" : @""),
(f & NSCommandKeyMask ? @"⌘" : @"")];
}
}
@end

436
Clocker/Clocker/ShortcutRecorder-master/Library/SRRecorderControl.h

@ -0,0 +1,436 @@
//
// SRRecorderControl.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Ilya Kulakov
#import <Cocoa/Cocoa.h>
#import <ShortcutRecorder/SRCommon.h>
/*!
Key code.
@discussion NSNumber representation of unsigned short.
Required key of SRRecorderControl's objectValue.
*/
extern NSString *const SRShortcutKeyCode;
/*!
Modifier flags.
@discussion NSNumber representation of NSEventModifierFlags.
Optional key of SRRecorderControl's objectValue.
*/
extern NSString *const SRShortcutModifierFlagsKey;
/*!
Interpretation of key code and modifier flags depending on system locale and input source
used when shortcut was taken.
@discussion NSString.
Optional key of SRRecorderControl's objectValue.
*/
extern NSString *const SRShortcutCharacters;
/*!
Interpretation of key code without modifier flags depending on system locale and input source
used when shortcut was taken.
@discussion NSString.
Optional key of SRRecorderControl's objectValue.
*/
extern NSString *const SRShortcutCharactersIgnoringModifiers;
@protocol SRRecorderControlDelegate;
/*!
An SRRecorderControl object is a control (but not a subclass of NSControl) that allows you to record shortcuts.
@discussion In addition to NSView bindings, exposes:
NSValueBinding. This binding supports 2 options:
- NSValueTransformerBindingOption
- NSValueTransformerNameBindingOption
NSEnabledBinding. This binding supports 2 options:
- NSValueTransformerBindingOption
- NSValueTransformerNameBindingOption
Note that at that moment, this binding _is not_ multivalue.
Required height: 25 points
Recommended min width: 100 points
*/
IB_DESIGNABLE
@interface SRRecorderControl : NSView /* <NSAccessibility, NSKeyValueBindingCreation, NSToolTipOwner, NSNibAwaking> */
/*!
The receivers delegate.
@discussion A recorder control delegate responds to editing-related messages. You can use to to prevent editing
in some cases or to validate typed shortcuts.
*/
@property (assign) IBOutlet NSObject<SRRecorderControlDelegate> *delegate;
/*!
Returns an integer bit field indicating allowed modifier flags.
@discussion Defaults to SRCocoaModifierFlagsMask.
*/
@property (readonly) IBInspectable NSEventModifierFlags allowedModifierFlags;
/*!
Returns an integer bit field indicating required modifier flags.
@discussion Defaults to 0.
*/
@property (readonly) IBInspectable NSEventModifierFlags requiredModifierFlags;
/*!
Determines whether shortcuts without modifier flags are allowed.
@discussion Defaults to NO.
*/
@property (readonly) IBInspectable BOOL allowsEmptyModifierFlags;
/*!
Determines whether the control reinterpret key code and modifier flags
using ASCII capable input source.
@discussion Defaults to YES.
If not set, the same key code may be draw differently depending on current input source.
E.g. with US English input source key code 0x0 is interpreted as "a",
however with Russian input source, it's interpreted as "ф".
*/
@property IBInspectable BOOL drawsASCIIEquivalentOfShortcut;
/*!
Determines whether Escape is used to cancel recording.
@discussion Defaults to YES.
If set, Escape without modifier flags cannot be recorded as shortcut.
*/
@property IBInspectable BOOL allowsEscapeToCancelRecording;
/*!
Determines whether delete (or forward delete) is used to remove current shortcut and end recording.
@discussion Defaults to YES.
If set, neither Delete nor Forward Delete without modifier flags can be recorded as shortcut.
*/
@property IBInspectable BOOL allowsDeleteToClearShortcutAndEndRecording;
/*!
Determines whether control enabled and can be edited or not.
@discussion Defaults to YES.
*/
@property (nonatomic, getter=isEnabled) IBInspectable BOOL enabled;
/*!
Determines whether recording is in process.
*/
@property (nonatomic, readonly) BOOL isRecording;
/*!
Returns dictionary representation of receiver's shortcut.
*/
@property (nonatomic, copy) NSDictionary *objectValue;
/*!
Configures recording behavior of the control.
@param newAllowedModifierFlags New allowed modifier flags.
@param newRequiredModifierFlags New required modifier flags.
@param newAllowsEmptyModifierFlags Determines whether empty modifier flags are allowed.
@discussion Flags are filtered using SRCocoaModifierFlagsMask. Flags does not affect object values set manually.
These restrictions can be ignored if delegate implements shortcutRecorder:shouldUnconditionallyAllowModifierFlags:forKeyCode: and returns YES for given modifier flags and key code.
Throws NSInvalidArgumentException if either required flags are not allowed
or required flags are not empty and no modifier flags are allowed.
@see SRRecorderControlDelegate
*/
- (void)setAllowedModifierFlags:(NSEventModifierFlags)newAllowedModifierFlags
requiredModifierFlags:(NSEventModifierFlags)newRequiredModifierFlags
allowsEmptyModifierFlags:(BOOL)newAllowsEmptyModifierFlags;
/*!
Called to initialize internal state after either initWithFrame or awakeFromNib is called.
*/
- (void)_initInternalState;
/*!
Turns on the recording mode.
@discussion You SHOULD not call this method directly.
*/
- (BOOL)beginRecording;
/*!
Turns off the recording mode. Current object value is preserved.
@discussion You SHOULD not call this method directly.
*/
- (void)endRecording;
/*!
Clears object value and turns off the recording mode.
@discussion You SHOULD not call this method directly.
*/
- (void)clearAndEndRecording;
/*!
Designated method to end recording. Sets a given object value, updates bindings and turns off the recording mode.
@discussion You SHOULD not call this method directly.
*/
- (void)endRecordingWithObjectValue:(NSDictionary *)anObjectValue;
/*!
Returns shape of the control.
@discussion Primarily used to draw appropriate focus ring.
*/
- (NSBezierPath *)controlShape;
/*!
Returns rect for label with given attributes.
@param aLabel Label for drawing.
@param anAttributes A dictionary of NSAttributedString text attributes to be applied to the string.
*/
- (NSRect)rectForLabel:(NSString *)aLabel withAttributes:(NSDictionary *)anAttributes;
/*!
Returns rect of the snap back button in the receiver coordinates.
*/
- (NSRect)snapBackButtonRect;
/*!
Returns rect of the clear button in the receiver coordinates.
@discussion Returned rect will have empty width (other values will be valid) if button should not be drawn.
*/
- (NSRect)clearButtonRect;
/*!
Returns label to be displayed by the receiver.
@discussion Returned value depends on isRecording state objectValue and currenlty pressed keys and modifier flags.
*/
- (NSString *)label;
/*!
Returns label for accessibility.
@discussion Returned value depends on isRecording state objectValue and currenlty pressed keys and modifier flags.
*/
- (NSString *)accessibilityLabel;
/*!
Returns string representation of object value.
*/
- (NSString *)stringValue;
/*!
Returns string representation of object value for accessibility.
*/
- (NSString *)accessibilityStringValue;
/*!
Returns attirbutes of label to be displayed by the receiver according to current state.
@see normalLabelAttributes
@see recordingLabelAttributes
@see disabledLabelAttributes
*/
- (NSDictionary *)labelAttributes;
/*!
Returns attributes of label to be displayed by the receiver in normal mode.
*/
- (NSDictionary *)normalLabelAttributes;
/*!
Returns attributes of label to be displayed by the receiver in recording mode.
*/
- (NSDictionary *)recordingLabelAttributes;
/*!
Returns attributes of label to be displayed by the receiver in disabled mode.
*/
- (NSDictionary *)disabledLabelAttributes;
/*!
Draws background of the receiver into current graphics context.
*/
- (void)drawBackground:(NSRect)aDirtyRect;
/*!
Draws interior of the receiver into current graphics context.
*/
- (void)drawInterior:(NSRect)aDirtyRect;
/*!
Draws label of the receiver into current graphics context.
*/
- (void)drawLabel:(NSRect)aDirtyRect;
/*!
Draws snap back button of the receiver into current graphics context.
*/
- (void)drawSnapBackButton:(NSRect)aDirtyRect;
/*!
Draws clear button of the receiver into current graphics context.
*/
- (void)drawClearButton:(NSRect)aDirtyRect;
/*!
Determines whether main button (representation of the receiver in normal mode) is highlighted.
*/
- (BOOL)isMainButtonHighlighted;
/*!
Determines whether snap back button is highlighted.
*/
- (BOOL)isSnapBackButtonHighlighted;
/*!
Determines whetehr clear button is highlighted.
*/
- (BOOL)isClearButtonHighlighted;
/*!
Determines whether modifier flags are valid for key code according to the receiver settings.
@param aModifierFlags Proposed modifier flags.
@param aKeyCode Code of the pressed key.
@see allowedModifierFlags
@see allowsEmptyModifierFlags
@see requiredModifierFlags
*/
- (BOOL)areModifierFlagsValid:(NSEventModifierFlags)aModifierFlags forKeyCode:(unsigned short)aKeyCode;
/*!
A helper method to propagate view-driven changes back to model.
@discussion This method makes it easier to propagate changes from a view
back to the model without overriding bind:toObject:withKeyPath:options:
@see http://tomdalling.com/blog/cocoa/implementing-your-own-cocoa-bindings/
*/
- (void)propagateValue:(id)aValue forBinding:(NSString *)aBinding;
@end
@protocol SRRecorderControlDelegate <NSObject>
@optional
/*!
Asks the delegate if editing should begin in the specified shortcut recorder.
@param aRecorder The shortcut recorder which editing is about to begin.
@result YES if an editing session should be initiated; otherwise, NO to disallow editing.
@discussion Implementation of this method by the delegate is optional. If it is not present, editing proceeds as if this method had returned YES.
*/
- (BOOL)shortcutRecorderShouldBeginRecording:(SRRecorderControl *)aRecorder;
/*!
Gives a delegate opportunity to bypass rules specified by allowed and required modifier flags.
@param aRecorder The shortcut recorder for which editing ended.
@param aModifierFlags Proposed modifier flags.
@param aKeyCode Code of the pressed key.
@result YES if recorder should bypass key code with given modifier flags despite settings like required modifier flags, allowed modifier flags.
@discussion Implementation of this method by the delegate is optional.
Normally, you wouldn't allow a user to record shourcut without modifier flags set: disallow 'a', but allow cmd-'a'.
However, some keys were designed to be key shortcuts by itself. E.g. Functional keys. By implementing this method a delegate can allow
these special keys to be set without modifier flags even when the control is configured to disallow empty modifier flags.
@see allowedModifierFlags
@see allowsEmptyModifierFlags
@see requiredModifierFlags
*/
- (BOOL)shortcutRecorder:(SRRecorderControl *)aRecorder shouldUnconditionallyAllowModifierFlags:(NSEventModifierFlags)aModifierFlags forKeyCode:(unsigned short)aKeyCode;
/*!
Asks the delegate if the shortcut can be set by the specified shortcut recorder.
@param aRecorder The shortcut recorder which shortcut is beign to be recordered.
@param aShortcut The Shortcut user typed.
@result YES if shortcut can be recordered. Otherwise NO.
@discussion Implementation of this method by the delegate is optional. If it is not present, shortcut is recordered as if this method had returned YES.
You may implement this method to filter shortcuts that were already set by other recorders.
@see SRValidator
*/
- (BOOL)shortcutRecorder:(SRRecorderControl *)aRecorder canRecordShortcut:(NSDictionary *)aShortcut;
/*!
Tells the delegate that editing stopped for the specified shortcut recorder.
@param aRecorder The shortcut recorder for which editing ended.
@discussion Implementation of this method by the delegate is optional.
*/
- (void)shortcutRecorderDidEndRecording:(SRRecorderControl *)aRecorder;
@end
FOUNDATION_STATIC_INLINE BOOL SRShortcutEqualToShortcut(NSDictionary *a, NSDictionary *b)
{
if (a == b)
return YES;
else if (a && !b)
return NO;
else if (!a && b)
return NO;
else
return ([a[SRShortcutKeyCode] isEqual:b[SRShortcutKeyCode]] && [a[SRShortcutModifierFlagsKey] isEqual:b[SRShortcutModifierFlagsKey]]);
}
FOUNDATION_STATIC_INLINE NSDictionary *SRShortcutWithCocoaModifierFlagsAndKeyCode(NSEventModifierFlags aModifierFlags, unsigned short aKeyCode)
{
return @{SRShortcutKeyCode: @(aKeyCode), SRShortcutModifierFlagsKey: @(aModifierFlags)};
}

1407
Clocker/Clocker/ShortcutRecorder-master/Library/SRRecorderControl.m

File diff suppressed because it is too large Load Diff

131
Clocker/Clocker/ShortcutRecorder-master/Library/SRValidator.h

@ -0,0 +1,131 @@
//
// SRValidator.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Andy Kim
// Silvio Rizzi
// Ilya Kulakov
#import <Cocoa/Cocoa.h>
@protocol SRValidatorDelegate;
/*!
Implements logic to check whether shortcut is taken by other parts of the application and system.
*/
@interface SRValidator : NSObject
@property (assign) NSObject<SRValidatorDelegate> *delegate;
- (instancetype)initWithDelegate:(NSObject<SRValidatorDelegate> *)aDelegate;
/*!
Determines whether shortcut is taken.
@discussion Key is checked in the following order:
1. If delegate implements shortcutValidator:isKeyCode:andFlagsTaken:reason:
2. If delegate allows system-wide shortcuts are checked
3. If delegate allows application menu it checked
@see SRValidatorDelegate
*/
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlagsTaken:(NSEventModifierFlags)aFlags error:(NSError **)outError;
/*!
Determines whether shortcut is taken in delegate.
@discussion If delegate does not implement appropriate method, returns immediately.
*/
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlagTakenInDelegate:(NSEventModifierFlags)aFlags error:(NSError **)outError;
/*!
Determines whether shortcut is taken by system-wide shortcuts.
@discussion Does not check whether delegate allows or disallows checking in system shortcuts.
*/
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlagsTakenInSystemShortcuts:(NSEventModifierFlags)aFlags error:(NSError **)outError;
/*!
Determines whether shortcut is taken by application menu item.
@discussion Does not check whether delegate allows or disallows checking in application menu.
*/
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlags:(NSEventModifierFlags)aFlags takenInMenu:(NSMenu *)aMenu error:(NSError **)outError;
@end
@protocol SRValidatorDelegate
@optional
/*!
Asks the delegate if aKeyCode and aFlags are valid.
@param aValidator The validator that validates key code and flags.
@param aKeyCode Key code to validate.
@param aFlags Flags to validate.
@param outReason If delegate decides that shortcut is invalid, it may pass here an error message.
@result YES if shortcut is valid. Otherwise NO.
@discussion Implementation of this method by the delegate is optional. If it is not present, checking proceeds as if this method had returned YES.
*/
- (BOOL)shortcutValidator:(SRValidator *)aValidator isKeyCode:(unsigned short)aKeyCode andFlagsTaken:(NSEventModifierFlags)aFlags reason:(NSString **)outReason;
/*!
Asks the delegate whether validator should check key equivalents of app's menu items.
@param aValidator The validator that going to check app's menu items.
@result YES if validator should check key equivalents of app's menu items. Otherwise NO.
@discussion Implementation of this method by the delegate is optional. If it is not present, checking proceeds as if this method had returned YES.
*/
- (BOOL)shortcutValidatorShouldCheckMenu:(SRValidator *)aValidator;
/*!
Asks the delegate whether it should check system shortcuts.
@param aValidator The validator that going to check system shortcuts.
@result YES if validator should check system shortcuts. Otherwise NO.
@discussion Implementation of this method by the delegate is optional. If it is not present, checking proceeds as if this method had returned YES.
*/
- (BOOL)shortcutValidatorShouldCheckSystemShortcuts:(SRValidator *)aValidator;
/*!
Asks the delegate whether it should use ASCII representation of key code when making error messages.
@param aValidator The validator that is about to make an error message.
@result YES if validator should use ASCII representation. Otherwise NO.
@discussion Implementation of this method by the delegate is optional. If it is not present, ASCII representation of key code is used.
*/
- (BOOL)shortcutValidatorShouldUseASCIIStringForKeyCodes:(SRValidator *)aValidator;
@end
@interface NSMenuItem (SRValidator)
/*!
Returns full path to the menu item. E.g. "Window ➝ Zoom"
*/
- (NSString *)SR_path;
@end

233
Clocker/Clocker/ShortcutRecorder-master/Library/SRValidator.m

@ -0,0 +1,233 @@
//
// SRValidator.h
// ShortcutRecorder
//
// Copyright 2006-2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors:
// David Dauer
// Jesper
// Jamie Kirkpatrick
// Andy Kim
// Silvio Rizzi
// Ilya Kulakov
#import "SRValidator.h"
#import "SRCommon.h"
#import "SRKeyCodeTransformer.h"
@implementation SRValidator
- (instancetype)initWithDelegate:(NSObject<SRValidatorDelegate> *)aDelegate;
{
self = [super init];
if (self)
{
_delegate = aDelegate;
}
return self;
}
- (instancetype)init
{
return [self initWithDelegate:nil];
}
#pragma mark Methods
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlagsTaken:(NSEventModifierFlags)aFlags error:(NSError **)outError;
{
if ([self isKeyCode:aKeyCode andFlagTakenInDelegate:aFlags error:outError])
return YES;
if ((![self.delegate respondsToSelector:@selector(shortcutValidatorShouldCheckSystemShortcuts:)] ||
[self.delegate shortcutValidatorShouldCheckSystemShortcuts:self]) &&
[self isKeyCode:aKeyCode andFlagsTakenInSystemShortcuts:aFlags error:outError])
{
return YES;
}
if ((![self.delegate respondsToSelector:@selector(shortcutValidatorShouldCheckMenu:)] ||
[self.delegate shortcutValidatorShouldCheckMenu:self]) &&
[self isKeyCode:aKeyCode andFlags:aFlags takenInMenu:[NSApp mainMenu] error:outError])
{
return YES;
}
return NO;
}
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlagTakenInDelegate:(NSEventModifierFlags)aFlags error:(NSError **)outError
{
if (self.delegate)
{
NSString *delegateReason = nil;
if ([self.delegate respondsToSelector:@selector(shortcutValidator:isKeyCode:andFlagsTaken:reason:)] &&
[self.delegate shortcutValidator:self
isKeyCode:aKeyCode
andFlagsTaken:aFlags
reason:&delegateReason])
{
if (outError)
{
BOOL isASCIIOnly = YES;
if ([self.delegate respondsToSelector:@selector(shortcutValidatorShouldUseASCIIStringForKeyCodes:)])
isASCIIOnly = [self.delegate shortcutValidatorShouldUseASCIIStringForKeyCodes:self];
NSString *shortcut = isASCIIOnly ? SRReadableASCIIStringForCocoaModifierFlagsAndKeyCode(aFlags, aKeyCode) : SRReadableStringForCocoaModifierFlagsAndKeyCode(aFlags, aKeyCode);
NSString *failureReason = [NSString stringWithFormat:
SRLoc(@"The key combination \"%@\" can't be used!"),
shortcut];
NSString *description = [NSString stringWithFormat:
SRLoc(@"The key combination \"%@\" can't be used because %@."),
shortcut,
[delegateReason length] ? delegateReason : @"it's already used"];
NSDictionary *userInfo = @{
NSLocalizedFailureReasonErrorKey : failureReason,
NSLocalizedDescriptionKey: description
};
*outError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:userInfo];
}
return YES;
}
}
return NO;
}
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlagsTakenInSystemShortcuts:(NSEventModifierFlags)aFlags error:(NSError **)outError
{
CFArrayRef s = NULL;
OSStatus err = CopySymbolicHotKeys(&s);
if (err != noErr)
return YES;
NSArray *symbolicHotKeys = (NSArray *)CFBridgingRelease(s);
aFlags &= SRCocoaModifierFlagsMask;
for (NSDictionary *symbolicHotKey in symbolicHotKeys)
{
if ((__bridge CFBooleanRef)symbolicHotKey[(__bridge NSString *)kHISymbolicHotKeyEnabled] != kCFBooleanTrue)
continue;
unsigned short symbolicHotKeyCode = [symbolicHotKey[(__bridge NSString *)kHISymbolicHotKeyCode] integerValue];
if (symbolicHotKeyCode == aKeyCode)
{
UInt32 symbolicHotKeyFlags = [symbolicHotKey[(__bridge NSString *)kHISymbolicHotKeyModifiers] unsignedIntValue];
symbolicHotKeyFlags &= SRCarbonModifierFlagsMask;
if (SRCarbonToCocoaFlags(symbolicHotKeyFlags) == aFlags)
{
if (outError)
{
BOOL isASCIIOnly = YES;
if ([self.delegate respondsToSelector:@selector(shortcutValidatorShouldUseASCIIStringForKeyCodes:)])
isASCIIOnly = [self.delegate shortcutValidatorShouldUseASCIIStringForKeyCodes:self];
NSString *shortcut = isASCIIOnly ? SRReadableASCIIStringForCocoaModifierFlagsAndKeyCode(aFlags, aKeyCode) : SRReadableStringForCocoaModifierFlagsAndKeyCode(aFlags, aKeyCode);
NSString *failureReason = [NSString stringWithFormat:
SRLoc(@"The key combination \"%@\" can't be used!"),
shortcut];
NSString *description = [NSString stringWithFormat:
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 panel in System Preferences."),
shortcut];
NSDictionary *userInfo = @{
NSLocalizedFailureReasonErrorKey: failureReason,
NSLocalizedDescriptionKey: description
};
*outError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:userInfo];
}
return YES;
}
}
}
return NO;
}
- (BOOL)isKeyCode:(unsigned short)aKeyCode andFlags:(NSEventModifierFlags)aFlags takenInMenu:(NSMenu *)aMenu error:(NSError **)outError
{
aFlags &= SRCocoaModifierFlagsMask;
for (NSMenuItem *menuItem in [aMenu itemArray])
{
if (menuItem.hasSubmenu && [self isKeyCode:aKeyCode andFlags:aFlags takenInMenu:menuItem.submenu error:outError])
return YES;
NSString *keyEquivalent = menuItem.keyEquivalent;
if (![keyEquivalent length])
continue;
NSEventModifierFlags keyEquivalentModifierMask = menuItem.keyEquivalentModifierMask;
if (SRKeyCodeWithFlagsEqualToKeyEquivalentWithFlags(aKeyCode, aFlags, keyEquivalent, keyEquivalentModifierMask))
{
if (outError)
{
BOOL isASCIIOnly = YES;
if ([self.delegate respondsToSelector:@selector(shortcutValidatorShouldUseASCIIStringForKeyCodes:)])
isASCIIOnly = [self.delegate shortcutValidatorShouldUseASCIIStringForKeyCodes:self];
NSString *shortcut = isASCIIOnly ? SRReadableASCIIStringForCocoaModifierFlagsAndKeyCode(aFlags, aKeyCode) : SRReadableStringForCocoaModifierFlagsAndKeyCode(aFlags, aKeyCode);
NSString *failureReason = [NSString stringWithFormat:SRLoc(@"The key combination \"%@\" can't be used!"), shortcut];
NSString *description = [NSString stringWithFormat:SRLoc(@"The key combination \"%@\" can't be used because it's already used by the menu item \"%@\"."), shortcut, menuItem.SR_path];
NSDictionary *userInfo = @{
NSLocalizedFailureReasonErrorKey: failureReason,
NSLocalizedDescriptionKey: description
};
*outError = [NSError errorWithDomain:NSCocoaErrorDomain code:0 userInfo:userInfo];
}
return YES;
}
}
return NO;
}
@end
@implementation NSMenuItem (SRValidator)
- (NSString *)SR_path
{
NSMutableArray *items = [NSMutableArray array];
static const NSUInteger Limit = 1000;
NSMenuItem *currentMenuItem = self;
NSUInteger i = 0;
do
{
[items insertObject:currentMenuItem atIndex:0];
currentMenuItem = currentMenuItem.parentItem;
++i;
}
while (currentMenuItem && i < Limit);
NSMutableString *path = [NSMutableString string];
for (NSMenuItem *menuItem in items)
[path appendFormat:@"%@➝", menuItem.title];
if ([path length] > 1)
[path deleteCharactersInRange:NSMakeRange([path length] - 1, 1)];
return path;
}
@end

54
Clocker/Clocker/ShortcutRecorder-master/Library/ShortcutRecorder.h

@ -0,0 +1,54 @@
//
// ShortcutRecorder.h
// ShortcutRecorder
// Copyright 2012 Contributors. All rights reserved.
//
// License: BSD
//
// Contributors to this file:
// Jesper
// Ilya Kulakov
#import <Cocoa/Cocoa.h>
#import <ShortcutRecorder/SRCommon.h>
#import <ShortcutRecorder/SRKeyCodeTransformer.h>
#import <ShortcutRecorder/SRModifierFlagsTransformer.h>
#import <ShortcutRecorder/SRKeyEquivalentTransformer.h>
#import <ShortcutRecorder/SRKeyEquivalentModifierMaskTransformer.h>
#import <ShortcutRecorder/SRValidator.h>
#import <ShortcutRecorder/SRRecorderControl.h>
#ifndef IBInspectable
#define IBInspectable
#endif
#ifndef IB_DESIGNABLE
#define IB_DESIGNABLE
#endif
#ifndef NSAppKitVersionNumber10_6
#define NSAppKitVersionNumber10_6 1038
#endif
#ifndef NSAppKitVersionNumber10_9
#define NSAppKitVersionNumber10_9 1265
#endif
#ifndef NSEDGEINSETS_DEFINED
typedef struct NSEdgeInsets {
CGFloat top;
CGFloat left;
CGFloat bottom;
CGFloat right;
} NSEdgeInsets;
NS_INLINE NSEdgeInsets NSEdgeInsetsMake(CGFloat top, CGFloat left, CGFloat bottom, CGFloat right) {
NSEdgeInsets e;
e.top = top;
e.left = left;
e.bottom = bottom;
e.right = right;
return e;
}
#endif

22
Clocker/Clocker/ShortcutRecorder-master/PTHotKey/Info.plist

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.5</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.5</string>
</dict>
</plist>

31
Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKey+ShortcutRecorder.h

@ -0,0 +1,31 @@
//
// PTHotKey+ShortcutRecorder.h
// ShortcutRecorder
//
// Created by Ilya Kulakov on 27.02.11.
// Copyright 2011 Wireload. All rights reserved.
//
#import <Cocoa/Cocoa.h>
#import "PTHotKey.h"
@interface PTHotKey (ShortcutRecorder)
+ (PTHotKey *)hotKeyWithIdentifier:(id)anIdentifier
keyCombo:(NSDictionary *)aKeyCombo
target:(id)aTarget
action:(SEL)anAction;
+ (PTHotKey *)hotKeyWithIdentifier:(id)anIdentifier
keyCombo:(NSDictionary *)aKeyCombo
target:(id)aTarget
action:(SEL)anAction
keyUpAction:(SEL)aKeyUpAction;
+ (PTHotKey *)hotKeyWithIdentifier:(id)anIdentifier
keyCombo:(NSDictionary *)aKeyCombo
target:(id)aTarget
action:(SEL)anAction
withObject:(id)anObject;
@end

53
Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKey+ShortcutRecorder.m

@ -0,0 +1,53 @@
//
// PTHotKey+ShortcutRecorder.m
// ShortcutRecorder
//
// Created by Ilya Kulakov on 27.02.11.
// Copyright 2011 Wireload. All rights reserved.
//
#import "PTHotKey+ShortcutRecorder.h"
#import "SRRecorderControl.h"
@implementation PTHotKey (ShortcutRecorder)
+ (PTHotKey *)hotKeyWithIdentifier:(id)anIdentifier
keyCombo:(NSDictionary *)aKeyCombo
target:(id)aTarget
action:(SEL)anAction
{
return [PTHotKey hotKeyWithIdentifier:anIdentifier keyCombo:aKeyCombo target:aTarget action:anAction withObject:nil];
}
+ (PTHotKey *)hotKeyWithIdentifier:(id)anIdentifier
keyCombo:(NSDictionary *)aKeyCombo
target:(id)aTarget
action:(SEL)anAction
withObject:(id)anObject
{
NSInteger keyCode = [[aKeyCombo objectForKey:@"keyCode"] integerValue];
NSUInteger modifiers = SRCocoaToCarbonFlags([[aKeyCombo objectForKey:@"modifierFlags"] unsignedIntegerValue]);
PTKeyCombo *newKeyCombo = [[PTKeyCombo alloc] initWithKeyCode:keyCode modifiers:modifiers];
PTHotKey *newHotKey = [[PTHotKey alloc] initWithIdentifier:anIdentifier keyCombo:newKeyCombo];
[newHotKey setTarget:aTarget];
[newHotKey setAction:anAction];
[newHotKey setObject:anObject];
return newHotKey;
}
+ (PTHotKey *)hotKeyWithIdentifier:(id)anIdentifier
keyCombo:(NSDictionary *)aKeyCombo
target:(id)aTarget
action:(SEL)anAction
keyUpAction:(SEL)aKeyUpAction
{
PTHotKey *newHotKey = [PTHotKey hotKeyWithIdentifier:anIdentifier
keyCombo:aKeyCombo
target:aTarget
action:anAction];
[newHotKey setKeyUpAction:aKeyUpAction];
return newHotKey;
}
@end

60
Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKey.h

@ -0,0 +1,60 @@
//
// PTHotKey.h
// Protein
//
// Created by Quentin Carnicelli on Sat Aug 02 2003.
// Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved.
//
// Contributors:
// Andy Kim
#import <Foundation/Foundation.h>
#import <Carbon/Carbon.h>
#import "PTKeyCombo.h"
@interface PTHotKey : NSObject
{
NSString* mIdentifier;
NSString* mName;
PTKeyCombo* mKeyCombo;
id mTarget;
id mObject;
SEL mAction;
SEL mKeyUpAction;
UInt32 mCarbonHotKeyID;
EventHotKeyRef mCarbonEventHotKeyRef;
}
- (id)initWithIdentifier: (id)identifier keyCombo: (PTKeyCombo*)combo;
- (id)initWithIdentifier: (id)identifier keyCombo: (PTKeyCombo*)combo withObject: (id)object;
- (id)init;
- (void)setIdentifier: (id)ident;
- (id)identifier;
- (void)setName: (NSString*)name;
- (NSString*)name;
- (void)setKeyCombo: (PTKeyCombo*)combo;
- (PTKeyCombo*)keyCombo;
- (void)setTarget: (id)target;
- (id)target;
- (void)setObject: (id)object;
- (id)object;
- (void)setAction: (SEL)action;
- (SEL)action;
- (void)setKeyUpAction: (SEL)action;
- (SEL)keyUpAction;
- (UInt32)carbonHotKeyID;
- (void)setCarbonHotKeyID: (UInt32)hotKeyID;
- (EventHotKeyRef)carbonEventHotKeyRef;
- (void)setCarbonEventHotKeyRef:(EventHotKeyRef)hotKeyRef;
- (void)invoke;
- (void)uninvoke;
@end

156
Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKey.m

@ -0,0 +1,156 @@
//
// PTHotKey.m
// Protein
//
// Created by Quentin Carnicelli on Sat Aug 02 2003.
// Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved.
//
#import "PTHotKey.h"
#import "PTHotKeyCenter.h"
#import "PTKeyCombo.h"
@implementation PTHotKey
- (id)init
{
return [self initWithIdentifier: nil keyCombo: nil withObject:nil];
}
- (id)initWithIdentifier: (id)identifier keyCombo: (PTKeyCombo*)combo
{
return [self initWithIdentifier: identifier keyCombo: combo withObject:nil];
}
- (id)initWithIdentifier: (id)identifier keyCombo: (PTKeyCombo*)combo withObject: (id)object
{
self = [super init];
if( self )
{
[self setIdentifier: identifier];
[self setKeyCombo: combo];
[self setObject: object];
}
return self;
}
- (NSString*)description
{
return [NSString stringWithFormat: @"<%@: %@, %@>", NSStringFromClass( [self class] ), [self identifier], [self keyCombo]];
}
#pragma mark -
- (void)setIdentifier: (id)ident
{
mIdentifier = ident;
}
- (id)identifier
{
return mIdentifier;
}
- (void)setKeyCombo: (PTKeyCombo*)combo
{
if( combo == nil )
combo = [PTKeyCombo clearKeyCombo];
mKeyCombo = combo;
}
- (PTKeyCombo*)keyCombo
{
return mKeyCombo;
}
- (void)setName: (NSString*)name
{
mName = name;
}
- (NSString*)name
{
return mName;
}
- (void)setTarget: (id)target
{
mTarget = target;
}
- (id)target
{
return mTarget;
}
- (void)setObject:(id)object
{
mObject = object;
}
- (id)object
{
return mObject;
}
- (void)setAction: (SEL)action
{
mAction = action;
}
- (SEL)action
{
return mAction;
}
- (void)setKeyUpAction: (SEL)action
{
mKeyUpAction = action;
}
- (SEL)keyUpAction
{
return mKeyUpAction;
}
- (UInt32)carbonHotKeyID
{
return mCarbonHotKeyID;
}
- (void)setCarbonHotKeyID: (UInt32)hotKeyID;
{
mCarbonHotKeyID = hotKeyID;
}
- (EventHotKeyRef)carbonEventHotKeyRef
{
return mCarbonEventHotKeyRef;
}
- (void)setCarbonEventHotKeyRef: (EventHotKeyRef)hotKeyRef
{
mCarbonEventHotKeyRef = hotKeyRef;
}
#pragma mark -
- (void)invoke
{
if(mAction)
[NSApp sendAction:mAction to:mTarget from:self];
}
- (void)uninvoke
{
if(mKeyUpAction)
[NSApp sendAction:mKeyUpAction to:mTarget from:self];
}
@end

44
Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKeyCenter.h

@ -0,0 +1,44 @@
//
// PTHotKeyCenter.h
// Protein
//
// Created by Quentin Carnicelli on Sat Aug 02 2003.
// Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved.
//
// Contributors:
// Quentin D. Carnicelli
// Finlay Dobbie
// Vincent Pottier
// Andy Kim
#import <Cocoa/Cocoa.h>
#import <Carbon/Carbon.h>
@class PTHotKey;
@interface PTHotKeyCenter : NSObject
{
NSMutableDictionary* mHotKeys; //Keys are carbon hot key IDs
BOOL mEventHandlerInstalled;
UInt32 mHotKeyCount; // Used to assign new hot key ID
BOOL mIsPaused;
EventHandlerRef mEventHandler;
}
+ (PTHotKeyCenter *)sharedCenter;
- (BOOL)registerHotKey: (PTHotKey*)hotKey;
- (void)unregisterHotKey: (PTHotKey*)hotKey;
- (NSArray*)allHotKeys;
- (PTHotKey*)hotKeyWithIdentifier: (id)ident;
- (void)sendEvent: (NSEvent*)event;
- (void)pause;
- (void)resume;
- (BOOL)isPaused;
@end

334
Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTHotKeyCenter.m

@ -0,0 +1,334 @@
//
// PTHotKeyCenter.m
// Protein
//
// Created by Quentin Carnicelli on Sat Aug 02 2003.
// Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved.
//
#import "PTHotKeyCenter.h"
#import "PTHotKey.h"
#import "PTKeyCombo.h"
@interface PTHotKeyCenter (Private)
- (PTHotKey*)_hotKeyForCarbonHotKey: (EventHotKeyRef)carbonHotKey;
- (PTHotKey*)_hotKeyForCarbonHotKeyID: (EventHotKeyID)hotKeyID;
- (void)_updateEventHandler;
- (void)_hotKeyDown: (PTHotKey*)hotKey;
- (void)_hotKeyUp: (PTHotKey*)hotKey;
static OSStatus hotKeyEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void* refCon );
@end
@implementation PTHotKeyCenter
static PTHotKeyCenter *_sharedHotKeyCenter = nil;
+ (PTHotKeyCenter*)sharedCenter
{
if( _sharedHotKeyCenter == nil )
{
_sharedHotKeyCenter = [[self alloc] init];
}
return _sharedHotKeyCenter;
}
- (id)init
{
self = [super init];
if( self )
{
mHotKeys = [[NSMutableDictionary alloc] init];
}
return self;
}
#pragma mark -
- (BOOL)registerHotKey: (PTHotKey*)hotKey
{
if ( mIsPaused == NO )
{
OSStatus err;
EventHotKeyID hotKeyID;
EventHotKeyRef carbonHotKey;
if( [[self allHotKeys] containsObject: hotKey] == YES )
[self unregisterHotKey: hotKey];
if( [[hotKey keyCombo] isValidHotKeyCombo] == NO )
return YES;
hotKeyID.signature = 'PTHk';
hotKeyID.id = ++mHotKeyCount;
err = RegisterEventHotKey( (SInt32)[[hotKey keyCombo] keyCode],
(UInt32)[[hotKey keyCombo] modifiers],
hotKeyID,
GetEventDispatcherTarget(),
0,
&carbonHotKey );
if( err )
return NO;
[hotKey setCarbonHotKeyID:hotKeyID.id];
[hotKey setCarbonEventHotKeyRef:carbonHotKey];
if( hotKey )
[mHotKeys setObject: hotKey forKey: [NSNumber numberWithInteger:hotKeyID.id]];
[self _updateEventHandler];
}
else
{
EventHotKeyID hotKeyID = {'PTHk', ++mHotKeyCount};
[hotKey setCarbonHotKeyID:hotKeyID.id];
if( hotKey )
[mHotKeys setObject: hotKey forKey: [NSNumber numberWithInteger:hotKeyID.id]];
}
return YES;
}
- (void)unregisterHotKey: (PTHotKey*)hotKey
{
if ( mIsPaused == NO )
{
EventHotKeyRef carbonHotKey;
if( [[self allHotKeys] containsObject: hotKey] == NO )
return;
carbonHotKey = [hotKey carbonEventHotKeyRef];
if( carbonHotKey )
{
UnregisterEventHotKey( carbonHotKey );
//Watch as we ignore 'err':
[mHotKeys removeObjectForKey: [NSNumber numberWithInteger:[hotKey carbonHotKeyID]]];
[hotKey setCarbonHotKeyID:0];
[hotKey setCarbonEventHotKeyRef:NULL];
[self _updateEventHandler];
//See that? Completely ignored
}
}
else
{
[mHotKeys removeObjectForKey: [NSNumber numberWithInteger:[hotKey carbonHotKeyID]]];
[hotKey setCarbonHotKeyID:0];
[hotKey setCarbonEventHotKeyRef:NULL];
}
}
- (NSArray*)allHotKeys
{
return [mHotKeys allValues];
}
- (PTHotKey*)hotKeyWithIdentifier: (id)ident
{
NSEnumerator* hotKeysEnum = [[self allHotKeys] objectEnumerator];
PTHotKey* hotKey;
if( !ident )
return nil;
while( (hotKey = [hotKeysEnum nextObject]) != nil )
{
if( [[hotKey identifier] isEqual: ident] )
return hotKey;
}
return nil;
}
#pragma mark -
- (PTHotKey*)_hotKeyForCarbonHotKey: (EventHotKeyRef)carbonHotKeyRef
{
NSEnumerator *e = [mHotKeys objectEnumerator];
PTHotKey *hotkey = nil;
while( (hotkey = [e nextObject]) )
{
if( [hotkey carbonEventHotKeyRef] == carbonHotKeyRef )
return hotkey;
}
return nil;
}
- (PTHotKey*)_hotKeyForCarbonHotKeyID: (EventHotKeyID)hotKeyID
{
return [mHotKeys objectForKey:[NSNumber numberWithInteger:hotKeyID.id]];
}
- (void)_updateEventHandler
{
if( [mHotKeys count] && mEventHandlerInstalled == NO )
{
EventTypeSpec eventSpec[2] = {
{ kEventClassKeyboard, kEventHotKeyPressed },
{ kEventClassKeyboard, kEventHotKeyReleased }
};
InstallEventHandler( GetEventDispatcherTarget(),
(EventHandlerProcPtr)hotKeyEventHandler,
2, eventSpec, nil, &mEventHandler);
mEventHandlerInstalled = YES;
}
}
- (void)_hotKeyDown: (PTHotKey*)hotKey
{
[hotKey invoke];
}
- (void)_hotKeyUp: (PTHotKey*)hotKey
{
[hotKey uninvoke];
}
- (void)sendEvent: (NSEvent*)event
{
// Not sure why this is needed? - Andy Kim (Aug 23, 2009)
short subType;
EventHotKeyRef carbonHotKey;
if( [event type] == NSSystemDefined )
{
subType = [event subtype];
if( subType == 6 ) //6 is hot key down
{
carbonHotKey= (EventHotKeyRef)[event data1]; //data1 is our hot key ref
if( carbonHotKey != nil )
{
PTHotKey* hotKey = [self _hotKeyForCarbonHotKey: carbonHotKey];
[self _hotKeyDown: hotKey];
}
}
else if( subType == 9 ) //9 is hot key up
{
carbonHotKey= (EventHotKeyRef)[event data1];
if( carbonHotKey != nil )
{
PTHotKey* hotKey = [self _hotKeyForCarbonHotKey: carbonHotKey];
[self _hotKeyUp: hotKey];
}
}
}
}
- (OSStatus)sendCarbonEvent: (EventRef)event
{
OSStatus err;
EventHotKeyID hotKeyID;
PTHotKey* hotKey;
NSAssert( GetEventClass( event ) == kEventClassKeyboard, @"Unknown event class" );
err = GetEventParameter( event,
kEventParamDirectObject,
typeEventHotKeyID,
nil,
sizeof(EventHotKeyID),
nil,
&hotKeyID );
if( err )
return err;
if( hotKeyID.signature != 'PTHk' )
return eventNotHandledErr;
if (hotKeyID.id == 0)
return eventNotHandledErr;
hotKey = [self _hotKeyForCarbonHotKeyID:hotKeyID];
switch( GetEventKind( event ) )
{
case kEventHotKeyPressed:
[self _hotKeyDown: hotKey];
break;
case kEventHotKeyReleased:
[self _hotKeyUp: hotKey];
break;
default:
return eventNotHandledErr;
break;
}
return noErr;
}
- (void)pause
{
if ( mIsPaused )
return;
mIsPaused = YES;
for (NSNumber *hotKeyID in mHotKeys)
{
PTHotKey *hotKey = [mHotKeys objectForKey:hotKeyID];
EventHotKeyRef carbonHotKey = [hotKey carbonEventHotKeyRef];
UnregisterEventHotKey( carbonHotKey );
[hotKey setCarbonEventHotKeyRef:NULL];
}
if (mEventHandler != NULL)
{
RemoveEventHandler(mEventHandler);
mEventHandler = NULL;
mEventHandlerInstalled = NO;
}
}
- (void)resume
{
if ( mIsPaused == NO)
return;
mIsPaused = NO;
for (NSNumber *hotKeyIDNumber in mHotKeys)
{
PTHotKey *hotKey = [mHotKeys objectForKey:hotKeyIDNumber];
EventHotKeyRef carbonHotKey = NULL;
EventHotKeyID hotKeyID;
hotKeyID.signature = 'PTHk';
hotKeyID.id = [hotKey carbonHotKeyID];
RegisterEventHotKey( (SInt32)[[hotKey keyCombo] keyCode],
(UInt32)[[hotKey keyCombo] modifiers],
hotKeyID,
GetEventDispatcherTarget(),
0,
&carbonHotKey );
[hotKey setCarbonEventHotKeyRef:carbonHotKey];
}
[self _updateEventHandler];
}
- (BOOL)isPaused
{
return mIsPaused;
}
static OSStatus hotKeyEventHandler(EventHandlerCallRef inHandlerRef, EventRef inEvent, void* refCon )
{
return [[PTHotKeyCenter sharedCenter] sendCarbonEvent: inEvent];
}
@end

26
Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTKeyCodeTranslator.h

@ -0,0 +1,26 @@
//
// PTKeyCodeTranslator.h
// Chercher
//
// Created by Finlay Dobbie on Sat Oct 11 2003.
// Copyright (c) 2003 Cliché Software. All rights reserved.
//
#import <Carbon/Carbon.h>
@interface PTKeyCodeTranslator : NSObject
{
TISInputSourceRef keyboardLayout;
const UCKeyboardLayout *uchrData;
UInt32 keyTranslateState;
UInt32 deadKeyState;
}
+ (id)currentTranslator;
- (id)initWithKeyboardLayout:(TISInputSourceRef)aLayout;
- (NSString *)translateKeyCode:(short)keyCode;
- (TISInputSourceRef)keyboardLayout;
@end

71
Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTKeyCodeTranslator.m

@ -0,0 +1,71 @@
//
// PTKeyCodeTranslator.m
// Chercher
//
// Created by Finlay Dobbie on Sat Oct 11 2003.
// Copyright (c) 2003 Cliché Software. All rights reserved.
//
#import "PTKeyCodeTranslator.h"
@implementation PTKeyCodeTranslator
+ (id)currentTranslator
{
static PTKeyCodeTranslator *current = nil;
TISInputSourceRef currentLayout = TISCopyCurrentKeyboardLayoutInputSource();
if (current == nil) {
current = [[PTKeyCodeTranslator alloc] initWithKeyboardLayout:currentLayout];
} else if ([current keyboardLayout] != currentLayout) {
current = [[PTKeyCodeTranslator alloc] initWithKeyboardLayout:currentLayout];
}
CFRelease(currentLayout);
return current;
}
- (id)initWithKeyboardLayout:(TISInputSourceRef)aLayout
{
if ((self = [super init]) != nil) {
keyboardLayout = aLayout;
CFRetain(keyboardLayout);
CFDataRef uchr = TISGetInputSourceProperty( keyboardLayout , kTISPropertyUnicodeKeyLayoutData );
uchrData = ( const UCKeyboardLayout* )CFDataGetBytePtr(uchr);
}
return self;
}
- (void)dealloc
{
CFRelease(keyboardLayout);
}
- (NSString *)translateKeyCode:(short)keyCode {
UniCharCount maxStringLength = 4, actualStringLength;
UniChar unicodeString[4];
UCKeyTranslate( uchrData, keyCode, kUCKeyActionDisplay, 0, LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit, &deadKeyState, maxStringLength, &actualStringLength, unicodeString );
return [NSString stringWithCharacters:unicodeString length:1];
}
- (TISInputSourceRef)keyboardLayout {
return keyboardLayout;
}
- (NSString *)description {
NSString *kind;
kind = @"uchr";
NSString *layoutName;
layoutName = (__bridge NSString *)(TISGetInputSourceProperty( keyboardLayout, kTISPropertyLocalizedName ));
return [NSString stringWithFormat:@"PTKeyCodeTranslator layout=%@ (%@)", layoutName, kind];
}
@end

38
Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTKeyCombo.h

@ -0,0 +1,38 @@
//
// PTKeyCombo.h
// Protein
//
// Created by Quentin Carnicelli on Sat Aug 02 2003.
// Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface PTKeyCombo : NSObject <NSCopying>
{
NSInteger mKeyCode;
NSUInteger mModifiers;
}
+ (id)clearKeyCombo;
+ (id)keyComboWithKeyCode: (NSInteger)keyCode modifiers: (NSUInteger)modifiers;
- (id)initWithKeyCode: (NSInteger)keyCode modifiers: (NSUInteger)modifiers;
- (id)initWithPlistRepresentation: (id)plist;
- (id)plistRepresentation;
- (BOOL)isEqual: (PTKeyCombo*)combo;
- (NSInteger)keyCode;
- (NSUInteger)modifiers;
- (BOOL)isClearCombo;
- (BOOL)isValidHotKeyCombo;
@end
@interface PTKeyCombo (UserDisplayAdditions)
- (NSString*)keyCodeString;
- (NSUInteger)modifierMask;
@end

127
Clocker/Clocker/ShortcutRecorder-master/PTHotKey/PTKeyCombo.m

@ -0,0 +1,127 @@
//
// PTKeyCombo.m
// Protein
//
// Created by Quentin Carnicelli on Sat Aug 02 2003.
// Copyright (c) 2003 Quentin D. Carnicelli. All rights reserved.
//
#import "PTKeyCombo.h"
#import "PTKeyCodeTranslator.h"
@implementation PTKeyCombo
+ (id)clearKeyCombo
{
return [self keyComboWithKeyCode: -1 modifiers: -1];
}
+ (id)keyComboWithKeyCode: (NSInteger)keyCode modifiers: (NSUInteger)modifiers
{
return [[self alloc] initWithKeyCode: keyCode modifiers: modifiers];
}
- (id)initWithKeyCode: (NSInteger)keyCode modifiers: (NSUInteger)modifiers
{
self = [super init];
if( self )
{
switch ( keyCode )
{
case kVK_F1:
case kVK_F2:
case kVK_F3:
case kVK_F4:
case kVK_F5:
case kVK_F6:
case kVK_F7:
case kVK_F8:
case kVK_F9:
case kVK_F10:
case kVK_F11:
case kVK_F12:
case kVK_F13:
case kVK_F14:
case kVK_F15:
case kVK_F16:
case kVK_F17:
case kVK_F18:
case kVK_F19:
case kVK_F20:
mModifiers = modifiers | NSFunctionKeyMask;
break;
default:
mModifiers = modifiers;
break;
}
mKeyCode = keyCode;
}
return self;
}
- (id)initWithPlistRepresentation: (id)plist
{
int keyCode, modifiers;
if( !plist || ![plist count] )
{
keyCode = -1;
modifiers = -1;
}
else
{
keyCode = [[plist objectForKey: @"keyCode"] intValue];
if( keyCode < 0 ) keyCode = -1;
modifiers = [[plist objectForKey: @"modifiers"] intValue];
if( modifiers <= 0 ) modifiers = -1;
}
return [self initWithKeyCode: keyCode modifiers: modifiers];
}
- (id)plistRepresentation
{
return [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInteger: [self keyCode]], @"keyCode",
[NSNumber numberWithInteger: [self modifiers]], @"modifiers",
nil];
}
- (id)copyWithZone:(NSZone*)zone;
{
return self;
}
- (BOOL)isEqual: (PTKeyCombo*)combo
{
return [self keyCode] == [combo keyCode] &&
[self modifiers] == [combo modifiers];
}
#pragma mark -
- (NSInteger)keyCode
{
return mKeyCode;
}
- (NSUInteger)modifiers
{
return mModifiers;
}
- (BOOL)isValidHotKeyCombo
{
return mKeyCode >= 0 && mModifiers > 0;
}
- (BOOL)isClearCombo
{
return mKeyCode == -1 && mModifiers == 0;
}
@end

112
Clocker/Clocker/ShortcutRecorder-master/README.md

@ -0,0 +1,112 @@
ShortcutRecorder 2
====================
![pre-Yosemite ShortcutRecorder Preview](Demo/example.png)
![Yosemite ShortcutRecorder Preview](Demo/example-yosemite.png)
The only user interface control to record shortcuts. For Mac OS X 10.6+, 64bit.
- :microscope: Support for Xcode 6 Quick Help
- :microscope: Support for Xcode 6 Interface Builder integration
- Fresh Look & Feel (brought to you by [Wireload](http://wireload.net) and [John Wells](https://github.com/jwells89))
- With Retina support
- Auto Layout ready
- Correct drawing on Layer-backed and Layer-hosted views
- Accessibility for people with disabilities
- Revised codebase with Automatic Reference Counting support
- Translated into 24 languages
Includes framework to set global shortcuts (PTHotKey).
Get Sources
-----------
The preferred way to add the ShortcutRecorder to your project is to use git submodules:
`git submodule add git://github.com/Kentzo/ShortcutRecorder.git`
You can download sources from the site as well.
Integrate into your project
---------------------------
First, add ShortcutRecorder.xcodeproj to your workspace via Xcode ([Apple docs](https://developer.apple.com/library/mac/recipes/xcode_help-structure_navigator/articles/Adding_an_Existing_Project_to_a_Workspace.html)). Don't have a workspace? No problem, just add ShortcutRecorder.xcodeproj via the "Add Files to" dialog.
Next step is to ensure your target is linked against the ShortcutRecorder or/and PTHotKey frameworks ([Apple docs](http://developer.apple.com/library/ios/#recipes/xcode_help-project_editor/Articles/AddingaLibrarytoaTarget.html#//apple_ref/doc/uid/TP40010155-CH17)). Desired frameworks will be listed under *Workspace*.
Now it's time to make frameworks part of your app. To do this, you need to add custom Build Phase ([Apple docs](http://developer.apple.com/library/ios/#recipes/xcode_help-project_editor/Articles/CreatingaCopyFilesBuildPhase.html)). Remember to set *Destination* to *Frameworks* and clean up *Subpath*.
Finally, ensure your app will find frameworks upon start. Open Build Settings of your target, look up *Runtime Search Paths*. Add `@executable_path/../Frameworks` to the list of paths.
Add control in Interface Builder
--------------------------------
Since Xcode 4 Apple removed Interface Builder Plugins. You can only use it to add and position/resize ShortcutRecorder control. To do this, add Custom View and set its class to SRRecorderControl.
SRRecorderControl has fixed height of 25 points so ensure you do not use autoresizing masks/layout rules which allows vertical resizing. I recommend you to pin height in case you're using Auto Layout.
Usage
-----
First, we want to keep value of the control across relaunches of the app. We can simply achieve this by using NSUserDefaultsController and bindings:
[self.pingShortcutRecorder bind:NSValueBinding
toObject:[NSUserDefaultsController sharedUserDefaultsController]
withKeyPath:@"values.ping"
options:nil];
The value can be used to set key equivalent of NSMenuItem or NSButton. It can also be used to register a global shortcut.
Setting key equivalent of NSMenuItem using bindings:
[self.pingItem bind:@"keyEquivalent"
toObject:defaults
withKeyPath:@"values.ping"
options:@{NSValueTransformerBindingOption: [SRKeyEquivalentTransformer new]}];
[self.pingItem bind:@"keyEquivalentModifierMask"
toObject:defaults
withKeyPath:@"values.ping"
options:@{NSValueTransformerBindingOption: [SRKeyEquivalentModifierMaskTransformer new]}];
Setting key equivalent of NSButton using bindings:
[self.pingButton bind:@"keyEquivalent"
toObject:defaults
withKeyPath:@"values.ping"
options:@{NSValueTransformerBindingOption: [SRKeyEquivalentTransformer new]}];
[self.pingButton bind:@"keyEquivalentModifierMask"
toObject:defaults
withKeyPath:@"values.ping"
options:@{NSValueTransformerBindingOption: [SRKeyEquivalentModifierMaskTransformer new]}];
Setting global shortcut using PTHotKeyCenter:
PTHotKeyCenter *hotKeyCenter = [PTHotKeyCenter sharedCenter];
PTHotKey *oldHotKey = [hotKeyCenter hotKeyWithIdentifier:aKeyPath];
[hotKeyCenter unregisterHotKey:oldHotKey];
PTHotKey *newHotKey = [PTHotKey hotKeyWithIdentifier:aKeyPath
keyCombo:newShortcut
target:self
action:@selector(ping:)];
[hotKeyCenter registerHotKey:newHotKey];
Key Equivalents and Keyboard Layout
----------------------------------------------------
While ShortcutRecorder keeps your shortcuts as combination of *key code* and modifier masks, key equivalents are expressed using *key character* and modifier mask. The difference is that position of key code on keyboard does not depend on current keyboard layout while position of key character does.
ShortcutRecorder includes two special transformers to simplify binding to the key equivalents of NSMenuItem and NSButton:
- SRKeyEquivalentTransformer
- SRKeyEquivalentModifierMaskTransformer
SRKeyEquivalentTransformer uses ASCII keyboard layout to convert key code into character, therefore resulting character does not depend on keyboard layout.
The drawback is that position of the character on keyboard may change depending on layout and used modifier keys (primarly Option and Shift).
NSButton
--------
If you're going to bind ShortcutRecorder to key equivalent of NSButton, I encourage you to require `NSCommandKeyMask`.
This is because NSButton handles key equivalents very strange. Rather than investigating full information of the keyboard event, it just asks for `charactersIgnoringModifiers`
and compares returned value with its `keyEquivalent`. Unfortunately, Cocoa returns layout-independent (ASCII) representation of characters only when NSCommandKeyMask is set.
If it's not set, assigned shortcut likely won't work with other layouts.
Questions
---------
Still have questions? [Create an issue](https://github.com/Kentzo/ShortcutRecorder/issues/new) immediately and feel free to ping me.
Paid Support
------------
If functional you need is missing but you're ready to pay for it, feel free to contact me. If not, create an issue anyway, I'll take a look as soon as I can.

40
Clocker/Clocker/ShortcutRecorder-master/Resources/LICENSE.txt

@ -0,0 +1,40 @@
Copyright (c) 2006, contributors to ShortcutRecorder. (See the contributors listed in detail later in the file, or see <http://wafflesoftware.net/shortcut/contributors/>.)
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The name of the contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=====================================================================
Contributors to Shortcut Recorder, in no order in particular:
Jesper, waffle software, <wootest+shortcutrecorder@gmail.com>. Initial idea and concept, first shot at implementation using NSView.
David Dauer, <david@daviddauer.de>. Refinement, cleaner reimplementation, documentation, IB Palette.
Jamie Kirkpatrick, Kirk Consulting Ltd, <jkp@kirkconsulting.co.uk>. Further modularisation and re-factoring, and general bug fixes.
Ilya Kulakov, <kulakov.ilya@gmail.com>. ShortcutRecorder 2.0 and further support.
Alexander Ljungberg, <aljungberg@wireload.net>. Graphics for ShortcutRecorder 2.0
=====================================================================
Some rights reserved: <http://creativecommons.org/licenses/by/3.0/>
For more information, visit <http://blog.oofn.net/projects/misc/>

BIN
Clocker/Clocker/ShortcutRecorder-master/Resources/ShorcutRecorder Yosemite.sketch

Binary file not shown.

BIN
Clocker/Clocker/ShortcutRecorder-master/Resources/ca.lproj/ShortcutRecorder.strings

Binary file not shown.

BIN
Clocker/Clocker/ShortcutRecorder-master/Resources/cs.lproj/ShortcutRecorder.strings

Binary file not shown.

BIN
Clocker/Clocker/ShortcutRecorder-master/Resources/de.lproj/ShortcutRecorder.strings

Binary file not shown.

BIN
Clocker/Clocker/ShortcutRecorder-master/Resources/el.lproj/ShortcutRecorder.strings

Binary file not shown.

BIN
Clocker/Clocker/ShortcutRecorder-master/Resources/en.lproj/ShortcutRecorder.strings

Binary file not shown.

BIN
Clocker/Clocker/ShortcutRecorder-master/Resources/es-MX.lproj/ShortcutRecorder.strings

Binary file not shown.

BIN
Clocker/Clocker/ShortcutRecorder-master/Resources/es.lproj/ShortcutRecorder.strings

Binary file not shown.

BIN
Clocker/Clocker/ShortcutRecorder-master/Resources/fr.lproj/ShortcutRecorder.strings

Binary file not shown.

BIN
Clocker/Clocker/ShortcutRecorder-master/Resources/it.lproj/ShortcutRecorder.strings

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save