source: trunk/Cocoa/Pester/Source/NJRHotKeyField.m @ 355

Last change on this file since 355 was 355, checked in by Nicholas Riley, 12 years ago

English.lproj/MainMenu.nib: Modernize menu and alarm set dialog
layout. Use keyed archiving (10.2+) nib format.

Info-Pester.plist: Moved from old PBX project.

NJRFSObjectSelector.m: Bug fixes from code sent to Joey: remove
incorrect usage of tryToPerform:with:; fix logic error in menu
construction. Work around Cocoa's deciding that the menu font size
needs adjustment when it doesn't - so the menu font size now matches
the button font size, though the position is still off. Don't pop up
a menu if we're disabled. Use IconRefs? for menu icons, though not
(yet) for the button icon.

NJRHistoryTrackingComboBox.m: Remove item height adjustment
workaround; it now makes the items too tall.

NJRHotKey.m: Add a missing [super dealloc] caught by current GCC.

NJRHotKeyField.m: Add a missing [super dealloc] caught by current GCC.

NJRHotKeyManager.m: Add a missing [super dealloc] caught by current
GCC.

NJRIntervalField.m: Fix some type errors.

NJRQTMediaPopUpButton.m: Replace SoundFileManager? SPI usage, which
doesn't work in Leopard anyway, with manual enumeration of system
sounds. Start migration to QTKit. Use IconRefs? for menu icons.

NJRReadMeController.m: Change source encoding to UTF-8.

NJRSoundManager.m: Fix a type error.

NJRVoicePopUpButton.m: Change source encoding to UTF-8.

NSMenuItem-NJRExtensions.[hm]: Code from ICeCoffEE to use IconRefs? for
menu item icons.

PSAlarm.m: Change source encoding to UTF-8.

PSAlarms.m: Fix a signedness mismatch.

PSAlarmsController.m: Change source encoding to UTF-8.

PSAlarmSetController.m: Set keyboard focus after unchecking "Do
script:" and "Play" checkboxes.

PSAlerts.m: Add a missing [super dealloc] caught by current GCC. Fix
a memory leak in property list serialization.

PSPowerManager.[hm]: There's now API for scheduling wakeups; use it
(the old code asserted on startup). To fix: removing scheduled
wakeup. Fix a small type-checking error.

PSPreferencesController.m: Add a missing [super dealloc] caught by
current GCC.

PSScriptAlert.m: Change source encoding to UTF-8.

PSTimeDateEditor.m: Fix a tiny, and one-time, memory leak.

PSTimer.m: Update for new PSPowerManager API.

Pester.pbproj: Deleted; now supporting OS X 10.4+ (up from 10.1,
aiee.)

Pester.xcodeproj: Xcode 2.4+ project, upgraded targets, etc.

SoundFileManager?.h: Deleted; this SPI no longer exists in Leopard and
possibly earlier.

