Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 311471
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 12, 20262026-05-12T07:55:40+00:00 2026-05-12T07:55:40+00:00

The problem I have is that I have an NSOutlineView with Drag and Drop

  • 0

The problem I have is that I have an NSOutlineView with Drag and Drop (see the bottom of post for code to make drag and drop work), it works, but when I drag one row into another row the dragged row becomes a child but it also stays where it was as a parent, and when I delete either row both of them get deleted.
To show you what I mean, I have recorded the problem, here is the link – http://dvlp.me/6kya9

And here is the code which makes drag and drop work in the outline view.

Header File.

@interface _NSControllerTreeProxy : NSObject 
{
    // opaque
}
//
// Number of objects at the root level.
//
- (unsigned int)count;

- (id)nodeAtIndexPath:(id)fp8;
- (id)objectAtIndexPath:(id)fp8;
@end

@interface _NSArrayControllerTreeNode : NSObject
{
    // opaque
}
- (unsigned int)count;
- (id)observedObject;
- (id)parentNode;
- (id)nodeAtIndexPath:(id)fp8;
- (id)subnodeAtIndex:(unsigned int)fp8;
- (BOOL)isLeaf;
- (id)indexPath;
- (id)objectAtIndexPath:(id)fp8;
@end

// some more detailed reverse engineering is available here
// http://www.blueboxmoon.com/wiki/?page=Binding%20Tree


@interface DragController : NSObject
{
    IBOutlet NSTreeController *groupTreeControl;
    IBOutlet NSOutlineView *treeTable;

    NSArray* dragType;

    _NSArrayControllerTreeNode* draggedNode;


}

- (void) resortGroups:(NSManagedObjectContext*)objectContext forParent:(NSManagedObject*)parent;
- (NSArray* ) getSubGroups:(NSManagedObjectContext*)objectContext forParent:(NSManagedObject*)parent;
- (BOOL) category:(NSManagedObject* )cat isSubCategoryOf:(NSManagedObject* ) possibleSub;

@end

#define INTERVAL 10

Implemetation File.

@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
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-12T07:55:41+00:00Added an answer on May 12, 2026 at 7:55 am

    Just did a Bit of searching around, and found how to fix it.
    In the Attributes for the NSTreeController set the fetch predicate as parent == nil.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

The problem I have is that whenever I try to drag and drop with
We are running ColdFusion MX7. One problem we have is that we have a
Problem: I have a table that prints out vertical but I would like it
this is my regex for digital dnumbers: \d+(.\d+)+(,\d+) but now i have problem that
I have created a Sub-Class of NSOutlineView and used the below code to make
I have problem that seems to be rather trivial but I was not able
The basic problem I have here is that I have one xml file that
Problem: I have code that looks for a file and open it. By default
I have that problem, in html I have this code: <div> <div class='category' style=display:block>
well I have that problem, im using a lightbox srcipt and im opening an

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.