开发者

how to toggle rich text formatting in NSTextView programmatically in cocoa

I w开发者_Go百科ant to toggle rich text formatting in NSTextView. I have tried following:

[contentView setRichText:NO];
[contentView setImportsGraphics:NO];

but, that didn't changed the NSTextView content and still allowing to do the text formatting.

Please let me know the simple way to toggle/switch rich text formatting in NSTextView just like TextEdit.

I already check the "TextEdit" sample project, but it seems to be very hard to find the usable code from it.

Thanks


Found some help from following link.

click here to see solution

Based on solution given in above link, i have created category for my view controller as follows:

#define TabWidth @"TabWidth"

@interface MyViewController (Helper)

- (NSDictionary *)defaultTextAttributes:(BOOL)forRichText;
- (void)removeAttachments;
- (void)setRichText:(BOOL)flag;

@end

@implementation MyViewController (Helper)

- (NSDictionary *)defaultTextAttributes:(BOOL)forRichText {
    static NSParagraphStyle *defaultRichParaStyle = nil;
    NSMutableDictionary *textAttributes = [[[NSMutableDictionary alloc] initWithCapacity:2] autorelease];
    if (forRichText) {
        [textAttributes setObject:[NSFont userFontOfSize:0.0] forKey:NSFontAttributeName];
        if (defaultRichParaStyle == nil) {  // We do this once...
            NSInteger cnt;
            NSString *measurementUnits = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleMeasurementUnits"];
            CGFloat tabInterval = ([@"Centimeters" isEqual:measurementUnits]) ? (72.0 / 2.54) : (72.0 / 2.0);  // Every cm or half inch
            NSMutableParagraphStyle *paraStyle = [[[NSMutableParagraphStyle alloc] init] autorelease];
            [paraStyle setTabStops:[NSArray array]];    // This first clears all tab stops
            for (cnt = 0; cnt < 12; cnt++) {    // Add 12 tab stops, at desired intervals...
                NSTextTab *tabStop = [[NSTextTab alloc] initWithType:NSLeftTabStopType location:tabInterval * (cnt + 1)];
                [paraStyle addTabStop:tabStop];
                [tabStop release];
            }
            defaultRichParaStyle = [paraStyle copy];
        }
        [textAttributes setObject:defaultRichParaStyle forKey:NSParagraphStyleAttributeName];
    } else {
        NSFont *plainFont = [NSFont userFixedPitchFontOfSize:0.0];
        NSInteger tabWidth = [[NSUserDefaults standardUserDefaults] integerForKey:TabWidth];
        CGFloat charWidth = [@" " sizeWithAttributes:[NSDictionary dictionaryWithObject:plainFont forKey:NSFontAttributeName]].width;
        if (charWidth == 0) charWidth = [[plainFont screenFontWithRenderingMode:NSFontDefaultRenderingMode] maximumAdvancement].width;

        // Now use a default paragraph style, but with the tab width adjusted
        NSMutableParagraphStyle *mStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
        [mStyle setTabStops:[NSArray array]];
        [mStyle setDefaultTabInterval:(charWidth * tabWidth)];
        [textAttributes setObject:[[mStyle copy] autorelease] forKey:NSParagraphStyleAttributeName];

        // Also set the font
        [textAttributes setObject:plainFont forKey:NSFontAttributeName];
    }
    return textAttributes;
}

/* Used when converting to plain text
 */
- (void)removeAttachments {
    NSTextStorage *attrString = [contentView textStorage];
    NSUInteger loc = 0;
    NSUInteger end = [attrString length];
    [attrString beginEditing];
    while (loc < end) { /* Run through the string in terms of attachment runs */
        NSRange attachmentRange;    /* Attachment attribute run */
        NSTextAttachment *attachment = [attrString attribute:NSAttachmentAttributeName atIndex:loc longestEffectiveRange:&attachmentRange inRange:NSMakeRange(loc, end-loc)];
        if (attachment) {   /* If there is an attachment and it is on an attachment character, remove the character */
            unichar ch = [[attrString string] characterAtIndex:loc];
            if (ch == NSAttachmentCharacter) {
                if ([contentView shouldChangeTextInRange:NSMakeRange(loc, 1) replacementString:@""]) {
                    [attrString replaceCharactersInRange:NSMakeRange(loc, 1) withString:@""];
                    [contentView didChangeText];
                }
                end = [attrString length];  /* New length */
            }
            else loc++; /* Just skip over the current character... */
        }
        else loc = NSMaxRange(attachmentRange);
    }
    [attrString endEditing];
}

- (void)setRichText:(BOOL)flag {
    NSDictionary *textAttributes;

    BOOL isRichText = flag;

    if (!isRichText) [self removeAttachments];

    [contentView setRichText:isRichText];
    [contentView setUsesRuler:isRichText];    /* If NO, this correctly gets rid
                                               of the ruler if it was up */
    if (isRichText && NO)
        [contentView setRulerVisible:YES];    /* Show ruler if rich, and desired */
    [contentView setImportsGraphics:isRichText];

    textAttributes = [self defaultTextAttributes:isRichText];

    if ([[contentView textStorage] length]) {
        [[contentView textStorage] setAttributes:textAttributes range: NSMakeRange(0,[[contentView textStorage] length])];
    }
    [contentView setTypingAttributes:textAttributes];
}

@end

Where contentView is IBOutlet of NSTextView. Hope this will help someone or let me know if someone has shorter method.

Thanks

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