Improved all the character and paragraph attribute methods

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@6602 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2000-05-20 16:55:08 +00:00
parent a5b915e256
commit dcc14de701

View file

@ -252,11 +252,12 @@ static NSRange MakeRangeFromAbs (int a1,int a2) // not the same as NSMakeRange!
+ (void) setSelectionWordGranularitySet: (NSCharacterSet*)aSet;
+ (void) setSelectionParagraphGranularitySet: (NSCharacterSet*)aSet;
+ (NSDictionary*) defaultTypingAttributes;
//
// private
//
- (void) deleteRange: (NSRange)aRange backspace: (BOOL)flag;
- (NSDictionary*) defaultTypingAttributes;
- (void) setSelectedRangeNoDrawing: (NSRange)range;
- (void) drawInsertionPointAtIndex: (unsigned)index
@ -786,7 +787,7 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
{
int aLine = 0;
int insertionLineIndex = 0;
unsigned oldMax = NSMaxRange(aRange);
//unsigned oldMax = NSMaxRange(aRange);
//unsigned newMax = oldMax + insertionDelta;
NSPoint drawingPoint = NSZeroPoint;
NSScanner *pScanner;
@ -1318,20 +1319,22 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
[self setMinSize: frameRect.size];
[self setMaxSize: NSMakeSize(HUGE,HUGE)];
_alignment = NSLeftTextAlignment;
_tf.is_field_editor = NO;
_tf.is_editable = YES;
_tf.is_selectable = YES;
_tf.is_rich_text = NO;
_tf.uses_font_panel = NO;
_tf.imports_graphics = NO;
_tf.draws_background = NO;
_tf.is_horizontally_resizable = NO;
_tf.is_vertically_resizable = YES;
_tf.uses_font_panel = YES;
_tf.uses_ruler = YES;
_tf.is_ruler_visible = NO;
_tf.is_field_editor = NO;
_tf.draws_background = YES;
[self setBackgroundColor: [NSColor textBackgroundColor]];
[self setTextColor: [NSColor textColor]];
ASSIGN(_caret_color, [NSColor blackColor]);
_default_font = RETAIN([NSFont userFontOfSize: 12]);
[self setTypingAttributes: [[self class] defaultTypingAttributes]];
[self setBackgroundColor: [NSColor textBackgroundColor]];
// sets up the contents object
[self setString: @""];
//[self setSelectedRange: NSMakeRange (0, 0)];
@ -1342,8 +1345,6 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
{
[self unregisterDraggedTypes];
RELEASE(_background_color);
RELEASE(_default_font);
RELEASE(_text_color);
RELEASE(_caret_color);
RELEASE(_textStorage);
RELEASE(_typingAttributes);
@ -1376,9 +1377,13 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
- (void) replaceCharactersInRange: (NSRange)aRange
withString: (NSString*)aString
{
if (![self shouldChangeTextInRange: aRange
replacementString: nil])
return;
[_textStorage beginEditing];
[_textStorage replaceCharactersInRange: aRange withString: aString];
[_textStorage endEditing];
[self didChangeText];
[self sizeToFit];
}
@ -1387,7 +1392,7 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
RELEASE(_textStorage);
_textStorage = [[NSTextStorage alloc]
initWithString: aString
attributes: [self defaultTypingAttributes]];
attributes: [self typingAttributes]];
[self _buildUpLayout];
[self sizeToFit];
@ -1500,6 +1505,8 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
- (void)setImportsGraphics: (BOOL)flag
{
if (flag)
_tf.is_rich_text = flag;
_tf.imports_graphics = flag;
[self updateDragTypeRegistration];
}
@ -1509,6 +1516,7 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
_tf.is_rich_text = flag;
if (!flag)
{
_tf.imports_graphics = flag;
[self setString: [self string]];
}
@ -1546,11 +1554,7 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
- (void) toggleRuler: (id)sender
{
NSScrollView *sv = [self enclosingScrollView];
_tf.is_ruler_visible = !_tf.is_ruler_visible;
if (sv != nil)
[sv setRulersVisible: _tf.is_ruler_visible];
[self setRulerVisible: !_tf.is_ruler_visible];
}
//
@ -1595,13 +1599,10 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
}
else // no selection
{
if ([self isRichText])
if (_tf.is_rich_text)
{
[self setTypingAttributes: [NSMutableDictionary
dictionaryWithDictionary:
[_textStorage
attributesAtIndex: range.location
effectiveRange: NULL]]];
[self setTypingAttributes: [_textStorage attributesAtIndex: range.location
effectiveRange: NULL]];
}
// <!>enable caret timed entry
}
@ -1623,7 +1624,7 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
NSStringPboardType];
NSPasteboard *pboard = [NSPasteboard generalPasteboard];
if ([self isRichText])
if (_tf.is_rich_text)
[types addObject: NSRTFPboardType];
if (_tf.imports_graphics)
@ -1634,7 +1635,7 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
[pboard setString: [[self string] substringWithRange: _selected_range]
forType: NSStringPboardType];
if ([self isRichText])
if (_tf.is_rich_text)
[pboard setData: [self RTFFromRange: _selected_range]
forType: NSRTFPboardType];
@ -1674,7 +1675,7 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
NSParagraphStyle *style;
NSData * data = nil;
if (![self isRichText])
if (!_tf.is_rich_text)
return;
// FIXME: Should use rulerAttributesInRange:
@ -1729,12 +1730,20 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
}
/*
* Managing Font and Color
* Managing Font
*/
- (NSFont*) font
{
// FIXME: Should take the font of the first text, if there is some
return _default_font;
if ([_textStorage length])
{
NSFont *font = [_textStorage attribute: NSFontAttributeName
atIndex: 0
effectiveRange: NULL];
if (font != nil)
return font;
}
return [_typingAttributes objectForKey: NSFontAttributeName];
}
/*
@ -1744,64 +1753,60 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
*/
- (void) changeFont: (id)sender
{
if (_tf.uses_font_panel)
{
if ([self isRichText])
{
NSRange searchRange = _selected_range;
NSRange foundRange;
int maxSelRange;
NSRange foundRange;
int maxSelRange;
NSRange aRange= [self rangeForUserCharacterAttributeChange];
NSRange searchRange = aRange;
[_textStorage beginEditing];
for (maxSelRange = NSMaxRange(_selected_range);
searchRange.location < maxSelRange;
searchRange = NSMakeRange (NSMaxRange (foundRange),
maxSelRange - NSMaxRange(foundRange)))
{
NSFont *font = [_textStorage attribute: NSFontAttributeName
atIndex: searchRange.location
longestEffectiveRange: &foundRange
inRange: searchRange];
if (font)
{
[self setFont: [sender convertFont: font]
ofRange: foundRange];
}
}
[_textStorage endEditing];
}
else
{
[self setFont: [sender convertFont: _default_font]];
}
if (aRange.location == NSNotFound)
return;
if (![self shouldChangeTextInRange: aRange
replacementString: nil])
return;
[_textStorage beginEditing];
for (maxSelRange = NSMaxRange(aRange);
searchRange.location < maxSelRange;
searchRange = NSMakeRange (NSMaxRange (foundRange),
maxSelRange - NSMaxRange(foundRange)))
{
NSFont *font = [_textStorage attribute: NSFontAttributeName
atIndex: searchRange.location
longestEffectiveRange: &foundRange
inRange: searchRange];
if (font != nil)
{
[self setFont: [sender convertFont: font]
ofRange: foundRange];
}
}
[_textStorage endEditing];
[self didChangeText];
// FIXME: set typing attributes
}
- (void) setFont: (NSFont*)font
{
NSRange fullRange = NSMakeRange(0, [_textStorage length]);
ASSIGN(_default_font, font);
[_textStorage beginEditing];
[_textStorage addAttribute: NSFontAttributeName
value: font
range: fullRange];
[_textStorage endEditing];
[self setFont: font ofRange: fullRange];
[_typingAttributes setObject: font forKey: NSFontAttributeName];
}
- (void) setFont: (NSFont*)font
ofRange: (NSRange)aRange
{
if ([self isRichText])
if (font != nil)
{
if (font != nil)
{
[_textStorage beginEditing];
[_textStorage addAttribute: NSFontAttributeName
value: font
range: aRange];
[_textStorage endEditing];
}
if (![self shouldChangeTextInRange: aRange
replacementString: nil])
return;
[_textStorage beginEditing];
[_textStorage addAttribute: NSFontAttributeName
value: font
range: aRange];
[_textStorage endEditing];
[self didChangeText];
}
}
@ -1810,84 +1815,87 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
*/
- (NSTextAlignment) alignment
{
return _alignment;
NSRange aRange = [self rangeForUserParagraphAttributeChange];
NSParagraphStyle *aStyle;
if (aRange.location != NSNotFound)
{
aStyle = [_textStorage attribute: NSParagraphStyleAttributeName
atIndex: aRange.location
effectiveRange: NULL];
if (aStyle != nil)
return [aStyle alignment];
}
// Get alignment from typing attributes
return [[[self typingAttributes]
objectForKey: NSParagraphStyleAttributeName] alignment];
}
- (void) setAlignment: (NSTextAlignment) mode
{
_alignment = mode;
[_textStorage beginEditing];
[_textStorage setAlignment: NSCenterTextAlignment
range: NSMakeRange(0, [_textStorage length])];
[_textStorage endEditing];
[self setAlignment: mode
range: NSMakeRange(0, [_textStorage length])];
}
- (void) alignCenter: (id) sender
{
if ([self isRichText])
{
[_textStorage beginEditing];
[_textStorage setAlignment: NSCenterTextAlignment
range: _selected_range];
[_textStorage endEditing];
}
else
[self setAlignment: NSCenterTextAlignment];
[self setAlignment: NSCenterTextAlignment
range: [self rangeForUserParagraphAttributeChange]];
}
- (void) alignLeft: (id) sender
{
if ([self isRichText])
{
[_textStorage beginEditing];
[_textStorage setAlignment: NSLeftTextAlignment
range: _selected_range];
[_textStorage endEditing];
}
else
[self setAlignment: NSLeftTextAlignment];
[self setAlignment: NSLeftTextAlignment
range: [self rangeForUserParagraphAttributeChange]];
}
- (void) alignRight: (id) sender
{
if ([self isRichText])
{
[_textStorage beginEditing];
[_textStorage setAlignment: NSRightTextAlignment
range: _selected_range];
[_textStorage endEditing];
}
else
[self setAlignment: NSRightTextAlignment];
[self setAlignment: NSRightTextAlignment
range: [self rangeForUserParagraphAttributeChange]];
}
/*
* Text colour
*/
- (NSColor*) textColor
{
return _text_color;
NSRange aRange = [self rangeForUserCharacterAttributeChange];
if (aRange.location != NSNotFound)
return [_textStorage attribute: NSForegroundColorAttributeName
atIndex: aRange.location
effectiveRange: NULL];
else
return [_typingAttributes objectForKey: NSForegroundColorAttributeName];
}
- (void) setTextColor: (NSColor*) color
range: (NSRange) aRange
{
if ([self isRichText])
if (aRange.location == NSNotFound)
return;
if (![self shouldChangeTextInRange: aRange
replacementString: nil])
return;
[_textStorage beginEditing];
if (color != nil)
{
[_textStorage beginEditing];
if (color != nil)
{
[_textStorage addAttribute: NSForegroundColorAttributeName
value: color
range: aRange];
}
else
{
[_textStorage removeAttribute: NSForegroundColorAttributeName
range: aRange];
}
[_textStorage endEditing];
[_textStorage addAttribute: NSForegroundColorAttributeName
value: color
range: aRange];
[_typingAttributes setObject: color forKey: NSForegroundColorAttributeName];
}
else
{
[_textStorage removeAttribute: NSForegroundColorAttributeName
range: aRange];
}
[_textStorage endEditing];
[self didChangeText];
}
- (void) setColor: (NSColor*) color
@ -1900,20 +1908,7 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
{
NSRange fullRange = NSMakeRange(0, [_textStorage length]);
ASSIGN (_text_color, color);
[_textStorage beginEditing];
if (color != nil)
{
[_textStorage addAttribute: NSForegroundColorAttributeName
value: color
range: fullRange];
}
else
{
[_textStorage removeAttribute: NSForegroundColorAttributeName
range: fullRange];
}
[_textStorage endEditing];
[self setTextColor: color range: fullRange];
}
//
@ -1921,23 +1916,25 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
//
- (void) subscript: (id)sender
{
NSRange aRange;
NSRange aRange = [self rangeForUserCharacterAttributeChange];
if (_tf.is_rich_text)
aRange = _selected_range;
else
aRange = NSMakeRange(0, [_textStorage length]);
if (aRange.location == NSNotFound)
return;
if (aRange.length)
{
if (![self shouldChangeTextInRange: aRange
replacementString: nil])
return;
[_textStorage beginEditing];
[_textStorage subscriptRange: aRange];
[_textStorage endEditing];
[self didChangeText];
}
else
{
// FIXME: Set the typing attributes
/* [[self typingAttributes]
/* [_typingAttributes
setObject: [NSNumber numberWithInt: ]
forKey: NSSuperScriptAttributeName]; */
}
@ -1945,18 +1942,20 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
- (void) superscript: (id)sender
{
NSRange aRange;
NSRange aRange = [self rangeForUserCharacterAttributeChange];
if (_tf.is_rich_text)
aRange = _selected_range;
else
aRange = NSMakeRange(0, [_textStorage length]);
if (aRange.location == NSNotFound)
return;
if (aRange.length)
{
if (![self shouldChangeTextInRange: aRange
replacementString: nil])
return;
[_textStorage beginEditing];
[_textStorage superscriptRange: aRange];
[_textStorage endEditing];
[self didChangeText];
}
else
{
@ -1966,18 +1965,20 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
- (void) unscript: (id)sender
{
NSRange aRange;
NSRange aRange = [self rangeForUserCharacterAttributeChange];
if (_tf.is_rich_text)
aRange = _selected_range;
else
aRange = NSMakeRange(0, [_textStorage length]);
if (aRange.location == NSNotFound)
return;
if (aRange.length)
{
if (![self shouldChangeTextInRange: aRange
replacementString: nil])
return;
[_textStorage beginEditing];
[_textStorage unscriptRange: aRange];
[_textStorage endEditing];
[self didChangeText];
}
else
{
@ -1987,13 +1988,11 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
- (void) underline: (id)sender
{
NSRange aRange;
BOOL doUnderline = YES;
NSRange aRange = [self rangeForUserCharacterAttributeChange];
if (_tf.is_rich_text)
aRange = _selected_range;
else
aRange = NSMakeRange(0, [_textStorage length]);
if (aRange.location == NSNotFound)
return;
if ([[_textStorage attribute: NSUnderlineStyleAttributeName
atIndex: aRange.location
@ -2002,14 +2001,18 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
if (aRange.length)
{
if (![self shouldChangeTextInRange: aRange
replacementString: nil])
return;
[_textStorage beginEditing];
[_textStorage addAttribute: NSUnderlineStyleAttributeName
value: [NSNumber numberWithInt: doUnderline]
range: aRange];
[_textStorage endEditing];
[self didChangeText];
}
else // no redraw necess.
[[self typingAttributes]
[_typingAttributes
setObject: [NSNumber numberWithInt: doUnderline]
forKey: NSUnderlineStyleAttributeName];
}
@ -2607,12 +2610,15 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
flag = _tf.smart_insert_delete;
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
flag = _tf.allows_undo;
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &flag];
[aCoder encodeValueOfObjCType: "I" at: &_alignment];
[aCoder encodeObject: _typingAttributes];
[aCoder encodeObject: _background_color];
[aCoder encodeObject: _text_color];
[aCoder encodeObject: _default_font];
[aCoder encodeValueOfObjCType: @encode(NSRange) at: &_selected_range];
[aCoder encodeObject: _caret_color];
[aCoder encodeValueOfObjCType: @encode(NSSize) at: &_minSize];
[aCoder encodeValueOfObjCType: @encode(NSSize) at: &_maxSize];
}
- initWithCoder: aDecoder
@ -2647,12 +2653,15 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
_tf.is_ruler_visible = flag;
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
_tf.smart_insert_delete = flag;
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &flag];
_tf.allows_undo = flag;
[aDecoder decodeValueOfObjCType: "I" at: &_alignment];
_typingAttributes = [aDecoder decodeObject];
_background_color = [aDecoder decodeObject];
_text_color = RETAIN([aDecoder decodeObject]);
_default_font = RETAIN([aDecoder decodeObject]);
[aDecoder decodeValueOfObjCType: @encode(NSRange) at: &_selected_range];
_caret_color = [aDecoder decodeObject];
[aDecoder decodeValueOfObjCType: @encode(NSSize) at: &_minSize];
[aDecoder decodeValueOfObjCType: @encode(NSSize) at: &_maxSize];
// build up the layout information that dont get stored
[self _buildUpLayout];
@ -2689,6 +2698,9 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
- (void) replaceRange: (NSRange) aRange
withAttributedString: (NSAttributedString*) attrString
{
if (![self shouldChangeTextInRange: aRange
replacementString: [attrString string]])
return;
[_textStorage beginEditing];
if ([self isRichText])
[_textStorage replaceCharactersInRange: aRange
@ -2697,6 +2709,7 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
[_textStorage replaceCharactersInRange: aRange
withString: [attrString string]];
[_textStorage endEditing];
[self didChangeText];
// ScrollView interaction
[self sizeToFit];
}
@ -2711,6 +2724,19 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
[self sizeToFit];
}
@end
@implementation NSText(NSTextView)
- (void) setRulerVisible: (BOOL)flag
{
NSScrollView *sv = [self enclosingScrollView];
_tf.is_ruler_visible = flag;
if (sv != nil)
[sv setRulersVisible: _tf.is_ruler_visible];
}
- (int) spellCheckerDocumentTag
{
if (!_spellCheckerDocumentTag)
@ -2719,39 +2745,54 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
return _spellCheckerDocumentTag;
}
- (BOOL) shouldChangeTextInRange: (NSRange)affectedCharRange
replacementString: (NSString*)replacementString
{
return YES;
}
- (void) didChangeText
{
[[NSNotificationCenter defaultCenter]
postNotificationName: NSTextDidChangeNotification object: self];
}
// central text inserting method (takes care
// of optimized redraw/ cursor positioning)
- (void) insertText: (NSString*) insertString
{
NSRange insertRange = [self rangeForUserTextChange];
if (insertRange.location == NSNotFound)
return;
if ([self isRichText])
{
[self replaceRange: _selected_range
[self replaceRange: insertRange
withAttributedString: AUTORELEASE([[NSAttributedString alloc]
initWithString: insertString
attributes: [self typingAttributes]])];
}
else
{
[self replaceCharactersInRange: _selected_range
[self replaceCharactersInRange: insertRange
withString: insertString];
}
// move cursor <!> [self selectionRangeForProposedRange: ]
[self setSelectedRange:
NSMakeRange (_selected_range.location + [insertString length], 0)];
NSMakeRange (insertRange.location + [insertString length], 0)];
// remember x for row - stable cursor movements
_currentCursor = [self rectForCharacterIndex:
_selected_range.location].origin;
// broadcast notification
[[NSNotificationCenter defaultCenter]
postNotificationName: NSTextDidChangeNotification
object: self];
}
- (void) setTypingAttributes: (NSDictionary*) dict
{
if (dict == nil)
dict = [[self class] defaultTypingAttributes];
if (![dict isKindOfClass: [NSMutableDictionary class]])
{
RELEASE(_typingAttributes);
@ -2761,13 +2802,9 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
ASSIGN(_typingAttributes, (NSMutableDictionary*)dict);
}
- (NSMutableDictionary*) typingAttributes
- (NSDictionary*) typingAttributes
{
if (_typingAttributes != nil)
return _typingAttributes;
else
return [NSMutableDictionary dictionaryWithDictionary:
[self defaultTypingAttributes]];
return [NSDictionary dictionaryWithDictionary: _typingAttributes];
}
- (void) updateFontPanel
@ -2775,30 +2812,15 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
// update fontPanel only if told so
if (_tf.uses_font_panel)
{
BOOL isMultiple = NO;
NSFont *currentFont = nil;
NSRange longestRange;
NSFont *currentFont = [_textStorage attribute: NSFontAttributeName
atIndex: _selected_range.location
longestEffectiveRange: &longestRange
inRange: _selected_range];
if ([self isRichText])
{
NSRange longestRange;
currentFont = [_textStorage attribute: NSFontAttributeName
atIndex: _selected_range.location
longestEffectiveRange: &longestRange
inRange: _selected_range];
if (NSEqualRanges (longestRange, _selected_range))
isMultiple = NO;
else
{
isMultiple = YES;
}
}
else
currentFont = _default_font;
[[NSFontManager sharedFontManager] setSelectedFont: currentFont
isMultiple: isMultiple];
[[NSFontManager sharedFontManager]
setSelectedFont: currentFont
isMultiple: NSEqualRanges(longestRange, _selected_range)];
}
}
@ -2833,50 +2855,108 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
- (NSRange) selectionRangeForProposedRange: (NSRange)proposedCharRange
granularity: (NSSelectionGranularity)granularity
{
NSCharacterSet *set = nil;
unsigned index;
NSRange aRange;
NSRange newRange = proposedCharRange;
NSString *string = [self string];
unsigned lastIndex = [string length] - 1;
unsigned lpos = MIN(lastIndex, proposedCharRange.location);
// <!>better: rpos = MAX(0, (int)NSMaxRange(proposedCharRange) - 1);
unsigned rpos = NSMaxRange(proposedCharRange);
BOOL rmemberstate, lmemberstate;
unsigned length = [string length];
if (![string length])
if (proposedCharRange.location > length)
{
return NSMakeRange(0,0);
proposedCharRange.location = length;
proposedCharRange.length = 0;
}
if (proposedCharRange.length > length - proposedCharRange.location)
{
proposedCharRange.length = length - proposedCharRange.location;
}
if (!length)
return proposedCharRange;
switch (granularity)
{
case NSSelectByCharacter:
return NSIntersectionRange (proposedCharRange,
NSMakeRange (0, lastIndex + 2));
case NSSelectByWord:
set = selectionWordGranularitySet;
break;
index = [_textStorage nextWordFromIndex: proposedCharRange.location
forward: NO];
newRange.location = index;
index = [_textStorage nextWordFromIndex: NSMaxRange(proposedCharRange)
forward: YES];
if (index > newRange.location)
newRange.length = index - 1 - newRange.location;
return newRange;
case NSSelectByParagraph:
set = selectionParagraphGranularitySet;
break;
return [[self string] lineRangeForRange: proposedCharRange];
case NSSelectByCharacter:
default:
aRange = [string rangeOfComposedCharacterSequenceAtIndex: proposedCharRange.location];
newRange.location = aRange.location;
// If the proposedCharRange is empty we only ajust the beginning
if (!proposedCharRange.length)
return newRange;
aRange = [string rangeOfComposedCharacterSequenceAtIndex: NSMaxRange(proposedCharRange)];
newRange.length = NSMaxRange(aRange) - newRange.location;
return newRange;
}
// now work on set...
lmemberstate = [set characterIsMember: [string characterAtIndex: lpos]];
rmemberstate = [set characterIsMember: [string characterAtIndex:
MIN (rpos, lastIndex)]];
while (rpos <= lastIndex
&& ([set characterIsMember: [string characterAtIndex: rpos]]
== rmemberstate))
rpos++;
}
while (lpos
&& ([set characterIsMember: [string characterAtIndex: lpos]]
== lmemberstate))
lpos--;
- (NSRange) rangeForUserCharacterAttributeChange
{
if (!_tf.is_editable || !_tf.uses_font_panel)
return NSMakeRange(NSNotFound, 0);
if ([set characterIsMember: [string characterAtIndex: lpos]] != lmemberstate
&& lpos < proposedCharRange.location)
lpos++;
if (_tf.is_rich_text)
// This expects the selection to be already corrected to characters
return _selected_range;
else
return NSMakeRange(0, [_textStorage length]);
}
return MakeRangeFromAbs(lpos,rpos);
- (NSRange) rangeForUserParagraphAttributeChange
{
if (!_tf.is_editable || !_tf.uses_ruler)
return NSMakeRange(NSNotFound, 0);
if (_tf.is_rich_text)
return [self selectionRangeForProposedRange: _selected_range
granularity: NSSelectByParagraph];
else
return NSMakeRange(0, [_textStorage length]);
}
- (NSRange) rangeForUserTextChange
{
if (!_tf.is_editable)
return NSMakeRange(NSNotFound, 0);
// This expects the selection to be already corrected to characters
return _selected_range;
}
- (void) setAlignment: (NSTextAlignment)alignment
range: (NSRange)aRange
{
NSMutableParagraphStyle *style;
if (aRange.location == NSNotFound)
return;
if (![self shouldChangeTextInRange: aRange
replacementString: nil])
return;
[_textStorage beginEditing];
[_textStorage setAlignment: alignment
range: aRange];
[_textStorage endEditing];
[self didChangeText];
// Set the typing attributes
style = [[_typingAttributes objectForKey: NSParagraphStyleAttributeName]
mutableCopy];
[style setAlignment: alignment];
// FIXME: Should use setTypingAttributes
[_typingAttributes setObject: style forKey: NSParagraphStyleAttributeName];
}
- (NSArray*) acceptableDragTypes
@ -2913,11 +2993,12 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
ASSIGN(invSelectionParagraphGranularitySet, [aSet invertedSet]);
}
- (NSDictionary*) defaultTypingAttributes
+ (NSDictionary*) defaultTypingAttributes
{
return [NSDictionary dictionaryWithObjectsAndKeys:
_default_font, NSFontAttributeName,
_text_color, NSForegroundColorAttributeName,
[NSParagraphStyle defaultParagraphStyle], NSParagraphStyleAttributeName,
[NSFont userFontOfSize: 12], NSFontAttributeName,
[NSColor textColor], NSForegroundColorAttributeName,
nil];
}
@ -2980,23 +3061,6 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
// end: drag accepting---------------------------------
- (BOOL) writeSelectionToPasteboard: (NSPasteboard*)pb
types: (NSArray*)sendTypes
{
NSArray *types;
NSString *string;
if ([sendTypes containsObject: NSStringPboardType] == NO)
{
return NO;
}
types = [NSArray arrayWithObjects: NSStringPboardType, nil];
[pb declareTypes: types owner: nil];
string = [self string];
string = [string substringWithRange: _selected_range];
return [pb setString: string forType: NSStringPboardType];
}
// <!>
// handle ruler pasteboard as well!
- (BOOL) performPasteOperation: (NSPasteboard*)pboard
@ -3034,7 +3098,7 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
if (_selected_range.length)
[self setFont: font ofRange: _selected_range];
else
[[self typingAttributes]
[_typingAttributes
setObject: font
forKey: NSFontAttributeName];
}
@ -3114,12 +3178,6 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
return NO;
}
- (BOOL) readSelectionFromPasteboard: (NSPasteboard*)pb
{
return [self performPasteOperation: pb];
}
// central text deletion/backspace method
// (takes care of optimized redraw/ cursor positioning)
- (void) deleteRange: (NSRange) aRange
@ -3142,9 +3200,13 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
deleteRange = NSMakeRange (MAX (0, aRange.location - 1), 1);
}
if (![self shouldChangeTextInRange: aRange
replacementString: @""])
return;
[_textStorage beginEditing];
[_textStorage deleteCharactersInRange: deleteRange];
[_textStorage endEditing];
[self didChangeText];
// ScrollView interaction
[self sizeToFit];
@ -3155,10 +3217,6 @@ scanRange(NSScanner *scanner, NSCharacterSet* aSet)
// remember x for row - stable cursor movements
_currentCursor = [self rectForCharacterIndex:
_selected_range.location].origin;
// broadcast notification
[[NSNotificationCenter defaultCenter]
postNotificationName: NSTextDidChangeNotification
object: self];
}
- (unsigned) characterIndexForPoint: (NSPoint) point