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:
FredKiefer 2000-05-20 16:55:08 +00:00
parent 4613b1db24
commit 5d7f9e85ea

View file

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