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

Last change on this file since 435 was 388, checked in by Nicholas Riley, 13 years ago

APEMain.m: Note missing Xcode 3 support. Add Terminal 2.0 support.

English.lproj/APE Manager plugin.nib:

English.lproj/APEInfo.rtfd:

ICeCoffEE.[hm]: Bring triggering window and app to front if error
dialog displayed in ICCF_HandleException. Remove initial word
selection. Launch preexisting selection if present. Remove 10.3
support. Update for new ICeCoffEETrigger API. Rename downEvent
parameter for consistency.

ICeCoffEE.xcodeproj: Added files.

ICeCoffEEParser.m: Handle multiline URLs.

ICeCoffEETTView.[hm]: Terminal 2.0 support (thank you for having a
usable NSTextInput implementation!)

ICeCoffEETTViewTrigger.[hm]: ICeCoffEETrigger implementation for
TTView. Can't set range as we do for NSTextView because you can't
have an arbitrary empty selection range in Terminal, so we pass it
directly to ICCF_LaunchURLFromTTView.

ICeCoffEETerminal.[hm]: Fix capitalization on ICeCoffEETermSubviewSuper.
Pass downEvent to ICCF_HandleException so it can bring the triggering
window to the front.

ICeCoffEETextViewTrigger.[hm]: Moved from ICeCoffEETrigger.

ICeCoffEETrigger.[hm]: Now an abstract superclass. Replace direct
access to ICCF_sharedTrigger with +cancel. Create 0-character range
(if click outside selectedRange) or save selectedRange. Move
debugging logs here from ICeCoffEE.m. Add description method.

ICeCoffEEWebKit.m: Pass downEvent to ICCF_HandleException so it can
bring the triggering window to the front.

Installer components/ui/ui.plist: Updated for 1.5d3.

TestParser?.m: Handle multiline URLs; newlines are printed as \ and
tabs as >. Implement ICCF_StringByRemovingCharactersInSet, which will
move elsewhere once Internet Config support is removed.

VERSION.xcconfig: Updated for 1.5d3.

urls.plist: Test for multiline URLs.

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    NS_DURING
43
44        NSString *s = [self string];
45        unsigned length = [s length];
46        NSCAssert(s != nil && length != 0, ICCF_LocalizedString(@"No text was found"));
47       
48        ICCF_StartIC();
49       
50        // XXX handle discontiguous/rectangular selection with [self valueForKey: @"textSelectionRanges"] => NSIndexSet   
51        NSCAssert(range.location < length, ICCF_LocalizedString(@"Sorry, ICeCoffEE was unable to find anything to select"));
52        if (range.length == 0) {
53            range.length = 1;
54            range = ICCF_URLEnclosingRange(s, range);
55            [self setSelectedRange: range];
56        }
57       
58        iccfURLAction keyboardAction = ICCF_KeyboardAction(triggeringEvent);
59        if (ICCF_LaunchURL([s substringWithRange: range], keyboardAction)) {
60            if (ICCF_prefs.textBlinkEnabled) {
61                for (unsigned i = 0 ; i < ICCF_prefs.textBlinkCount ; i++) {
62                    [self clearTextSelection];
63                    [self display];
64                    usleep(kICBlinkDelayUsecs);
65                    [self setSelectedRange: range];
66                    [self display];
67                    usleep(kICBlinkDelayUsecs);
68                }
69            }
70        } else if (keyboardAction.presentMenu) {
71            // mouse up used to cancel menu?
72            // XXX next click lost if Esc used; next drag behaves like Command-drag
73            ICCF_discardNextMouseUp = YES;
74        }
75       
76    NS_HANDLER
77        ICCF_HandleException(localException, triggeringEvent);
78    NS_ENDHANDLER
79   
80    ICCF_StopIC();
81}
82
83
84@implementation ICeCoffEETTView
85
86static NSEvent *ICCF_downEvent;
87
88- (void)mouseUp:(NSEvent *)upEvent;
89{
90    if (ICCF_downEvent != nil) {
91        NSPoint downPt = [ICCF_downEvent locationInWindow];
92        NSPoint upPt = [upEvent locationInWindow];
93        if (abs(downPt.x - upPt.x) <= kICHysteresisPixels && abs(downPt.y - upPt.y) <= kICHysteresisPixels) {
94            [ICeCoffEETTViewTrigger setTriggerForEvent: ICCF_downEvent onTarget: self];
95            ICCF_discardNextMouseUp = YES; // otherwise Command-Option-click => cursor repositioning Option-click
96        }
97        [ICCF_downEvent release];
98        ICCF_downEvent = nil;
99    }
100    ICLog(@"ICeCoffEETTView up: %@", upEvent);
101    if (ICCF_discardNextMouseUp) {
102        ICCF_discardNextMouseUp = NO;
103        return;
104    }
105    [super mouseUp: upEvent];
106}
107
108- (void)mouseDown:(NSEvent *)downEvent;
109{
110    [ICeCoffEETrigger cancel];
111
112    if (ICCF_enabled && ICCF_prefs.commandClickEnabled && ICCF_EventIsCommandMouseDown(downEvent)) {
113        [ICCF_downEvent release];
114        ICCF_downEvent = [downEvent retain];
115    }
116    ICLog(@"ICeCoffEETTView down: %@", downEvent);
117    [super mouseDown: downEvent];
118}
119
120- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender;
121{
122    if (!ICCF_prefs.terminalRequireOptionForSelfDrag || [sender draggingSource] != self || ([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask)) {
123        [super draggingEntered: sender];
124        // 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.
125        return NSDragOperationCopy;
126    }
127    return NSDragOperationNone;
128}
129
130@end
Note: See TracBrowser for help on using the repository browser.