Question

Does anyone here know how to make cells in NSOutlineView's editible? Im using the sampe code from apple and I cant seem to get it work at all.

I am trying to set it up so that when you click twice in rapid succession on a cell in the NSOutlineView, the cell becomes editible so the user can update the text inside the cell. (In the same way as it works in xcode, and mail and so on).

I am including most of the rest of the code of this controller in the vain hope someone can spot what I am doing wrong, this is very frustrating. I know shouldEditTableColumn is being called as it is returning the NSLog message upon double click.

@implementation DisplayHierarchyController
- (void)awakeFromNib {
    // cache the reused icon images
    folderImage = [[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericFolderIcon)] retain];
    [folderImage setSize:NSMakeSize(16,16)];
    objectImage = [[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericPreferencesIcon)] retain];
    [objectImage setSize:NSMakeSize(16,16)];
    diagramImage = [[[NSWorkspace sharedWorkspace] iconForFileType:NSFileTypeForHFSTypeCode(kGenericEditionFileIcon)] retain];
    [diagramImage setSize:NSMakeSize(16,16)];
    //
    // Tell the outline view to use a special type of cell
    //NSTableColumn *tableColumn = [[outline tableColumns] objectAtIndex: 0];
    //ImageTextCell *imageTextCell = [[[ImageTextCell alloc] init] autorelease];
    //[imageTextCell setEditable:YES];
    //[tableColumn setDataCell:imageTextCell];
    //
    [[[outline tableColumns] objectAtIndex: 0] setEditable: YES];
}
- (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    NSLog(@"edit %@", tableColumn);
    return YES;
}
- (NSCell *)outlineView:(NSOutlineView *)outlineView dataCellForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    ImageTextCell *imageTextCell = [[[ImageTextCell alloc] init] autorelease];
    [imageTextCell setEditable:YES];
    return imageTextCell;
}
// Returns the object that will be displayed in the tree
- (id)outlineView: (NSOutlineView *)outlineView child: (int)index ofItem: (id)item {
    if(item == nil)
        return [[document children] objectAtIndex: index];
    if([item isKindOfClass: [Item class]])
        return [[item children] objectAtIndex: index];
    return document;
}
- (BOOL)outlineView: (NSOutlineView *)outlineView isItemExpandable: (id)item {
if([item isKindOfClass: [Item class]])
    return [[item children] count]>0;
return NO;
}
- (int)outlineView: (NSOutlineView *)outlineView numberOfChildrenOfItem: (id)item {
    if(item == nil)
        return document.children.count;
    if([item isKindOfClass: [Item class]])
        return [[item children] count];
    return 0;
}
- (id)outlineView: (NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
    if([item isKindOfClass: [Item class]])
        return [item name];
    return @"n/a";
}
- (void)outlineView:(NSOutlineView *)outlineView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {
    NSLog(@"setObjectValue called");
}
- (void)outlineView:(NSOutlineView *)olv willDisplayCell:(NSCell*)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    [cell setEditable: YES];
    [cell setAllowsEditingTextAttributes: YES];
    [(ImageTextCell*)cell setImage: objectImage];
}
- (BOOL)control:(NSControl *)control textShouldBeginEditing:(NSText *)fieldEditor {
    return YES;
}
- (BOOL)control:(NSControl *)control textShouldEndEditing:(NSText *)fieldEditor {
    if ([[fieldEditor string] length] == 0) {
        // don't allow empty node names
        return NO;
    } else {
        return YES;
    }
}
@end
Was it helpful?

Solution

I know this is a very old post, but if any one is experiencing the same issue, this may not be an issue related to code. For my case it was an issue related to do with a value set in the XIB itself.

So lets say you've copied all the Apple code, and you've got your NSOutlineView up and running, and some how its still not editable, go to your XIB and set the following setting of the NSTextField of the cell you want to be editable. In my case the behavior setting was set to none by default. Maybe its the same problem for you

enter image description here

Cheers.

OTHER TIPS

Is the column itself set as editable? Ordinarily, you would do this in IB.

Also, have you implemented the outlineView:setObjectValue: method in your data source?

Ive just discovered I can "fake it" by altering the shouldEditTableColumn. Its really not ideal, but it works. After so many hours trying to get it to work, at least this is something:

- (BOOL)outlineView:(NSOutlineView *)outlineView shouldEditTableColumn:(NSTableColumn *)tableColumn item:(id)item {
    NSLog(@"edit %@", tableColumn);
    [outline editColumn:0 row:[outline selectedRow] withEvent:[NSApp currentEvent] select:YES];
    return YES;
}

I found a way around this. Set the data cell for the column in IB (programmatically in awakeFromNib should work too). I actually use 2 different custom cell classes. My solution:

NSCell *cell = [tableColumn dataCellForRow: [outlineView rowForItem: item]];

if ([item isKindOfClass: [NSString class]])
    return [[[ShadowTextCell alloc] initTextCell: [cell stringValue]] autorelease];
return cell;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top