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

Last change on this file since 436 was 436, checked in by Nicholas Riley, 12 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.