OSxTextView Code Listing

OSxTextView.h

#import <Cocoa/Cocoa.h>
#import "Macros.h"
#import "OSxImageViewController.h"
#import "OSxReport.h"

@interface OSxTextView : NSTextView <NSTextViewDelegate, NSTextStorageDelegate> {
    OSxImageViewController *_imageController;
    long _firstLineCharsInserted;
    NSTextView *clickedTextView;
    NSTextAttachmentCell *clickedCell;
    NSUInteger clickedCharIndex;
    NSPoint lastClick;
}

- (IBAction)insertTable:(id)sender;
- (IBAction)orderFrontTablePanel:(id)sender;

@end

OSxTextView.m

#import "OSxTextView.h"
#import "OSxTextAttachmentCell.h"


@implementation OSxTextView




- (id)initWithCoder:(NSCoder *)coder
{
    self = [super initWithCoder:coder];
    if (self) {
        [self initialise];
    }
    return self;
}
- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
        [self initialise];
    }
    
    return self;
}
- (void)initialise
{
    //LOG(@"initialise called");
    clickedTextView = nil;
    clickedCell = nil;
    clickedCharIndex = -1;
    
    [self setRichText:YES];
    [self setImportsGraphics:YES];
    [self setAllowsImageEditing:YES];
    [self setUsesRuler:YES];
    [self setRulerVisible:NO];
    [self setUsesFindBar:YES];
    [self setUsesInspectorBar:YES];
    // Set default size to be A4 Portrait
    [self.textContainer setContainerSize:NSMakeSize((19*72*0.401), 10000*72)]; //0.39370
    [self.textContainer setWidthTracksTextView:NO];
    [self.textContainer setHeightTracksTextView:NO];
    self.delegate = self;
    [self.textStorage setDelegate:self];
}

- (BOOL)acceptsFirstResponder
{
    return YES;
}
- (BOOL)becomeFirstResponder
{
    return YES;
}
- (NSMenu *)textView:(NSTextView *)textView menu:(NSMenu *)menu forEvent:(NSEvent *)event atIndex:(NSUInteger)charIndex
{
    
    // Check for an attachment
    NSTextAttachment *attachment = [[textView textStorage] attribute:NSAttachmentAttributeName atIndex:charIndex effectiveRange:NULL];
    
    // Possibly check it’s of the kind of attachment you want to handle, too
    // We assume they are all images for now.
    // Check if the image needs resizing, otherwise just ignore it.
    if (attachment) {
        clickedTextView = textView;
        clickedCell = (NSTextAttachmentCell*)[attachment attachmentCell];
        clickedCharIndex = charIndex;
        
        return [self imageMenu:NO];
    
    }
    
    // Otherwise just do the default
    return menu;
}

