source: trunk/ICeCoffEE/ICeCoffEE/ICeCoffEETTView.m@ 495

Last change on this file since 495 was 436, checked in by Nicholas Riley, 16 years ago

Use @try/@catch/@finally rather than macro-based exceptions

File size: 4.3 KB
Line 
1//
2// ICeCoffEETTView.m
3// ICeCoffEE
4//
5// Created by Nicholas Riley on 2/21/08.
6// Copyright 2008 Nicholas Riley. All rights reserved.
7//
8
9#import "ICeCoffEETTView.h"
10#import "ICeCoffEE.h"
11#import "ICeCoffEEParser.h"
12#import "ICeCoffEETTViewTrigger.h"
13#include <unistd.h>
14
15static NSRange ICCF_zeroRange = { NSNotFound, 5 };
16
17@implementation ICeCoffEETTViewSuper
18// NSTextInput implementation
19- (void)insertText:(id)aString {}
20- (void)doCommandBySelector:(SEL)aSelector {}
21- (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange {}
22- (void)unmarkText {}
23- (BOOL)hasMarkedText { return NO; }
24- (long)conversationIdentifier { return 0; }
25- (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange { return nil; }
26- (NSRange)markedRange { return ICCF_zeroRange; }
27- (NSRange)selectedRange { return ICCF_zeroRange; }
28- (NSRect)firstRectForCharacterRange:(NSRange)theRange { return NSZeroRect; }
29- (unsigned int)characterIndexForPoint:(NSPoint)thePoint { return 0; }
30- (NSArray*)validAttributesForMarkedText { return nil; }
31// Selection
32- (void)clearTextSelection {}
33- (void)setSelectedRange:(NSRange)charRange {}
34// misc. other stuff
35- (NSString *)string { return nil; }
36@end
37
38static BOOL ICCF_discardNextMouseUp = NO;
39
40void ICCF_LaunchURLFromTTView(ICeCoffEETTView *self, NSEvent *triggeringEvent, NSRange range) {
41
42 @try {
43 NSString *s = [self string];
44 unsigned length = [s length];
45 NSCAssert(s != nil && length != 0, ICCF_LocalizedString(@"No text was found"));
46
47 ICCF_StartIC();
48
49 // XXX handle discontiguous/rectangular selection with [self valueForKey: @"textSelectionRanges"] => NSIndexSet
50 NSCAssert(range.location < length, ICCF_LocalizedString(@"Sorry, ICeCoffEE was unable to find anything to select"));
51 if (range.length == 0) {
52 range.length = 1;
53 range = ICCF_URLEnclosingRange(s, range);
54 [self setSelectedRange: range];
55 }
56
57 iccfURLAction keyboardAction = ICCF_KeyboardAction(triggeringEvent);
58 if (ICCF_LaunchURL([s substringWithRange: range], keyboardAction)) {
59 if (ICCF_prefs.textBlinkEnabled) {
60 for (unsigned i = 0 ; i < ICCF_prefs.textBlinkCount ; i++) {
61 [self clearTextSelection];
62 [self display];
63 usleep(kICBlinkDelayUsecs);
64 [self setSelectedRange: range];
65 [self display];
66 usleep(kICBlinkDelayUsecs);
67 }
68 }
69 } else if (keyboardAction.presentMenu) {
70 // mouse up used to cancel menu?
71 // XXX next click lost if Esc used; next drag behaves like Command-drag
72 ICCF_discardNextMouseUp = YES;
73 }
74 } @catch (NSException *e) {
75 ICCF_HandleException(e, triggeringEvent);
76 }
77
78 ICCF_StopIC();
79}
80
81
82@implementation ICeCoffEETTView
83
84static NSEvent *ICCF_downEvent;
85
86- (void)mouseUp:(NSEvent *)upEvent;
87{
88 if (ICCF_downEvent != nil) {
89 NSPoint downPt = [ICCF_downEvent locationInWindow];
90 NSPoint upPt = [upEvent locationInWindow];
91 if (abs(downPt.x - upPt.x) <= kICHysteresisPixels && abs(downPt.y - upPt.y) <= kICHysteresisPixels) {
92 [ICeCoffEETTViewTrigger setTriggerForEvent: ICCF_downEvent onTarget: self];
93 ICCF_discardNextMouseUp = YES; // otherwise Command-Option-click => cursor repositioning Option-click
94 }
95 [ICCF_downEvent release];
96 ICCF_downEvent = nil;
97 }
98 ICLog(@"ICeCoffEETTView up: %@", upEvent);
99 if (ICCF_discardNextMouseUp) {
100 ICCF_discardNextMouseUp = NO;
101 return;
102 }
103 [super mouseUp: upEvent];
104}
105
106- (void)mouseDown:(NSEvent *)downEvent;
107{
108 [ICeCoffEETrigger cancel];
109
110 if (ICCF_enabled && ICCF_prefs.commandClickEnabled && ICCF_EventIsCommandMouseDown(downEvent)) {
111 [ICCF_downEvent release];
112 ICCF_downEvent = [downEvent retain];
113 }
114 ICLog(@"ICeCoffEETTView down: %@", downEvent);
115 [super mouseDown: downEvent];
116}
117
118- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender;
119{
120 if (!ICCF_prefs.terminalRequireOptionForSelfDrag || [sender draggingSource] != self || ([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask)) {
121 [super draggingEntered: sender];
122 // When doing non-self drags, this works around one bug in Terminal wherein the option key acts as a toggle, and it shouldn't (see Aqua HIG). Unfortunately, this messes up drag feedback for self drags, but I don't know of any way to fix it. Not that most Cocoa apps get it remotely right, anyway.
123 return NSDragOperationCopy;
124 }
125 return NSDragOperationNone;
126}
127
128@end
Note: See TracBrowser for help on using the repository browser.