// // PSPreferencesController.m // Pester // // Created by Nicholas Riley on Sat Mar 29 2003. // Copyright (c) 2003 Nicholas Riley. All rights reserved. // #import "PSPreferencesController.h" #import "PSApplication.h" #import "NJRHotKeyField.h" #import "NJRHotKey.h" #import "NJRHotKeyManager.h" // NSUserDefaults key static NSString * const PSSetAlarmHotKey = @"Pester set alarm system-wide keyboard shortcut"; // NJRHotKeyManager shortcut identifier static NSString * const PSSetAlarmHotKeyShortcut = @"PSSetAlarmHotKeyShortcut"; @implementation PSPreferencesController + (void)readPreferences; { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NJRHotKeyManager *hotKeyManager = [NJRHotKeyManager sharedManager]; NJRHotKey *hotKey = [[[NJRHotKey alloc] initWithPropertyList: [defaults dictionaryForKey: PSSetAlarmHotKey]] autorelease]; if (hotKey == nil) { [hotKeyManager removeShortcutWithIdentifier: PSSetAlarmHotKeyShortcut]; } else { if (![hotKeyManager addShortcutWithIdentifier: PSSetAlarmHotKeyShortcut hotKey: hotKey target: NSApp action: @selector(orderFrontSetAlarmPanel:)]) { [defaults removeObjectForKey: PSSetAlarmHotKey]; NSRunAlertPanel(NSLocalizedString(@"Can't reserve alarm key equivalent", "Hot key set failure"), NSLocalizedString(@"Pester was unable to reserve the key equivalent %@. Please select another in Pester's Preferences, or click Clear to remove it.", "Hot key set failure"), nil, nil, nil, [hotKey keyGlyphs]); [(PSApplication *)NSApp performSelector: @selector(orderFrontPreferencesPanel:) withObject: self afterDelay: 0.1]; } } } #pragma mark interface updating - (void)update; { // perform any interface propagation that needs to be done } #pragma mark preferences I/O - (void)readFromPrefs; { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NJRHotKey *hotKey = [[NJRHotKey alloc] initWithPropertyList: [defaults dictionaryForKey: PSSetAlarmHotKey]]; [setAlarmHotKey setHotKey: hotKey]; [hotKey release]; } - (void)writeToPrefs; { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; [defaults setObject: [[setAlarmHotKey hotKey] propertyListRepresentation] forKey: @"Pester set alarm system-wide keyboard shortcut"]; [defaults synchronize]; [[self class] readPreferences]; } #pragma mark initialize-release - (id)init { if ( (self = [super initWithWindowNibName: @"Preferences"]) != nil) { [[self window] center]; // connect outlets [self readFromPrefs]; [self update]; // command NSMutableCharacterSet *set = [[NSCharacterSet alphanumericCharacterSet] mutableCopy]; [set addCharactersInString: @"`-=[]/\\, "]; commandRejectSet = [set copy]; [set release]; // no modifiers, shift, option, option-shift set = [[NSCharacterSet alphanumericCharacterSet] mutableCopy]; [set formUnionWithCharacterSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; [set formUnionWithCharacterSet: [NSCharacterSet punctuationCharacterSet]]; [set addCharactersInString: @"\t\r\e\x7f\x03\x19"]; // tab, CR, escape, delete, enter, backtab [set addCharactersInRange: NSMakeRange(0xF700, 0x1FF)]; // reserved function key range [set removeCharactersInRange: NSMakeRange(NSF1FunctionKey, 15)]; // F1-F15 textRejectSet = [set copy]; [set release]; // command-shift commandShiftRejectSet = [[NSCharacterSet characterSetWithCharactersInString: @"ACFGHIPQS~? "] retain]; // command-option commandOptionRejectSet = [[NSCharacterSet characterSetWithCharactersInString: @"DW\\-= "] retain]; } return self; } - (void)dealloc; { [textRejectSet release]; [commandRejectSet release]; [commandShiftRejectSet release]; [commandOptionRejectSet release]; [super dealloc]; } #pragma mark actions - (IBAction)hotKeySet:(NJRHotKeyField *)sender; { [self writeToPrefs]; } - (IBAction)showWindow:(id)sender; { [self readFromPrefs]; [super showWindow: sender]; } @end @implementation PSPreferencesController (NJRHotKeyFieldDelegate) - (BOOL)hotKeyField:(NJRHotKeyField *)hotKeyField shouldAcceptCharacter:(unichar)keyChar modifierFlags:(unsigned)modifierFlags rejectionMessage:(NSString **)message; { *message = nil; if (modifierFlags == 0 || modifierFlags == NSShiftKeyMask || modifierFlags == NSAlternateKeyMask || modifierFlags == (NSShiftKeyMask | NSAlternateKeyMask)) { *message = modifierFlags == 0 ? @"key is reserved for typing text" : @"key combination is reserved for typing text"; return ![textRejectSet characterIsMember: keyChar]; } if (modifierFlags == NSCommandKeyMask) { *message = @"key combination is reserved for application use"; return ![commandRejectSet characterIsMember: keyChar]; } if (modifierFlags == (NSCommandKeyMask | NSShiftKeyMask)) { *message = @"key combination is reserved for application use"; return ![commandShiftRejectSet characterIsMember: keyChar]; } if (modifierFlags == (NSCommandKeyMask | NSAlternateKeyMask)) { *message = @"key combination is reserved for Mac OS X use"; return ![commandOptionRejectSet characterIsMember: keyChar]; } return YES; } @end