Deleting A Row From An Outline View


Deleting A Row From An Outline View



I have an outline view and a button. I want the button to remove the selected row in the outline view. I have binded the Outline View's Selection Index Paths to the Tree Controller, connected the button to the Tree Controller's remove: selector, and binded the button to the canRemove: property of the Tree Controller. But once I have done all of that (which I expected to work) it completely breaks the outline view, when I say breaks I mean it no longer works, it doesn't show any data that I have added.

Now for some more information, here are some pictures of the connections of the Array Controller and the Tree Controller.

NSArrayController Connections

alt text

NSTreeController Connections (As you can see without the Selection Index Paths Binding)

alt text

One Final thing, the Outline View has a Data Source which allows it to do drag and drop, I think that has something to do with it not working, so below is the code in the data source.

The Implementation File.

#import "DragController.h"   @implementation DragController - (void)awakeFromNib {        dragType = [NSArray arrayWithObjects:   @"factorialDragType", nil];      [ dragType retain ];       [ treeTable registerForDraggedTypes:dragType ];     NSSortDescriptor* sortDesc = [[NSSortDescriptor alloc] initWithKey:@"position" ascending:YES];     [groupTreeControl setSortDescriptors:[NSArray arrayWithObject: sortDesc]];     [ sortDesc release ]; }      //------------------------------------ #pragma mark NSOutlineView datasource methods -- see NSOutlineViewDataSource //---------------------------------------------------------------------------    - (BOOL) outlineView : (NSOutlineView *) outlineView            writeItems : (NSArray*) items          toPasteboard : (NSPasteboard*) pboard {      [ pboard declareTypes:dragType owner:self ];             // items is an array of _NSArrayControllerTreeNode see http://theocacao.com/document.page/130 for more info     draggedNode = [ items objectAtIndex:0 ];      return YES;  }     - (BOOL)outlineView:(NSOutlineView *)outlineView acceptDrop:(id <NSDraggingInfo>)info item:(id)item childIndex:(int)index {      _NSArrayControllerTreeNode* parentNode = item;     _NSArrayControllerTreeNode* siblingNode;     _NSControllerTreeProxy* proxy = [ groupTreeControl arrangedObjects ];      NSManagedObject* draggedGroup = [ draggedNode observedObject ];      BOOL draggingDown = NO;     BOOL isRootLevelDrag = NO;      // ----------------------     // Setup comparison paths     // -------------------------     NSIndexPath* draggedPath = [ draggedNode indexPath ];     NSIndexPath* siblingPath =  [ NSIndexPath indexPathWithIndex:  index  ];     if ( parentNode == NULL ) {              isRootLevelDrag = YES;     } else {         // A non-root drag - the index value is relative to this parent's children         siblingPath = [ [ parentNode indexPath ] indexPathByAddingIndex: index ];     }      // ----------------------     // Compare paths - modify sibling path for down drags, exit for redundant drags     // -----------------------------------------------------------------------------         switch ( [ draggedPath compare:siblingPath] ) {         case NSOrderedAscending:  // reset path for down dragging             if ( isRootLevelDrag ) {                 siblingPath = [ NSIndexPath indexPathWithIndex: index  - 1];                                          } else {                 siblingPath = [ [ parentNode indexPath ] indexPathByAddingIndex: index - 1 ];              }             draggingDown = YES;             break;          case NSOrderedSame:             return NO;             break;                    }      siblingNode = [ proxy nodeAtIndexPath:siblingPath ];          //  NSLog(@"returning early");     //  return NO;  // TODO robustify       // ------------------------------------------------------------      // SPECIAL CASE: Dragging to the bottom     // ------------------------------------------------------------     // - K                               - K                            - C                              - C     // - - U                             - - C     OR     - U                                - F     // - - C     ====>     - - F                    - F                              - K     // - - F               - U              - K                              - U     // ------------------------------------------------------------      if ( isRootLevelDrag  && siblingNode == NULL ) {                 draggingDown = YES;         siblingPath = [ NSIndexPath indexPathWithIndex: [ proxy count ] - 1 ];                   siblingNode = [ proxy nodeAtIndexPath:siblingPath ] ;     }      // ------------------------------------------------------------      // Give the dragged item a position relative to it's new sibling     // ------------------------------------------------------------      NSManagedObject* sibling = [ siblingNode observedObject ];        NSNumber* bystanderPosition = [ sibling valueForKey:@"position"];     int newPos =   ( draggingDown ? [ bystanderPosition intValue ]  + 1 : [ bystanderPosition intValue ]  - 1 );     [draggedGroup setValue:[ NSNumber numberWithInt:newPos ] forKey:@"position"];         // ----------------------------------------------------------------------------------------------     // Set the new parent for the dragged item, resort the position attributes and refresh the tree     // ----------------------------------------------------------------------------------------------         [ draggedGroup setValue:[ parentNode observedObject ] forKey:@"parent" ];     [ self resortGroups:[draggedGroup managedObjectContext] forParent:[ parentNode observedObject ] ];               [ groupTreeControl rearrangeObjects ];       return YES;              }       - (NSArray* ) getSubGroups:(NSManagedObjectContext*)objectContext forParent:(NSManagedObject*)parent {     NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];     NSEntityDescription *entity = [NSEntityDescription entityForName:@"projects" inManagedObjectContext:objectContext];      [request setEntity:entity];     NSSortDescriptor* aSortDesc = [[NSSortDescriptor alloc] initWithKey:@"position" ascending:YES];     [request setSortDescriptors:[NSArray arrayWithObject: aSortDesc] ];     [aSortDesc release];      NSPredicate* validationPredicate = [NSPredicate predicateWithFormat:@"parent == %@", parent ];      [ request setPredicate:validationPredicate ];      NSError *error = nil;  // TODO - check the error bozo     return [objectContext executeFetchRequest:request error:&error];     }     - (void) resortGroups:(NSManagedObjectContext*)objectContext forParent:(NSManagedObject*)parent {      NSArray *array = [ self getSubGroups:objectContext forParent:parent ];      // Reset the indexes...     NSEnumerator *enumerator = [array objectEnumerator];     NSManagedObject* anObject;     int index = 0;     while (anObject = [enumerator nextObject]) {         // Multiply index by 10 to make dragging code easier to implement ;) ....         [anObject setValue:[ NSNumber numberWithInt:(index * INTERVAL ) ] forKey:@"position"];             index++;     }      }  - (NSDragOperation)outlineView:(NSOutlineView *)outlineView validateDrop:(id <NSDraggingInfo>)info proposedItem:(id)item proposedChildIndex:(int)index {      _NSArrayControllerTreeNode* newParent = item;      // drags to the root are always acceptable     if ( newParent == NULL ) {           return  NSDragOperationGeneric;      }      // Verify that we are not dragging a parent to one of it's ancestors     // causes a parent loop where a group of nodes point to each other and disappear     // from the control      NSManagedObject* dragged = [ draggedNode observedObject ];           NSManagedObject* newP = [ newParent observedObject ];      if ( [ self category:dragged isSubCategoryOf:newP ] ) {         return NO;     }             return NSDragOperationGeneric; }  - (BOOL) category:(NSManagedObject* )cat isSubCategoryOf:(NSManagedObject* ) possibleSub {      // Depends on your interpretation of subCategory ....     if ( cat == possibleSub ) { return YES; }      NSManagedObject* possSubParent = [possibleSub valueForKey:@"parent"];         if ( possSubParent == NULL ) {  return NO; }      while ( possSubParent != NULL ) {                if ( possSubParent == cat ) { return YES;   }          // move up the tree         possSubParent = [possSubParent valueForKey:@"parent"];               }         return NO; }     // This method gets called by the framework but the values from bindings are used instead - (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item {      return NULL; }  /*   The following are implemented as stubs because they are required when   implementing an NSOutlineViewDataSource. Because we use bindings on the  table column these methods are never called. The NSLog statements have been  included to prove that these methods are not called.  */ - (int)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item {     NSLog(@"numberOfChildrenOfItem");     return 1; }  - (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item {     NSLog(@"isItemExpandable");     return NO; }  - (id)outlineView:(NSOutlineView *)outlineView child:(int)index ofItem:(id)item {     NSLog(@"child of Item");     return NULL; }    @end 

How do you create hybrid Xcode projects for Mac & iPhone?

1:

Data Store for a Mac/iPhone Hybrid App
I have figured it out, so I will post the answer to guidance all those who may have the same problem. NSMutableArray memory managementTo fix it simply did this.. Should I explicitly release?
  1. Bind the NSTreeController's managedObjectContext directly to the managedObjectContext property of the AppDelegate, and remove the whole NSArrayController. Cocoa/WebKit, having “window.open()” JavaScript links opening in an instance of SafariNSTreeController must add/remove items from the managedObjectContext, although not from the NSArrayController's arrangedObjects, as it is read-only.. Examples of Cocoa/Objective-C and Distributed Objects?
  2. Now connect the add although ton to the Tree Controller's add: connection.. How to show a local image in the webview?
  3. Finally connect the remove although ton to the Tree Controller's remove: connection.. Mouseover in NSTableView

2:

add:.
  • Recessed Button (D…
  • Recessed Button (N…
Are those “New” and “Delete”?. If so, you left your Delete although ton connected to the add: action. Connect it to remove: instead.. (Also, you should use gradient although tons with NSAddTemplate and NSRemoveTemplate images instead of recessed although tons with verbal labels. See the Accounts pane in System Preferences for an case of this in action, and the HIG for a description of what recessed although tons are supposed to be used for.).


57 out of 100 based on 72 user ratings 667 reviews