• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Changing font stuff in NSTextView + Undo
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Changing font stuff in NSTextView + Undo


  • Subject: Re: Changing font stuff in NSTextView + Undo
  • From: Douglas Davidson <email@hidden>
  • Date: Mon, 2 Feb 2004 11:14:28 -0800

On Jan 31, 2004, at 11:50 AM, Bernie Zenis wrote:

The basics of what I have so far is the following pseudo-code:
range = [NSTextView rangeForUserCharacterAttributeChange];
if (range.location == NSNotFound) return;
if (![NSTextView shouldChangeTextInRange:range replacementString:nil]) return;
if (![NSTextView isRichText]) {

You don't need to explicitly query this. If the view is plain text, then rangeForUserCharacterAttributeChange will cover the whole text. If the view is not editable, the rangeForUserCharacterAttributeChange will be {NSNotFound, 0}. The range tells you what you should do.

oldFont = [NSTextView font];
newFont = MyConvertFont(oldFont);
[NSTextView setFont:newFont];
} else if (range.length == 0) {
oldAttrs = [NSTextView typingAttributes];
oldFont = [oldAttrs objectForKey:NSFontAttributeName];
newFont = MyConvertFont(oldFont);
newAttrs = [NSMutableDictionary dictionaryWithDictionary:oldAttrs];
[newAttrs setObject:newFont forKey:NSFontAttributeName];
[NSTextView setTypingAttributes:newAttrs];

Usually you will want to set the typing attributes whether the range length is 0 or not.

} else {
attrString = [NSTextView attributedSubstringFromRange:range];
while (not all attrString scanned) {
oldFont = [attrString attribute:NSFontAttributeName...];
newFont = MyConvertFont(oldFont);
[NSTextView setFont:newFont range:...];

When you're doing this sort of detailed modification, it's probably better to talk to the text storage directly.

}
}
[NSTextView didChangeText];
[[NSTextView undoManager] setActionName:@"Set Font"];

Here's some sample code. You could also put this in a category method on NSTextView, in which case you would replace "myTextView" here with "self".

NSRange charRange = [myTextView rangeForUserCharacterAttributeChange];
if (charRange.location != NSNotFound) {
NSTextStorage *text = [myTextView textStorage];
NSFont *oldFont, *newFont;
NSMutableDictionary *typingAttrs = [NSMutableDictionary dictionaryWithDictionary:[myTextView typingAttributes]];
if ((charRange.length > 0) && [myTextView shouldChangeTextInRange:charRange replacementString:nil]) {
unsigned curCharIndex = charRange.location;
NSRange fontCharRange;

[text beginEditing];
while (NSLocationInRange(curCharIndex, charRange)) {
oldFont = [text attribute:NSFontAttributeName atIndex:curCharIndex longestEffectiveRange:&fontCharRange inRange:charRange];
fontCharRange = NSIntersectionRange(fontCharRange, charRange);
newFont = MyConvertFont(oldFont);
[text addAttribute:NSFontAttributeName value:newFont range:fontCharRange];
curCharIndex = NSMaxRange(fontCharRange);
}
[text endEditing];
[myTextView didChangeText];

[[myTextView undoManager] setActionName:NSLocalizedString(@"Set Font", @"Undo title for font conversion")];
newFont = [text attribute:NSFontAttributeName atIndex:charRange.location effectiveRange:NULL];
} else {
oldFont = [typingAttrs objectForKey:NSFontAttributeName];
if (!oldFont) {
if (charRange.length > 0) {
oldFont = [text attribute:NSFontAttributeName atIndex:charRange.location effectiveRange:NULL];
} else if (charRange.location > 0) {
oldFont = [text attribute:NSFontAttributeName atIndex:charRange.location - 1 effectiveRange:NULL];
}
}
newFont = MyConvertFont(oldFont);
}
[typingAttrs setObject:newFont forKey:NSFontAttributeName];
[myTextView setTypingAttributes:newAttrs];
}
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
  • Prev by Date: Re: Cocoa/Windows parallel dvlpmt
  • Next by Date: [SOLVED !] Disabling_Expose_for_some_windows,_some_day?
  • Previous by thread: Re: Packager
  • Next by thread: [SOLVED !] Disabling_Expose_for_some_windows,_some_day?
  • Index(es):
    • Date
    • Thread