Created
October 27, 2009 20:23
-
-
Save anonymous/219916 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// TextView.m | |
// TextDidChange | |
// | |
// Created by Timothy J. Wood on 10/27/09. | |
// Copyright 2009 The Omni Group. All rights reserved. | |
// | |
/* | |
A button hooked up to -insertFoo: yields: | |
2009-10-27 13:22:37.971 TextDidChange[1897:a0b] insert range:{0, 0} | |
2009-10-27 13:22:37.974 TextDidChange[1897:a0b] in processEditing editedMask:2 editedRange:{0, 3} changeInLength:3 | |
2009-10-27 13:22:37.975 TextDidChange[1897:a0b] in didChangeText: rangeForUserTextChange = {3, 0} | |
2009-10-27 13:22:37.975 TextDidChange[1897:a0b] in didChangeText: editedMask:0 editedRange:{9223372036854775807, 3} changeInLength:0 | |
copying & pasting that "foo" right after yields: | |
2009-10-27 13:22:40.132 TextDidChange[1897:a0b] in processEditing editedMask:3 editedRange:{3, 3} changeInLength:3 | |
2009-10-27 13:22:40.134 TextDidChange[1897:a0b] in didChangeText: rangeForUserTextChange = {6, 0} | |
2009-10-27 13:22:40.134 TextDidChange[1897:a0b] in didChangeText: editedMask:0 editedRange:{9223372036854775807, 3} changeInLength:0 | |
then, selecting and deleting the first foo: | |
2009-10-27 13:22:42.243 TextDidChange[1897:a0b] in processEditing editedMask:2 editedRange:{0, 0} changeInLength:-3 | |
2009-10-27 13:22:42.244 TextDidChange[1897:a0b] in didChangeText: rangeForUserTextChange = {0, 0} | |
2009-10-27 13:22:42.245 TextDidChange[1897:a0b] in didChangeText: editedMask:0 editedRange:{9223372036854775807, 0} changeInLength:0 | |
*/ | |
#import "TextView.h" | |
@interface TextStorage : NSTextStorage | |
{ | |
NSMutableAttributedString *_contents; | |
} | |
@end | |
@implementation TextStorage | |
// NSTextStorage is abstract; minimal concrete subclass | |
- init; | |
{ | |
if (!(self = [super init])) | |
return nil; | |
_contents = [[NSMutableAttributedString alloc] initWithString:@"" attributes:nil]; | |
return self; | |
} | |
- (void)dealloc; | |
{ | |
[_contents release]; | |
[super dealloc]; | |
} | |
#pragma mark - | |
#pragma NSAttributedString subclass | |
- (NSUInteger)length; | |
{ | |
return [_contents length]; | |
} | |
- (NSString *)string; | |
{ | |
return [_contents string]; | |
} | |
- (NSDictionary *)attributesAtIndex:(NSUInteger)location effectiveRange:(NSRangePointer)range; | |
{ | |
return [_contents attributesAtIndex:location effectiveRange:range]; | |
} | |
#pragma mark - | |
#pragma NSMutableAttributedString subclass | |
- (void)beginEditing; | |
{ | |
[super beginEditing]; | |
[_contents beginEditing]; | |
} | |
- (void)endEditing; | |
{ | |
[_contents endEditing]; | |
[super endEditing]; | |
} | |
- (void)replaceCharactersInRange:(NSRange)range withString:(NSString *)str; | |
{ | |
[_contents replaceCharactersInRange:range withString:str]; | |
[self edited:NSTextStorageEditedCharacters range:range changeInLength:[str length] - range.length]; | |
} | |
- (void)replaceCharactersInRange:(NSRange)range withAttributedString:(NSAttributedString *)attributedString; | |
{ | |
[_contents replaceCharactersInRange:range withAttributedString:attributedString]; | |
[self edited:NSTextStorageEditedAttributes|NSTextStorageEditedCharacters range:range changeInLength:[attributedString length] - range.length]; | |
} | |
- (void)setAttributes:(NSDictionary *)attrs range:(NSRange)range; | |
{ | |
[_contents setAttributes:attrs range:range]; | |
[self edited:NSTextStorageEditedAttributes range:range changeInLength:0]; | |
} | |
#pragma mark - | |
#pragma mark NSTextStorage subclass | |
- (void)processEditing; | |
{ | |
NSLog(@"in processEditing editedMask:%ld editedRange:%@ changeInLength:%ld", [self editedMask], NSStringFromRange([self editedRange]), [self changeInLength]); | |
[super processEditing]; | |
} | |
@end | |
@implementation TextView | |
- (void)awakeFromNib; | |
{ | |
// Terrible | |
TextStorage *textStorage = [[TextStorage alloc] init]; | |
[[self layoutManager] replaceTextStorage:textStorage]; | |
[textStorage release]; | |
} | |
- (void)didChangeText; | |
{ | |
NSLog(@"in didChangeText: rangeForUserTextChange = %@", NSStringFromRange([self rangeForUserTextChange])); | |
NSTextStorage *textStorage = [self textStorage]; | |
NSLog(@"in didChangeText: editedMask:%ld editedRange:%@ changeInLength:%ld", [textStorage editedMask], NSStringFromRange([textStorage editedRange]), [textStorage changeInLength]); | |
[super didChangeText]; | |
} | |
- (IBAction)insertFoo:(id)sender; | |
{ | |
// ... not bothering with multi-range for test ... | |
NSRange range = [self selectionRangeForProposedRange:[self selectedRange] granularity:[self selectionGranularity]]; | |
NSLog(@"insert range:%@", NSStringFromRange(range)); | |
if ([self shouldChangeTextInRange:range replacementString:@"foo"]) { | |
NSTextStorage *textStorage = [self textStorage]; | |
[textStorage beginEditing]; | |
[textStorage replaceCharactersInRange:range withString:@"foo"]; | |
[textStorage endEditing]; | |
[self didChangeText]; | |
} | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment