-
Notifications
You must be signed in to change notification settings - Fork 20
/
Copy pathWLContextualMenuManager.m
181 lines (156 loc) · 6.24 KB
/
WLContextualMenuManager.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
//
// YLContextualMenuManager.m
// MacBlueTelnet
//
// Created by Lan Yung-Luen on 11/28/07.
// Copyright 2007 yllan.org. All rights reserved.
//
// new interface, by boost @ 9#
#import "WLContextualMenuManager.h"
#import "WLEmoticonsPanelController.h"
#import "SynthesizeSingleton.h"
#import "Carbon/Carbon.h"
#ifdef _DEBUG
#import "WLEncoder.h"
#endif
NSString *const WLContextualMenuItemTitleFormatAttributeName = @"Title Format";
NSString *const WLContextualMenuItemURLFormatAttributeName = @"URL Format";
NSString *const WLOpenURLMenuItemFilename = @"contextualMenuItems";
@implementation WLContextualMenuManager
SYNTHESIZE_SINGLETON_FOR_CLASS(WLContextualMenuManager);
@synthesize openURLItemArray = _openURLItemArray;
- (id)init {
if (self = [super init]) {
@synchronized(self) {
// init may be called multiple times,
// but there is only one shared instance.
// So we need to make sure this array have been initialized only once
if (!_openURLItemArray) {
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *preferredLocalizationName = (NSString *)[[mainBundle preferredLocalizations] objectAtIndex:0];
_openURLItemArray = [[NSArray arrayWithContentsOfFile:
[mainBundle pathForResource:WLOpenURLMenuItemFilename
ofType:@"plist"
inDirectory:nil
forLocalization:preferredLocalizationName]] copy];
}
}
}
return self;
}
+ (NSMenuItem *)menuItemWithDictionary:(NSDictionary *)dictionary
selectedString:(NSString *)s {
NSString *title = [NSString stringWithFormat:
[dictionary valueForKey:WLContextualMenuItemTitleFormatAttributeName],
s, nil];
NSString *url = [NSString stringWithFormat:
[dictionary valueForKey:WLContextualMenuItemURLFormatAttributeName],
[s stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding], nil];
NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:title
action:@selector(openURL:)
keyEquivalent:@""];
[item setToolTip:url];
[item setRepresentedObject:url];
return [item autorelease];
}
+ (NSMenu *)menuWithSelectedString:(NSString*)selectedString {
NSMenu *menu = [[[NSMenu alloc] init] autorelease];
// Remove all '\n' '\r' ' ' from the URL string
NSString *longURL = [selectedString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
longURL = [longURL stringByReplacingOccurrencesOfString:@" " withString:@""];
longURL = [longURL stringByReplacingOccurrencesOfString:@"\r" withString:@""];
if ([[longURL componentsSeparatedByString:@"."] count] > 1) {
if (![longURL hasPrefix:@"http://"])
longURL = [@"http://" stringByAppendingString:longURL];
[menu addItemWithTitle:longURL
action:@selector(openURL:)
keyEquivalent:@""];
}
if ([selectedString length] > 0) {
[menu addItemWithTitle:NSLocalizedString(@"Search in Spotlight", @"Menu")
action:@selector(spotlight:)
keyEquivalent:@""];
[menu addItemWithTitle:NSLocalizedString(@"Look Up in Dictionary", @"Menu")
action:@selector(lookupDictionary:)
keyEquivalent:@""];
[menu addItem:[NSMenuItem separatorItem]];
#ifdef _DEBUG
if ([selectedString length] >= 1) {
unichar ch = [selectedString characterAtIndex:0];
if (ch >= 0x007F) {
unichar u2bCode = [WLEncoder fromUnicode:ch encoding:WLBig5Encoding];
unichar u2gCode = [WLEncoder fromUnicode:ch encoding:WLGBKEncoding];
NSString *str = [NSString stringWithFormat:@"%@ : ch = %04x, U2B[ch] = %04x, U2G[ch] = %04x", selectedString, ch, u2bCode, u2gCode];
[menu addItemWithTitle:str action:@selector(copyCodeInfo:) keyEquivalent:@""];
}
}
#endif
if ([[[NSApp keyWindow] firstResponder] respondsToSelector:@selector(copy:)]) {
NSMenuItem *item = [[[NSMenuItem alloc] initWithTitle:NSLocalizedString(@"Copy", @"Menu")
action:@selector(copy:)
keyEquivalent:@""] autorelease];
[item setTarget:[[NSApp keyWindow] firstResponder]];
[menu addItem:item];
}
[menu addItemWithTitle:NSLocalizedString(@"Save as Emoticon", @"Menu")
action:@selector(saveAsEmoticon:)
keyEquivalent:@""];
if ([[[WLContextualMenuManager sharedInstance] openURLItemArray] count] > 0) {
// User customized menu items
[menu addItem:[NSMenuItem separatorItem]];
for (NSObject *obj in [[WLContextualMenuManager sharedInstance] openURLItemArray]) {
if ([obj isKindOfClass:[NSDictionary class]]) {
NSMenuItem *item = [WLContextualMenuManager menuItemWithDictionary:(NSDictionary *)obj
selectedString:selectedString];
[menu addItem:item];
}
}
}
}
for (int i = 0; i < [menu numberOfItems]; ++i) {
NSMenuItem *item = [menu itemAtIndex:i];
if ([item isSeparatorItem])
continue;
if ([item target] == nil)
[item setTarget:self];
if ([item representedObject] == nil)
[item setRepresentedObject:selectedString];
}
return menu;
}
#ifdef _DEBUG
+ (void)copyCodeInfo:(id)sender {
NSString *s = [sender title];
NSPasteboard *pb = [NSPasteboard generalPasteboard];
NSMutableArray *types = [NSMutableArray arrayWithObject:NSStringPboardType];
if (!s) s = @"";
[pb declareTypes:types owner:self];
[pb setString:s forType:NSStringPboardType];
}
#endif
+ (void)openURL:(id)sender {
NSString *u = [sender representedObject];
if (!u) {
u = [sender title];
}
if (![u hasPrefix:@"http://"]) {
u = [@"http://" stringByAppendingString:[u stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];
}
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:u]];
}
+ (void)spotlight:(id)sender {
NSString *u = [sender representedObject];
HISearchWindowShow((CFStringRef)u, kNilOptions);
}
+ (void)lookupDictionary:(id)sender {
NSString *u = [sender representedObject];
NSPasteboard *spb = [NSPasteboard pasteboardWithUniqueName];
[spb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:self];
[spb setString:u forType:NSStringPboardType];
NSPerformService(@"Look Up in Dictionary", spb);
}
+ (void)saveAsEmoticon:(id)sender {
NSString *s = [sender representedObject];
[[WLEmoticonsPanelController sharedInstance] addEmoticonFromString:s];
}
@end