source: trunk/ICeCoffEE/ICeCoffEE/ICeCoffEEKeyEquivalents.m@ 426

Last change on this file since 426 was 319, checked in by Nicholas Riley, 17 years ago

VERSION: Starting with 1.5d1.

ICeCoffEEKeyEquivalents.m: Support "collision font" for displaying key
equivalent conflicts.

ICeCoffEE.m: Increase debug ICCF_MAX_URL_LEN to 120 for testing. Set
icons in ICCF_ConsolidateServicesMenu (needs better caching).

ICeCoffEEServicePrefController.m: Display icons, proper key
equivalents (instead of #, what was I thinking?!) and conflicts. Fix
a dumb bug in ICCF_PropagateServiceStateChange. Ellipsize long menu
items rather than chopping them off. Fix key equivalent column
getting moved when expanding disclosure triangles.

ICeCoffEELabeledIconCell.[hm]: An IconRef-displaying text cell.

Info-APE Module.plist: Update version to 1.5d1.

ICeCoffEE.xcodeproj: Added files, no significant changes.

English.lproj/InfoPlist.strings: Update version to 1.5d1.

English.lproj/APEInfo.rtfd/TXT.rtf: Some overdue documentation
updates.

ICeCoffEEShared.[hm]: Enable debugging; we're now using
kICServiceShortcut (though not yet for customizable shortcuts) so
define its data type.

ICeCoffEETerminal.m: Remove some useless code to "extend to beginning
of string" which seems to have been stolen from the NSTextView
implementation and not well understood. Handle common uses of
parentheses in URLs; still need to do this for NSTextView.

ICeCoffEESetServicesMenu.[hm]: Needs renaming; now with icon
extraction functionality and semi-working code to create a service
info dictionary.

Info-APEManagerPrefPane.plist: Update version to 1.5d1.

File size: 6.6 KB
Line 
1//
2// ICeCoffEEKeyEquivalents.m
3// ICeCoffEE APE
4//
5// Created by Nicholas Riley on Mon Jun 9 2003.
6// Copyright (c) 2002 Nicholas Riley. All rights reserved.
7//
8
9// Original implementations of these functions are in NSString-NJRExtensions
10// and NSFont-NJRExtensions from Pester.
11
12#import <Carbon/Carbon.h>
13#import <AppKit/AppKit.h>
14
15static NSFont *themeFont(ThemeFontID fontID) {
16 NSFont *themeFont = nil;
17 Str255 pstrFontName;
18 SInt16 fontSize = 0;
19 OSStatus status;
20 // can't simulate algorithmic styles in Cocoa in any case, so here's hoping nothing will be passed back - XXX guess this should at least accommodate the bold system font, but we don't need it
21 status = GetThemeFont(fontID, smSystemScript, pstrFontName, &fontSize, NULL);
22
23 if (status == noErr) {
24 NSString *fontName = (NSString *)CFStringCreateWithPascalString(NULL, pstrFontName, CFStringGetSystemEncoding());
25 themeFont = [NSFont fontWithName: fontName size: fontSize];
26 [fontName release];
27 }
28 if (themeFont == nil) {
29 themeFont = [NSFont systemFontOfSize: fontSize == 0 ? [NSFont systemFontSize] : fontSize];
30 }
31 return themeFont;
32}
33
34static NSString *stringWithCharacter(unichar character) {
35 return [NSString stringWithCharacters: &character length: 1];
36}
37
38static unichar combiningHelpChar[] = {0x003F, 0x20DD};
39
40static NSFont *menuItemCmdKeyFont = nil;
41static NSFont *menuItemFont = nil;
42static NSFont *collisionFont = nil;
43static NSParagraphStyle *keyEquivParaStyle;
44
45static inline void initialize() {
46 if (menuItemCmdKeyFont != nil) return;
47
48 menuItemCmdKeyFont = [themeFont(kThemeMenuItemCmdKeyFont) retain];
49 menuItemFont = [themeFont(kThemeMenuItemFont) retain];
50 collisionFont = [themeFont(kThemeSmallSystemFont) retain];
51
52 NSMutableParagraphStyle *paraStyle = [[NSMutableParagraphStyle alloc] init];
53 [paraStyle setTabStops: [NSArray arrayWithObjects:
54 [[[NSTextTab alloc] initWithType: NSRightTabStopType location: 30] autorelease],
55 [[[NSTextTab alloc] initWithType: NSLeftTabStopType location: 30.01] autorelease],
56 nil]];
57 [paraStyle setLineBreakMode: NSLineBreakByClipping];
58 keyEquivParaStyle = [paraStyle copy];
59 [paraStyle release];
60}
61
62// set tabs here, for ICeCoffEE (not in Pester)
63static NSAttributedString *attributedStringWithFont(NSString *self, NSFont *font) {
64 return [[[NSAttributedString alloc] initWithString: self attributes: [NSDictionary dictionaryWithObjectsAndKeys: font, NSFontAttributeName, keyEquivParaStyle, NSParagraphStyleAttributeName, nil]] autorelease];
65}
66
67static NSString *keyEquivalentString(NSString *self) {
68 if ([self length] != 0) {
69 const char *str = [self UTF8String];
70 unichar keyChar;
71 if (str[1] != '\0') {
72 keyChar = [self characterAtIndex: 0];
73 switch (keyChar) {
74 case NSUpArrowFunctionKey: keyChar = 0x21E1; break;
75 case NSDownArrowFunctionKey: keyChar = 0x21E3; break;
76 case NSLeftArrowFunctionKey: keyChar = 0x21E0; break;
77 case NSRightArrowFunctionKey: keyChar = 0x21E2; break;
78 case NSInsertFunctionKey:
79 return [NSString stringWithCharacters: combiningHelpChar length: 2];
80 case NSDeleteFunctionKey: keyChar = 0x2326; break;
81 case NSHomeFunctionKey: keyChar = 0x2196; break;
82 case NSEndFunctionKey: keyChar = 0x2198; break;
83 case NSPageUpFunctionKey: keyChar = 0x21DE; break;
84 case NSPageDownFunctionKey: keyChar = 0x21DF; break;
85 case NSClearLineFunctionKey: keyChar = 0x2327; break;
86 default:
87 if (keyChar >= NSF1FunctionKey && keyChar <= NSF35FunctionKey) {
88 return [NSString stringWithFormat: @"F%u", keyChar - NSF1FunctionKey + 1];
89 }
90 return [NSString stringWithFormat: @"[unknown %lX]", keyChar];
91 }
92 } else if (str[0] >= 'A' && str[0] <= 'Z') {
93 return self;
94 } else if (str[0] >= 'a' && str[0] <= 'z') return [self uppercaseString];
95 else switch (str[0]) {
96 case '\t': keyChar = 0x21e5; break;
97 case '\r': keyChar = 0x21a9; break;
98 case '\e': keyChar = 0x238b; break;
99 case ' ': keyChar = 0x2423; break;
100 case 0x7f: keyChar = 0x232b; break; // delete
101 case 0x03: keyChar = 0x2324; break; // enter
102 case 0x19: keyChar = 0x21e4; break; // backtab
103 case 0: return @"";
104 // case '': keyChar = 0x; break;
105 default: return self; // return [NSString stringWithFormat: @"[huh? %x]", (int)str[0]];
106 }
107 return stringWithCharacter(keyChar);
108 }
109 return self;
110}
111
112NSAttributedString *ICCF_KeyEquivalentAttributedStringWithModifierFlags(NSString *self, unsigned int modifierFlags, unsigned count) {
113 initialize();
114 NSString *keyEquivalentStringNoMask = keyEquivalentString(self);
115 // use tabs here, for ICeCoffEE (not in Pester, at least without better subclassing)
116 NSAttributedString *keyEquivalentAttributedString =
117 attributedStringWithFont(
118 [NSString stringWithFormat: @"\t%@%@%@%@\t%@",
119 (modifierFlags & NSControlKeyMask) ? stringWithCharacter(kControlUnicode) : @"",
120 (modifierFlags & NSAlternateKeyMask) ? stringWithCharacter(kOptionUnicode) : @"",
121 (modifierFlags & NSShiftKeyMask) ? stringWithCharacter(kShiftUnicode) : @"",
122 (modifierFlags & NSCommandKeyMask) ? stringWithCharacter(kCommandUnicode) : @"",
123 keyEquivalentStringNoMask], menuItemCmdKeyFont);
124 unsigned noMaskLength = [keyEquivalentStringNoMask length];
125 if (noMaskLength > 3 || // Fxx
126 (noMaskLength == 1 && [keyEquivalentStringNoMask characterAtIndex: 0] <= 0x7F)) {
127 NSMutableAttributedString *astr = [keyEquivalentAttributedString mutableCopy];
128 [astr setAttributes: [NSDictionary dictionaryWithObject: menuItemFont forKey: NSFontAttributeName] range: NSMakeRange([astr length] - noMaskLength, noMaskLength)];
129 keyEquivalentAttributedString = [[astr copy] autorelease];
130 [astr release];
131 }
132 if (count > 1) {
133 NSMutableAttributedString *astr = [keyEquivalentAttributedString mutableCopy];
134 [astr appendAttributedString: [[[NSAttributedString alloc]
135 initWithString: [NSString stringWithFormat: @" (%u)", count]
136 attributes: [NSDictionary dictionaryWithObjectsAndKeys: collisionFont, NSFontAttributeName, [NSColor redColor], NSForegroundColorAttributeName, nil]] autorelease]];
137 keyEquivalentAttributedString = [[astr copy] autorelease];
138 [astr release];
139 }
140 return keyEquivalentAttributedString;
141}
Note: See TracBrowser for help on using the repository browser.