Re: Attribute Fixing and NSAttachment
Re: Attribute Fixing and NSAttachment
- Subject: Re: Attribute Fixing and NSAttachment
- From: "Timothy J. Wood" <email@hidden>
- Date: Fri, 12 Aug 2005 13:50:31 -0700
On Aug 11, 2005, at 1:21 PM, Steve Shepard wrote:
The NSTextStorage attribute fixing code appears to be stripping NSFont
attributes from NSAttachments (see below). This is unfortunate because
it means that the text view uses the font from the default typing
attributes when the cursor is placed after an attachment.
Is there a better way to to work around the problem than subclassing
NSTextView and overriding setTypingAttributes: or (in 10.4)
implementing textView:shouldChangeTypingAttributes:toAttributes: and
special-casing attachments?
OmniOutliner 3 prevents the stripping of font attributes from
attachment ranges since we have fonts displayed in our attachments.
The approach I used was to override -fixAttachmentAttributeInRange:
on NSTextStorage to ONLY do its advertized behavior:
---
Cleans up attachment attributes in aRange, removing all attachment
attributes assigned to characters other than NSAttachmentCharacter.
Raises an NSRangeException if any part of aRange lies beyond the end
of the receiver’s characters.
---
So, our implementation looks like the following (the -
mutateRanges:... code is in our OmniAppKit framework, but you can
probably figure out what this is doing from this snippet).
-tim
static NSAttributedString *_killAttachmentsOnPlainCharacters
(NSMutableAttributedString *source, NSDictionary *attributes, NSRange
matchRange, NSRange effectiveAttributeRange, BOOL *isEditing, void
*context)
{
if ([attributes objectForKey:NSAttachmentAttributeName]) {
// We have to process the entire effective range since the -
mutateRanges:matchingString:context: doesn't expect us to subdivide
the range (i.e., it won't check if we did and thus will skip to the
character after the effective range). We directly replace attributes
here to avoid creating new attributed strings (since this can get
called pretty frequently).
NSString *string = [source string];
unsigned int characterIndex;
for (characterIndex = effectiveAttributeRange.location;
characterIndex < effectiveAttributeRange.location +
effectiveAttributeRange.length; characterIndex++) {
if ([string characterAtIndex:characterIndex] !=
NSAttachmentCharacter) {
// Might want to search forward until we get to the
end of the effective range or the first attachment character (so that
we call -removeAttribute:range: fewer times for big paste operations
where we started out with typing attributes based on an adjacent
attachment).
if (!*isEditing) {
*isEditing = YES;
[source beginEditing];
}
[source removeAttribute:NSAttachmentAttributeName
range:(NSRange){characterIndex, 1}];
}
}
}
return nil; // We just edit in place
}
- (void)fixAttachmentAttributeInRange:(NSRange)aRange;
{
// This is document as "removing all attachment attributes
assigned to characters other than NSAttachmentCharacter". But, it
also removes interesting attributes from attachment character (like
font size, etc). We hate that since we want our attachments to be
able to know what their attributes are in case they want to draw
embedded text using those attributes!
// We'll just reimplement the documented portion of this.
[self mutateRanges:_killAttachmentsOnPlainCharacters
matchingString:nil context:self];
}
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden