1 | //
|
---|
2 | // ICeCoffEETerminal.m
|
---|
3 | // ICeCoffEE
|
---|
4 | //
|
---|
5 | // Created by Nicholas Riley on Mon Jan 28 2002.
|
---|
6 | // Copyright (c) 2002 Nicholas Riley. All rights reserved.
|
---|
7 | //
|
---|
8 |
|
---|
9 | #import "ICeCoffEETerminal.h"
|
---|
10 | #import "ICeCoffEEScanner.h"
|
---|
11 | #import "ICeCoffEE.h"
|
---|
12 | #import <Carbon/Carbon.h>
|
---|
13 | #include <unistd.h>
|
---|
14 |
|
---|
15 | static NSRange ICCF_zeroRange = { NSNotFound, 5 };
|
---|
16 |
|
---|
17 | #define min(a,b) (a < b ? a : b)
|
---|
18 | #define max(a,b) (a > b ? a : b)
|
---|
19 |
|
---|
20 | @interface TermStorage:NSObject
|
---|
21 | - (struct _FSelPt)selPt0;
|
---|
22 | - (struct _FSelPt)selPt1;
|
---|
23 | - (BOOL)hasSelection;
|
---|
24 | - (void)startSelectionAtLine:(unsigned int)row column:(unsigned short)column;
|
---|
25 | - (void)startSelectionAtLine:(unsigned int)row offset:(unsigned short)offset;
|
---|
26 | - (void)endSelectionAtLine:(unsigned int)row offset:(unsigned short)offset;
|
---|
27 | - (void)selectWhitespaceDelimitedTextAtLine:(unsigned int)line offset:(unsigned short)offset;
|
---|
28 | - (void)selectWordAtLine:(unsigned int)line offset:(unsigned short)offset;
|
---|
29 | - (NSString *)selectedString;
|
---|
30 | - (unsigned int)numberOfLines;
|
---|
31 | - (unsigned int)effectiveColumnsForLine:(unsigned int)line;
|
---|
32 | - (void)clearSelection;
|
---|
33 | - (BOOL)isSelected:(unsigned int)line :(unsigned int)column;
|
---|
34 | @end
|
---|
35 |
|
---|
36 | @interface TermController:NSObject
|
---|
37 | - (TermStorage *)storage;
|
---|
38 | @end
|
---|
39 |
|
---|
40 | @implementation ICECoffEETermSubviewSuper
|
---|
41 | // NSTextInput implementation
|
---|
42 | - (void)insertText:(id)aString {}
|
---|
43 | - (void)doCommandBySelector:(SEL)aSelector {}
|
---|
44 | - (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange {}
|
---|
45 | - (void)unmarkText {}
|
---|
46 | - (BOOL)hasMarkedText { return NO; }
|
---|
47 | - (long)conversationIdentifier { return 0; }
|
---|
48 | - (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange { return nil; }
|
---|
49 | - (NSRange)markedRange { return ICCF_zeroRange; }
|
---|
50 | - (NSRange)selectedRange { return ICCF_zeroRange; }
|
---|
51 | - (NSRect)firstRectForCharacterRange:(NSRange)theRange { return NSZeroRect; }
|
---|
52 | - (unsigned int)characterIndexForPoint:(NSPoint)thePoint { return 0; }
|
---|
53 | - (NSArray*)validAttributesForMarkedText { return nil; }
|
---|
54 |
|
---|
55 | // misc. other stuff
|
---|
56 | - (void)_optionClickEvent:(NSEvent *)event:(unsigned int)row:(unsigned short)column {}
|
---|
57 | - (void)setNeedsDisplay; {}
|
---|
58 |
|
---|
59 | @end
|
---|
60 |
|
---|
61 | @interface ICeCoffEETerminalRange : NSObject
|
---|
62 | {
|
---|
63 | TermStorage *storage;
|
---|
64 | struct _FSelPt pt0;
|
---|
65 | struct _FSelPt pt1;
|
---|
66 | unsigned int width;
|
---|
67 | unsigned int height;
|
---|
68 | }
|
---|
69 |
|
---|
70 | + (ICeCoffEETerminalRange *)rangeWithTerminal:(ICeCoffEETerminal *)terminal;
|
---|
71 | + (ICeCoffEETerminalRange *)rangeWithTerminal:(ICeCoffEETerminal *)terminal pt0:(struct _FSelPt)selPt0 pt1:(struct _FSelPt)selPt1;
|
---|
72 |
|
---|
73 | - (id)initWithTerminal:(ICeCoffEETerminal *)terminal;
|
---|
74 | - (id)initWithTerminal:(ICeCoffEETerminal *)terminal pt0:(struct _FSelPt)selPt0 pt1:(struct _FSelPt)selPt1;
|
---|
75 |
|
---|
76 | - (struct _FSelPt)pt0;
|
---|
77 | - (struct _FSelPt)pt1;
|
---|
78 |
|
---|
79 | - (NSString *)stringFromRange;
|
---|
80 |
|
---|
81 | - (void)growBackwardByLength:(unsigned long)length;
|
---|
82 | - (void)growForwardByLength:(unsigned long)length;
|
---|
83 |
|
---|
84 | - (void)shrinkBackByLength:(unsigned long)length;
|
---|
85 | - (void)shrinkFrontByLength:(unsigned long)length;
|
---|
86 |
|
---|
87 | - (BOOL)rangeIsEmpty;
|
---|
88 |
|
---|
89 | - (void)select;
|
---|
90 |
|
---|
91 | @end
|
---|
92 |
|
---|
93 | @implementation ICeCoffEETerminalRange
|
---|
94 |
|
---|
95 | + (ICeCoffEETerminalRange *)rangeWithTerminal:(ICeCoffEETerminal *)terminal;
|
---|
96 | {
|
---|
97 | return [[[self alloc] initWithTerminal: terminal] autorelease];
|
---|
98 | }
|
---|
99 |
|
---|
100 | + (ICeCoffEETerminalRange *)rangeWithTerminal:(ICeCoffEETerminal *)terminal pt0:(struct _FSelPt)selPt0 pt1:(struct _FSelPt)selPt1;
|
---|
101 | {
|
---|
102 | return [[[self alloc] initWithTerminal: terminal pt0: selPt0 pt1: selPt1] autorelease];
|
---|
103 | }
|
---|
104 |
|
---|
105 | - (id)initWithTerminal:(ICeCoffEETerminal *)terminal;
|
---|
106 | {
|
---|
107 | if ( (self = [self init]) != nil) {
|
---|
108 | storage = [(TermController *)[terminal valueForKey: @"controller"] storage];
|
---|
109 | pt0 = [storage selPt0];
|
---|
110 | pt1 = [storage selPt1];
|
---|
111 | width = [storage effectiveColumnsForLine: pt0.line];
|
---|
112 | height = [storage numberOfLines];
|
---|
113 | }
|
---|
114 | return self;
|
---|
115 | }
|
---|
116 |
|
---|
117 | - (id)initWithTerminal:(ICeCoffEETerminal *)terminal pt0:(struct _FSelPt)selPt0 pt1:(struct _FSelPt)selPt1;
|
---|
118 | {
|
---|
119 | if ( (self = [self initWithTerminal: terminal]) != nil) {
|
---|
120 | pt0 = selPt0;
|
---|
121 | pt1 = selPt1;
|
---|
122 | }
|
---|
123 | return self;
|
---|
124 | }
|
---|
125 |
|
---|
126 | - (struct _FSelPt)pt0;
|
---|
127 | {
|
---|
128 | return pt0;
|
---|
129 | }
|
---|
130 |
|
---|
131 | - (struct _FSelPt)pt1;
|
---|
132 | {
|
---|
133 | return pt1;
|
---|
134 | }
|
---|
135 |
|
---|
136 | - (NSString *)stringFromRange;
|
---|
137 | {
|
---|
138 | struct _FSelPt oldPt0 = [storage selPt0], oldPt1 = [storage selPt1];
|
---|
139 | NSString *str;
|
---|
140 |
|
---|
141 | [storage startSelectionAtLine: pt0.line offset: pt0.col];
|
---|
142 | [storage endSelectionAtLine: pt1.line offset: pt1.col];
|
---|
143 |
|
---|
144 | str = [storage selectedString];
|
---|
145 |
|
---|
146 | [storage startSelectionAtLine: oldPt0.line offset: oldPt0.col];
|
---|
147 | [storage endSelectionAtLine: oldPt1.line offset: oldPt1.col];
|
---|
148 |
|
---|
149 | return str;
|
---|
150 | }
|
---|
151 |
|
---|
152 | - (struct _FSelPt)_moveBack:(struct _FSelPt)pt byLength:(unsigned long)length;
|
---|
153 | {
|
---|
154 | unsigned int extraLines = length / width;
|
---|
155 | if ((long)(pt.line - extraLines) < 0) {
|
---|
156 | pt.line = 0;
|
---|
157 | pt.col = 0;
|
---|
158 | } else if (pt.line - extraLines == 0) {
|
---|
159 | pt.line = 0;
|
---|
160 | pt.col += width - (length % height);
|
---|
161 | if (pt.col < width) pt.col = 0;
|
---|
162 | else pt.col -= width;
|
---|
163 | } else {
|
---|
164 | pt.line -= extraLines;
|
---|
165 | pt.col += width - (length % height);
|
---|
166 | if (pt.col < width) pt.line--;
|
---|
167 | else pt.col -= width;
|
---|
168 | }
|
---|
169 | return pt;
|
---|
170 | }
|
---|
171 |
|
---|
172 | - (struct _FSelPt)_moveForward:(struct _FSelPt)pt byLength:(unsigned long)length;
|
---|
173 | {
|
---|
174 | unsigned int extraLines = length / width;
|
---|
175 | if (pt.line + extraLines >= height) {
|
---|
176 | pt.line = height - 1;
|
---|
177 | pt.col = width - 1;
|
---|
178 | } else if (pt.line + extraLines == height - 1) {
|
---|
179 | pt.line = height - 1;
|
---|
180 | pt.col += length % height;
|
---|
181 | if (pt.col >= width) pt.col = width - 1;
|
---|
182 | } else {
|
---|
183 | pt.line += extraLines;
|
---|
184 | pt.col = pt.col + (length % height);
|
---|
185 | if (pt.col > width) {
|
---|
186 | pt.line++;
|
---|
187 | pt.col -= width;
|
---|
188 | }
|
---|
189 | }
|
---|
190 | return pt;
|
---|
191 | }
|
---|
192 |
|
---|
193 | - (BOOL)rangeIsEmpty;
|
---|
194 | {
|
---|
195 | return (pt1.line < pt0.line) || (pt1.line == pt0.line && pt1.col <= pt0.col);
|
---|
196 | }
|
---|
197 |
|
---|
198 | - (void)growBackwardByLength:(unsigned long)length;
|
---|
199 | {
|
---|
200 | pt0 = [self _moveBack: pt0 byLength: length];
|
---|
201 | }
|
---|
202 |
|
---|
203 | - (void)growForwardByLength:(unsigned long)length;
|
---|
204 | {
|
---|
205 | pt1 = [self _moveForward: pt1 byLength: length];
|
---|
206 | }
|
---|
207 |
|
---|
208 | - (void)shrinkFrontByLength:(unsigned long)length;
|
---|
209 | {
|
---|
210 | pt0 = [self _moveForward: pt0 byLength: length];
|
---|
211 | }
|
---|
212 |
|
---|
213 | - (void)shrinkBackByLength:(unsigned long)length;
|
---|
214 | {
|
---|
215 | pt1 = [self _moveBack: pt1 byLength: length];
|
---|
216 | }
|
---|
217 |
|
---|
218 | - (void)select;
|
---|
219 | {
|
---|
220 | [storage startSelectionAtLine: pt0.line offset: pt0.col];
|
---|
221 | [storage endSelectionAtLine: pt1.line offset: pt1.col];
|
---|
222 | }
|
---|
223 |
|
---|
224 | - (NSString *)description;
|
---|
225 | {
|
---|
226 | return [NSString stringWithFormat: @"L%uC%hu - L%uC%hu: |%@|", pt0.line, pt0.col, pt1.line, pt1.col, [[self stringFromRange] stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]];
|
---|
227 | }
|
---|
228 |
|
---|
229 | @end
|
---|
230 |
|
---|
231 | // TermSubview's NSTextInput implementation is essentially a noop: make one that does something
|
---|
232 | @implementation ICeCoffEETerminal // XXX normally in category (NSTextInput), but APE doesnÕt work if I do that
|
---|
233 |
|
---|
234 | - (NSRange)selectedRange {
|
---|
235 | TermStorage *storage = [(TermController *)[self valueForKey: @"controller"] storage];
|
---|
236 | struct _FSelPt selPt0 = [storage selPt0], selPt1 = [storage selPt1];
|
---|
237 | unsigned width = [storage effectiveColumnsForLine: selPt0.line];
|
---|
238 | unsigned pt0 = selPt0.line * width + selPt0.col;
|
---|
239 | ICLog(@"selPt0 %d x %d selPt1 %d x %d", selPt0.line, selPt0.col, selPt1.line, selPt1.col);
|
---|
240 | return NSMakeRange(pt0, selPt1.line * width + selPt1.col - pt0);
|
---|
241 | }
|
---|
242 |
|
---|
243 | // XXX string isn't padded: what we need is something like the ICeCoffEE 1.2.x method, adapted to Terminal 1.2, but we've chosen another way
|
---|
244 | - (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange;
|
---|
245 | {
|
---|
246 | TermStorage *storage = [(TermController *)[self valueForKey: @"controller"] storage];
|
---|
247 | struct _FSelPt oldPt0 = [storage selPt0], oldPt1 = [storage selPt1], realPt0, realPt1;
|
---|
248 | unsigned pt1 = theRange.location + theRange.length;
|
---|
249 | unsigned width = [storage effectiveColumnsForLine: 0];
|
---|
250 | NSAttributedString *str;
|
---|
251 |
|
---|
252 | realPt0.line = theRange.location / width;
|
---|
253 | realPt0.col = theRange.location % width;
|
---|
254 | realPt1.line = pt1 / width;
|
---|
255 | realPt1.col = pt1 % width;
|
---|
256 |
|
---|
257 | [storage startSelectionAtLine: realPt0.line offset: realPt0.col];
|
---|
258 | [storage endSelectionAtLine: realPt1.line offset: realPt1.col];
|
---|
259 |
|
---|
260 | str = [[NSAttributedString alloc] initWithString: [storage selectedString]];
|
---|
261 |
|
---|
262 | NSAssert2([str length] == theRange.length, @"Substring has length %lu when we expected %lu", [str length], theRange.length);
|
---|
263 |
|
---|
264 | [storage startSelectionAtLine: oldPt0.line offset: oldPt0.col];
|
---|
265 | [storage endSelectionAtLine: oldPt1.line offset: oldPt1.col];
|
---|
266 |
|
---|
267 | return [str autorelease];
|
---|
268 | }
|
---|
269 |
|
---|
270 | static NSEvent *ICCF_downEvent;
|
---|
271 | static unsigned int ICCF_line;
|
---|
272 | static unsigned short ICCF_col;
|
---|
273 | static BOOL ICCF_optionClickRegistered;
|
---|
274 |
|
---|
275 | - (void)setSelectedRange:(NSRange)charRange affinity:(NSSelectionAffinity)affinity stillSelecting:(BOOL)stillSelectingFlag;
|
---|
276 | {
|
---|
277 | TermStorage *storage = [(TermController *)[self valueForKey: @"controller"] storage];
|
---|
278 | unsigned width = [storage effectiveColumnsForLine: 0];
|
---|
279 | unsigned pt1 = charRange.location + charRange.length;
|
---|
280 | [storage startSelectionAtLine: charRange.location / width offset: charRange.location % width];
|
---|
281 | [storage endSelectionAtLine: pt1 / width offset: pt1 % width];
|
---|
282 | // [self refresh];
|
---|
283 | }
|
---|
284 |
|
---|
285 | void ICCF_LaunchURLFromTerminal(ICeCoffEETerminal *self) {
|
---|
286 | NSCharacterSet *urlLeftDelimiters = nil, *urlRightDelimiters = nil;
|
---|
287 |
|
---|
288 | ICeCoffEETerminalRange *termRange = nil, *selRange = nil;
|
---|
289 | NSString *s;
|
---|
290 | NSRange range, delimiterRange;
|
---|
291 |
|
---|
292 | NS_DURING
|
---|
293 |
|
---|
294 | TermStorage *storage = [(TermController *)[self valueForKey: @"controller"] storage];
|
---|
295 |
|
---|
296 | if ([storage hasSelection] && [storage isSelected: ICCF_line : ICCF_col]) {
|
---|
297 | selRange = [ICeCoffEETerminalRange rangeWithTerminal: self];
|
---|
298 | } else { // select something
|
---|
299 | [storage selectWordAtLine: ICCF_line offset: ICCF_col];
|
---|
300 | selRange = [ICeCoffEETerminalRange rangeWithTerminal: self];
|
---|
301 | NSCAssert(![selRange rangeIsEmpty], ICCF_LocalizedString(@"Sorry, ICeCoffEE was unable to find anything to select"));
|
---|
302 | }
|
---|
303 |
|
---|
304 | // However, word selection does not capture even the approximate boundaries of a URL
|
---|
305 | // (text to a space/line ending character); it'll stop at a period in the middle of a hostname.
|
---|
306 | // So, we expand it as follows:
|
---|
307 |
|
---|
308 | ICCF_Delimiters(&urlLeftDelimiters, &urlRightDelimiters);
|
---|
309 |
|
---|
310 | termRange = [ICeCoffEETerminalRange rangeWithTerminal: self pt0: [selRange pt0] pt1: [selRange pt0]];
|
---|
311 | // add 1 to range to trap delimiters that are on the edge of the selection (i.e., <...)
|
---|
312 | [termRange growForwardByLength: 1];
|
---|
313 | [termRange growBackwardByLength: ICCF_MAX_URL_LEN]; // potentially too big
|
---|
314 | s = [termRange stringFromRange];
|
---|
315 | ICLog(@"front %@", termRange);
|
---|
316 | delimiterRange = [s rangeOfCharacterFromSet: urlLeftDelimiters
|
---|
317 | options: NSLiteralSearch | NSBackwardsSearch];
|
---|
318 | if (delimiterRange.location == NSNotFound) {
|
---|
319 | // extend to beginning of string (as much as possible)
|
---|
320 | [selRange growBackwardByLength: [s length] - 1];
|
---|
321 | } else {
|
---|
322 | NSCAssert(delimiterRange.length == 1, @"Internal error: delimiter matched range is not of length 1");
|
---|
323 | [selRange growBackwardByLength: [s length] - delimiterRange.location - 2];
|
---|
324 | }
|
---|
325 |
|
---|
326 | ICLog(@"parsed front %@", selRange);
|
---|
327 |
|
---|
328 | termRange = [ICeCoffEETerminalRange rangeWithTerminal: self pt0: [selRange pt1] pt1: [selRange pt1]];
|
---|
329 | // subtract 1 from range to trap delimiters that are on the edge of the selection (i.e., ...>)
|
---|
330 | [termRange growBackwardByLength: 1];
|
---|
331 | [termRange growForwardByLength: ICCF_MAX_URL_LEN]; // potentially too big
|
---|
332 | s = [termRange stringFromRange];
|
---|
333 | ICLog(@"back %@", termRange);
|
---|
334 | delimiterRange = [s rangeOfCharacterFromSet: urlRightDelimiters
|
---|
335 | options: NSLiteralSearch];
|
---|
336 | if (delimiterRange.location == NSNotFound) {
|
---|
337 | // extend to end of string
|
---|
338 | [selRange growForwardByLength: [s length] - 1];
|
---|
339 | } else {
|
---|
340 | NSCAssert(delimiterRange.length == 1, @"Internal error: delimiter matched range is not of length 1");
|
---|
341 | [selRange growForwardByLength: delimiterRange.location - 1];
|
---|
342 | }
|
---|
343 |
|
---|
344 | ICCF_StartIC();
|
---|
345 |
|
---|
346 | s = [selRange stringFromRange];
|
---|
347 |
|
---|
348 | range = NSMakeRange(0, [s length]);
|
---|
349 |
|
---|
350 | ICCF_CheckRange(range);
|
---|
351 |
|
---|
352 | ICLog(@"parsed back %@", selRange);
|
---|
353 | NSLog(@"range of string %@", NSStringFromRange(range));
|
---|
354 | ICCF_ParseURL(s, &range);
|
---|
355 | ICLog(@"parsed range %@ |%@|", NSStringFromRange(range), [s substringWithRange: range]);
|
---|
356 |
|
---|
357 | [selRange shrinkFrontByLength: range.location];
|
---|
358 | [selRange shrinkBackByLength: [s length] - range.length - range.location];
|
---|
359 |
|
---|
360 | s = [selRange stringFromRange];
|
---|
361 | ICLog(@"reconstituted URL %@", selRange);
|
---|
362 |
|
---|
363 | [selRange select];
|
---|
364 | [self setNeedsDisplay];
|
---|
365 | [[self superview] display];
|
---|
366 |
|
---|
367 | ICCF_LaunchURL(s, ICCF_OptionKeyIsDown());
|
---|
368 |
|
---|
369 | if (ICCF_prefs.textBlinkEnabled) {
|
---|
370 | int i;
|
---|
371 | // Terminal flashes the selection one more time, so blink one fewer
|
---|
372 | for (i = 1 ; i < ICCF_prefs.textBlinkCount ; i++) {
|
---|
373 | [storage clearSelection];
|
---|
374 | [self setNeedsDisplay];
|
---|
375 | [[self superview] display];
|
---|
376 | usleep(kICBlinkDelayUsecs);
|
---|
377 | [selRange select];
|
---|
378 | [self setNeedsDisplay];
|
---|
379 | [[self superview] display];
|
---|
380 | usleep(kICBlinkDelayUsecs);
|
---|
381 | }
|
---|
382 | }
|
---|
383 | NS_HANDLER
|
---|
384 | ICCF_HandleException(localException);
|
---|
385 | NS_ENDHANDLER
|
---|
386 |
|
---|
387 | ICCF_StopIC();
|
---|
388 | }
|
---|
389 |
|
---|
390 | - (void)_optionClickEvent:(NSEvent *)event:(unsigned int)row:(unsigned short)column;
|
---|
391 | {
|
---|
392 | if (ICCF_downEvent != nil) {
|
---|
393 | ICCF_line = row; // XXX are these lines or rows? check with wrapping
|
---|
394 | ICCF_col = column;
|
---|
395 | ICCF_optionClickRegistered = YES;
|
---|
396 | } else {
|
---|
397 | [super _optionClickEvent: event :row :column];
|
---|
398 | }
|
---|
399 | }
|
---|
400 |
|
---|
401 | - (void)mouseUp:(NSEvent *)upEvent;
|
---|
402 | {
|
---|
403 | ICLog(@"ICeCoffEE Terminal up: %@", upEvent);
|
---|
404 | [super mouseUp: upEvent];
|
---|
405 | // don't want command-option-click, command-shift-click, etc. to trigger
|
---|
406 | if (ICCF_downEvent != nil) {
|
---|
407 | NSPoint downPt = [ICCF_downEvent locationInWindow];
|
---|
408 | NSPoint upPt = [upEvent locationInWindow];
|
---|
409 | [ICCF_downEvent release];
|
---|
410 | ICCF_downEvent = nil;
|
---|
411 | if (abs(downPt.x - upPt.x) <= kICHysteresisPixels && abs(downPt.y - upPt.y) <= kICHysteresisPixels) {
|
---|
412 | if (ICCF_optionClickRegistered) {
|
---|
413 | ICCF_optionClickRegistered = NO;
|
---|
414 | ICLog(@"========= launching... %d x %d", ICCF_line, ICCF_col);
|
---|
415 | ICCF_LaunchURLFromTerminal(self);
|
---|
416 | }
|
---|
417 | }
|
---|
418 | }
|
---|
419 | }
|
---|
420 |
|
---|
421 | - (void)mouseDown:(NSEvent *)downEvent;
|
---|
422 | {
|
---|
423 | if (ICCF_enabled && ICCF_prefs.commandClickEnabled && ICCF_EventIsCommandMouseDown(downEvent)) {
|
---|
424 | NSEvent *optionClickEvent = [NSEvent mouseEventWithType: NSLeftMouseDown location: [downEvent locationInWindow] modifierFlags: NSAlternateKeyMask timestamp: [downEvent timestamp] windowNumber: [downEvent windowNumber] context: [downEvent context] eventNumber: [downEvent eventNumber] clickCount: 1 pressure: 0];
|
---|
425 | [ICCF_downEvent release];
|
---|
426 | ICCF_downEvent = [downEvent retain];
|
---|
427 | ICLog(@"ICeCoffEE Terminal constructed: %@", optionClickEvent);
|
---|
428 | ICCF_optionClickRegistered = NO;
|
---|
429 | [super mouseDown: optionClickEvent];
|
---|
430 | } else {
|
---|
431 | [super mouseDown: downEvent];
|
---|
432 | }
|
---|
433 | }
|
---|
434 |
|
---|
435 | @end
|
---|