views:

42

answers:

2

Hi,

I'm trying to format some text in NSTextView to be placed in a single line with black background. One piece of text needs to be left aligned, the other piece (but still in the same line) needs to be centered.

NSString *header = [NSString stringWithFormat:
        @""
            "<table style=\"width: 100%; background: black; "
            "color: white; font-family: Arial; "
            "font-size: 16px;\"><tr><td>"
                "1. zadatak"
            "</td><td align=\"center\" width=\"100%\">"
            ""
                "%@"
            ""
            "</td></tr></table>"
        "", [self.problemname.stringValue uppercaseString]];

Unfortunately, no matter what width I specify, NSTextView appears to ignore the table width.

Any workarounds, different approaches, or other suggestions?


More info on the background of the problem.

I've written an app for writing tasks for programming contests. Each task author submits content in different format, so getting them to standardize it in a simple bundle would be of great benefit.

I need this for a printing module. I'm taking several NSTextViews and stitching them together.

These contests have the following document formatting which we're supposed to follow - Example PDF (GoogleDocs) :

Contest header
+------------------------------------------------+
| 1st Task           TITLE             20 points |
+------------------------------------------------+

Introductory text here.


                    Input

Explanation of input data


                   Output

Explanation of output data


                   Sample Data

Input:       | Input:
abcd         | bcde
             |
Output:      | Output:
efgh         | fghi
             |
More info:   |
info text    |
+1  A: 

NSTextView's HTML support is only rudimentary. It does't hook into WebKit or anything to render full HTML.

The only way I know of that comes even close to accomplishing what you're trying to do with an NSTextView is tab stops. You can add an NSTextTab with an alignment of NSCenterTextAlignment to the line's paragraph style. Then use a tab to separate the left-aligned text from the center-aligned text.

The biggest problem with this is that you have to calculate the center point of your text view and create your tab stop at that location every time the size of your text view changes.

I suppose you could also subclass NSLayoutManager, but that's probably more heavy-handed than you were expecting.

kperryua
That it doesn't support much of HTML, so much I've gathered -- in fact I was genuinely surprised that it supported CSS. Strange thing is, I have an HTML document doing the same thing, and TextEdit opens it much more nicely. I'll take a look at your suggestion; I'm trying to prepare the document for printing, so I'm not sure it'll be appropriate, if it's screen-specific.
Ivan Vučica
I found sample code in Apple's docs for programatically creating tables in NSAttributedStrings. I did not need to subclass NSLayoutManager :-)I'll paste my code in another answer.
Ivan Vučica
A: 

Modification of Apple's sample code for programmatically adding tables to NSAttributedString.

- (NSMutableAttributedString *) printTitleTableAttributedString
{
    NSMutableAttributedString *tableString = [[NSMutableAttributedString alloc] initWithString:@"\n\n"];
    NSTextTable *table = [[NSTextTable alloc] init];
    [table setNumberOfColumns:3];

    [tableString appendAttributedString:[self printTitleTableCellAttributedStringWithString:@"1. zadatak\n"
                                                                                      table:table
                                                                              textAlignment:NSLeftTextAlignment
                                                                                        row:0
                                                                                     column:0]];

    [tableString appendAttributedString:[self printTitleTableCellAttributedStringWithString:[self.problemname.stringValue stringByAppendingString:@"\n"]
                                                                                      table:table
                                                                              textAlignment:NSCenterTextAlignment
                                                                                        row:0
                                                                                     column:1]];

    [tableString appendAttributedString:[self printTitleTableCellAttributedStringWithString:@"20 bodova\n"
                                                                                      table:table
                                                                              textAlignment:NSRightTextAlignment
                                                                                        row:0
                                                                                     column:2]];
    [table release];
    return [tableString autorelease];
}



- (NSMutableAttributedString *) printTitleTableCellAttributedStringWithString:(NSString *)string
                                                                        table:(NSTextTable *)table
                                                                textAlignment:(NSTextAlignment)textAlignment
                                                                          row:(int)row
                                                                       column:(int)column
{
    NSColor *backgroundColor = [NSColor colorWithCalibratedRed:0 
                                                         green:0 
                                                          blue:0x80/255. 
                                                         alpha:0xFF];;
    NSColor *borderColor = [NSColor whiteColor];


    NSTextTableBlock *block = [[NSTextTableBlock alloc]
                               initWithTable:table
                               startingRow:row
                               rowSpan:1
                               startingColumn:column
                               columnSpan:1];
    [block setBackgroundColor:backgroundColor];
    [block setBorderColor:borderColor];
    [block setWidth:0.0 type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockBorder];
    [block setWidth:2.0 type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding];

    NSMutableParagraphStyle *paragraphStyle =
    [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    [paragraphStyle setTextBlocks:[NSArray arrayWithObjects:block, nil]];
    [paragraphStyle setAlignment:textAlignment];
    [block release];

    NSMutableAttributedString *cellString =
    [[NSMutableAttributedString alloc] initWithString:string];
    [cellString addAttribute:NSParagraphStyleAttributeName
                       value:paragraphStyle
                       range:NSMakeRange(0, [cellString length])];
    [cellString addAttribute:NSForegroundColorAttributeName
                       value:[NSColor whiteColor]
                       range:NSMakeRange(0, [cellString length])];
    [paragraphStyle release];

    return [cellString autorelease];
}

Then I just append it into the textview:

[printText.textStorage setAttributedString:[self printTitleTableAttributedString]];
Ivan Vučica