- (void)resizeImage
{
    if (clickedCell !=nil) {
    NSImage * image = [clickedCell image];
    
    NSSize imageSize = [image size];
    
    if (imageSize.width > self.textContainer.containerSize.width) {
        // Pop up a message to the user before doing this because at the moment its a destructive resizing !!
        // Put the image in a new Window
        
        // Scale the images height down to match the width of document
        float height = imageSize.height * (self.textContainer.containerSize.width - 20 ) / imageSize.width;
        
        NSSize size = NSMakeSize(self.textContainer.containerSize.width - 20, height);
        
        NSImage *newImage = [self imageResize:image newSize: size];
        NSTextAttachment *attachment = [self.textStorage attribute:NSAttachmentAttributeName atIndex:clickedCharIndex effectiveRange:NULL];
        NSTextAttachmentCell *newCell = [[NSTextAttachmentCell alloc] initImageCell:[[NSImage alloc] initWithData:[newImage TIFFRepresentation]]];
        
        [attachment setAttachmentCell:newCell];
        
        [self setSelectedRange:NSMakeRange(clickedCharIndex+1, 0)];
        
        if ([[self textStorage] length] == (clickedCharIndex+1))
            [self insertText:@"\n"];

        [self didChangeText];
        
     }
    clickedCell = nil;
    clickedCharIndex = -1;
    clickedTextView = nil;
    }
}
- (void)viewImage
{
    if (clickedCell !=nil) {
        NSData *data;
        
        if ([[[clickedCell attachment] fileWrapper] isRegularFile]) {
            data = [[[clickedCell attachment] fileWrapper] regularFileContents];
            
            CGImageSourceRef isr = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
            NSString *type = (__bridge NSString*)CGImageSourceGetType(isr);
            
            if ([type isEqualToString:@"com.adobe.pdf"]) {
                //Write a temporary file and open it with Preview
                NSString *filePath = [self pathForTemporaryFileWithPrefix:@"pdf"];

                NSError *error;
                NSURL *fileUrl = [[NSURL alloc] initFileURLWithPath:filePath];
                [[[clickedCell attachment] fileWrapper] writeToURL:fileUrl options:NSFileWrapperWritingAtomic originalContentsURL:nil error:&error];
                [[NSWorkspace sharedWorkspace] openFile:filePath];
                clickedCell = nil;
                clickedCharIndex = -1;
                clickedTextView = nil;

                return;
            }
            
            
        } else {
            data = [[[clickedCell attachment] fileWrapper] serializedRepresentation];
        }
        
        if (data == nil) { //try the cell

            data = (NSData*)[clickedCell image] ;

        }
        
        if (data != nil) {

            OSxImageViewController *imageController = [[OSxImageViewController alloc] initWithWindowNibName:@"ImageWindow"];
            //Controller* controller = [[Controller alloc] init];
            [imageController showWindow:self];
            [imageController setTheImageData:data];
        }
        clickedCell = nil;
        clickedCharIndex = -1;
        clickedTextView = nil;

    }
}
// We actually want to get a PNG or TIFF version so its always visible on the iPad.
- (NSImage *)imageResize:(NSImage*)anImage newSize:(NSSize)newSize {
    NSImage *sourceImage = anImage;
    [sourceImage setScalesWhenResized:YES];
    
    // Report an error if the source isn't a valid image
    if (![sourceImage isValid])
    {
        NSLog(@"Invalid Image");
    } else
    {
        NSImage *smallImage = [[NSImage alloc] initWithSize: newSize];
        [smallImage lockFocus];
        [sourceImage setSize: newSize];
        [[NSGraphicsContext currentContext] setImageInterpolation:NSImageInterpolationHigh];
        [sourceImage drawAtPoint:NSZeroPoint fromRect:NSMakeRect(0, 0, newSize.width, newSize.height) operation:NSCompositeCopy fraction:1.0];
        [smallImage unlockFocus];
        return smallImage;
    }
    return nil;
}
- (IBAction)orderFrontTablePanel:(id)sender
{
    //LOG(@"orderFrontTablePanel called.");
    [super orderFrontTablePanel:sender];
}
- (IBAction) insertTable:(id)sender
{
    NSRange charRange = [self rangeForUserTextChange];
    NSTextStorage *myTextStorage = [self textStorage];
    
    if ([self isEditable] && charRange.location != NSNotFound)
    {
        NSMutableAttributedString *attrStringToInsert = [self tableAttributedString];
        if ([self shouldChangeTextInRange:charRange replacementString:nil])
        {
            [myTextStorage replaceCharactersInRange:charRange
                               withAttributedString:attrStringToInsert];
            [self setSelectedRange:NSMakeRange(charRange.location, 0)
                                affinity:NSSelectionAffinityUpstream stillSelecting:NO];
            [self didChangeText];
        }
    }
}
- (IBAction) styleHeading1:(id)sender
{
    NSRange charRange = [self rangeForUserParagraphAttributeChange];
    if (charRange.location == NSNotFound) return;
    
    NSTextStorage *myTextStorage = [self textStorage];
    
    if ([self isEditable] && charRange.location != NSNotFound)
    {
        [myTextStorage beginEditing];
        [myTextStorage addAttributes:[OSxReport heading1Style] range:charRange];
        [myTextStorage endEditing];
        [self didChangeText];
    }
    // Now set the typing attributes so that any subsequent text typed is in the correct style
    [self setTypingAttributes:[OSxReport heading1Style]];
}
- (IBAction) styleHeading2:(id)sender
{
    NSRange charRange = [self rangeForUserParagraphAttributeChange];
    if (charRange.location == NSNotFound) return;

    NSTextStorage *myTextStorage = [self textStorage];
    
    if ([self isEditable] && charRange.location != NSNotFound)
    {
        [myTextStorage beginEditing];
        [myTextStorage addAttributes:[OSxReport heading2Style] range:charRange];
        [myTextStorage endEditing];
        [self didChangeText];
    }
    // Now set the typing attributes so that any subsequent text typed is in the correct style
    [self setTypingAttributes:[OSxReport heading2Style]];
}
- (IBAction) styleHeading3:(id)sender
{
    NSRange charRange = [self rangeForUserParagraphAttributeChange];
    if (charRange.location == NSNotFound) return;

    NSTextStorage *myTextStorage = [self textStorage];
    
    if ([self isEditable] && charRange.location != NSNotFound)
    {
        [myTextStorage beginEditing];
        [myTextStorage addAttributes:[OSxReport heading3Style] range:charRange];
        [myTextStorage endEditing];
        [self didChangeText];
    }
    // Now set the typing attributes so that any subsequent text typed is in the correct style
    [self setTypingAttributes:[OSxReport heading3Style]];
}
- (IBAction) styleBullet1:(id)sender
{
    NSRange selectedRange = [self selectedRange];
    FLOG(@" selectedRange is %u, %u", selectedRange.location, selectedRange.length);
    // Do nothing if no selection
    if (selectedRange.location == NSNotFound) return;
    
    // Get the end of the last paragraph
    NSRange charRange = [self rangeForUserParagraphAttributeChange];
    FLOG(@" initial charRange is %u, %u", charRange.location, charRange.length);
    long initialLength = charRange.length-1;
    FLOG(@" initial length is %ld", initialLength);
    
    NSTextStorage *myTextStorage = [self textStorage];
    [myTextStorage beginEditing];

    charRange = [self insertBulletsInSelectedParagraphsIfRequired];
    FLOG(@" modified charRange is %u, %u", charRange.location, charRange.length);
    
    long finalLength = charRange.length;
    long addedChars = finalLength - initialLength;
    FLOG(@" addedChars is %ld", addedChars);
    
    if ([self isEditable] && charRange.location != NSNotFound)
    {
        [myTextStorage addAttributes:[OSxReport bullet1Style] range:charRange];
    }
    // Now set the typing attributes so that any subsequent text typed is in the correct style
    [self setTypingAttributes:[OSxReport bullet1Style]];
    
    // Reset the selection to look like it was at the start
    NSRange endRange = NSMakeRange(selectedRange.location+_firstLineCharsInserted, selectedRange.length+addedChars-_firstLineCharsInserted);
    FLOG(@" endRange is %u, %u", charRange.location, charRange.length);
    [myTextStorage endEditing];
    [self didChangeText];
    [self setSelectedRange:endRange];

}
- (IBAction) styleBullet2:(id)sender
{
    NSRange selectedRange = [self selectedRange];

    // Do nothing if no selection
    if (selectedRange.location == NSNotFound) return;
    
    NSRange charRange = [self rangeForUserParagraphAttributeChange];
    long initialLength = charRange.length-1;
    
    NSTextStorage *myTextStorage = [self textStorage];
    [myTextStorage beginEditing];
    charRange = [self insertBulletsInSelectedParagraphsIfRequired];
    long finalLength = charRange.length;
    long addedChars = finalLength - initialLength;
    
    if ([self isEditable] && charRange.location != NSNotFound)
    {
        [myTextStorage addAttributes:[OSxReport bullet2Style] range:charRange];
        
    }
    // Now set the typing attributes so that any subsequent text typed is in the correct style
    [self setTypingAttributes:[OSxReport bullet2Style]];

    // Reset the selection to look like it was at the start
    NSRange endRange = NSMakeRange(selectedRange.location+_firstLineCharsInserted, selectedRange.length+addedChars-_firstLineCharsInserted);

    [myTextStorage endEditing];
    [self didChangeText];
    [self setSelectedRange:endRange];

}
- (NSRange)insertBulletsInSelectedParagraphsIfRequired {
    
    NSRange charRange = [self rangeForUserParagraphAttributeChange];
    
    NSUInteger start = charRange.location;
    NSUInteger end = charRange.location+charRange.length;
    
    NSRange startRange = NSMakeRange(start, 0);
    //bool done = NO;
    long numberOfInsertedChars = 0;
    long totalInsertedChars = 0;
    bool firstLine = YES;
    _firstLineCharsInserted = 0;
    
    
    // If start == end then the paragraph is an empty one so do once only
    //
    if (start == end) {
        // Get the first paragraph range
        NSRange paraRange = [self.textStorage.string paragraphRangeForRange:startRange];
        
        //Now insert a bullet if required
        numberOfInsertedChars = [self insertBullet:paraRange];
        if (firstLine) {
            _firstLineCharsInserted = numberOfInsertedChars;
            firstLine = NO;
        }
        
        totalInsertedChars += numberOfInsertedChars;
        
        // Now get the new range (it may have changed if we inserted characters)
        paraRange = [self.textStorage.string paragraphRangeForRange:startRange];
        
        
        // Also add the number of inserted characters to the "end" value since this would also change
        end += numberOfInsertedChars;
        
        
    } else {
        
        while (start < end) {
            // Get the first paragraph range
            NSRange paraRange = [self.textStorage.string paragraphRangeForRange:startRange];
            
            //Now insert a bullet if required
            numberOfInsertedChars = [self insertBullet:paraRange];
            if (firstLine) {
                _firstLineCharsInserted = numberOfInsertedChars;
                firstLine = NO;
            }
            
            totalInsertedChars += numberOfInsertedChars;
            
            // Now get the new range (it may have changed if we inserted characters)
            paraRange = [self.textStorage.string paragraphRangeForRange:startRange];
            
            
            // Also add the number of inserted characters to the "end" value since this would also change
            end += numberOfInsertedChars;
            
            start = paraRange.location + paraRange.length;
            startRange = NSMakeRange(start, 0);
            
        }
        
    }
    // Now pass back the new range which includes any inserted characters
    NSRange newRange = NSMakeRange(charRange.location, charRange.length+totalInsertedChars-1);
    
    return newRange;
    
}
// Check for existence of (tab) "\t" in string and add "-\t" if not found
// Returns number of characters inserted
- (long)insertBullet:(NSRange)range {
    NSTextStorage *myTextStorage = [self textStorage];
    
    // Check for "\t" in the string and add "-\t" if not found
    NSAttributedString *attrString = [myTextStorage attributedSubstringFromRange:range];
    NSString *string = [attrString string];
    
    if ([string rangeOfString:@"\t"].location == NSNotFound) {
        
       // FLOG(@"string does not contain tab so insert one");
        NSString *tabString = @"-\t";
        NSAttributedString * aStr = [[NSAttributedString alloc] initWithString:tabString];
        
        // Insert a bullet and tab
        [self.textStorage beginEditing];
        [[self textStorage] insertAttributedString:aStr atIndex:range.location];
        [self.textStorage endEditing];
        
        return [tabString length];
        
    } else {
        
        //FLOG(@"string contains tab");
        return 0;
    }
}
- (IBAction) styleNormal:(id)sender
{
    NSRange charRange = [self rangeForUserParagraphAttributeChange];
    if (charRange.location == NSNotFound) return;

    NSTextStorage *myTextStorage = [self textStorage];
    
    if ([self isEditable] && charRange.location != NSNotFound)
    {
        [myTextStorage beginEditing];

        [myTextStorage addAttributes:[OSxReport normalStyle] range:charRange];
        [myTextStorage endEditing];
        [self didChangeText];
    }
    // Now set the typing attributes so that any subsequent text typed is in the correct style
    [self setTypingAttributes:[OSxReport normalStyle]];
}
- (IBAction) styleTableHeader:(id)sender
{
    NSRange charRange = [self rangeForUserParagraphAttributeChange];
    if (charRange.location == NSNotFound) return;

    NSTextStorage *myTextStorage = [self textStorage];
    
    if ([self isEditable] && charRange.location != NSNotFound)
    {
        [myTextStorage addAttributes:[OSxReport tableHeadingStyle] range:charRange];
        [self didChangeText];
    }
    // Now set the typing attributes so that any subsequent text typed is in the correct style
    [self setTypingAttributes:[OSxReport tableHeadingStyle]];
}
- (IBAction) styleTableNormal:(id)sender
{
    NSRange charRange = [self rangeForUserParagraphAttributeChange];
    if (charRange.location == NSNotFound) return;

    NSTextStorage *myTextStorage = [self textStorage];
    
    if ([self isEditable] && charRange.location != NSNotFound)
    {
        [myTextStorage addAttributes:[OSxReport tableNormalStyle] range:charRange];
        [self didChangeText];
    }
    // Now set the typing attributes so that any subsequent text typed is in the correct style
    [self setTypingAttributes:[OSxReport tableNormalStyle]];
}
- (NSMutableAttributedString *) tableAttributedString
{
    NSMutableAttributedString *tableString = [[NSMutableAttributedString alloc] initWithString:@"\n\n"];
    NSTextTable *table = [[NSTextTable alloc] init];
    
    NSColor *headingBackground = [self colorRed:TABLE_HEADING_BACKGROUND
                                                 green:TABLE_HEADING_BACKGROUND
                                                  blue:TABLE_HEADING_BACKGROUND];
    NSColor *borderColor = [NSColor lightGrayColor];
    NSColor *tableBackground = [NSColor whiteColor];
    
    [table setNumberOfColumns:2];
    [table setContentWidth:90.0 type:NSTextBlockPercentageValueType];
    
    [tableString appendAttributedString:[self tableCellAttributedStringWithString:@"Column 1 Heading\n"
                                                                            table:table
                                                                  backgroundColor:headingBackground
                                                                      borderColor:borderColor
                                                                              row:0
                                                                           column:0
                                                                             font:[OSxReport tableHeadingFont]]];
    
    [tableString appendAttributedString:[self tableCellAttributedStringWithString:@"Column 2 Heading\n"
                                                                            table:table
                                                                  backgroundColor:headingBackground
                                                                      borderColor:borderColor
                                                                              row:0
                                                                           column:1
                                         font:[OSxReport tableHeadingFont]]];
    
    [tableString appendAttributedString:[self tableCellAttributedStringWithString:@"\n"
                                                                            table:table
                                                                  backgroundColor:tableBackground
                                                                      borderColor:borderColor
                                                                              row:1
                                                                           column:0
                                         font:[OSxReport tableFont]]];
    
    [tableString appendAttributedString:[self tableCellAttributedStringWithString:@"\n"
                                                                            table:table
                                                                  backgroundColor:tableBackground
                                                                      borderColor:borderColor
                                                                              row:1
                                                                           column:1
                                         font:[OSxReport tableFont]]];
    
    return tableString;
}
- (NSMutableAttributedString *) tableCellAttributedStringWithString:(NSString *)string
                                                              table:(NSTextTable *)table
                                                    backgroundColor:(NSColor *)backgroundColor
                                                        borderColor:(NSColor *)borderColor
                                                                row:(int)row
                                                             column:(int)column
                                                               font:(NSFont *)font
{
    
    NSTextTableBlock *block = [[NSTextTableBlock alloc]
                               initWithTable:table
                               startingRow:row
                               rowSpan:1
                               startingColumn:column
                               columnSpan:1];
    [block setBackgroundColor:backgroundColor];
    [block setBorderColor:borderColor];
    [block setWidth:1.0 type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockBorder];
    [block setWidth:1.0 type:NSTextBlockAbsoluteValueType forLayer:NSTextBlockPadding];
    
    NSMutableParagraphStyle *paragraphStyle =
    [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    [paragraphStyle setTextBlocks:[NSArray arrayWithObjects:block, nil]];
    
    NSMutableAttributedString *cellString =
    [[NSMutableAttributedString alloc] initWithString:string];
    [cellString addAttribute:NSParagraphStyleAttributeName
                       value:paragraphStyle
                       range:NSMakeRange(0, [cellString length])];
    [cellString addAttribute:NSFontAttributeName
                       value:font
                       range:NSMakeRange(0, [cellString length])];
    
    return cellString;
}
- (NSColor*)colorRed:(int)red green:(int)green blue:(int) blue
{
    return [NSColor colorWithSRGBRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:1.0];
}
- (void) rightMouseDown:(NSEvent *)theEvent {
    lastClick = [self convertPoint: theEvent.locationInWindow fromView: nil];
    [super rightMouseDown:theEvent];
}
- (NSMenu*)imageMenu:(BOOL)resize
{
    // NSLog(@"Delegate getContextMenu called ");
    
    NSMenu *theMenu = [[NSMenu alloc] initWithTitle:@"Image Menu"] ;
    NSMenuItem *addViewerMI = [[NSMenuItem alloc] initWithTitle:@"Open in Viewer" action:@selector(viewImage) keyEquivalent:@""] ;
    [addViewerMI setTarget:self];
    [theMenu insertItem:addViewerMI   atIndex:0];
    NSMenuItem *copyImage = [[NSMenuItem alloc] initWithTitle:@"Copy Image" action:@selector(copyImage) keyEquivalent:@""] ;
    [copyImage setTarget:self];
    [theMenu insertItem:copyImage   atIndex:1];
    
    if (resize) {
        NSMenuItem *addResizeMI = [[NSMenuItem alloc] initWithTitle:@"Resize" action:@selector(resizeImage) keyEquivalent:@""] ;
        [addResizeMI setTarget:self];
        [theMenu insertItem:addResizeMI   atIndex:2];
    }
    [theMenu setAllowsContextMenuPlugIns:NO];
    
    return theMenu;
}
- (void)copyImage {
    NSUInteger charIndex = self.selectedRange.location;
    
    NSTextAttachment *attachment = [self.textStorage attribute:NSAttachmentAttributeName atIndex:charIndex effectiveRange:NULL];
    
    if (attachment.fileWrapper.isRegularFile) {
        
        NSData *data =attachment.fileWrapper.regularFileContents;
        
        //CGImageSourceRef isr = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
        //NSString *type = (__bridge NSString*)CGImageSourceGetType(isr);
        
        NSImage *img = [[NSImage alloc] initWithData:data];
        
        NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
        [pasteboard clearContents];
        NSArray *copiedObjects = [NSArray arrayWithObject:img];
        [pasteboard writeObjects:copiedObjects];
    }
}
- (NSString *)pathForTemporaryFileWithPrefix:(NSString *)prefix
{
    NSString *  result;
    CFUUIDRef   uuid;
    CFStringRef uuidStr;
    
    uuid = CFUUIDCreate(NULL);
    assert(uuid != NULL);
    
    uuidStr = CFUUIDCreateString(NULL, uuid);
    assert(uuidStr != NULL);
    
    result = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.%@", uuidStr, prefix]];
    assert(result != nil);
    
    CFRelease(uuidStr);
    CFRelease(uuid);
    
    return result;
}
// This method is called whenever text is processed by the textStorage
// We look for any attachments and and NSTextAttachmentCells and replace
// them with our subclass
- (void)textStorageWillProcessEditing:(NSNotification *)aNotification {
    //FLOG(@"textStorageWillProcessEditing: called");
    NSRange range = [self.textStorage editedRange];
    //FLOG(@"     editRange is %lu, %lu", range.location, range.length);
    
    [self.textStorage enumerateAttributesInRange:range options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:
     ^(NSDictionary *attributes, NSRange range, BOOL *stop) {
         
         // Iterate over each attribute and look for a Font Size
         [attributes enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
             if ([[key description] isEqualToString:NSAttachmentAttributeName]) {
                 //FLOG(@" attachment of class %@ found", [obj class]);
                 
                 NSTextAttachment *attachment = (NSTextAttachment *)obj;
                 //LOG(@" attachment found");
                 
                 //Replace the default attachment cell with our own
                 [self replaceAttachmentCell:attachment];
             }
             
         }];
     }];
}

// Here we replace the default NSTextAttachmentCell with our own subclass
// which will scale the cells drawing rectangle so it is 0.9 x width
// of the line
//
- (void)replaceAttachmentCell:(NSTextAttachment*)attachment {
    
    // If its one we have already replaced then return
    if ([attachment.attachmentCell isKindOfClass:[OSxTextAttachmentCell class]]) {
        //LOG(@" attachmentCell is already an OSTextAttachmentCell so do nothing");
        return;
    }
    
    //LOG(@" attachmentCell is NOT OSTextAttachmentCell so replace it");
    
    // Get the current attachment cell
    NSTextAttachmentCell *cell = (NSTextAttachmentCell *)[attachment attachmentCell] ;
    
    // Get the image from it
    NSImage * image = [cell image];
    
    // Create a new one with the image
    OSxTextAttachmentCell *newCell = [[OSxTextAttachmentCell alloc] initImageCell:image];
    
    // Now replace the attachment cell
    [attachment setAttachmentCell:newCell];
    
    return;
}
@end

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s