1997-09-01 21:59:51 +00:00
|
|
|
/*
|
|
|
|
NSGAttributedString.m
|
|
|
|
|
|
|
|
Implementation of concrete subclass of a string class with attributes
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
Copyright (C) 1997, 1999 Free Software Foundation, Inc.
|
1997-09-01 21:59:51 +00:00
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
Written by: ANOQ of the sun < anoq@vip.cybercity.dk >
|
1997-11-21 18:19:29 +00:00
|
|
|
Date: November 1997
|
1997-09-01 21:59:51 +00:00
|
|
|
|
1997-11-21 18:19:29 +00:00
|
|
|
This file is part of GNUStep-base
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
This library is distributed in the hope that it will be useful,
|
1997-09-01 21:59:51 +00:00
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
If you are interested in a warranty or support for this source code,
|
|
|
|
contact Scott Christley < scottc@net-community.com > for more information.
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
|
|
License along with this library; if not, write to the Free
|
|
|
|
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
|
1997-11-21 18:19:29 +00:00
|
|
|
//FIXME: 1) The NSMutableString object returned from the -mutableString method
|
|
|
|
// in NSMutableAttributedString is NOT tracked for changes to update
|
|
|
|
// NSMutableAttributedString's attributes as it should.
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
//FIXME: 2) If out-of-memory exceptions are raised in some methods,
|
1997-11-21 18:19:29 +00:00
|
|
|
// inconsistencies may develop, because the two internal arrays in
|
|
|
|
// NSGAttributedString and NSGMutableAttributedString called
|
|
|
|
// attributeArray and locateArray must always be syncronized.
|
|
|
|
|
|
|
|
//FIXME: 3) The method _setAttributesFrom: must be overridden by
|
|
|
|
// concrete subclasses of NSAttributedString which is WRONG and
|
1999-04-05 07:07:03 +00:00
|
|
|
// VERY bad ! I haven't found any other way to make
|
|
|
|
// - initWithString: attributes: the designated initializer
|
1997-11-21 18:19:29 +00:00
|
|
|
// in NSAttributedString and still implement
|
|
|
|
// - initWithAttributedString: without having to override it
|
|
|
|
// in the concrete subclass.
|
|
|
|
|
|
|
|
#include <Foundation/NSGAttributedString.h>
|
1997-09-01 21:59:51 +00:00
|
|
|
#include <Foundation/NSException.h>
|
|
|
|
#include <Foundation/NSValue.h>
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
@interface GSAttrInfo : NSObject
|
|
|
|
{
|
|
|
|
@public
|
|
|
|
NSDictionary *attr;
|
|
|
|
unsigned loc;
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
1997-09-01 21:59:51 +00:00
|
|
|
@implementation NSGAttributedString
|
|
|
|
|
|
|
|
void _setAttributesFrom(
|
1999-04-05 07:07:03 +00:00
|
|
|
NSAttributedString *attributedString,
|
|
|
|
NSRange aRange,
|
|
|
|
NSMutableArray *attributeArray,
|
1997-09-01 21:59:51 +00:00
|
|
|
NSMutableArray *locateArray)
|
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
//always called immediately after -initWithString: attributes:
|
1997-09-01 21:59:51 +00:00
|
|
|
NSRange effectiveRange;
|
|
|
|
NSDictionary *attributeDict;
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
if (aRange.length <= 0)
|
1997-09-01 21:59:51 +00:00
|
|
|
return;//No attributes
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
attributeDict = [attributedString attributesAtIndex: aRange.location
|
|
|
|
effectiveRange: &effectiveRange];
|
|
|
|
[attributeArray replaceObjectAtIndex: 0 withObject: attributeDict];
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
|
|
while (NSMaxRange(effectiveRange) < NSMaxRange(aRange))
|
1999-04-05 07:07:03 +00:00
|
|
|
{
|
|
|
|
attributeDict =
|
|
|
|
[attributedString attributesAtIndex: NSMaxRange(effectiveRange)
|
|
|
|
effectiveRange: &effectiveRange];
|
|
|
|
[attributeArray addObject: attributeDict];
|
|
|
|
[locateArray addObject:
|
|
|
|
[NSNumber numberWithUnsignedInt:
|
|
|
|
effectiveRange.location-aRange.location]];
|
|
|
|
}
|
1997-09-01 21:59:51 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
void _initWithString(
|
1999-04-05 07:07:03 +00:00
|
|
|
NSString *aString,
|
|
|
|
NSDictionary *attributes,
|
|
|
|
NSString **textChars,
|
|
|
|
NSMutableArray **attributeArray,
|
1997-09-01 21:59:51 +00:00
|
|
|
NSMutableArray **locateArray)
|
|
|
|
{
|
|
|
|
if (aString)
|
1999-04-05 07:07:03 +00:00
|
|
|
*textChars = [(*textChars) initWithString: aString];
|
1997-09-01 21:59:51 +00:00
|
|
|
else
|
1997-11-21 18:19:29 +00:00
|
|
|
*textChars = [(*textChars) init];
|
1997-09-01 21:59:51 +00:00
|
|
|
*attributeArray = [[NSMutableArray alloc] init];
|
|
|
|
*locateArray = [[NSMutableArray alloc] init];
|
1999-04-05 07:07:03 +00:00
|
|
|
if (! attributes)
|
|
|
|
attributes = [[NSDictionary alloc] init];
|
|
|
|
[(*attributeArray) addObject: attributes];
|
|
|
|
[attributes release];
|
|
|
|
[(*locateArray) addObject: [NSNumber numberWithUnsignedInt: 0]];
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
NSDictionary *_attributesAtIndexEffectiveRange(
|
1999-04-05 07:07:03 +00:00
|
|
|
unsigned int index,
|
|
|
|
NSRange *aRange,
|
|
|
|
unsigned int tmpLength,
|
|
|
|
NSMutableArray *attributeArray,
|
|
|
|
NSMutableArray *locateArray,
|
1997-09-01 21:59:51 +00:00
|
|
|
unsigned int *foundIndex)
|
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
unsigned int low, high, used, cnt, foundLoc, nextLoc;
|
1997-09-01 21:59:51 +00:00
|
|
|
NSDictionary *foundDict;
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
if (index <0 || index >= tmpLength)
|
|
|
|
{
|
|
|
|
[NSException raise: NSRangeException
|
|
|
|
format: @"index is out of range in function "
|
|
|
|
@"_attributesAtIndexEffectiveRange()"];
|
|
|
|
}
|
1997-09-01 21:59:51 +00:00
|
|
|
|
|
|
|
//Binary search for efficiency in huge attributed strings
|
|
|
|
used = [attributeArray count];
|
1999-04-05 07:07:03 +00:00
|
|
|
low = 0;
|
1997-09-01 21:59:51 +00:00
|
|
|
high = used - 1;
|
1999-04-05 07:07:03 +00:00
|
|
|
while (low <= high)
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
cnt = (low+high)/2;
|
|
|
|
foundDict = [attributeArray objectAtIndex: cnt];
|
|
|
|
foundLoc = [[locateArray objectAtIndex: cnt] unsignedIntValue];
|
|
|
|
if (foundLoc > index)
|
|
|
|
{
|
|
|
|
high = cnt-1;
|
|
|
|
}
|
1997-09-01 21:59:51 +00:00
|
|
|
else
|
1999-04-05 07:07:03 +00:00
|
|
|
{
|
|
|
|
if (cnt >= used -1)
|
|
|
|
nextLoc = tmpLength;
|
|
|
|
else
|
|
|
|
nextLoc = [[locateArray objectAtIndex: cnt+1] unsignedIntValue];
|
|
|
|
if (foundLoc == index || index < nextLoc)
|
|
|
|
{
|
|
|
|
//Found
|
|
|
|
if (aRange)
|
|
|
|
{
|
|
|
|
aRange->location = foundLoc;
|
|
|
|
aRange->length = nextLoc - foundLoc;
|
|
|
|
}
|
|
|
|
if (foundIndex)
|
|
|
|
*foundIndex = cnt;
|
|
|
|
return foundDict;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
low = cnt+1;
|
|
|
|
}
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
1999-04-05 07:07:03 +00:00
|
|
|
NSCAssert(NO, @"Error in binary search algorithm");
|
1997-09-01 21:59:51 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) encodeWithCoder: aCoder
|
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
[super encodeWithCoder: aCoder];
|
|
|
|
[aCoder encodeObject: textChars];
|
|
|
|
[aCoder encodeObject: attributeArray];
|
|
|
|
[aCoder encodeObject: locateArray];
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- initWithCoder: aCoder
|
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
self = [super initWithCoder: aCoder];
|
1998-09-02 12:34:38 +00:00
|
|
|
[aCoder decodeValueOfObjCType: @encode(id) at: &textChars];
|
|
|
|
[aCoder decodeValueOfObjCType: @encode(id) at: &attributeArray];
|
|
|
|
[aCoder decodeValueOfObjCType: @encode(id) at: &locateArray];
|
1997-09-01 21:59:51 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
- _setAttributesFrom: (NSAttributedString *)attributedString
|
|
|
|
range: (NSRange)aRange
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
//always called immediately after -initWithString: attributes:
|
|
|
|
_setAttributesFrom(attributedString, aRange, attributeArray, locateArray);
|
1997-09-01 21:59:51 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
- (id)initWithString: (NSString *)aString attributes: (NSDictionary *)attributes
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
self = [super initWithString: aString attributes: attributes];
|
1997-09-01 21:59:51 +00:00
|
|
|
textChars = [NSString alloc];
|
1999-04-05 07:07:03 +00:00
|
|
|
_initWithString(aString, attributes, &textChars, &attributeArray, &locateArray);
|
1997-09-01 21:59:51 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *)string
|
|
|
|
{
|
|
|
|
return textChars;
|
|
|
|
}
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
- (NSDictionary *)attributesAtIndex: (unsigned int)index effectiveRange: (NSRange *)aRange
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
|
|
|
return _attributesAtIndexEffectiveRange(
|
1999-04-05 07:07:03 +00:00
|
|
|
index, aRange, [self length], attributeArray, locateArray, NULL);
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)dealloc
|
|
|
|
{
|
|
|
|
[textChars release];
|
|
|
|
[attributeArray release];
|
|
|
|
[locateArray release];
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
@implementation NSGMutableAttributedString
|
|
|
|
|
|
|
|
- (void) encodeWithCoder: aCoder
|
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
[super encodeWithCoder: aCoder];
|
|
|
|
[aCoder encodeObject: textChars];
|
|
|
|
[aCoder encodeObject: attributeArray];
|
|
|
|
[aCoder encodeObject: locateArray];
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- initWithCoder: aCoder
|
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
self = [super initWithCoder: aCoder];
|
1998-09-02 12:34:38 +00:00
|
|
|
[aCoder decodeValueOfObjCType: @encode(id) at: &textChars];
|
|
|
|
[aCoder decodeValueOfObjCType: @encode(id) at: &attributeArray];
|
|
|
|
[aCoder decodeValueOfObjCType: @encode(id) at: &locateArray];
|
1997-09-01 21:59:51 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
- _setAttributesFrom: (NSAttributedString *)attributedString
|
|
|
|
range: (NSRange)aRange
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
//always called immediately after -initWithString: attributes:
|
|
|
|
_setAttributesFrom(attributedString, aRange, attributeArray, locateArray);
|
1997-09-01 21:59:51 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
- (id)initWithString: (NSString *)aString attributes: (NSDictionary *)attributes
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
self = [super initWithString: aString attributes: attributes];
|
1997-09-01 21:59:51 +00:00
|
|
|
textChars = [NSMutableString alloc];
|
1999-04-05 07:07:03 +00:00
|
|
|
_initWithString(aString, attributes, &textChars, &attributeArray, &locateArray);
|
1997-09-01 21:59:51 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *)string
|
|
|
|
{
|
|
|
|
return textChars;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSMutableString *)mutableString
|
|
|
|
{
|
|
|
|
return textChars;
|
|
|
|
}
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
- (NSDictionary *)attributesAtIndex: (unsigned int)index effectiveRange: (NSRange *)aRange
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
|
|
|
return _attributesAtIndexEffectiveRange(
|
1999-04-05 07:07:03 +00:00
|
|
|
index, aRange, [self length], attributeArray, locateArray, NULL);
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
- (void)setAttributes: (NSDictionary *)attributes range: (NSRange)range
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
unsigned int tmpLength, arrayIndex, arraySize, location;
|
1997-09-01 21:59:51 +00:00
|
|
|
NSRange effectiveRange;
|
1999-04-05 07:07:03 +00:00
|
|
|
NSNumber *afterRangeLocation, *beginRangeLocation;
|
1997-09-01 21:59:51 +00:00
|
|
|
NSDictionary *attrs;
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
if (! attributes)
|
1997-09-01 21:59:51 +00:00
|
|
|
attributes = [NSDictionary dictionary];
|
|
|
|
tmpLength = [self length];
|
1999-04-05 07:07:03 +00:00
|
|
|
if (range.location < 0 || NSMaxRange(range) > tmpLength)
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
[NSException raise: NSRangeException
|
|
|
|
format: @"RangeError in method -replaceCharactersInRange: "
|
|
|
|
@"withString: in class NSMutableAttributedString"];
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
1999-04-05 07:07:03 +00:00
|
|
|
arraySize = [locateArray count];
|
|
|
|
if (NSMaxRange(range) < tmpLength)
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
attrs = _attributesAtIndexEffectiveRange(
|
|
|
|
NSMaxRange(range), &effectiveRange, tmpLength,
|
|
|
|
attributeArray, locateArray, &arrayIndex);
|
|
|
|
|
|
|
|
afterRangeLocation =
|
|
|
|
[NSNumber numberWithUnsignedInt: NSMaxRange(range)];
|
|
|
|
if (effectiveRange.location > range.location)
|
|
|
|
{
|
|
|
|
[locateArray replaceObjectAtIndex: arrayIndex
|
|
|
|
withObject: afterRangeLocation];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
arrayIndex++;
|
|
|
|
//There shouldn't be anything wrong in putting an object (attrs) in
|
|
|
|
//an array more than once should there? The object will not change.
|
|
|
|
[attributeArray insertObject: attrs atIndex: arrayIndex];
|
|
|
|
[locateArray insertObject: afterRangeLocation atIndex: arrayIndex];
|
|
|
|
}
|
|
|
|
arrayIndex--;
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
arrayIndex = arraySize - 1;
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
while (arrayIndex > 0 &&
|
|
|
|
[[locateArray objectAtIndex: arrayIndex-1] unsignedIntValue]
|
|
|
|
>= range.location)
|
|
|
|
{
|
|
|
|
[locateArray removeObjectAtIndex: arrayIndex];
|
|
|
|
[attributeArray removeObjectAtIndex: arrayIndex];
|
|
|
|
arrayIndex--;
|
|
|
|
}
|
|
|
|
beginRangeLocation = [NSNumber numberWithUnsignedInt: range.location];
|
|
|
|
location = [[locateArray objectAtIndex: arrayIndex] unsignedIntValue];
|
|
|
|
if (location >= range.location)
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
if (location > range.location)
|
|
|
|
{
|
|
|
|
[locateArray replaceObjectAtIndex: arrayIndex
|
|
|
|
withObject: beginRangeLocation];
|
|
|
|
}
|
|
|
|
[attributeArray replaceObjectAtIndex: arrayIndex
|
|
|
|
withObject: attributes];
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
|
|
|
else
|
1999-04-05 07:07:03 +00:00
|
|
|
{
|
|
|
|
arrayIndex++;
|
|
|
|
[attributeArray insertObject: attributes atIndex: arrayIndex];
|
|
|
|
[locateArray insertObject: beginRangeLocation atIndex: arrayIndex];
|
|
|
|
}
|
1997-09-01 21:59:51 +00:00
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
/* Primitive method ! Sets attributes and values for a given range of
|
|
|
|
* characters, replacing any previous attributes and values for that range.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Sets the attributes for the characters in aRange to attributes.
|
|
|
|
* These new attributes replace any attributes previously associated with
|
|
|
|
* the characters in aRange. Raises an NSRangeException if any part of
|
|
|
|
* aRange lies beyond the end of the receiver's characters.
|
|
|
|
* See also: - addAtributes: range: , - removeAttributes: range:
|
|
|
|
*/
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
- (void)replaceCharactersInRange: (NSRange)range withString: (NSString *)aString
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
unsigned int tmpLength, arrayIndex, arraySize, cnt, location, moveLocations;
|
1997-09-01 21:59:51 +00:00
|
|
|
NSRange effectiveRange;
|
|
|
|
NSDictionary *attrs;
|
|
|
|
NSNumber *afterRangeLocation;
|
|
|
|
|
1999-04-05 07:07:03 +00:00
|
|
|
if (! aString)
|
1997-09-01 21:59:51 +00:00
|
|
|
aString = @"";
|
|
|
|
tmpLength = [self length];
|
1999-04-05 07:07:03 +00:00
|
|
|
if (range.location < 0 || NSMaxRange(range) > tmpLength)
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
[NSException raise: NSRangeException
|
|
|
|
format: @"RangeError in method -replaceCharactersInRange: "
|
|
|
|
@"withString: in class NSMutableAttributedString"];
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
1999-04-05 07:07:03 +00:00
|
|
|
arraySize = [locateArray count];
|
|
|
|
if (NSMaxRange(range) < tmpLength)
|
1997-09-01 21:59:51 +00:00
|
|
|
{
|
1999-04-05 07:07:03 +00:00
|
|
|
attrs = _attributesAtIndexEffectiveRange(
|
|
|
|
NSMaxRange(range), &effectiveRange, tmpLength,
|
|
|
|
attributeArray, locateArray, &arrayIndex);
|
|
|
|
|
|
|
|
moveLocations = [aString length] - range.length;
|
|
|
|
afterRangeLocation =
|
|
|
|
[NSNumber numberWithUnsignedInt: NSMaxRange(range)+moveLocations];
|
|
|
|
|
|
|
|
if (effectiveRange.location > range.location)
|
|
|
|
{
|
|
|
|
[locateArray replaceObjectAtIndex: arrayIndex
|
|
|
|
withObject: afterRangeLocation];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
arrayIndex++;
|
|
|
|
//There shouldn't be anything wrong in putting an object (attrs) in
|
|
|
|
//an array more than once should there? The object will not change.
|
|
|
|
[attributeArray insertObject: attrs atIndex: arrayIndex];
|
|
|
|
[locateArray insertObject: afterRangeLocation atIndex: arrayIndex];
|
|
|
|
}
|
|
|
|
|
|
|
|
for (cnt = arrayIndex+1;cnt < arraySize;cnt++)
|
|
|
|
{
|
|
|
|
location = [[locateArray objectAtIndex: cnt] unsignedIntValue]
|
|
|
|
+ moveLocations;
|
|
|
|
[locateArray replaceObjectAtIndex: cnt
|
|
|
|
withObject: [NSNumber numberWithUnsignedInt: location]];
|
|
|
|
}
|
|
|
|
arrayIndex--;
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
arrayIndex = arraySize - 1;
|
1999-04-05 07:07:03 +00:00
|
|
|
while (arrayIndex > 0 &&
|
|
|
|
[[locateArray objectAtIndex: arrayIndex] unsignedIntValue] > range.location)
|
|
|
|
{
|
|
|
|
[locateArray removeObjectAtIndex: arrayIndex];
|
|
|
|
[attributeArray removeObjectAtIndex: arrayIndex];
|
|
|
|
arrayIndex--;
|
|
|
|
}
|
|
|
|
[textChars replaceCharactersInRange: range withString: aString];
|
1997-09-01 21:59:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)dealloc
|
|
|
|
{
|
|
|
|
[textChars release];
|
|
|
|
[attributeArray release];
|
|
|
|
[locateArray release];
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|