Fixed a possible crasher where an ITMultilineTextFieldCell is treated as
[ITKit.git] / ITMultilineTextFieldCell.m
1 //
2 //  ITMultilineTextFieldCell.m
3 //  ITKit
4 //
5 //  Created by Joseph Spiros on Fri Mar 05 2004.
6 //  Copyright (c) 2004 __MyCompanyName__. All rights reserved.
7 //
8
9 #import "ITMultilineTextFieldCell.h"
10
11
12 @implementation ITMultilineTextFieldCell
13
14 - (void)drawInteriorWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
15 {
16     if ([[self objectValue] isKindOfClass:[NSArray class]]) {
17     
18         /*
19             Okay, here's the different possibilities for the objectValue of this cell, and how they're displayed:
20             
21                 NSArray of NSStrings - Draw first line with System Font, following lines with Small System Font
22                 NSArray of NSAttributedStrings - Draw as given
23                 NSArray of both - Draw each line as above!
24             
25             The number of lines is determined by the contents of the array...
26         */
27     
28         NSColor *defaultColor;
29         NSMutableParagraphStyle *paragraphStyle = [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] autorelease];
30         [paragraphStyle setLineBreakMode:NSLineBreakByTruncatingTail];
31         NSPoint cellPoint = cellFrame.origin;
32         NSSize cellSize = cellFrame.size;
33         
34         NSRect secondaryLineRect;
35         
36         if ([self isHighlighted] && ([self highlightColorWithFrame:cellFrame inView:controlView]!=[NSColor secondarySelectedControlColor])) {
37             defaultColor = [NSColor whiteColor];
38         } else {
39             defaultColor = [NSColor blackColor];
40         }
41         
42         // Process the first line...
43         {
44             NSDictionary *firstLineAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont boldSystemFontOfSize:[NSFont systemFontSize]], NSFontAttributeName, defaultColor, NSForegroundColorAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil];
45             
46             NSRect firstLineRect = NSMakeRect(cellPoint.x+5, cellPoint.y+1, cellSize.width-5, cellSize.height);
47             
48             id firstString = [[self objectValue] objectAtIndex:0];
49             NSMutableAttributedString *firstAttrString;
50             
51             if ([firstString isKindOfClass:[NSAttributedString class]]) {
52                 firstAttrString = [[[NSMutableAttributedString alloc] initWithAttributedString:firstString] autorelease];
53                 [firstAttrString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0,[firstAttrString length])];
54                 if ([defaultColor isEqual:[NSColor whiteColor]]) {
55                 [firstAttrString addAttribute:NSForegroundColorAttributeName value:defaultColor range:NSMakeRange(0,[firstAttrString length])];
56                 }
57             } else if ([firstString isKindOfClass:[NSString class]]) {
58                 firstAttrString = [[[NSMutableAttributedString alloc] initWithString:firstString attributes:firstLineAttributes] autorelease];
59             } else {
60                 firstAttrString = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"Object (%@) is not a string", firstString] attributes:firstLineAttributes] autorelease];
61             }
62             
63             [controlView lockFocus];
64             
65             [firstAttrString drawInRect:firstLineRect];
66             
67             [controlView unlockFocus];
68             
69             secondaryLineRect = NSMakeRect(cellPoint.x+5, (cellPoint.y+1+[firstAttrString size].height), cellSize.width-5, cellSize.height);
70         }
71         
72         // Process the secondary lines
73         {
74             NSDictionary *secondaryLineAttributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSFont systemFontOfSize:[NSFont smallSystemFontSize]], NSFontAttributeName, defaultColor, NSForegroundColorAttributeName, paragraphStyle, NSParagraphStyleAttributeName, nil];
75             
76             NSMutableArray *tMArray = [NSMutableArray arrayWithArray:[self objectValue]];
77             [tMArray removeObjectAtIndex:0]; // Remove the first line string... already handled that above!
78             
79             NSEnumerator *enumerator = [tMArray objectEnumerator];
80             id secondaryString;
81             
82             while (secondaryString = [enumerator nextObject]) {
83                 
84                 NSMutableAttributedString *secondaryAttrString;
85                 
86                 if ([secondaryString isKindOfClass:[NSAttributedString class]]) {
87                     secondaryAttrString = [[[NSMutableAttributedString alloc] initWithAttributedString:secondaryString] autorelease];
88                     [secondaryAttrString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0,[secondaryAttrString length])];
89                     if ([defaultColor isEqual:[NSColor whiteColor]]) {
90                     [secondaryAttrString addAttribute:NSForegroundColorAttributeName value:defaultColor range:NSMakeRange(0,[secondaryAttrString length])];
91                     }
92                 } else if ([secondaryString isKindOfClass:[NSString class]]) {
93                     secondaryAttrString = [[[NSMutableAttributedString alloc] initWithString:secondaryString attributes:secondaryLineAttributes] autorelease];
94                 } else {
95                     secondaryAttrString = [[[NSMutableAttributedString alloc] initWithString:[NSString stringWithFormat:@"Object (%@) is not a string", secondaryString] attributes:secondaryLineAttributes] autorelease];
96                 }
97                 
98                 [controlView lockFocus];
99                 
100                 [secondaryAttrString drawInRect:secondaryLineRect];
101                 
102                 [controlView unlockFocus];
103                 
104                 secondaryLineRect.origin.y = secondaryLineRect.origin.y+[secondaryAttrString size].height; // modify the rect for the next loop, based on the size and location of the most recently processed line.
105             
106             }
107         }
108     } else {
109         [super drawInteriorWithFrame:cellFrame inView:controlView];
110     }
111 }
112
113 @end