diff options
Diffstat (limited to 'cocoa/ScintillaView.mm')
-rw-r--r-- | cocoa/ScintillaView.mm | 2494 |
1 files changed, 1146 insertions, 1348 deletions
diff --git a/cocoa/ScintillaView.mm b/cocoa/ScintillaView.mm index df03add5f..ea6f6f510 100644 --- a/cocoa/ScintillaView.mm +++ b/cocoa/ScintillaView.mm @@ -17,221 +17,201 @@ using namespace Scintilla; // Add backend property to ScintillaView as a private category. // Specified here as backend accessed by SCIMarginView and SCIContentView. -@interface ScintillaView () -@property (nonatomic, readonly) Scintilla::ScintillaCocoa* backend; +@interface ScintillaView() +@property(nonatomic, readonly) Scintilla::ScintillaCocoa *backend; @end // Two additional cursors we need, which aren't provided by Cocoa. -static NSCursor* reverseArrowCursor; -static NSCursor* waitCursor; +static NSCursor *reverseArrowCursor; +static NSCursor *waitCursor; NSString *const SCIUpdateUINotification = @"SCIUpdateUI"; /** * Provide an NSCursor object that matches the Window::Cursor enumeration. */ -static NSCursor *cursorFromEnum(Window::Cursor cursor) -{ - switch (cursor) - { - case Window::cursorText: - return [NSCursor IBeamCursor]; - case Window::cursorArrow: - return [NSCursor arrowCursor]; - case Window::cursorWait: - return waitCursor; - case Window::cursorHoriz: - return [NSCursor resizeLeftRightCursor]; - case Window::cursorVert: - return [NSCursor resizeUpDownCursor]; - case Window::cursorReverseArrow: - return reverseArrowCursor; - case Window::cursorUp: - default: - return [NSCursor arrowCursor]; - } +static NSCursor *cursorFromEnum(Window::Cursor cursor) { + switch (cursor) { + case Window::cursorText: + return [NSCursor IBeamCursor]; + case Window::cursorArrow: + return [NSCursor arrowCursor]; + case Window::cursorWait: + return waitCursor; + case Window::cursorHoriz: + return [NSCursor resizeLeftRightCursor]; + case Window::cursorVert: + return [NSCursor resizeUpDownCursor]; + case Window::cursorReverseArrow: + return reverseArrowCursor; + case Window::cursorUp: + default: + return [NSCursor arrowCursor]; + } } // Add marginWidth and owner properties as a private category. -@interface SCIMarginView () -@property (assign) int marginWidth; -@property (nonatomic, weak) ScintillaView* owner; +@interface SCIMarginView() +@property(assign) int marginWidth; +@property(nonatomic, weak) ScintillaView *owner; @end @implementation SCIMarginView { - int marginWidth; - ScintillaView *__weak owner; - NSMutableArray *currentCursors; + int marginWidth; + ScintillaView *__weak owner; + NSMutableArray *currentCursors; } @synthesize marginWidth, owner; -- (instancetype)initWithScrollView:(NSScrollView *)aScrollView -{ - self = [super initWithScrollView:aScrollView orientation:NSVerticalRuler]; - if (self != nil) - { - owner = nil; - marginWidth = 20; - currentCursors = [NSMutableArray arrayWithCapacity:0]; - for (size_t i=0; i<=SC_MAX_MARGIN; i++) - { - [currentCursors addObject: reverseArrowCursor]; - } - self.clientView = aScrollView.documentView; - if ([self respondsToSelector: @selector(setAccessibilityLabel:)]) - self.accessibilityLabel = @"Scintilla Margin"; - } - return self; +- (instancetype) initWithScrollView: (NSScrollView *) aScrollView { + self = [super initWithScrollView: aScrollView orientation: NSVerticalRuler]; + if (self != nil) { + owner = nil; + marginWidth = 20; + currentCursors = [NSMutableArray arrayWithCapacity: 0]; + for (size_t i=0; i<=SC_MAX_MARGIN; i++) { + [currentCursors addObject: reverseArrowCursor]; + } + self.clientView = aScrollView.documentView; + if ([self respondsToSelector: @selector(setAccessibilityLabel:)]) + self.accessibilityLabel = @"Scintilla Margin"; + } + return self; } -- (void) setFrame: (NSRect) frame -{ - super.frame = frame; +- (void) setFrame: (NSRect) frame { + super.frame = frame; - [self.window invalidateCursorRectsForView: self]; + [self.window invalidateCursorRectsForView: self]; } -- (CGFloat)requiredThickness -{ - return marginWidth; +- (CGFloat) requiredThickness { + return marginWidth; } -- (void)drawHashMarksAndLabelsInRect:(NSRect)aRect -{ - if (owner) { - NSRect contentRect = self.scrollView.contentView.bounds; - NSRect marginRect = self.bounds; - // Ensure paint to bottom of view to avoid glitches - if (marginRect.size.height > contentRect.size.height) { - // Legacy scroll bar mode leaves a poorly painted corner - aRect = marginRect; - } - owner.backend->PaintMargin(aRect); - } +- (void) drawHashMarksAndLabelsInRect: (NSRect) aRect { + if (owner) { + NSRect contentRect = self.scrollView.contentView.bounds; + NSRect marginRect = self.bounds; + // Ensure paint to bottom of view to avoid glitches + if (marginRect.size.height > contentRect.size.height) { + // Legacy scroll bar mode leaves a poorly painted corner + aRect = marginRect; + } + owner.backend->PaintMargin(aRect); + } } /** * Called by the framework if it wants to show a context menu for the margin. */ -- (NSMenu*) menuForEvent: (NSEvent*) theEvent -{ - NSMenu *menu = [owner menuForEvent: theEvent]; - if (menu) { - return menu; - } else if (owner.backend->ShouldDisplayPopupOnMargin()) { - return owner.backend->CreateContextMenu(theEvent); - } else { - return nil; - } +- (NSMenu *) menuForEvent: (NSEvent *) theEvent { + NSMenu *menu = [owner menuForEvent: theEvent]; + if (menu) { + return menu; + } else if (owner.backend->ShouldDisplayPopupOnMargin()) { + return owner.backend->CreateContextMenu(theEvent); + } else { + return nil; + } } -- (void) mouseDown: (NSEvent *) theEvent -{ - NSClipView *textView = self.scrollView.contentView; - [textView.window makeFirstResponder:textView]; - owner.backend->MouseDown(theEvent); +- (void) mouseDown: (NSEvent *) theEvent { + NSClipView *textView = self.scrollView.contentView; + [textView.window makeFirstResponder: textView]; + owner.backend->MouseDown(theEvent); } -- (void) rightMouseDown: (NSEvent *) theEvent -{ - [NSMenu popUpContextMenu:[self menuForEvent: theEvent] withEvent:theEvent forView:self]; +- (void) rightMouseDown: (NSEvent *) theEvent { + [NSMenu popUpContextMenu: [self menuForEvent: theEvent] withEvent: theEvent forView: self]; - owner.backend->RightMouseDown(theEvent); + owner.backend->RightMouseDown(theEvent); } -- (void) mouseDragged: (NSEvent *) theEvent -{ - owner.backend->MouseMove(theEvent); +- (void) mouseDragged: (NSEvent *) theEvent { + owner.backend->MouseMove(theEvent); } -- (void) mouseMoved: (NSEvent *) theEvent -{ - owner.backend->MouseMove(theEvent); +- (void) mouseMoved: (NSEvent *) theEvent { + owner.backend->MouseMove(theEvent); } -- (void) mouseUp: (NSEvent *) theEvent -{ - owner.backend->MouseUp(theEvent); +- (void) mouseUp: (NSEvent *) theEvent { + owner.backend->MouseUp(theEvent); } // Not a simple button so return failure -- (BOOL)accessibilityPerformPress -{ - return NO; +- (BOOL) accessibilityPerformPress { + return NO; } /** * This method is called to give us the opportunity to define our mouse sensitive rectangle. */ -- (void) resetCursorRects -{ - [super resetCursorRects]; - - int x = 0; - NSRect marginRect = self.bounds; - size_t co = currentCursors.count; - for (size_t i=0; i<co; i++) - { - long cursType = owner.backend->WndProc(SCI_GETMARGINCURSORN, i, 0); - long width =owner.backend->WndProc(SCI_GETMARGINWIDTHN, i, 0); - NSCursor *cc = cursorFromEnum(static_cast<Window::Cursor>(cursType)); - currentCursors[i] = cc; - marginRect.origin.x = x; - marginRect.size.width = width; - [self addCursorRect: marginRect cursor: cc]; - [cc setOnMouseEntered: YES]; - x += width; - } +- (void) resetCursorRects { + [super resetCursorRects]; + + int x = 0; + NSRect marginRect = self.bounds; + size_t co = currentCursors.count; + for (size_t i=0; i<co; i++) { + long cursType = owner.backend->WndProc(SCI_GETMARGINCURSORN, i, 0); + long width =owner.backend->WndProc(SCI_GETMARGINWIDTHN, i, 0); + NSCursor *cc = cursorFromEnum(static_cast<Window::Cursor>(cursType)); + currentCursors[i] = cc; + marginRect.origin.x = x; + marginRect.size.width = width; + [self addCursorRect: marginRect cursor: cc]; + [cc setOnMouseEntered: YES]; + x += width; + } } @end // Add owner property as a private category. -@interface SCIContentView () -@property (nonatomic, weak) ScintillaView* owner; +@interface SCIContentView() +@property(nonatomic, weak) ScintillaView *owner; @end @implementation SCIContentView { - ScintillaView* __weak mOwner; - NSCursor* mCurrentCursor; - NSTrackingArea *trackingArea; + ScintillaView *__weak mOwner; + NSCursor *mCurrentCursor; + NSTrackingArea *trackingArea; - // Set when we are in composition mode and partial input is displayed. - NSRange mMarkedTextRange; + // Set when we are in composition mode and partial input is displayed. + NSRange mMarkedTextRange; } @synthesize owner = mOwner; //-------------------------------------------------------------------------------------------------- -- (NSView*) initWithFrame: (NSRect) frame -{ - self = [super initWithFrame: frame]; +- (NSView *) initWithFrame: (NSRect) frame { + self = [super initWithFrame: frame]; - if (self != nil) - { - // Some initialization for our view. - mCurrentCursor = [NSCursor arrowCursor]; - trackingArea = nil; - mMarkedTextRange = NSMakeRange(NSNotFound, 0); + if (self != nil) { + // Some initialization for our view. + mCurrentCursor = [NSCursor arrowCursor]; + trackingArea = nil; + mMarkedTextRange = NSMakeRange(NSNotFound, 0); - [self registerForDraggedTypes: @[NSStringPboardType, ScintillaRecPboardType, NSFilenamesPboardType]]; + [self registerForDraggedTypes: @[NSStringPboardType, ScintillaRecPboardType, NSFilenamesPboardType]]; - // Set up accessibility in the text role - if ([self respondsToSelector: @selector(setAccessibilityElement:)]) - { - self.accessibilityElement = TRUE; - self.accessibilityEnabled = TRUE; - self.accessibilityLabel = NSLocalizedString(@"Scintilla", nil); // No real localization - self.accessibilityRoleDescription = @"source code editor"; - self.accessibilityRole = NSAccessibilityTextAreaRole; - self.accessibilityIdentifier = @"Scintilla"; - } - } + // Set up accessibility in the text role + if ([self respondsToSelector: @selector(setAccessibilityElement:)]) { + self.accessibilityElement = TRUE; + self.accessibilityEnabled = TRUE; + self.accessibilityLabel = NSLocalizedString(@"Scintilla", nil); // No real localization + self.accessibilityRoleDescription = @"source code editor"; + self.accessibilityRole = NSAccessibilityTextAreaRole; + self.accessibilityIdentifier = @"Scintilla"; + } + } - return self; + return self; } //-------------------------------------------------------------------------------------------------- @@ -239,20 +219,18 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * When the view is resized or scrolled we need to update our tracking area. */ -- (void) updateTrackingAreas -{ - if (trackingArea) - { - [self removeTrackingArea:trackingArea]; - } +- (void) updateTrackingAreas { + if (trackingArea) { + [self removeTrackingArea: trackingArea]; + } - int opts = (NSTrackingActiveAlways | NSTrackingInVisibleRect | NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved); - trackingArea = [[NSTrackingArea alloc] initWithRect:self.bounds - options:opts - owner:self - userInfo:nil]; - [self addTrackingArea: trackingArea]; - [super updateTrackingAreas]; + int opts = (NSTrackingActiveAlways | NSTrackingInVisibleRect | NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved); + trackingArea = [[NSTrackingArea alloc] initWithRect: self.bounds + options: opts + owner: self + userInfo: nil]; + [self addTrackingArea: trackingArea]; + [super updateTrackingAreas]; } //-------------------------------------------------------------------------------------------------- @@ -260,11 +238,10 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * When the view is resized we need to let the backend know. */ -- (void) setFrame: (NSRect) frame -{ - super.frame = frame; +- (void) setFrame: (NSRect) frame { + super.frame = frame; - mOwner.backend->Resize(); + mOwner.backend->Resize(); } //-------------------------------------------------------------------------------------------------- @@ -272,14 +249,13 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Called by the backend if a new cursor must be set for the view. */ -- (void) setCursor: (int) cursor -{ - Window::Cursor eCursor = (Window::Cursor)cursor; - mCurrentCursor = cursorFromEnum(eCursor); +- (void) setCursor: (int) cursor { + Window::Cursor eCursor = (Window::Cursor)cursor; + mCurrentCursor = cursorFromEnum(eCursor); - // Trigger recreation of the cursor rectangle(s). - [self.window invalidateCursorRectsForView: self]; - [mOwner updateMarginCursors]; + // Trigger recreation of the cursor rectangle(s). + [self.window invalidateCursorRectsForView: self]; + [mOwner updateMarginCursors]; } //-------------------------------------------------------------------------------------------------- @@ -287,14 +263,13 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * This method is called to give us the opportunity to define our mouse sensitive rectangle. */ -- (void) resetCursorRects -{ - [super resetCursorRects]; +- (void) resetCursorRects { + [super resetCursorRects]; - // We only have one cursor rect: our bounds. - const NSRect visibleBounds = mOwner.backend->GetBounds(); - [self addCursorRect: visibleBounds cursor: mCurrentCursor]; - [mCurrentCursor setOnMouseEntered: YES]; + // We only have one cursor rect: our bounds. + const NSRect visibleBounds = mOwner.backend->GetBounds(); + [self addCursorRect: visibleBounds cursor: mCurrentCursor]; + [mCurrentCursor setOnMouseEntered: YES]; } //-------------------------------------------------------------------------------------------------- @@ -302,24 +277,23 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Called before repainting. */ -- (void) viewWillDraw -{ - if (!mOwner) { - [super viewWillDraw]; - return; - } +- (void) viewWillDraw { + if (!mOwner) { + [super viewWillDraw]; + return; + } - const NSRect *rects; - NSInteger nRects = 0; - [self getRectsBeingDrawn:&rects count:&nRects]; - if (nRects > 0) { - NSRect rectUnion = rects[0]; - for (int i=0;i<nRects;i++) { - rectUnion = NSUnionRect(rectUnion, rects[i]); - } - mOwner.backend->WillDraw(rectUnion); - } - [super viewWillDraw]; + const NSRect *rects; + NSInteger nRects = 0; + [self getRectsBeingDrawn: &rects count: &nRects]; + if (nRects > 0) { + NSRect rectUnion = rects[0]; + for (int i=0; i<nRects; i++) { + rectUnion = NSUnionRect(rectUnion, rects[i]); + } + mOwner.backend->WillDraw(rectUnion); + } + [super viewWillDraw]; } //-------------------------------------------------------------------------------------------------- @@ -327,12 +301,11 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Called before responsive scrolling overdraw. */ -- (void) prepareContentInRect: (NSRect) rect -{ - if (mOwner) - mOwner.backend->WillDraw(rect); +- (void) prepareContentInRect: (NSRect) rect { + if (mOwner) + mOwner.backend->WillDraw(rect); #if MAC_OS_X_VERSION_MAX_ALLOWED > 1080 - [super prepareContentInRect: rect]; + [super prepareContentInRect: rect]; #endif } @@ -341,15 +314,14 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Gets called by the runtime when the view needs repainting. */ -- (void) drawRect: (NSRect) rect -{ - CGContextRef context = (CGContextRef) [NSGraphicsContext currentContext].graphicsPort; +- (void) drawRect: (NSRect) rect { + CGContextRef context = (CGContextRef) [NSGraphicsContext currentContext].graphicsPort; - if (!mOwner.backend->Draw(rect, context)) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self setNeedsDisplay:YES]; - }); - } + if (!mOwner.backend->Draw(rect, context)) { + dispatch_async(dispatch_get_main_queue(), ^ { + [self setNeedsDisplay: YES]; + }); + } } //-------------------------------------------------------------------------------------------------- @@ -361,16 +333,14 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) * Note that because of returning YES here most coordinates we use now (e.g. for painting, * invalidating rectangles etc.) are given with +Y pointing down! */ -- (BOOL) isFlipped -{ - return YES; +- (BOOL) isFlipped { + return YES; } //-------------------------------------------------------------------------------------------------- -- (BOOL) isOpaque -{ - return YES; +- (BOOL) isOpaque { + return YES; } //-------------------------------------------------------------------------------------------------- @@ -378,10 +348,9 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Implement the "click through" behavior by telling the caller we accept the first mouse event too. */ -- (BOOL) acceptsFirstMouse: (NSEvent *) theEvent -{ +- (BOOL) acceptsFirstMouse: (NSEvent *) theEvent { #pragma unused(theEvent) - return YES; + return YES; } //-------------------------------------------------------------------------------------------------- @@ -389,9 +358,8 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Make this view accepting events as first responder. */ -- (BOOL) acceptsFirstResponder -{ - return YES; +- (BOOL) acceptsFirstResponder { + return YES; } //-------------------------------------------------------------------------------------------------- @@ -399,115 +367,105 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Called by the framework if it wants to show a context menu for the editor. */ -- (NSMenu*) menuForEvent: (NSEvent*) theEvent -{ - NSMenu *menu = [mOwner menuForEvent: theEvent]; - if (menu) { - return menu; - } else if (mOwner.backend->ShouldDisplayPopupOnText()) { - return mOwner.backend->CreateContextMenu(theEvent); - } else { - return nil; - } +- (NSMenu *) menuForEvent: (NSEvent *) theEvent { + NSMenu *menu = [mOwner menuForEvent: theEvent]; + if (menu) { + return menu; + } else if (mOwner.backend->ShouldDisplayPopupOnText()) { + return mOwner.backend->CreateContextMenu(theEvent); + } else { + return nil; + } } //-------------------------------------------------------------------------------------------------- // Adoption of NSTextInputClient protocol. -- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange -{ - const NSInteger lengthCharacters = self.accessibilityNumberOfCharacters; - if (aRange.location > lengthCharacters) { - return nil; - } - const NSRange posRange = mOwner.backend->PositionsFromCharacters(aRange); - // The backend validated aRange and may have removed characters beyond the end of the document. - const NSRange charRange = mOwner.backend->CharactersFromPositions(posRange); - if (!NSEqualRanges(aRange, charRange)) - { - *actualRange = charRange; - } - - [mOwner message: SCI_SETTARGETRANGE wParam: posRange.location lParam: NSMaxRange(posRange)]; - std::string text([mOwner message: SCI_TARGETASUTF8] + 1, 0); - [mOwner message: SCI_TARGETASUTF8 wParam: 0 lParam: reinterpret_cast<sptr_t>(&text[0])]; - text = FixInvalidUTF8(text); - NSString *result = @(text.c_str()); - NSMutableAttributedString *asResult = [[NSMutableAttributedString alloc] initWithString:result]; - - const NSRange rangeAS = NSMakeRange(0, asResult.length); - // SCI_GETSTYLEAT reports a signed byte but want an unsigned to index into styles - const char styleByte = static_cast<char>([mOwner message: SCI_GETSTYLEAT wParam:posRange.location]); - const long style = static_cast<unsigned char>(styleByte); - std::string fontName([mOwner message: SCI_STYLEGETFONT wParam:style lParam:0] + 1, 0); - [mOwner message: SCI_STYLEGETFONT wParam:style lParam:(sptr_t)&fontName[0]]; - const CGFloat fontSize = [mOwner message: SCI_STYLEGETSIZEFRACTIONAL wParam:style] / 100.0f; - NSString *sFontName = @(fontName.c_str()); - NSFont *font = [NSFont fontWithName:sFontName size:fontSize]; - [asResult addAttribute:NSFontAttributeName value:font range:rangeAS]; - - return asResult; -} - -//-------------------------------------------------------------------------------------------------- - -- (NSUInteger) characterIndexForPoint: (NSPoint) point -{ - const NSRect rectPoint = {point, NSZeroSize}; - const NSRect rectInWindow = [self.window convertRectFromScreen:rectPoint]; - const NSRect rectLocal = [self.superview.superview convertRect:rectInWindow fromView:nil]; - - const long position = [mOwner message: SCI_CHARPOSITIONFROMPOINT - wParam: rectLocal.origin.x - lParam: rectLocal.origin.y]; - if (position == INVALID_POSITION) - { - return NSNotFound; - } - else - { - const NSRange index = mOwner.backend->CharactersFromPositions(NSMakeRange(position, 0)); - return index.location; - } -} - -//-------------------------------------------------------------------------------------------------- - -- (void) doCommandBySelector: (SEL) selector -{ +- (NSAttributedString *) attributedSubstringForProposedRange: (NSRange) aRange actualRange: (NSRangePointer) actualRange { + const NSInteger lengthCharacters = self.accessibilityNumberOfCharacters; + if (aRange.location > lengthCharacters) { + return nil; + } + const NSRange posRange = mOwner.backend->PositionsFromCharacters(aRange); + // The backend validated aRange and may have removed characters beyond the end of the document. + const NSRange charRange = mOwner.backend->CharactersFromPositions(posRange); + if (!NSEqualRanges(aRange, charRange)) { + *actualRange = charRange; + } + + [mOwner message: SCI_SETTARGETRANGE wParam: posRange.location lParam: NSMaxRange(posRange)]; + std::string text([mOwner message: SCI_TARGETASUTF8] + 1, 0); + [mOwner message: SCI_TARGETASUTF8 wParam: 0 lParam: reinterpret_cast<sptr_t>(&text[0])]; + text = FixInvalidUTF8(text); + NSString *result = @(text.c_str()); + NSMutableAttributedString *asResult = [[NSMutableAttributedString alloc] initWithString: result]; + + const NSRange rangeAS = NSMakeRange(0, asResult.length); + // SCI_GETSTYLEAT reports a signed byte but want an unsigned to index into styles + const char styleByte = static_cast<char>([mOwner message: SCI_GETSTYLEAT wParam: posRange.location]); + const long style = static_cast<unsigned char>(styleByte); + std::string fontName([mOwner message: SCI_STYLEGETFONT wParam: style lParam: 0] + 1, 0); + [mOwner message: SCI_STYLEGETFONT wParam: style lParam: (sptr_t)&fontName[0]]; + const CGFloat fontSize = [mOwner message: SCI_STYLEGETSIZEFRACTIONAL wParam: style] / 100.0f; + NSString *sFontName = @(fontName.c_str()); + NSFont *font = [NSFont fontWithName: sFontName size: fontSize]; + [asResult addAttribute: NSFontAttributeName value: font range: rangeAS]; + + return asResult; +} + +//-------------------------------------------------------------------------------------------------- + +- (NSUInteger) characterIndexForPoint: (NSPoint) point { + const NSRect rectPoint = {point, NSZeroSize}; + const NSRect rectInWindow = [self.window convertRectFromScreen: rectPoint]; + const NSRect rectLocal = [self.superview.superview convertRect: rectInWindow fromView: nil]; + + const long position = [mOwner message: SCI_CHARPOSITIONFROMPOINT + wParam: rectLocal.origin.x + lParam: rectLocal.origin.y]; + if (position == INVALID_POSITION) { + return NSNotFound; + } else { + const NSRange index = mOwner.backend->CharactersFromPositions(NSMakeRange(position, 0)); + return index.location; + } +} + +//-------------------------------------------------------------------------------------------------- + +- (void) doCommandBySelector: (SEL) selector { #pragma clang diagnostic push #pragma clang diagnostic ignored "-Warc-performSelector-leaks" - if ([self respondsToSelector: @selector(selector)]) - [self performSelector: selector withObject: nil]; + if ([self respondsToSelector: @selector(selector)]) + [self performSelector: selector withObject: nil]; #pragma clang diagnostic pop } //-------------------------------------------------------------------------------------------------- -- (NSRect) firstRectForCharacterRange: (NSRange) aRange actualRange: (NSRangePointer) actualRange -{ +- (NSRect) firstRectForCharacterRange: (NSRange) aRange actualRange: (NSRangePointer) actualRange { #pragma unused(actualRange) - const NSRange posRange = mOwner.backend->PositionsFromCharacters(aRange); + const NSRange posRange = mOwner.backend->PositionsFromCharacters(aRange); - NSRect rect; - rect.origin.x = [mOwner message: SCI_POINTXFROMPOSITION wParam: 0 lParam: posRange.location]; - rect.origin.y = [mOwner message: SCI_POINTYFROMPOSITION wParam: 0 lParam: posRange.location]; - const NSUInteger rangeEnd = NSMaxRange(posRange); - rect.size.width = [mOwner message: SCI_POINTXFROMPOSITION wParam: 0 lParam: rangeEnd] - rect.origin.x; - rect.size.height = [mOwner message: SCI_POINTYFROMPOSITION wParam: 0 lParam: rangeEnd] - rect.origin.y; - rect.size.height += [mOwner message: SCI_TEXTHEIGHT wParam: 0 lParam: 0]; - const NSRect rectInWindow = [self.superview.superview convertRect:rect toView:nil]; - const NSRect rectScreen = [self.window convertRectToScreen:rectInWindow]; + NSRect rect; + rect.origin.x = [mOwner message: SCI_POINTXFROMPOSITION wParam: 0 lParam: posRange.location]; + rect.origin.y = [mOwner message: SCI_POINTYFROMPOSITION wParam: 0 lParam: posRange.location]; + const NSUInteger rangeEnd = NSMaxRange(posRange); + rect.size.width = [mOwner message: SCI_POINTXFROMPOSITION wParam: 0 lParam: rangeEnd] - rect.origin.x; + rect.size.height = [mOwner message: SCI_POINTYFROMPOSITION wParam: 0 lParam: rangeEnd] - rect.origin.y; + rect.size.height += [mOwner message: SCI_TEXTHEIGHT wParam: 0 lParam: 0]; + const NSRect rectInWindow = [self.superview.superview convertRect: rect toView: nil]; + const NSRect rectScreen = [self.window convertRectToScreen: rectInWindow]; - return rectScreen; + return rectScreen; } //-------------------------------------------------------------------------------------------------- -- (BOOL) hasMarkedText -{ - return mMarkedTextRange.length > 0; +- (BOOL) hasMarkedText { + return mMarkedTextRange.length > 0; } //-------------------------------------------------------------------------------------------------- @@ -517,17 +475,14 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) * selection if there is any. * First removes the replacementRange. */ -- (void) insertText: (id) aString replacementRange: (NSRange) replacementRange -{ - if ((mMarkedTextRange.location != NSNotFound) && (replacementRange.location != NSNotFound)) - { +- (void) insertText: (id) aString replacementRange: (NSRange) replacementRange { + if ((mMarkedTextRange.location != NSNotFound) && (replacementRange.location != NSNotFound)) { NSLog(@"Trying to insertText when there is both a marked range and a replacement range"); } // Remove any previously marked text first. mOwner.backend->CompositionUndo(); - if (mMarkedTextRange.location != NSNotFound) - { + if (mMarkedTextRange.location != NSNotFound) { const NSRange posRangeMark = mOwner.backend->PositionsFromCharacters(mMarkedTextRange); [mOwner message: SCI_SETEMPTYSELECTION wParam: posRangeMark.location]; } @@ -538,8 +493,7 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) // Its replacing a non-existent position so do nothing. return; - if (replacementRange.location != NSNotFound) - { + if (replacementRange.location != NSNotFound) { const NSRange posRangeReplacement = mOwner.backend->PositionsFromCharacters(replacementRange); [mOwner message: SCI_DELETERANGE wParam: posRangeReplacement.location @@ -547,42 +501,38 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) [mOwner message: SCI_SETEMPTYSELECTION wParam: posRangeReplacement.location]; } - NSString* newText = @""; - if ([aString isKindOfClass:[NSString class]]) - newText = (NSString*) aString; - else if ([aString isKindOfClass:[NSAttributedString class]]) - newText = (NSString*) [aString string]; + NSString *newText = @""; + if ([aString isKindOfClass: [NSString class]]) + newText = (NSString *) aString; + else if ([aString isKindOfClass: [NSAttributedString class]]) + newText = (NSString *) [aString string]; mOwner.backend->InsertText(newText); } //-------------------------------------------------------------------------------------------------- -- (NSRange) markedRange -{ - return mMarkedTextRange; +- (NSRange) markedRange { + return mMarkedTextRange; } //-------------------------------------------------------------------------------------------------- -- (NSRange) selectedRange -{ - const NSRange posRangeSel = [mOwner selectedRangePositions]; - if (posRangeSel.length == 0) - { - NSTextInputContext *tic = [NSTextInputContext currentInputContext]; - // Chinese input causes malloc crash when empty selection returned with actual - // position so return NSNotFound. - // If this is applied to European input, it stops the accented character - // chooser from appearing. - // May need to add more input source names. - if ([tic.selectedKeyboardInputSource - isEqualToString:@"com.apple.inputmethod.TCIM.Cangjie"]) - { - return NSMakeRange(NSNotFound, 0); - } - } - return mOwner.backend->CharactersFromPositions(posRangeSel); +- (NSRange) selectedRange { + const NSRange posRangeSel = [mOwner selectedRangePositions]; + if (posRangeSel.length == 0) { + NSTextInputContext *tic = [NSTextInputContext currentInputContext]; + // Chinese input causes malloc crash when empty selection returned with actual + // position so return NSNotFound. + // If this is applied to European input, it stops the accented character + // chooser from appearing. + // May need to add more input source names. + if ([tic.selectedKeyboardInputSource + isEqualToString: @"com.apple.inputmethod.TCIM.Cangjie"]) { + return NSMakeRange(NSNotFound, 0); + } + } + return mOwner.backend->CharactersFromPositions(posRangeSel); } //-------------------------------------------------------------------------------------------------- @@ -596,114 +546,96 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) * @param range The range of the new text to select (given relative to the insertion point of the new text). * @param replacementRange The range to remove before insertion. */ -- (void) setMarkedText: (id) aString selectedRange: (NSRange)range replacementRange: (NSRange)replacementRange -{ - NSString* newText = @""; - if ([aString isKindOfClass:[NSString class]]) - newText = (NSString*) aString; - else - if ([aString isKindOfClass:[NSAttributedString class]]) - newText = (NSString*) [aString string]; - - // Replace marked text if there is one. - if (mMarkedTextRange.length > 0) - { - mOwner.backend->CompositionUndo(); - if (replacementRange.location != NSNotFound) - { - // This situation makes no sense and has not occurred in practice. - NSLog(@"Can not handle a replacement range when there is also a marked range"); - } - else - { - replacementRange = mMarkedTextRange; - const NSRange posRangeMark = mOwner.backend->PositionsFromCharacters(mMarkedTextRange); - [mOwner message: SCI_SETEMPTYSELECTION wParam: posRangeMark.location]; - } - } - else - { - // Must perform deletion before entering composition mode or else - // both document and undo history will not contain the deleted text - // leading to an inaccurate and unusable undo history. - - // Convert selection virtual space into real space - mOwner.backend->ConvertSelectionVirtualSpace(); - - if (replacementRange.location != NSNotFound) - { - const NSRange posRangeReplacement = mOwner.backend->PositionsFromCharacters(replacementRange); - [mOwner message: SCI_DELETERANGE - wParam: posRangeReplacement.location - lParam: posRangeReplacement.length]; - } - else // No marked or replacement range, so replace selection - { - if (!mOwner.backend->ScintillaCocoa::ClearAllSelections()) { - // Some of the selection is protected so can not perform composition here - return; - } - // Ensure only a single selection. - mOwner.backend->SelectOnlyMainSelection(); - const NSRange posRangeSel = [mOwner selectedRangePositions]; - replacementRange = mOwner.backend->CharactersFromPositions(posRangeSel); - } - } - - // To support IME input to multiple selections, the following code would - // need to insert newText at each selection, mark each piece of new text and then - // select range relative to each insertion. - - if (newText.length) - { - // Switching into composition. - mOwner.backend->CompositionStart(); - - NSRange posRangeCurrent = mOwner.backend->PositionsFromCharacters(NSMakeRange(replacementRange.location, 0)); - // Note: Scintilla internally works almost always with bytes instead chars, so we need to take - // this into account when determining selection ranges and such. - int lengthInserted = mOwner.backend->InsertText(newText); - posRangeCurrent.length = lengthInserted; - mMarkedTextRange = mOwner.backend->CharactersFromPositions(posRangeCurrent); - // Mark the just inserted text. Keep the marked range for later reset. - [mOwner setGeneralProperty: SCI_SETINDICATORCURRENT value: INDIC_IME]; - [mOwner setGeneralProperty: SCI_INDICATORFILLRANGE - parameter: posRangeCurrent.location - value: posRangeCurrent.length]; - } - else - { - mMarkedTextRange = NSMakeRange(NSNotFound, 0); - // Re-enable undo action collection if composition ended (indicated by an empty mark string). - mOwner.backend->CompositionCommit(); - } - - // Select the part which is indicated in the given range. It does not scroll the caret into view. - if (range.length > 0) - { - // range is in characters so convert to bytes for selection. - range.location += replacementRange.location; - NSRange posRangeSelect = mOwner.backend->PositionsFromCharacters(range); - [mOwner setGeneralProperty: SCI_SETSELECTION parameter: NSMaxRange(posRangeSelect) value: posRangeSelect.location]; - } -} - -//-------------------------------------------------------------------------------------------------- - -- (void) unmarkText -{ - if (mMarkedTextRange.length > 0) - { - mOwner.backend->CompositionCommit(); - mMarkedTextRange = NSMakeRange(NSNotFound, 0); - } -} - -//-------------------------------------------------------------------------------------------------- - -- (NSArray*) validAttributesForMarkedText -{ - return @[]; +- (void) setMarkedText: (id) aString selectedRange: (NSRange) range replacementRange: (NSRange) replacementRange { + NSString *newText = @""; + if ([aString isKindOfClass: [NSString class]]) + newText = (NSString *) aString; + else if ([aString isKindOfClass: [NSAttributedString class]]) + newText = (NSString *) [aString string]; + + // Replace marked text if there is one. + if (mMarkedTextRange.length > 0) { + mOwner.backend->CompositionUndo(); + if (replacementRange.location != NSNotFound) { + // This situation makes no sense and has not occurred in practice. + NSLog(@"Can not handle a replacement range when there is also a marked range"); + } else { + replacementRange = mMarkedTextRange; + const NSRange posRangeMark = mOwner.backend->PositionsFromCharacters(mMarkedTextRange); + [mOwner message: SCI_SETEMPTYSELECTION wParam: posRangeMark.location]; + } + } else { + // Must perform deletion before entering composition mode or else + // both document and undo history will not contain the deleted text + // leading to an inaccurate and unusable undo history. + + // Convert selection virtual space into real space + mOwner.backend->ConvertSelectionVirtualSpace(); + + if (replacementRange.location != NSNotFound) { + const NSRange posRangeReplacement = mOwner.backend->PositionsFromCharacters(replacementRange); + [mOwner message: SCI_DELETERANGE + wParam: posRangeReplacement.location + lParam: posRangeReplacement.length]; + } else { // No marked or replacement range, so replace selection + if (!mOwner.backend->ScintillaCocoa::ClearAllSelections()) { + // Some of the selection is protected so can not perform composition here + return; + } + // Ensure only a single selection. + mOwner.backend->SelectOnlyMainSelection(); + const NSRange posRangeSel = [mOwner selectedRangePositions]; + replacementRange = mOwner.backend->CharactersFromPositions(posRangeSel); + } + } + + // To support IME input to multiple selections, the following code would + // need to insert newText at each selection, mark each piece of new text and then + // select range relative to each insertion. + + if (newText.length) { + // Switching into composition. + mOwner.backend->CompositionStart(); + + NSRange posRangeCurrent = mOwner.backend->PositionsFromCharacters(NSMakeRange(replacementRange.location, 0)); + // Note: Scintilla internally works almost always with bytes instead chars, so we need to take + // this into account when determining selection ranges and such. + int lengthInserted = mOwner.backend->InsertText(newText); + posRangeCurrent.length = lengthInserted; + mMarkedTextRange = mOwner.backend->CharactersFromPositions(posRangeCurrent); + // Mark the just inserted text. Keep the marked range for later reset. + [mOwner setGeneralProperty: SCI_SETINDICATORCURRENT value: INDIC_IME]; + [mOwner setGeneralProperty: SCI_INDICATORFILLRANGE + parameter: posRangeCurrent.location + value: posRangeCurrent.length]; + } else { + mMarkedTextRange = NSMakeRange(NSNotFound, 0); + // Re-enable undo action collection if composition ended (indicated by an empty mark string). + mOwner.backend->CompositionCommit(); + } + + // Select the part which is indicated in the given range. It does not scroll the caret into view. + if (range.length > 0) { + // range is in characters so convert to bytes for selection. + range.location += replacementRange.location; + NSRange posRangeSelect = mOwner.backend->PositionsFromCharacters(range); + [mOwner setGeneralProperty: SCI_SETSELECTION parameter: NSMaxRange(posRangeSelect) value: posRangeSelect.location]; + } +} + +//-------------------------------------------------------------------------------------------------- + +- (void) unmarkText { + if (mMarkedTextRange.length > 0) { + mOwner.backend->CompositionCommit(); + mMarkedTextRange = NSMakeRange(NSNotFound, 0); + } +} + +//-------------------------------------------------------------------------------------------------- + +- (NSArray *) validAttributesForMarkedText { + return @[]; } // End of the NSTextInputClient protocol adoption. @@ -715,54 +647,47 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) * handles shortcuts. The input is then forwarded to the Cocoa text input system, which in turn does * its own input handling (character composition via NSTextInputClient protocol): */ -- (void) keyDown: (NSEvent *) theEvent -{ - if (mMarkedTextRange.length == 0) - mOwner.backend->KeyboardInput(theEvent); - NSArray* events = @[theEvent]; - [self interpretKeyEvents: events]; +- (void) keyDown: (NSEvent *) theEvent { + if (mMarkedTextRange.length == 0) + mOwner.backend->KeyboardInput(theEvent); + NSArray *events = @[theEvent]; + [self interpretKeyEvents: events]; } //-------------------------------------------------------------------------------------------------- -- (void) mouseDown: (NSEvent *) theEvent -{ - mOwner.backend->MouseDown(theEvent); +- (void) mouseDown: (NSEvent *) theEvent { + mOwner.backend->MouseDown(theEvent); } //-------------------------------------------------------------------------------------------------- -- (void) mouseDragged: (NSEvent *) theEvent -{ - mOwner.backend->MouseMove(theEvent); +- (void) mouseDragged: (NSEvent *) theEvent { + mOwner.backend->MouseMove(theEvent); } //-------------------------------------------------------------------------------------------------- -- (void) mouseUp: (NSEvent *) theEvent -{ - mOwner.backend->MouseUp(theEvent); +- (void) mouseUp: (NSEvent *) theEvent { + mOwner.backend->MouseUp(theEvent); } //-------------------------------------------------------------------------------------------------- -- (void) mouseMoved: (NSEvent *) theEvent -{ - mOwner.backend->MouseMove(theEvent); +- (void) mouseMoved: (NSEvent *) theEvent { + mOwner.backend->MouseMove(theEvent); } //-------------------------------------------------------------------------------------------------- -- (void) mouseEntered: (NSEvent *) theEvent -{ - mOwner.backend->MouseEntered(theEvent); +- (void) mouseEntered: (NSEvent *) theEvent { + mOwner.backend->MouseEntered(theEvent); } //-------------------------------------------------------------------------------------------------- -- (void) mouseExited: (NSEvent *) theEvent -{ - mOwner.backend->MouseExited(theEvent); +- (void) mouseExited: (NSEvent *) theEvent { + mOwner.backend->MouseExited(theEvent); } //-------------------------------------------------------------------------------------------------- @@ -774,13 +699,12 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) * Pinch gestures and key commands can be used for magnification. */ #ifdef SCROLL_WHEEL_MAGNIFICATION -- (void) scrollWheel: (NSEvent *) theEvent -{ - if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) { - mOwner.backend->MouseWheel(theEvent); - } else { - [super scrollWheel:theEvent]; - } +- (void) scrollWheel: (NSEvent *) theEvent { + if (([theEvent modifierFlags] & NSCommandKeyMask) != 0) { + mOwner.backend->MouseWheel(theEvent); + } else { + [super scrollWheel: theEvent]; + } } #endif @@ -789,20 +713,19 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * Ensure scrolling is aligned to whole lines instead of starting part-way through a line */ -- (NSRect)adjustScroll:(NSRect)proposedVisibleRect -{ - if (!mOwner) - return proposedVisibleRect; - NSRect rc = proposedVisibleRect; - // Snap to lines - NSRect contentRect = self.bounds; - if ((rc.origin.y > 0) && (NSMaxY(rc) < contentRect.size.height)) { - // Only snap for positions inside the document - allow outside - // for overshoot. - long lineHeight = mOwner.backend->WndProc(SCI_TEXTHEIGHT, 0, 0); - rc.origin.y = roundf(static_cast<XYPOSITION>(rc.origin.y) / lineHeight) * lineHeight; - } - return rc; +- (NSRect) adjustScroll: (NSRect) proposedVisibleRect { + if (!mOwner) + return proposedVisibleRect; + NSRect rc = proposedVisibleRect; + // Snap to lines + NSRect contentRect = self.bounds; + if ((rc.origin.y > 0) && (NSMaxY(rc) < contentRect.size.height)) { + // Only snap for positions inside the document - allow outside + // for overshoot. + long lineHeight = mOwner.backend->WndProc(SCI_TEXTHEIGHT, 0, 0); + rc.origin.y = roundf(static_cast<XYPOSITION>(rc.origin.y) / lineHeight) * lineHeight; + } + return rc; } //-------------------------------------------------------------------------------------------------- @@ -810,10 +733,9 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * The editor is getting the foreground control (the one getting the input focus). */ -- (BOOL) becomeFirstResponder -{ - mOwner.backend->WndProc(SCI_SETFOCUS, 1, 0); - return YES; +- (BOOL) becomeFirstResponder { + mOwner.backend->WndProc(SCI_SETFOCUS, 1, 0); + return YES; } //-------------------------------------------------------------------------------------------------- @@ -821,10 +743,9 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) /** * The editor is losing the input focus. */ -- (BOOL) resignFirstResponder -{ - mOwner.backend->WndProc(SCI_SETFOCUS, 0, 0); - return YES; +- (BOOL) resignFirstResponder { + mOwner.backend->WndProc(SCI_SETFOCUS, 0, 0); + return YES; } //-------------------------------------------------------------------------------------------------- @@ -833,36 +754,31 @@ static NSCursor *cursorFromEnum(Window::Cursor cursor) * Implement NSDraggingSource. */ -- (NSDragOperation)draggingSession: (NSDraggingSession *) session -sourceOperationMaskForDraggingContext: (NSDraggingContext) context -{ +- (NSDragOperation) draggingSession: (NSDraggingSession *) session + sourceOperationMaskForDraggingContext: (NSDraggingContext) context { #pragma unused(session) - switch(context) - { - case NSDraggingContextOutsideApplication: - return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; + switch (context) { + case NSDraggingContextOutsideApplication: + return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; - case NSDraggingContextWithinApplication: - default: - return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; - } + case NSDraggingContextWithinApplication: + default: + return NSDragOperationCopy | NSDragOperationMove | NSDragOperationDelete; + } } -- (void)draggingSession:(NSDraggingSession *)session - movedToPoint:(NSPoint)screenPoint -{ +- (void) draggingSession: (NSDraggingSession *) session + movedToPoint: (NSPoint) screenPoint { #pragma unused(session, screenPoint) } -- (void)draggingSession:(NSDraggingSession *)session - endedAtPoint:(NSPoint)screenPoint - operation:(NSDragOperation)operation -{ +- (void) draggingSession: (NSDraggingSession *) session + endedAtPoint: (NSPoint) screenPoint + operation: (NSDragOperation) operation { #pragma unused(session, screenPoint) - if (operation == NSDragOperationDelete) - { - mOwner.backend->WndProc(SCI_CLEAR, 0, 0); - } + if (operation == NSDragOperationDelete) { + mOwner.backend->WndProc(SCI_CLEAR, 0, 0); + } } /** @@ -874,9 +790,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Called when an external drag operation enters the view. */ -- (NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender -{ - return mOwner.backend->DraggingEntered(sender); +- (NSDragOperation) draggingEntered: (id <NSDraggingInfo>) sender { + return mOwner.backend->DraggingEntered(sender); } //-------------------------------------------------------------------------------------------------- @@ -884,9 +799,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Called frequently during an external drag operation if we are the target. */ -- (NSDragOperation) draggingUpdated: (id <NSDraggingInfo>) sender -{ - return mOwner.backend->DraggingUpdated(sender); +- (NSDragOperation) draggingUpdated: (id <NSDraggingInfo>) sender { + return mOwner.backend->DraggingUpdated(sender); } //-------------------------------------------------------------------------------------------------- @@ -894,24 +808,21 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Drag image left the view. Clean up if necessary. */ -- (void) draggingExited: (id <NSDraggingInfo>) sender -{ - mOwner.backend->DraggingExited(sender); +- (void) draggingExited: (id <NSDraggingInfo>) sender { + mOwner.backend->DraggingExited(sender); } //-------------------------------------------------------------------------------------------------- -- (BOOL) prepareForDragOperation: (id <NSDraggingInfo>) sender -{ +- (BOOL) prepareForDragOperation: (id <NSDraggingInfo>) sender { #pragma unused(sender) - return YES; + return YES; } //-------------------------------------------------------------------------------------------------- -- (BOOL) performDragOperation: (id <NSDraggingInfo>) sender -{ - return mOwner.backend->PerformDragOperation(sender); +- (BOOL) performDragOperation: (id <NSDraggingInfo>) sender { + return mOwner.backend->PerformDragOperation(sender); } //-------------------------------------------------------------------------------------------------- @@ -919,106 +830,88 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Drag operation is done. Notify editor. */ -- (void) concludeDragOperation: (id <NSDraggingInfo>) sender -{ - // Clean up is the same as if we are no longer the drag target. - mOwner.backend->DraggingExited(sender); +- (void) concludeDragOperation: (id <NSDraggingInfo>) sender { + // Clean up is the same as if we are no longer the drag target. + mOwner.backend->DraggingExited(sender); } //-------------------------------------------------------------------------------------------------- // NSResponder actions. -- (void) selectAll: (id) sender -{ +- (void) selectAll: (id) sender { #pragma unused(sender) - mOwner.backend->SelectAll(); + mOwner.backend->SelectAll(); } -- (void) deleteBackward: (id) sender -{ +- (void) deleteBackward: (id) sender { #pragma unused(sender) - mOwner.backend->DeleteBackward(); + mOwner.backend->DeleteBackward(); } -- (void) cut: (id) sender -{ +- (void) cut: (id) sender { #pragma unused(sender) - mOwner.backend->Cut(); + mOwner.backend->Cut(); } -- (void) copy: (id) sender -{ +- (void) copy: (id) sender { #pragma unused(sender) - mOwner.backend->Copy(); + mOwner.backend->Copy(); } -- (void) paste: (id) sender -{ +- (void) paste: (id) sender { #pragma unused(sender) - if (mMarkedTextRange.location != NSNotFound) - { - [[NSTextInputContext currentInputContext] discardMarkedText]; - mOwner.backend->CompositionCommit(); - mMarkedTextRange = NSMakeRange(NSNotFound, 0); - } - mOwner.backend->Paste(); + if (mMarkedTextRange.location != NSNotFound) { + [[NSTextInputContext currentInputContext] discardMarkedText]; + mOwner.backend->CompositionCommit(); + mMarkedTextRange = NSMakeRange(NSNotFound, 0); + } + mOwner.backend->Paste(); } -- (void) undo: (id) sender -{ +- (void) undo: (id) sender { #pragma unused(sender) - if (mMarkedTextRange.location != NSNotFound) - { - [[NSTextInputContext currentInputContext] discardMarkedText]; - mOwner.backend->CompositionCommit(); - mMarkedTextRange = NSMakeRange(NSNotFound, 0); - } - mOwner.backend->Undo(); + if (mMarkedTextRange.location != NSNotFound) { + [[NSTextInputContext currentInputContext] discardMarkedText]; + mOwner.backend->CompositionCommit(); + mMarkedTextRange = NSMakeRange(NSNotFound, 0); + } + mOwner.backend->Undo(); } -- (void) redo: (id) sender -{ +- (void) redo: (id) sender { #pragma unused(sender) - mOwner.backend->Redo(); + mOwner.backend->Redo(); } -- (BOOL) canUndo -{ - return mOwner.backend->CanUndo() && (mMarkedTextRange.location == NSNotFound); +- (BOOL) canUndo { + return mOwner.backend->CanUndo() && (mMarkedTextRange.location == NSNotFound); } -- (BOOL) canRedo -{ - return mOwner.backend->CanRedo(); +- (BOOL) canRedo { + return mOwner.backend->CanRedo(); } -- (BOOL) validateUserInterfaceItem: (id <NSValidatedUserInterfaceItem>) anItem -{ - SEL action = anItem.action; - if (action==@selector(undo:)) { - return [self canUndo]; - } - else if (action==@selector(redo:)) { - return [self canRedo]; - } - else if (action==@selector(cut:) || action==@selector(copy:) || action==@selector(clear:)) { - return mOwner.backend->HasSelection(); - } - else if (action==@selector(paste:)) { - return mOwner.backend->CanPaste(); - } - return YES; +- (BOOL) validateUserInterfaceItem: (id <NSValidatedUserInterfaceItem>) anItem { + SEL action = anItem.action; + if (action==@selector(undo:)) { + return [self canUndo]; + } else if (action==@selector(redo:)) { + return [self canRedo]; + } else if (action==@selector(cut:) || action==@selector(copy:) || action==@selector(clear:)) { + return mOwner.backend->HasSelection(); + } else if (action==@selector(paste:)) { + return mOwner.backend->CanPaste(); + } + return YES; } -- (void) clear: (id) sender -{ - [self deleteBackward:sender]; +- (void) clear: (id) sender { + [self deleteBackward: sender]; } -- (BOOL) isEditable -{ - return mOwner.backend->WndProc(SCI_GETREADONLY, 0, 0) == 0; +- (BOOL) isEditable { + return mOwner.backend->WndProc(SCI_GETREADONLY, 0, 0) == 0; } #pragma mark - NSAccessibility @@ -1037,8 +930,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : Text of the whole document as a string. */ - (id) accessibilityValue { - const sptr_t length = [mOwner message: SCI_GETLENGTH]; - return mOwner.backend->RangeTextAsString(NSMakeRange(0,static_cast<int>(length))); + const sptr_t length = [mOwner message: SCI_GETLENGTH]; + return mOwner.backend->RangeTextAsString(NSMakeRange(0, static_cast<int>(length))); } //-------------------------------------------------------------------------------------------------- @@ -1047,9 +940,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : Line of the caret. */ - (NSInteger) accessibilityInsertionPointLineNumber { - const int caret = static_cast<int>([mOwner message: SCI_GETCURRENTPOS]); - const NSRange rangeCharactersCaret = mOwner.backend->CharactersFromPositions(NSMakeRange(caret, 0)); - return mOwner.backend->VisibleLineForIndex(rangeCharactersCaret.location); + const int caret = static_cast<int>([mOwner message: SCI_GETCURRENTPOS]); + const NSRange rangeCharactersCaret = mOwner.backend->CharactersFromPositions(NSMakeRange(caret, 0)); + return mOwner.backend->VisibleLineForIndex(rangeCharactersCaret.location); } //-------------------------------------------------------------------------------------------------- @@ -1057,8 +950,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * NSAccessibility : Not implemented and not called by VoiceOver. */ -- (NSRange)accessibilityRangeForPosition:(NSPoint)point { - return NSMakeRange(0,0); +- (NSRange) accessibilityRangeForPosition: (NSPoint) point { + return NSMakeRange(0, 0); } //-------------------------------------------------------------------------------------------------- @@ -1067,9 +960,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : Number of characters in the whole document. */ - (NSInteger) accessibilityNumberOfCharacters { - sptr_t length = [mOwner message: SCI_GETLENGTH]; - const NSRange posRange = mOwner.backend->CharactersFromPositions(NSMakeRange(length, 0)); - return posRange.location; + sptr_t length = [mOwner message: SCI_GETLENGTH]; + const NSRange posRange = mOwner.backend->CharactersFromPositions(NSMakeRange(length, 0)); + return posRange.location; } //-------------------------------------------------------------------------------------------------- @@ -1078,10 +971,10 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : The selection text as a string. */ - (NSString *) accessibilitySelectedText { - const sptr_t positionBegin = [mOwner message: SCI_GETSELECTIONSTART]; - const sptr_t positionEnd = [mOwner message: SCI_GETSELECTIONEND]; - const NSRange posRangeSel = NSMakeRange(positionBegin, positionEnd-positionBegin); - return mOwner.backend->RangeTextAsString(posRangeSel); + const sptr_t positionBegin = [mOwner message: SCI_GETSELECTIONSTART]; + const sptr_t positionEnd = [mOwner message: SCI_GETSELECTIONEND]; + const NSRange posRangeSel = NSMakeRange(positionBegin, positionEnd-positionBegin); + return mOwner.backend->RangeTextAsString(posRangeSel); } //-------------------------------------------------------------------------------------------------- @@ -1090,10 +983,10 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : The character range of the main selection. */ - (NSRange) accessibilitySelectedTextRange { - const sptr_t positionBegin = [mOwner message: SCI_GETSELECTIONSTART]; - const sptr_t positionEnd = [mOwner message: SCI_GETSELECTIONEND]; - const NSRange posRangeSel = NSMakeRange(positionBegin, positionEnd-positionBegin); - return mOwner.backend->CharactersFromPositions(posRangeSel); + const sptr_t positionBegin = [mOwner message: SCI_GETSELECTIONSTART]; + const sptr_t positionEnd = [mOwner message: SCI_GETSELECTIONEND]; + const NSRange posRangeSel = NSMakeRange(positionBegin, positionEnd-positionBegin); + return mOwner.backend->CharactersFromPositions(posRangeSel); } //-------------------------------------------------------------------------------------------------- @@ -1103,8 +996,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * This method is the only setter required for reasonable VoiceOver behaviour. */ - (void) setAccessibilitySelectedTextRange: (NSRange) range { - NSRange rangePositions = mOwner.backend->PositionsFromCharacters(range); - [mOwner message: SCI_SETSELECTION wParam: rangePositions.location lParam:NSMaxRange(rangePositions)]; + NSRange rangePositions = mOwner.backend->PositionsFromCharacters(range); + [mOwner message: SCI_SETSELECTION wParam: rangePositions.location lParam: NSMaxRange(rangePositions)]; } //-------------------------------------------------------------------------------------------------- @@ -1113,14 +1006,14 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : Range of the glyph at a character index. * Currently doesn't try to handle composite characters. */ -- (NSRange) accessibilityRangeForIndex: (NSInteger)index { - sptr_t length = [mOwner message: SCI_GETLENGTH]; - const NSRange rangeLength = mOwner.backend->CharactersFromPositions(NSMakeRange(length, 0)); - NSRange rangePositions = NSMakeRange(length, 0); - if (index < rangeLength.location) { - rangePositions = mOwner.backend->PositionsFromCharacters(NSMakeRange(index, 1)); - } - return mOwner.backend->CharactersFromPositions(rangePositions); +- (NSRange) accessibilityRangeForIndex: (NSInteger) index { + sptr_t length = [mOwner message: SCI_GETLENGTH]; + const NSRange rangeLength = mOwner.backend->CharactersFromPositions(NSMakeRange(length, 0)); + NSRange rangePositions = NSMakeRange(length, 0); + if (index < rangeLength.location) { + rangePositions = mOwner.backend->PositionsFromCharacters(NSMakeRange(index, 1)); + } + return mOwner.backend->CharactersFromPositions(rangePositions); } //-------------------------------------------------------------------------------------------------- @@ -1129,13 +1022,13 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : All the text ranges. * Currently only returns the main selection. */ -- (NSArray<NSValue *>*) accessibilitySelectedTextRanges { - const sptr_t positionBegin = [mOwner message: SCI_GETSELECTIONSTART]; - const sptr_t positionEnd = [mOwner message: SCI_GETSELECTIONEND]; - const NSRange posRangeSel = NSMakeRange(positionBegin, positionEnd-positionBegin); - NSRange rangeCharacters = mOwner.backend->CharactersFromPositions(posRangeSel); - NSValue *valueRange = [NSValue valueWithRange:(NSRange)rangeCharacters]; - return @[valueRange]; +- (NSArray<NSValue *> *) accessibilitySelectedTextRanges { + const sptr_t positionBegin = [mOwner message: SCI_GETSELECTIONSTART]; + const sptr_t positionEnd = [mOwner message: SCI_GETSELECTIONEND]; + const NSRange posRangeSel = NSMakeRange(positionBegin, positionEnd-positionBegin); + NSRange rangeCharacters = mOwner.backend->CharactersFromPositions(posRangeSel); + NSValue *valueRange = [NSValue valueWithRange: (NSRange)rangeCharacters]; + return @[valueRange]; } //-------------------------------------------------------------------------------------------------- @@ -1144,14 +1037,14 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : Character range currently visible. */ - (NSRange) accessibilityVisibleCharacterRange { - const sptr_t lineTopVisible = [mOwner message: SCI_GETFIRSTVISIBLELINE]; - const sptr_t lineTop = [mOwner message:SCI_DOCLINEFROMVISIBLE wParam:lineTopVisible]; - const sptr_t lineEndVisible = lineTopVisible + [mOwner message: SCI_LINESONSCREEN] - 1; - const sptr_t lineEnd = [mOwner message:SCI_DOCLINEFROMVISIBLE wParam:lineEndVisible]; - const sptr_t posStartView = [mOwner message: SCI_POSITIONFROMLINE wParam: lineTop]; - const sptr_t posEndView = [mOwner message: SCI_GETLINEENDPOSITION wParam: lineEnd]; - const NSRange posRangeSel = NSMakeRange(posStartView, posEndView-posStartView); - return mOwner.backend->CharactersFromPositions(posRangeSel); + const sptr_t lineTopVisible = [mOwner message: SCI_GETFIRSTVISIBLELINE]; + const sptr_t lineTop = [mOwner message: SCI_DOCLINEFROMVISIBLE wParam: lineTopVisible]; + const sptr_t lineEndVisible = lineTopVisible + [mOwner message: SCI_LINESONSCREEN] - 1; + const sptr_t lineEnd = [mOwner message: SCI_DOCLINEFROMVISIBLE wParam: lineEndVisible]; + const sptr_t posStartView = [mOwner message: SCI_POSITIONFROMLINE wParam: lineTop]; + const sptr_t posEndView = [mOwner message: SCI_GETLINEENDPOSITION wParam: lineEnd]; + const NSRange posRangeSel = NSMakeRange(posStartView, posEndView-posStartView); + return mOwner.backend->CharactersFromPositions(posRangeSel); } //-------------------------------------------------------------------------------------------------- @@ -1159,8 +1052,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * NSAccessibility : Character range of a line. */ -- (NSRange)accessibilityRangeForLine:(NSInteger)line { - return mOwner.backend->RangeForVisibleLine(line); +- (NSRange) accessibilityRangeForLine: (NSInteger) line { + return mOwner.backend->RangeForVisibleLine(line); } //-------------------------------------------------------------------------------------------------- @@ -1168,8 +1061,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * NSAccessibility : Line number of a text position in characters. */ -- (NSInteger)accessibilityLineForIndex:(NSInteger)index { - return mOwner.backend->VisibleLineForIndex(index); +- (NSInteger) accessibilityLineForIndex: (NSInteger) index { + return mOwner.backend->VisibleLineForIndex(index); } //-------------------------------------------------------------------------------------------------- @@ -1180,10 +1073,10 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Producing a nice rectangle is a little tricky particularly when including new * lines. Needs to improve the case where parts of two lines are included. */ -- (NSRect)accessibilityFrameForRange:(NSRange)range { - const NSRect rectInView = mOwner.backend->FrameForRange(range); - const NSRect rectInWindow = [self.superview.superview convertRect:rectInView toView:nil]; - return [self.window convertRectToScreen:rectInWindow]; +- (NSRect) accessibilityFrameForRange: (NSRange) range { + const NSRect rectInView = mOwner.backend->FrameForRange(range); + const NSRect rectInWindow = [self.superview.superview convertRect: rectInView toView: nil]; + return [self.window convertRectToScreen: rectInWindow]; } //-------------------------------------------------------------------------------------------------- @@ -1191,9 +1084,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * NSAccessibility : A range of text as a string. */ -- (NSString *) accessibilityStringForRange:(NSRange)range { - const NSRange posRange = mOwner.backend->PositionsFromCharacters(range); - return mOwner.backend->RangeTextAsString(posRange); +- (NSString *) accessibilityStringForRange: (NSRange) range { + const NSRange posRange = mOwner.backend->PositionsFromCharacters(range); + return mOwner.backend->RangeTextAsString(posRange); } //-------------------------------------------------------------------------------------------------- @@ -1202,10 +1095,10 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * NSAccessibility : A range of text as an attributed string. * Currently no attributes are set. */ -- (NSAttributedString *) accessibilityAttributedStringForRange:(NSRange)range { - const NSRange posRange = mOwner.backend->PositionsFromCharacters(range); - NSString *result = mOwner.backend->RangeTextAsString(posRange); - return [[NSMutableAttributedString alloc] initWithString:result]; +- (NSAttributedString *) accessibilityAttributedStringForRange: (NSRange) range { + const NSRange posRange = mOwner.backend->PositionsFromCharacters(range); + NSString *result = mOwner.backend->RangeTextAsString(posRange); + return [[NSMutableAttributedString alloc] initWithString: result]; } //-------------------------------------------------------------------------------------------------- @@ -1213,28 +1106,28 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * NSAccessibility : Show the context menu at the caret. */ -- (BOOL)accessibilityPerformShowMenu { - const sptr_t caret = [mOwner message: SCI_GETCURRENTPOS]; - NSRect rect; - rect.origin.x = [mOwner message: SCI_POINTXFROMPOSITION wParam: 0 lParam: caret]; - rect.origin.y = [mOwner message: SCI_POINTYFROMPOSITION wParam: 0 lParam: caret]; - rect.origin.y += [mOwner message: SCI_TEXTHEIGHT wParam: 0 lParam: 0]; - rect.size.width = 1.0; - rect.size.height = 1.0; - NSRect rectInWindow = [self.superview.superview convertRect:rect toView:nil]; - NSPoint pt = rectInWindow.origin; - NSEvent *event = [NSEvent mouseEventWithType: NSRightMouseDown - location: pt - modifierFlags: 0 - timestamp: 0 - windowNumber: self.window.windowNumber - context: nil - eventNumber: 0 - clickCount: 1 - pressure: 0.0]; - NSMenu *menu = mOwner.backend->CreateContextMenu(event); - [NSMenu popUpContextMenu:menu withEvent:event forView:self]; - return YES; +- (BOOL) accessibilityPerformShowMenu { + const sptr_t caret = [mOwner message: SCI_GETCURRENTPOS]; + NSRect rect; + rect.origin.x = [mOwner message: SCI_POINTXFROMPOSITION wParam: 0 lParam: caret]; + rect.origin.y = [mOwner message: SCI_POINTYFROMPOSITION wParam: 0 lParam: caret]; + rect.origin.y += [mOwner message: SCI_TEXTHEIGHT wParam: 0 lParam: 0]; + rect.size.width = 1.0; + rect.size.height = 1.0; + NSRect rectInWindow = [self.superview.superview convertRect: rect toView: nil]; + NSPoint pt = rectInWindow.origin; + NSEvent *event = [NSEvent mouseEventWithType: NSRightMouseDown + location: pt + modifierFlags: 0 + timestamp: 0 + windowNumber: self.window.windowNumber + context: nil + eventNumber: 0 + clickCount: 1 + pressure: 0.0]; + NSMenu *menu = mOwner.backend->CreateContextMenu(event); + [NSMenu popUpContextMenu: menu withEvent: event forView: self]; + return YES; } //-------------------------------------------------------------------------------------------------- @@ -1245,23 +1138,23 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context //-------------------------------------------------------------------------------------------------- @implementation ScintillaView { - // The back end is kind of a controller and model in one. - // It uses the content view for display. - Scintilla::ScintillaCocoa* mBackend; + // The back end is kind of a controller and model in one. + // It uses the content view for display. + Scintilla::ScintillaCocoa *mBackend; - // This is the actual content to which the backend renders itself. - SCIContentView* mContent; + // This is the actual content to which the backend renders itself. + SCIContentView *mContent; - NSScrollView *scrollView; - SCIMarginView *marginView; + NSScrollView *scrollView; + SCIMarginView *marginView; - CGFloat zoomDelta; + CGFloat zoomDelta; - // Area to display additional controls (e.g. zoom info, caret position, status info). - NSView <InfoBarCommunicator>* mInfoBar; - BOOL mInfoBarAtTop; + // Area to display additional controls (e.g. zoom info, caret position, status info). + NSView <InfoBarCommunicator> *mInfoBar; + BOOL mInfoBarAtTop; - id<ScintillaNotificationProtocol> __unsafe_unretained mDelegate; + id<ScintillaNotificationProtocol> __unsafe_unretained mDelegate; } @synthesize backend = mBackend; @@ -1279,20 +1172,18 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Initialize custom cursor. */ -+ (void) initialize -{ - if (self == [ScintillaView class]) - { - NSBundle* bundle = [NSBundle bundleForClass: [ScintillaView class]]; ++ (void) initialize { + if (self == [ScintillaView class]) { + NSBundle *bundle = [NSBundle bundleForClass: [ScintillaView class]]; - NSString* path = [bundle pathForResource: @"mac_cursor_busy" ofType: @"tiff" inDirectory: nil]; - NSImage* image = [[NSImage alloc] initWithContentsOfFile: path]; - waitCursor = [[NSCursor alloc] initWithImage: image hotSpot: NSMakePoint(2, 2)]; + NSString *path = [bundle pathForResource: @"mac_cursor_busy" ofType: @"tiff" inDirectory: nil]; + NSImage *image = [[NSImage alloc] initWithContentsOfFile: path]; + waitCursor = [[NSCursor alloc] initWithImage: image hotSpot: NSMakePoint(2, 2)]; - path = [bundle pathForResource: @"mac_cursor_flipped" ofType: @"tiff" inDirectory: nil]; - image = [[NSImage alloc] initWithContentsOfFile: path]; - reverseArrowCursor = [[NSCursor alloc] initWithImage: image hotSpot: NSMakePoint(12, 2)]; - } + path = [bundle pathForResource: @"mac_cursor_flipped" ofType: @"tiff" inDirectory: nil]; + image = [[NSImage alloc] initWithContentsOfFile: path]; + reverseArrowCursor = [[NSCursor alloc] initWithImage: image hotSpot: NSMakePoint(12, 2)]; + } } //-------------------------------------------------------------------------------------------------- @@ -1301,9 +1192,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Specify the SCIContentView class. Can be overridden in a subclass to provide an SCIContentView subclass. */ -+ (Class) contentViewClass -{ - return [SCIContentView class]; ++ (Class) contentViewClass { + return [SCIContentView class]; } //-------------------------------------------------------------------------------------------------- @@ -1311,24 +1201,22 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Receives zoom messages, for example when a "pinch zoom" is performed on the trackpad. */ -- (void) magnifyWithEvent: (NSEvent *) event -{ +- (void) magnifyWithEvent: (NSEvent *) event { #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 - zoomDelta += event.magnification * 10.0; + zoomDelta += event.magnification * 10.0; - if (fabs(zoomDelta)>=1.0) { - long zoomFactor = static_cast<long>([self getGeneralProperty: SCI_GETZOOM] + zoomDelta); - [self setGeneralProperty: SCI_SETZOOM parameter: zoomFactor value:0]; - zoomDelta = 0.0; - } + if (fabs(zoomDelta)>=1.0) { + long zoomFactor = static_cast<long>([self getGeneralProperty: SCI_GETZOOM] + zoomDelta); + [self setGeneralProperty: SCI_SETZOOM parameter: zoomFactor value: 0]; + zoomDelta = 0.0; + } #endif } -- (void) beginGestureWithEvent: (NSEvent *) event -{ +- (void) beginGestureWithEvent: (NSEvent *) event { // Scintilla is only interested in this event as the starft of a zoom #pragma unused(event) - zoomDelta = 0.0; + zoomDelta = 0.0; } //-------------------------------------------------------------------------------------------------- @@ -1336,10 +1224,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Sends a new notification of the given type to the default notification center. */ -- (void) sendNotification: (NSString*) notificationName -{ - NSNotificationCenter* center = [NSNotificationCenter defaultCenter]; - [center postNotificationName: notificationName object: self]; +- (void) sendNotification: (NSString *) notificationName { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center postNotificationName: notificationName object: self]; } //-------------------------------------------------------------------------------------------------- @@ -1352,31 +1239,27 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * @param location Carries the new location (e.g. caret) if the type is a caret change or similar type. * @param value Carries the new zoom value if the type is a zoom change. */ -- (void) notify: (NotificationType) type message: (NSString*) message location: (NSPoint) location - value: (float) value -{ +- (void) notify: (NotificationType) type message: (NSString *) message location: (NSPoint) location + value: (float) value { // These parameters are just to conform to the protocol #pragma unused(message) #pragma unused(location) - switch (type) - { - case IBNZoomChanged: - { - // Compute point increase/decrease based on default font size. - long fontSize = [self getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; - int zoom = (int) (fontSize * (value - 1)); - [self setGeneralProperty: SCI_SETZOOM value: zoom]; - break; - } - default: - break; - }; + switch (type) { + case IBNZoomChanged: { + // Compute point increase/decrease based on default font size. + long fontSize = [self getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; + int zoom = (int)(fontSize * (value - 1)); + [self setGeneralProperty: SCI_SETZOOM value: zoom]; + break; + } + default: + break; + }; } //-------------------------------------------------------------------------------------------------- -- (void) setCallback: (id <InfoBarCommunicator>) callback -{ +- (void) setCallback: (id <InfoBarCommunicator>) callback { // Not used. Only here to satisfy protocol. #pragma unused(callback) } @@ -1387,12 +1270,11 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Prevents drawing of the inner view to avoid flickering when doing many visual updates * (like clearing all marks and setting new ones etc.). */ -- (void) suspendDrawing: (BOOL) suspend -{ - if (suspend) - [self.window disableFlushWindow]; - else - [self.window enableFlushWindow]; +- (void) suspendDrawing: (BOOL) suspend { + if (suspend) + [self.window disableFlushWindow]; + else + [self.window enableFlushWindow]; } //-------------------------------------------------------------------------------------------------- @@ -1403,65 +1285,56 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * A delegate can be set to receive all notifications. If set no handling takes place here, except * for action pertaining to internal stuff (like the info bar). */ -- (void) notification: (SCNotification*)scn -{ - // Parent notification. Details are passed as SCNotification structure. - - if (mDelegate != nil) - { - [mDelegate notification: scn]; - if (scn->nmhdr.code != SCN_ZOOM && scn->nmhdr.code != SCN_UPDATEUI) - return; - } - - switch (scn->nmhdr.code) - { - case SCN_MARGINCLICK: - { - if (scn->margin == 2) - { - // Click on the folder margin. Toggle the current line if possible. - long line = [self getGeneralProperty: SCI_LINEFROMPOSITION parameter: scn->position]; - [self setGeneralProperty: SCI_TOGGLEFOLD value: line]; - } - break; - }; - case SCN_MODIFIED: - { - // Decide depending on the modification type what to do. - // There can be more than one modification carried by one notification. - if (scn->modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) - [self sendNotification: NSTextDidChangeNotification]; - break; - } - case SCN_ZOOM: - { - // A zoom change happened. Notify info bar if there is one. - float zoom = [self getGeneralProperty: SCI_GETZOOM parameter: 0]; - long fontSize = [self getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; - float factor = (zoom / fontSize) + 1; - [mInfoBar notify: IBNZoomChanged message: nil location: NSZeroPoint value: factor]; - break; - } - case SCN_UPDATEUI: - { - // Triggered whenever changes in the UI state need to be reflected. - // These can be: caret changes, selection changes etc. - NSPoint caretPosition = mBackend->GetCaretPosition(); - [mInfoBar notify: IBNCaretChanged message: nil location: caretPosition value: 0]; - [self sendNotification: SCIUpdateUINotification]; - if (scn->updated & (SC_UPDATE_SELECTION | SC_UPDATE_CONTENT)) - { - [self sendNotification: NSTextViewDidChangeSelectionNotification]; - } - break; - } - case SCN_FOCUSOUT: - [self sendNotification: NSTextDidEndEditingNotification]; - break; - case SCN_FOCUSIN: // Nothing to do for now. - break; - } +- (void) notification: (SCNotification *) scn { + // Parent notification. Details are passed as SCNotification structure. + + if (mDelegate != nil) { + [mDelegate notification: scn]; + if (scn->nmhdr.code != SCN_ZOOM && scn->nmhdr.code != SCN_UPDATEUI) + return; + } + + switch (scn->nmhdr.code) { + case SCN_MARGINCLICK: { + if (scn->margin == 2) { + // Click on the folder margin. Toggle the current line if possible. + long line = [self getGeneralProperty: SCI_LINEFROMPOSITION parameter: scn->position]; + [self setGeneralProperty: SCI_TOGGLEFOLD value: line]; + } + break; + }; + case SCN_MODIFIED: { + // Decide depending on the modification type what to do. + // There can be more than one modification carried by one notification. + if (scn->modificationType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) + [self sendNotification: NSTextDidChangeNotification]; + break; + } + case SCN_ZOOM: { + // A zoom change happened. Notify info bar if there is one. + float zoom = [self getGeneralProperty: SCI_GETZOOM parameter: 0]; + long fontSize = [self getGeneralProperty: SCI_STYLEGETSIZE parameter: STYLE_DEFAULT]; + float factor = (zoom / fontSize) + 1; + [mInfoBar notify: IBNZoomChanged message: nil location: NSZeroPoint value: factor]; + break; + } + case SCN_UPDATEUI: { + // Triggered whenever changes in the UI state need to be reflected. + // These can be: caret changes, selection changes etc. + NSPoint caretPosition = mBackend->GetCaretPosition(); + [mInfoBar notify: IBNCaretChanged message: nil location: caretPosition value: 0]; + [self sendNotification: SCIUpdateUINotification]; + if (scn->updated & (SC_UPDATE_SELECTION | SC_UPDATE_CONTENT)) { + [self sendNotification: NSTextViewDidChangeSelectionNotification]; + } + break; + } + case SCN_FOCUSOUT: + [self sendNotification: NSTextDidEndEditingNotification]; + break; + case SCN_FOCUSIN: // Nothing to do for now. + break; + } } //-------------------------------------------------------------------------------------------------- @@ -1470,13 +1343,12 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Setup a special indicator used in the editor to provide visual feedback for * input composition, depending on language, keyboard etc. */ -- (void) updateIndicatorIME -{ - [self setColorProperty: SCI_INDICSETFORE parameter: INDIC_IME fromHTML: @"#FF0000"]; - const bool drawInBackground = [self message: SCI_GETPHASESDRAW] != 0; - [self setGeneralProperty: SCI_INDICSETUNDER parameter: INDIC_IME value: drawInBackground]; - [self setGeneralProperty: SCI_INDICSETSTYLE parameter: INDIC_IME value: INDIC_PLAIN]; - [self setGeneralProperty: SCI_INDICSETALPHA parameter: INDIC_IME value: 100]; +- (void) updateIndicatorIME { + [self setColorProperty: SCI_INDICSETFORE parameter: INDIC_IME fromHTML: @"#FF0000"]; + const bool drawInBackground = [self message: SCI_GETPHASESDRAW] != 0; + [self setGeneralProperty: SCI_INDICSETUNDER parameter: INDIC_IME value: drawInBackground]; + [self setGeneralProperty: SCI_INDICSETSTYLE parameter: INDIC_IME value: INDIC_PLAIN]; + [self setGeneralProperty: SCI_INDICSETALPHA parameter: INDIC_IME value: 100]; } //-------------------------------------------------------------------------------------------------- @@ -1484,113 +1356,109 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Initialization of the view. Used to setup a few other things we need. */ -- (instancetype) initWithFrame: (NSRect) frame -{ - self = [super initWithFrame:frame]; - if (self) - { - mContent = [[[[self class] contentViewClass] alloc] initWithFrame:NSZeroRect]; - mContent.owner = self; - - // Initialize the scrollers but don't show them yet. - // Pick an arbitrary size, just to make NSScroller selecting the proper scroller direction - // (horizontal or vertical). - NSRect scrollerRect = NSMakeRect(0, 0, 100, 10); - scrollView = [[NSScrollView alloc] initWithFrame: scrollerRect]; - scrollView.documentView = mContent; - [scrollView setHasVerticalScroller:YES]; - [scrollView setHasHorizontalScroller:YES]; - scrollView.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable; - //[scrollView setScrollerStyle:NSScrollerStyleLegacy]; - //[scrollView setScrollerKnobStyle:NSScrollerKnobStyleDark]; - //[scrollView setHorizontalScrollElasticity:NSScrollElasticityNone]; - [self addSubview: scrollView]; - - marginView = [[SCIMarginView alloc] initWithScrollView:scrollView]; - marginView.owner = self; - marginView.ruleThickness = marginView.requiredThickness; - scrollView.verticalRulerView = marginView; - [scrollView setHasHorizontalRuler:NO]; - [scrollView setHasVerticalRuler:YES]; - [scrollView setRulersVisible:YES]; - - mBackend = new ScintillaCocoa(self, mContent, marginView); - - // Establish a connection from the back end to this container so we can handle situations - // which require our attention. - mBackend->SetDelegate(self); - - [self updateIndicatorIME]; - - NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; - [center addObserver:self - selector:@selector(applicationDidResignActive:) - name:NSApplicationDidResignActiveNotification - object:nil]; - - [center addObserver:self - selector:@selector(applicationDidBecomeActive:) - name:NSApplicationDidBecomeActiveNotification - object:nil]; - - [center addObserver:self - selector:@selector(windowWillMove:) - name:NSWindowWillMoveNotification - object:self.window]; - - [scrollView.contentView setPostsBoundsChangedNotifications:YES]; - [center addObserver:self - selector:@selector(scrollerAction:) - name:NSViewBoundsDidChangeNotification - object:scrollView.contentView]; - } - return self; -} - -//-------------------------------------------------------------------------------------------------- - -- (void) dealloc -{ - [[NSNotificationCenter defaultCenter] removeObserver:self]; - mBackend->Finalise(); - delete mBackend; - mBackend = NULL; - mContent.owner = nil; - [marginView setClientView:nil]; - [scrollView removeFromSuperview]; -} - -//-------------------------------------------------------------------------------------------------- - -- (void) applicationDidResignActive: (NSNotification *)note { +- (instancetype) initWithFrame: (NSRect) frame { + self = [super initWithFrame: frame]; + if (self) { + mContent = [[[[self class] contentViewClass] alloc] initWithFrame: NSZeroRect]; + mContent.owner = self; + + // Initialize the scrollers but don't show them yet. + // Pick an arbitrary size, just to make NSScroller selecting the proper scroller direction + // (horizontal or vertical). + NSRect scrollerRect = NSMakeRect(0, 0, 100, 10); + scrollView = [[NSScrollView alloc] initWithFrame: scrollerRect]; + scrollView.documentView = mContent; + [scrollView setHasVerticalScroller: YES]; + [scrollView setHasHorizontalScroller: YES]; + scrollView.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable; + //[scrollView setScrollerStyle:NSScrollerStyleLegacy]; + //[scrollView setScrollerKnobStyle:NSScrollerKnobStyleDark]; + //[scrollView setHorizontalScrollElasticity:NSScrollElasticityNone]; + [self addSubview: scrollView]; + + marginView = [[SCIMarginView alloc] initWithScrollView: scrollView]; + marginView.owner = self; + marginView.ruleThickness = marginView.requiredThickness; + scrollView.verticalRulerView = marginView; + [scrollView setHasHorizontalRuler: NO]; + [scrollView setHasVerticalRuler: YES]; + [scrollView setRulersVisible: YES]; + + mBackend = new ScintillaCocoa(self, mContent, marginView); + + // Establish a connection from the back end to this container so we can handle situations + // which require our attention. + mBackend->SetDelegate(self); + + [self updateIndicatorIME]; + + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserver: self + selector: @selector(applicationDidResignActive:) + name: NSApplicationDidResignActiveNotification + object: nil]; + + [center addObserver: self + selector: @selector(applicationDidBecomeActive:) + name: NSApplicationDidBecomeActiveNotification + object: nil]; + + [center addObserver: self + selector: @selector(windowWillMove:) + name: NSWindowWillMoveNotification + object: self.window]; + + [scrollView.contentView setPostsBoundsChangedNotifications: YES]; + [center addObserver: self + selector: @selector(scrollerAction:) + name: NSViewBoundsDidChangeNotification + object: scrollView.contentView]; + } + return self; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) dealloc { + [[NSNotificationCenter defaultCenter] removeObserver: self]; + mBackend->Finalise(); + delete mBackend; + mBackend = NULL; + mContent.owner = nil; + [marginView setClientView: nil]; + [scrollView removeFromSuperview]; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) applicationDidResignActive: (NSNotification *) note { #pragma unused(note) - mBackend->ActiveStateChanged(false); + mBackend->ActiveStateChanged(false); } //-------------------------------------------------------------------------------------------------- -- (void) applicationDidBecomeActive: (NSNotification *)note { +- (void) applicationDidBecomeActive: (NSNotification *) note { #pragma unused(note) - mBackend->ActiveStateChanged(true); + mBackend->ActiveStateChanged(true); } //-------------------------------------------------------------------------------------------------- -- (void) windowWillMove: (NSNotification *)note { +- (void) windowWillMove: (NSNotification *) note { #pragma unused(note) - mBackend->WindowWillMove(); + mBackend->WindowWillMove(); } //-------------------------------------------------------------------------------------------------- -- (void) viewDidMoveToWindow -{ - [super viewDidMoveToWindow]; +- (void) viewDidMoveToWindow { + [super viewDidMoveToWindow]; - [self positionSubViews]; + [self positionSubViews]; - // Enable also mouse move events for our window (and so this view). - [self.window setAcceptsMouseMovedEvents: YES]; + // Enable also mouse move events for our window (and so this view). + [self.window setAcceptsMouseMovedEvents: YES]; } //-------------------------------------------------------------------------------------------------- @@ -1598,38 +1466,35 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Used to position and size the parts of the editor (content, scrollers, info bar). */ -- (void) positionSubViews -{ - CGFloat scrollerWidth = [NSScroller scrollerWidthForControlSize:NSRegularControlSize - scrollerStyle:NSScrollerStyleLegacy]; - - NSSize size = self.frame.size; - NSRect barFrame = {{0, size.height - scrollerWidth}, {size.width, scrollerWidth}}; - BOOL infoBarVisible = mInfoBar != nil && !mInfoBar.hidden; - - // Horizontal offset of the content. Almost always 0 unless the vertical scroller - // is on the left side. - CGFloat contentX = 0; - NSRect scrollRect = {{contentX, 0}, {size.width, size.height}}; - - // Info bar frame. - if (infoBarVisible) - { - scrollRect.size.height -= scrollerWidth; - // Initial value already is as if the bar is at top. - if (!mInfoBarAtTop) - { - scrollRect.origin.y += scrollerWidth; - barFrame.origin.y = 0; - } - } +- (void) positionSubViews { + CGFloat scrollerWidth = [NSScroller scrollerWidthForControlSize: NSRegularControlSize + scrollerStyle: NSScrollerStyleLegacy]; + + NSSize size = self.frame.size; + NSRect barFrame = {{0, size.height - scrollerWidth}, {size.width, scrollerWidth}}; + BOOL infoBarVisible = mInfoBar != nil && !mInfoBar.hidden; + + // Horizontal offset of the content. Almost always 0 unless the vertical scroller + // is on the left side. + CGFloat contentX = 0; + NSRect scrollRect = {{contentX, 0}, {size.width, size.height}}; + + // Info bar frame. + if (infoBarVisible) { + scrollRect.size.height -= scrollerWidth; + // Initial value already is as if the bar is at top. + if (!mInfoBarAtTop) { + scrollRect.origin.y += scrollerWidth; + barFrame.origin.y = 0; + } + } - if (!NSEqualRects(scrollView.frame, scrollRect)) { - scrollView.frame = scrollRect; - } + if (!NSEqualRects(scrollView.frame, scrollRect)) { + scrollView.frame = scrollRect; + } - if (infoBarVisible) - mInfoBar.frame = barFrame; + if (infoBarVisible) + mInfoBar.frame = barFrame; } //-------------------------------------------------------------------------------------------------- @@ -1637,13 +1502,11 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Set the width of the margin. */ -- (void) setMarginWidth: (int) width -{ - if (marginView.ruleThickness != width) - { - marginView.marginWidth = width; - marginView.ruleThickness = marginView.requiredThickness; - } +- (void) setMarginWidth: (int) width { + if (marginView.ruleThickness != width) { + marginView.marginWidth = width; + marginView.ruleThickness = marginView.requiredThickness; + } } //-------------------------------------------------------------------------------------------------- @@ -1652,10 +1515,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Triggered by one of the scrollers when it gets manipulated by the user. Notify the backend * about the change. */ -- (void) scrollerAction: (id) sender -{ +- (void) scrollerAction: (id) sender { #pragma unused(sender) - mBackend->UpdateForScroll(); + mBackend->UpdateForScroll(); } //-------------------------------------------------------------------------------------------------- @@ -1663,14 +1525,13 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Used to reposition our content depending on the size of the view. */ -- (void) setFrame: (NSRect) newFrame -{ - NSRect previousFrame = self.frame; - super.frame = newFrame; - [self positionSubViews]; - if (!NSEqualRects(previousFrame, newFrame)) { - mBackend->Resize(); - } +- (void) setFrame: (NSRect) newFrame { + NSRect previousFrame = self.frame; + super.frame = newFrame; + [self positionSubViews]; + if (!NSEqualRects(previousFrame, newFrame)) { + mBackend->Resize(); + } } //-------------------------------------------------------------------------------------------------- @@ -1679,26 +1540,21 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Getter for the currently selected text in raw form (no formatting information included). * If there is no text available an empty string is returned. */ -- (NSString*) selectedString -{ - NSString *result = @""; +- (NSString *) selectedString { + NSString *result = @""; - const long length = mBackend->WndProc(SCI_GETSELTEXT, 0, 0); - if (length > 0) - { - std::string buffer(length + 1, '\0'); - try - { - mBackend->WndProc(SCI_GETSELTEXT, length + 1, (sptr_t) &buffer[0]); + const long length = mBackend->WndProc(SCI_GETSELTEXT, 0, 0); + if (length > 0) { + std::string buffer(length + 1, '\0'); + try { + mBackend->WndProc(SCI_GETSELTEXT, length + 1, (sptr_t) &buffer[0]); - result = @(buffer.c_str()); - } - catch (...) - { - } - } + result = @(buffer.c_str()); + } catch (...) { + } + } - return result; + return result; } //-------------------------------------------------------------------------------------------------- @@ -1706,13 +1562,11 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Delete a range from the document. */ -- (void) deleteRange: (NSRange) aRange -{ - if (aRange.length > 0) - { - NSRange posRange = mBackend->PositionsFromCharacters(aRange); - [self message: SCI_DELETERANGE wParam: posRange.location lParam: posRange.length]; - } +- (void) deleteRange: (NSRange) aRange { + if (aRange.length > 0) { + NSRange posRange = mBackend->PositionsFromCharacters(aRange); + [self message: SCI_DELETERANGE wParam: posRange.location lParam: posRange.length]; + } } //-------------------------------------------------------------------------------------------------- @@ -1721,26 +1575,21 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Getter for the current text in raw form (no formatting information included). * If there is no text available an empty string is returned. */ -- (NSString*) string -{ - NSString *result = @""; +- (NSString *) string { + NSString *result = @""; - const long length = mBackend->WndProc(SCI_GETLENGTH, 0, 0); - if (length > 0) - { - std::string buffer(length + 1, '\0'); - try - { - mBackend->WndProc(SCI_GETTEXT, length + 1, (sptr_t) &buffer[0]); + const long length = mBackend->WndProc(SCI_GETLENGTH, 0, 0); + if (length > 0) { + std::string buffer(length + 1, '\0'); + try { + mBackend->WndProc(SCI_GETTEXT, length + 1, (sptr_t) &buffer[0]); - result = @(buffer.c_str()); - } - catch (...) - { - } - } + result = @(buffer.c_str()); + } catch (...) { + } + } - return result; + return result; } //-------------------------------------------------------------------------------------------------- @@ -1748,45 +1597,40 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Setter for the current text (no formatting included). */ -- (void) setString: (NSString*) aString -{ - const char* text = aString.UTF8String; - mBackend->WndProc(SCI_SETTEXT, 0, (long) text); +- (void) setString: (NSString *) aString { + const char *text = aString.UTF8String; + mBackend->WndProc(SCI_SETTEXT, 0, (long) text); } //-------------------------------------------------------------------------------------------------- -- (void) insertString: (NSString*) aString atOffset: (int)offset -{ - const char* text = aString.UTF8String; - mBackend->WndProc(SCI_ADDTEXT, offset, (long) text); +- (void) insertString: (NSString *) aString atOffset: (int) offset { + const char *text = aString.UTF8String; + mBackend->WndProc(SCI_ADDTEXT, offset, (long) text); } //-------------------------------------------------------------------------------------------------- -- (void) setEditable: (BOOL) editable -{ - mBackend->WndProc(SCI_SETREADONLY, editable ? 0 : 1, 0); +- (void) setEditable: (BOOL) editable { + mBackend->WndProc(SCI_SETREADONLY, editable ? 0 : 1, 0); } //-------------------------------------------------------------------------------------------------- -- (BOOL) isEditable -{ - return mBackend->WndProc(SCI_GETREADONLY, 0, 0) == 0; +- (BOOL) isEditable { + return mBackend->WndProc(SCI_GETREADONLY, 0, 0) == 0; } //-------------------------------------------------------------------------------------------------- -- (SCIContentView*) content -{ - return mContent; +- (SCIContentView *) content { + return mContent; } //-------------------------------------------------------------------------------------------------- - (void) updateMarginCursors { - [self.window invalidateCursorRectsForView: marginView]; + [self.window invalidateCursorRectsForView: marginView]; } //-------------------------------------------------------------------------------------------------- @@ -1796,26 +1640,22 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * the result heavily depend on the message that is used for the call. Refer to the Scintilla * documentation to learn what can be used here. */ -+ (sptr_t) directCall: (ScintillaView*) sender message: (unsigned int) message wParam: (uptr_t) wParam - lParam: (sptr_t) lParam -{ - return ScintillaCocoa::DirectFunction( - reinterpret_cast<sptr_t>(sender->mBackend), message, wParam, lParam); ++ (sptr_t) directCall: (ScintillaView *) sender message: (unsigned int) message wParam: (uptr_t) wParam + lParam: (sptr_t) lParam { + return ScintillaCocoa::DirectFunction( + reinterpret_cast<sptr_t>(sender->mBackend), message, wParam, lParam); } -- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam lParam: (sptr_t) lParam -{ - return mBackend->WndProc(message, wParam, lParam); +- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam lParam: (sptr_t) lParam { + return mBackend->WndProc(message, wParam, lParam); } -- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam -{ - return mBackend->WndProc(message, wParam, 0); +- (sptr_t) message: (unsigned int) message wParam: (uptr_t) wParam { + return mBackend->WndProc(message, wParam, 0); } -- (sptr_t) message: (unsigned int) message -{ - return mBackend->WndProc(message, 0, 0); +- (sptr_t) message: (unsigned int) message { + return mBackend->WndProc(message, 0, 0); } //-------------------------------------------------------------------------------------------------- @@ -1827,9 +1667,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * @param parameter Additional info for this property like a parameter or index. * @param value The actual value. It depends on the property what this parameter means. */ -- (void) setGeneralProperty: (int) property parameter: (long) parameter value: (long) value -{ - mBackend->WndProc(property, parameter, value); +- (void) setGeneralProperty: (int) property parameter: (long) parameter value: (long) value { + mBackend->WndProc(property, parameter, value); } //-------------------------------------------------------------------------------------------------- @@ -1840,9 +1679,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * @param property Main property like SCI_STYLESETFORE for which a value is to be set. * @param value The actual value. It depends on the property what this parameter means. */ -- (void) setGeneralProperty: (int) property value: (long) value -{ - mBackend->WndProc(property, value, 0); +- (void) setGeneralProperty: (int) property value: (long) value { + mBackend->WndProc(property, value, 0); } //-------------------------------------------------------------------------------------------------- @@ -1855,9 +1693,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * @param extra Yet another parameter if needed. * @result A generic value which must be interpreted depending on the property queried. */ -- (long) getGeneralProperty: (int) property parameter: (long) parameter extra: (long) extra -{ - return mBackend->WndProc(property, parameter, extra); +- (long) getGeneralProperty: (int) property parameter: (long) parameter extra: (long) extra { + return mBackend->WndProc(property, parameter, extra); } //-------------------------------------------------------------------------------------------------- @@ -1865,9 +1702,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Convenience function to avoid unneeded extra parameter. */ -- (long) getGeneralProperty: (int) property parameter: (long) parameter -{ - return mBackend->WndProc(property, parameter, 0); +- (long) getGeneralProperty: (int) property parameter: (long) parameter { + return mBackend->WndProc(property, parameter, 0); } //-------------------------------------------------------------------------------------------------- @@ -1875,9 +1711,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Convenience function to avoid unneeded parameters. */ -- (long) getGeneralProperty: (int) property -{ - return mBackend->WndProc(property, 0, 0); +- (long) getGeneralProperty: (int) property { + return mBackend->WndProc(property, 0, 0); } //-------------------------------------------------------------------------------------------------- @@ -1885,9 +1720,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Use this variant if you have to pass in a reference to something (e.g. a text range). */ -- (long) getGeneralProperty: (int) property ref: (const void*) ref -{ - return mBackend->WndProc(property, 0, (sptr_t) ref); +- (long) getGeneralProperty: (int) property ref: (const void *) ref { + return mBackend->WndProc(property, 0, (sptr_t) ref); } //-------------------------------------------------------------------------------------------------- @@ -1895,16 +1729,15 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property setter for colors. */ -- (void) setColorProperty: (int) property parameter: (long) parameter value: (NSColor*) value -{ - if (value.colorSpaceName != NSDeviceRGBColorSpace) - value = [value colorUsingColorSpaceName: NSDeviceRGBColorSpace]; - long red = static_cast<long>(value.redComponent * 255); - long green = static_cast<long>(value.greenComponent * 255); - long blue = static_cast<long>(value.blueComponent * 255); +- (void) setColorProperty: (int) property parameter: (long) parameter value: (NSColor *) value { + if (value.colorSpaceName != NSDeviceRGBColorSpace) + value = [value colorUsingColorSpaceName: NSDeviceRGBColorSpace]; + long red = static_cast<long>(value.redComponent * 255); + long green = static_cast<long>(value.greenComponent * 255); + long blue = static_cast<long>(value.blueComponent * 255); - long color = (blue << 16) + (green << 8) + red; - mBackend->WndProc(property, parameter, color); + long color = (blue << 16) + (green << 8) + red; + mBackend->WndProc(property, parameter, color); } //-------------------------------------------------------------------------------------------------- @@ -1913,44 +1746,42 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Another color property setting, which allows to specify the color as string like in HTML * documents (i.e. with leading # and either 3 hex digits or 6). */ -- (void) setColorProperty: (int) property parameter: (long) parameter fromHTML: (NSString*) fromHTML -{ - if (fromHTML.length > 3 && [fromHTML characterAtIndex: 0] == '#') - { - bool longVersion = fromHTML.length > 6; - int index = 1; - - char value[3] = {0, 0, 0}; - value[0] = static_cast<char>([fromHTML characterAtIndex: index++]); - if (longVersion) - value[1] = static_cast<char>([fromHTML characterAtIndex: index++]); - else - value[1] = value[0]; - - unsigned rawRed; - [[NSScanner scannerWithString: @(value)] scanHexInt: &rawRed]; - - value[0] = static_cast<char>([fromHTML characterAtIndex: index++]); - if (longVersion) - value[1] = static_cast<char>([fromHTML characterAtIndex: index++]); - else - value[1] = value[0]; - - unsigned rawGreen; - [[NSScanner scannerWithString: @(value)] scanHexInt: &rawGreen]; - - value[0] = static_cast<char>([fromHTML characterAtIndex: index++]); - if (longVersion) - value[1] = static_cast<char>([fromHTML characterAtIndex: index++]); - else - value[1] = value[0]; - - unsigned rawBlue; - [[NSScanner scannerWithString: @(value)] scanHexInt: &rawBlue]; - - long color = (rawBlue << 16) + (rawGreen << 8) + rawRed; - mBackend->WndProc(property, parameter, color); - } +- (void) setColorProperty: (int) property parameter: (long) parameter fromHTML: (NSString *) fromHTML { + if (fromHTML.length > 3 && [fromHTML characterAtIndex: 0] == '#') { + bool longVersion = fromHTML.length > 6; + int index = 1; + + char value[3] = {0, 0, 0}; + value[0] = static_cast<char>([fromHTML characterAtIndex: index++]); + if (longVersion) + value[1] = static_cast<char>([fromHTML characterAtIndex: index++]); + else + value[1] = value[0]; + + unsigned rawRed; + [[NSScanner scannerWithString: @(value)] scanHexInt: &rawRed]; + + value[0] = static_cast<char>([fromHTML characterAtIndex: index++]); + if (longVersion) + value[1] = static_cast<char>([fromHTML characterAtIndex: index++]); + else + value[1] = value[0]; + + unsigned rawGreen; + [[NSScanner scannerWithString: @(value)] scanHexInt: &rawGreen]; + + value[0] = static_cast<char>([fromHTML characterAtIndex: index++]); + if (longVersion) + value[1] = static_cast<char>([fromHTML characterAtIndex: index++]); + else + value[1] = value[0]; + + unsigned rawBlue; + [[NSScanner scannerWithString: @(value)] scanHexInt: &rawBlue]; + + long color = (rawBlue << 16) + (rawGreen << 8) + rawRed; + mBackend->WndProc(property, parameter, color); + } } //-------------------------------------------------------------------------------------------------- @@ -1958,14 +1789,13 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property getter for colors. */ -- (NSColor*) getColorProperty: (int) property parameter: (long) parameter -{ - long color = mBackend->WndProc(property, parameter, 0); - CGFloat red = (color & 0xFF) / 255.0; - CGFloat green = ((color >> 8) & 0xFF) / 255.0; - CGFloat blue = ((color >> 16) & 0xFF) / 255.0; - NSColor* result = [NSColor colorWithDeviceRed: red green: green blue: blue alpha: 1]; - return result; +- (NSColor *) getColorProperty: (int) property parameter: (long) parameter { + long color = mBackend->WndProc(property, parameter, 0); + CGFloat red = (color & 0xFF) / 255.0; + CGFloat green = ((color >> 8) & 0xFF) / 255.0; + CGFloat blue = ((color >> 16) & 0xFF) / 255.0; + NSColor *result = [NSColor colorWithDeviceRed: red green: green blue: blue alpha: 1]; + return result; } //-------------------------------------------------------------------------------------------------- @@ -1973,9 +1803,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property setter for references (pointers, addresses). */ -- (void) setReferenceProperty: (int) property parameter: (long) parameter value: (const void*) value -{ - mBackend->WndProc(property, parameter, (sptr_t) value); +- (void) setReferenceProperty: (int) property parameter: (long) parameter value: (const void *) value { + mBackend->WndProc(property, parameter, (sptr_t) value); } //-------------------------------------------------------------------------------------------------- @@ -1983,9 +1812,8 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property getter for references (pointers, addresses). */ -- (const void*) getReferenceProperty: (int) property parameter: (long) parameter -{ - return (const void*) mBackend->WndProc(property, parameter, 0); +- (const void *) getReferenceProperty: (int) property parameter: (long) parameter { + return (const void *) mBackend->WndProc(property, parameter, 0); } //-------------------------------------------------------------------------------------------------- @@ -1993,10 +1821,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property setter for string values. */ -- (void) setStringProperty: (int) property parameter: (long) parameter value: (NSString*) value -{ - const char* rawValue = value.UTF8String; - mBackend->WndProc(property, parameter, (sptr_t) rawValue); +- (void) setStringProperty: (int) property parameter: (long) parameter value: (NSString *) value { + const char *rawValue = value.UTF8String; + mBackend->WndProc(property, parameter, (sptr_t) rawValue); } @@ -2005,10 +1832,9 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property getter for string values. */ -- (NSString*) getStringProperty: (int) property parameter: (long) parameter -{ - const char* rawValue = (const char*) mBackend->WndProc(property, parameter, 0); - return @(rawValue); +- (NSString *) getStringProperty: (int) property parameter: (long) parameter { + const char *rawValue = (const char *) mBackend->WndProc(property, parameter, 0); + return @(rawValue); } //-------------------------------------------------------------------------------------------------- @@ -2016,11 +1842,10 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property setter for lexer properties, which are commonly passed as strings. */ -- (void) setLexerProperty: (NSString*) name value: (NSString*) value -{ - const char* rawName = name.UTF8String; - const char* rawValue = value.UTF8String; - mBackend->WndProc(SCI_SETPROPERTY, (sptr_t) rawName, (sptr_t) rawValue); +- (void) setLexerProperty: (NSString *) name value: (NSString *) value { + const char *rawName = name.UTF8String; + const char *rawValue = value.UTF8String; + mBackend->WndProc(SCI_SETPROPERTY, (sptr_t) rawName, (sptr_t) rawValue); } //-------------------------------------------------------------------------------------------------- @@ -2028,11 +1853,10 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Specialized property getter for references (pointers, addresses). */ -- (NSString*) getLexerProperty: (NSString*) name -{ - const char* rawName = name.UTF8String; - const char* result = (const char*) mBackend->WndProc(SCI_SETPROPERTY, (sptr_t) rawName, 0); - return @(result); +- (NSString *) getLexerProperty: (NSString *) name { + const char *rawName = name.UTF8String; + const char *result = (const char *) mBackend->WndProc(SCI_SETPROPERTY, (sptr_t) rawName, 0); + return @(result); } //-------------------------------------------------------------------------------------------------- @@ -2040,8 +1864,7 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Sets the notification callback */ -- (void) registerNotifyCallback: (intptr_t) windowid value: (SciNotifyFunc) callback -{ +- (void) registerNotifyCallback: (intptr_t) windowid value: (SciNotifyFunc) callback { mBackend->RegisterNotifyCallback(windowid, callback); } @@ -2053,22 +1876,19 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Set newBar to nil if you want to hide the bar again. * The info bar's height is set to the height of the scrollbar. */ -- (void) setInfoBar: (NSView <InfoBarCommunicator>*) newBar top: (BOOL) top -{ - if (mInfoBar != newBar) - { - [mInfoBar removeFromSuperview]; +- (void) setInfoBar: (NSView <InfoBarCommunicator> *) newBar top: (BOOL) top { + if (mInfoBar != newBar) { + [mInfoBar removeFromSuperview]; - mInfoBar = newBar; - mInfoBarAtTop = top; - if (mInfoBar != nil) - { - [self addSubview: mInfoBar]; - [mInfoBar setCallback: self]; - } + mInfoBar = newBar; + mInfoBarAtTop = top; + if (mInfoBar != nil) { + [self addSubview: mInfoBar]; + [mInfoBar setCallback: self]; + } - [self positionSubViews]; - } + [self positionSubViews]; + } } //-------------------------------------------------------------------------------------------------- @@ -2076,17 +1896,15 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * Sets the edit's info bar status message. This call only has an effect if there is an info bar. */ -- (void) setStatusText: (NSString*) text -{ - if (mInfoBar != nil) - [mInfoBar notify: IBNStatusChanged message: text location: NSZeroPoint value: 0]; +- (void) setStatusText: (NSString *) text { + if (mInfoBar != nil) + [mInfoBar notify: IBNStatusChanged message: text location: NSZeroPoint value: 0]; } //-------------------------------------------------------------------------------------------------- -- (NSRange) selectedRange -{ - return [mContent selectedRange]; +- (NSRange) selectedRange { + return [mContent selectedRange]; } //-------------------------------------------------------------------------------------------------- @@ -2096,22 +1914,20 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * Unlike selectedRange, this can return empty ranges inside the document. */ -- (NSRange) selectedRangePositions -{ - const sptr_t positionBegin = [self message: SCI_GETSELECTIONSTART]; - const sptr_t positionEnd = [self message: SCI_GETSELECTIONEND]; - return NSMakeRange(positionBegin, positionEnd-positionBegin); +- (NSRange) selectedRangePositions { + const sptr_t positionBegin = [self message: SCI_GETSELECTIONSTART]; + const sptr_t positionEnd = [self message: SCI_GETSELECTIONEND]; + return NSMakeRange(positionBegin, positionEnd-positionBegin); } //-------------------------------------------------------------------------------------------------- -- (void)insertText: (id) aString -{ - if ([aString isKindOfClass:[NSString class]]) - mBackend->InsertText(aString); - else if ([aString isKindOfClass:[NSAttributedString class]]) - mBackend->InsertText([aString string]); +- (void) insertText: (id) aString { + if ([aString isKindOfClass: [NSString class]]) + mBackend->InsertText(aString); + else if ([aString isKindOfClass: [NSAttributedString class]]) + mBackend->InsertText([aString string]); } //-------------------------------------------------------------------------------------------------- @@ -2119,18 +1935,17 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context /** * For backwards compatibility. */ -- (BOOL) findAndHighlightText: (NSString*) searchText - matchCase: (BOOL) matchCase - wholeWord: (BOOL) wholeWord - scrollTo: (BOOL) scrollTo - wrap: (BOOL) wrap -{ - return [self findAndHighlightText: searchText - matchCase: matchCase - wholeWord: wholeWord - scrollTo: scrollTo - wrap: wrap - backwards: NO]; +- (BOOL) findAndHighlightText: (NSString *) searchText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + scrollTo: (BOOL) scrollTo + wrap: (BOOL) wrap { + return [self findAndHighlightText: searchText + matchCase: matchCase + wholeWord: wholeWord + scrollTo: scrollTo + wrap: wrap + backwards: NO]; } //-------------------------------------------------------------------------------------------------- @@ -2140,82 +1955,73 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * * @result YES if something was found, NO otherwise. */ -- (BOOL) findAndHighlightText: (NSString*) searchText - matchCase: (BOOL) matchCase - wholeWord: (BOOL) wholeWord - scrollTo: (BOOL) scrollTo - wrap: (BOOL) wrap - backwards: (BOOL) backwards -{ - int searchFlags= 0; - if (matchCase) - searchFlags |= SCFIND_MATCHCASE; - if (wholeWord) - searchFlags |= SCFIND_WHOLEWORD; - - long selectionStart = [self getGeneralProperty: SCI_GETSELECTIONSTART parameter: 0]; - long selectionEnd = [self getGeneralProperty: SCI_GETSELECTIONEND parameter: 0]; - - // Sets the start point for the coming search to the beginning of the current selection. - // For forward searches we have therefore to set the selection start to the current selection end - // for proper incremental search. This does not harm as we either get a new selection if something - // is found or the previous selection is restored. - if (!backwards) - [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: selectionEnd]; - [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; - sptr_t result; - const char* textToSearch = searchText.UTF8String; - - // The following call will also set the selection if something was found. - if (backwards) - { - result = [ScintillaView directCall: self - message: SCI_SEARCHPREV - wParam: searchFlags - lParam: (sptr_t) textToSearch]; - if (result < 0 && wrap) - { - // Try again from the end of the document if nothing could be found so far and - // wrapped search is set. - [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: [self getGeneralProperty: SCI_GETTEXTLENGTH parameter: 0]]; - [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; - result = [ScintillaView directCall: self - message: SCI_SEARCHNEXT - wParam: searchFlags - lParam: (sptr_t) textToSearch]; - } - } - else - { - result = [ScintillaView directCall: self - message: SCI_SEARCHNEXT - wParam: searchFlags - lParam: (sptr_t) textToSearch]; - if (result < 0 && wrap) - { - // Try again from the start of the document if nothing could be found so far and - // wrapped search is set. - [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: 0]; - [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; - result = [ScintillaView directCall: self - message: SCI_SEARCHNEXT - wParam: searchFlags - lParam: (sptr_t) textToSearch]; - } - } - - if (result >= 0) - { - if (scrollTo) - [self setGeneralProperty: SCI_SCROLLCARET value: 0]; - } - else - { - // Restore the former selection if we did not find anything. - [self setGeneralProperty: SCI_SETSELECTIONSTART value: selectionStart]; - [self setGeneralProperty: SCI_SETSELECTIONEND value: selectionEnd]; - } - return (result >= 0) ? YES : NO; +- (BOOL) findAndHighlightText: (NSString *) searchText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + scrollTo: (BOOL) scrollTo + wrap: (BOOL) wrap + backwards: (BOOL) backwards { + int searchFlags= 0; + if (matchCase) + searchFlags |= SCFIND_MATCHCASE; + if (wholeWord) + searchFlags |= SCFIND_WHOLEWORD; + + long selectionStart = [self getGeneralProperty: SCI_GETSELECTIONSTART parameter: 0]; + long selectionEnd = [self getGeneralProperty: SCI_GETSELECTIONEND parameter: 0]; + + // Sets the start point for the coming search to the beginning of the current selection. + // For forward searches we have therefore to set the selection start to the current selection end + // for proper incremental search. This does not harm as we either get a new selection if something + // is found or the previous selection is restored. + if (!backwards) + [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: selectionEnd]; + [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; + sptr_t result; + const char *textToSearch = searchText.UTF8String; + + // The following call will also set the selection if something was found. + if (backwards) { + result = [ScintillaView directCall: self + message: SCI_SEARCHPREV + wParam: searchFlags + lParam: (sptr_t) textToSearch]; + if (result < 0 && wrap) { + // Try again from the end of the document if nothing could be found so far and + // wrapped search is set. + [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: [self getGeneralProperty: SCI_GETTEXTLENGTH parameter: 0]]; + [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; + result = [ScintillaView directCall: self + message: SCI_SEARCHNEXT + wParam: searchFlags + lParam: (sptr_t) textToSearch]; + } + } else { + result = [ScintillaView directCall: self + message: SCI_SEARCHNEXT + wParam: searchFlags + lParam: (sptr_t) textToSearch]; + if (result < 0 && wrap) { + // Try again from the start of the document if nothing could be found so far and + // wrapped search is set. + [self getGeneralProperty: SCI_SETSELECTIONSTART parameter: 0]; + [self setGeneralProperty: SCI_SEARCHANCHOR value: 0]; + result = [ScintillaView directCall: self + message: SCI_SEARCHNEXT + wParam: searchFlags + lParam: (sptr_t) textToSearch]; + } + } + + if (result >= 0) { + if (scrollTo) + [self setGeneralProperty: SCI_SCROLLCARET value: 0]; + } else { + // Restore the former selection if we did not find anything. + [self setGeneralProperty: SCI_SETSELECTIONSTART value: selectionStart]; + [self setGeneralProperty: SCI_SETSELECTIONEND value: selectionEnd]; + } + return (result >= 0) ? YES : NO; } //-------------------------------------------------------------------------------------------------- @@ -2225,108 +2031,100 @@ sourceOperationMaskForDraggingContext: (NSDraggingContext) context * * @result Number of entries replaced, 0 if none. */ -- (int) findAndReplaceText: (NSString*) searchText - byText: (NSString*) newText - matchCase: (BOOL) matchCase - wholeWord: (BOOL) wholeWord - doAll: (BOOL) doAll -{ - // The current position is where we start searching for single occurrences. Otherwise we start at - // the beginning of the document. - long startPosition; - if (doAll) - startPosition = 0; // Start at the beginning of the text if we replace all occurrences. - else - // For a single replacement we start at the current caret position. - startPosition = [self getGeneralProperty: SCI_GETCURRENTPOS]; - long endPosition = [self getGeneralProperty: SCI_GETTEXTLENGTH]; - - int searchFlags= 0; - if (matchCase) - searchFlags |= SCFIND_MATCHCASE; - if (wholeWord) - searchFlags |= SCFIND_WHOLEWORD; - [self setGeneralProperty: SCI_SETSEARCHFLAGS value: searchFlags]; - [self setGeneralProperty: SCI_SETTARGETSTART value: startPosition]; - [self setGeneralProperty: SCI_SETTARGETEND value: endPosition]; - - const char* textToSearch = searchText.UTF8String; - long sourceLength = strlen(textToSearch); // Length in bytes. - const char* replacement = newText.UTF8String; - long targetLength = strlen(replacement); // Length in bytes. - sptr_t result; - - int replaceCount = 0; - if (doAll) - { - while (true) - { - result = [ScintillaView directCall: self - message: SCI_SEARCHINTARGET - wParam: sourceLength - lParam: (sptr_t) textToSearch]; - if (result < 0) - break; - - replaceCount++; - [ScintillaView directCall: self - message: SCI_REPLACETARGET - wParam: targetLength - lParam: (sptr_t) replacement]; - - // The replacement changes the target range to the replaced text. Continue after that till the end. - // The text length might be changed by the replacement so make sure the target end is the actual - // text end. - [self setGeneralProperty: SCI_SETTARGETSTART value: [self getGeneralProperty: SCI_GETTARGETEND]]; - [self setGeneralProperty: SCI_SETTARGETEND value: [self getGeneralProperty: SCI_GETTEXTLENGTH]]; - } - } - else - { - result = [ScintillaView directCall: self - message: SCI_SEARCHINTARGET - wParam: sourceLength - lParam: (sptr_t) textToSearch]; - replaceCount = (result < 0) ? 0 : 1; - - if (replaceCount > 0) - { - [ScintillaView directCall: self - message: SCI_REPLACETARGET - wParam: targetLength - lParam: (sptr_t) replacement]; - - // For a single replace we set the new selection to the replaced text. - [self setGeneralProperty: SCI_SETSELECTIONSTART value: [self getGeneralProperty: SCI_GETTARGETSTART]]; - [self setGeneralProperty: SCI_SETSELECTIONEND value: [self getGeneralProperty: SCI_GETTARGETEND]]; - } - } - - return replaceCount; -} - -//-------------------------------------------------------------------------------------------------- - -- (void) setFontName: (NSString*) font - size: (int) size - bold: (BOOL) bold - italic: (BOOL) italic -{ - for (int i = 0; i < 128; i++) - { - [self setGeneralProperty: SCI_STYLESETFONT - parameter: i - value: (sptr_t)font.UTF8String]; - [self setGeneralProperty: SCI_STYLESETSIZE - parameter: i - value: size]; - [self setGeneralProperty: SCI_STYLESETBOLD - parameter: i - value: bold]; - [self setGeneralProperty: SCI_STYLESETITALIC - parameter: i - value: italic]; - } +- (int) findAndReplaceText: (NSString *) searchText + byText: (NSString *) newText + matchCase: (BOOL) matchCase + wholeWord: (BOOL) wholeWord + doAll: (BOOL) doAll { + // The current position is where we start searching for single occurrences. Otherwise we start at + // the beginning of the document. + long startPosition; + if (doAll) + startPosition = 0; // Start at the beginning of the text if we replace all occurrences. + else + // For a single replacement we start at the current caret position. + startPosition = [self getGeneralProperty: SCI_GETCURRENTPOS]; + long endPosition = [self getGeneralProperty: SCI_GETTEXTLENGTH]; + + int searchFlags= 0; + if (matchCase) + searchFlags |= SCFIND_MATCHCASE; + if (wholeWord) + searchFlags |= SCFIND_WHOLEWORD; + [self setGeneralProperty: SCI_SETSEARCHFLAGS value: searchFlags]; + [self setGeneralProperty: SCI_SETTARGETSTART value: startPosition]; + [self setGeneralProperty: SCI_SETTARGETEND value: endPosition]; + + const char *textToSearch = searchText.UTF8String; + long sourceLength = strlen(textToSearch); // Length in bytes. + const char *replacement = newText.UTF8String; + long targetLength = strlen(replacement); // Length in bytes. + sptr_t result; + + int replaceCount = 0; + if (doAll) { + while (true) { + result = [ScintillaView directCall: self + message: SCI_SEARCHINTARGET + wParam: sourceLength + lParam: (sptr_t) textToSearch]; + if (result < 0) + break; + + replaceCount++; + [ScintillaView directCall: self + message: SCI_REPLACETARGET + wParam: targetLength + lParam: (sptr_t) replacement]; + + // The replacement changes the target range to the replaced text. Continue after that till the end. + // The text length might be changed by the replacement so make sure the target end is the actual + // text end. + [self setGeneralProperty: SCI_SETTARGETSTART value: [self getGeneralProperty: SCI_GETTARGETEND]]; + [self setGeneralProperty: SCI_SETTARGETEND value: [self getGeneralProperty: SCI_GETTEXTLENGTH]]; + } + } else { + result = [ScintillaView directCall: self + message: SCI_SEARCHINTARGET + wParam: sourceLength + lParam: (sptr_t) textToSearch]; + replaceCount = (result < 0) ? 0 : 1; + + if (replaceCount > 0) { + [ScintillaView directCall: self + message: SCI_REPLACETARGET + wParam: targetLength + lParam: (sptr_t) replacement]; + + // For a single replace we set the new selection to the replaced text. + [self setGeneralProperty: SCI_SETSELECTIONSTART value: [self getGeneralProperty: SCI_GETTARGETSTART]]; + [self setGeneralProperty: SCI_SETSELECTIONEND value: [self getGeneralProperty: SCI_GETTARGETEND]]; + } + } + + return replaceCount; +} + +//-------------------------------------------------------------------------------------------------- + +- (void) setFontName: (NSString *) font + size: (int) size + bold: (BOOL) bold + italic: (BOOL) italic { + for (int i = 0; i < 128; i++) { + [self setGeneralProperty: SCI_STYLESETFONT + parameter: i + value: (sptr_t)font.UTF8String]; + [self setGeneralProperty: SCI_STYLESETSIZE + parameter: i + value: size]; + [self setGeneralProperty: SCI_STYLESETBOLD + parameter: i + value: bold]; + [self setGeneralProperty: SCI_STYLESETITALIC + parameter: i + value: italic]; + } } //-------------------------------------------------------------------------------------------------- |