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

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