File size: 5.7 KB
Line 
1//
2//  NJRHotKeyField.m
3//  Pester
4//
5//  Created by Nicholas Riley on Sat Mar 29 2003.
6//  Copyright (c) 2003 Nicholas Riley. All rights reserved.
7//
8
9#import "NJRHotKeyField.h"
10#import "NJRHotKeyFieldCell.h"
11#import "NJRHotKey.h"
12#import "NSString-NJRExtensions.h"
13
14static const NSRange zeroRange = {0, 0};
15static const unsigned int capturedModifierMask = (NSShiftKeyMask |
16                                                  NSControlKeyMask |
17                                                  NSAlternateKeyMask |
18                                                  NSCommandKeyMask);
19
20static NSParagraphStyle *leftAlignStyle = nil, *centerAlignStyle = nil;
21static NSDictionary *statusAttributes = nil;
22
23@implementation NJRHotKeyField
24
25+ (void)initialize;
26{
27    NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
28    [paraStyle setAlignment: NSLeftTextAlignment];
29    leftAlignStyle = [paraStyle copy];
30    [paraStyle setAlignment: NSCenterTextAlignment];
31    centerAlignStyle = [paraStyle copy];
32    [paraStyle release];
33
34    statusAttributes = [[NSDictionary alloc] initWithObjectsAndKeys:
35        [NSFont systemFontOfSize: [NSFont labelFontSize]], NSFontAttributeName,
36        centerAlignStyle, NSParagraphStyleAttributeName, nil];
37}
38
39- (void)_setUp;
40{
41    [self setAllowsEditingTextAttributes: YES];
42    [self setImportsGraphics: NO];
43    [self cell]->isa = [NJRHotKeyFieldCell class];
44}
45
46#pragma mark initialize-release
47
48- (id)initWithCoder:(NSCoder *)coder;
49{
50    if ( (self = [super initWithCoder: coder]) != nil) {
51        [self _setUp];
52    }
53    return self;
54}
55
56- (id)initWithFrame:(NSRect)frameRect;
57{
58    if ( (self = [super initWithFrame: frameRect]) != nil) {
59        [self _setUp];
60    }
61    return self;
62}
63
64- (void)dealloc;
65{
66    [hotKey release];
67    [super dealloc];
68}
69
70#pragma mark interface updating
71
72- (void)showStatus:(NSString *)error;
73{
74    [self setAttributedStringValue:
75        [[NSAttributedString alloc] initWithString: [NSString stringWithFormat: @"(%@)", error]
76                                        attributes: statusAttributes]];
77    [NSObject cancelPreviousPerformRequestsWithTarget: self selector: @selector(clearStatus) object: nil];
78    [self performSelector: @selector(clearStatus) withObject: nil afterDelay: 0.5];
79    [[self currentEditor] setSelectedRange: zeroRange];
80}
81
82- (void)previewKeyEquivalentAttributedString:(NSAttributedString *)equivString;
83{
84    NSMutableAttributedString *previewString = [equivString mutableCopy];
85    [previewString addAttribute: NSParagraphStyleAttributeName value: leftAlignStyle range: NSMakeRange(0, [previewString length])];
86    [self setAttributedStringValue: previewString];
87    [[self currentEditor] setSelectedRange: zeroRange];
88    [previewString release];
89}
90
91- (void)showKeyEquivalentAttributedStringFinalized:(BOOL)finalized;
92{
93    if ([hotKey characters] == nil) {
94        [self showStatus: @"none assigned"];
95        return;
96    }
97    NSMutableAttributedString *equivString = [[[hotKey characters] keyEquivalentAttributedStringWithModifierFlags: [hotKey modifierFlags]] mutableCopy];
98    [equivString addAttribute: NSParagraphStyleAttributeName
99                        value: (finalized ? centerAlignStyle : leftAlignStyle)
100                        range: NSMakeRange(0, [equivString length])];
101    [self setAttributedStringValue: equivString];
102    [[self currentEditor] setSelectedRange: zeroRange];
103    [equivString release];
104}
105
106- (void)clearStatus;
107{
108    if ([[[self attributedStringValue] attributesAtIndex: 0 effectiveRange: NULL] isEqualToDictionary: statusAttributes]) {
109        [self showKeyEquivalentAttributedStringFinalized: ([[NSApp currentEvent] modifierFlags] & capturedModifierMask) == 0];
110    }
111}
112
113#pragma mark event handling
114
115- (void)keyUp:(NSEvent *)theEvent;
116{
117    NSString *characters = [theEvent charactersIgnoringModifiers];
118    int length = [characters length];
119    if (length > 1) {
120        [self showStatus: @"please press only one non-modifier key"];
121        return;
122    }
123    if (length == 1) {
124        unsigned modifierFlags = ([theEvent modifierFlags] & capturedModifierMask);
125        id delegate = [self delegate];
126        NSString *message = nil;
127        if (delegate != nil && ![delegate hotKeyField: self shouldAcceptCharacter: [characters characterAtIndex: 0] modifierFlags: modifierFlags rejectionMessage: &message]) {
128            [self showStatus: message != nil ? message : @"key is unavailable for use"];
129        } else {
130            [self setHotKey: [NJRHotKey hotKeyWithCharacters: characters modifierFlags: modifierFlags keyCode: [theEvent keyCode]]];
131            [NSApp sendAction: [self action] to: [self target] from: self];
132            [self showKeyEquivalentAttributedStringFinalized: ([theEvent modifierFlags] & capturedModifierMask) == 0];
133        }
134    }
135}
136
137- (BOOL)performKeyEquivalent:(NSEvent *)theEvent;
138{
139    [self keyUp: theEvent];
140    return [super performKeyEquivalent: theEvent];
141}
142
143- (void)flagsChanged:(NSEvent *)theEvent;
144{
145    unsigned modifierFlags = [theEvent modifierFlags];
146
147    if ((modifierFlags & capturedModifierMask) == 0) {
148        [self showKeyEquivalentAttributedStringFinalized: YES];
149    } else {
150        [self previewKeyEquivalentAttributedString:
151            [@"" keyEquivalentAttributedStringWithModifierFlags: modifierFlags]];
152    }
153}
154
155#pragma mark acccessing
156
157- (NJRHotKey *)hotKey;
158{
159    return hotKey;
160}
161
162- (void)setHotKey:(NJRHotKey *)aKey;
163{
164    if (aKey != hotKey) {
165        [hotKey release];
166        hotKey = [aKey retain];
167        [self showKeyEquivalentAttributedStringFinalized: ([[NSApp currentEvent] modifierFlags] & capturedModifierMask) == 0];
168    }
169}
170
171#pragma mark actions
172
173- (IBAction)clear:(id)sender;
174{
175    [self setHotKey: nil];
176    [NSApp sendAction: [self action] to: [self target] from: self];
177    [self showKeyEquivalentAttributedStringFinalized: YES];
178}
179
180@end
Note: See TracBrowser for help on using the repository browser.