Hello,

to implement the automatic support of drag reordering in all NSTableViews of my Core Data based application, I subclassed NSArrayController using the very good tutorial supplied at

http://www.timisted.net/blog/archive/core-data-drag-drop/

I just put all the functionality in the new array controller class, in this way its most convenient for me, and I hope its also wise from a MVC standpoint.

One problem arose: I wanted to override the add: method and just add the renumbering of the objects in order to have a new object integrated into my numbering scheme:

- (IBAction)add:(id)sender
{
        [super add:sender];
        [self renumberViewPositions];
}

My NSManagedObjects all have an attribute viewPosition, which (via a SubClass) ist automaticall set to an appropriate Value upon awakeFromInsert.


---> The problem <---

In the renumbering routine, when I access [self arrangedobjects], or even if I do a new fetch on my managedObjectContext, the new object is not there yet. I tried all this:

        [[self managedObjectContext] processPendingChanges];
        [self prepareContent];
        [self fetch:sender];
        [self rearrangeObjects];

But it does not help.


---> The question <---

Is there a way to find that newly added object in this subclass? I do not think it depends on me subclassing NSArrayController, because something like

        NSError *error = nil;
        NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
        [request setEntity:[NSEntityDescription entityForName:[self entityName]
                 inManagedObjectContext:[self managedObjectContext]]];
NSArray *objects = [[self managedObjectContext] executeFetchRequest:request error:&error];

executed after the [super add:] does not contain the new object either.


---> The code (the important parts) <---

- header -----------------------------------------------------------------------------

#import <Cocoa/Cocoa.h>

enum AWWiewPositionArrayControllerPostitionValueTag {
        AWWiewPositionArrayControllerPostitionValueTemporary = -1,
        AWWiewPositionArrayControllerPostitionValueTop = -2,
        AWWiewPositionArrayControllerPostitionValueBottom = -3
} AWWiewPositionArrayControllerPostitionValue;

@interface AWViewPositionArrayController : NSArrayController
{
        NSTableView* _viewPositionTableview;
        IBOutlet NSArrayController* _boundToSelection;
}

@property (readwrite, retain) IBOutlet NSTableView* viewPositionTableView;

@end

- implementation ----------------------------------------------------------------------

#import "AWViewPositionArrayController.h"
#import "AWViewPositionManagedObject.h"

@implementation AWViewPositionArrayController

@synthesize viewPositionTableView = _viewPositionTableview;

- (NSArray *)viewPositionSortDescriptor
{
return [NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:@"viewPosition" ascending:YES]];
}

- (void) awakeFromNib
{
        [self.viewPositionTableView setDataSource:self];
        [self setSortDescriptors:[self viewPositionSortDescriptor]];
[self.viewPositionTableView registerForDraggedTypes:[NSArray arrayWithObjects:AWViewPositionArrayControllerDropType, nil]];
}

- (NSArray *)itemsUsingFetchPredicate:(NSPredicate *)fetchPredicate
{       
        //fetch the objects ourself from the managedobjectcontext.
//the arraycontrollers arrangeditems is only for syncing with the view and is not supposed to be used for this
        NSError *error = nil;
        NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
        [request setEntity:[NSEntityDescription entityForName:[self entityName]
                 inManagedObjectContext:[self managedObjectContext]]];
NSArray *objects = [[self managedObjectContext] executeFetchRequest:request error:&error];
        if (error) {
NSLog(@"Fetch error! In AWViewPositionArrayController:itemsUseingFetchPredicate");
        }
return [[objects filteredArrayUsingPredicate:fetchPredicate] sortedArrayUsingDescriptors:[self viewPositionSortDescriptor]];
}

- (NSArray *)itemsWithViewPosition:(int)value
{
NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat:@"viewPosition == %i", value];
        return [self itemsUsingFetchPredicate:fetchPredicate];
}

- (NSArray *)itemsWithNonTemporaryViewPosition
{
NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat:@"viewPosition >= 0"];
        return [self itemsUsingFetchPredicate:fetchPredicate];
}

- (NSArray *)itemsWithViewPositionGreaterThanOrEqualTo:(int)value
{
NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat:@"viewPosition >= %i", value];
        return [self itemsUsingFetchPredicate:fetchPredicate];
}

- (NSArray *)itemsWithViewPositionBetween:(int)lowValue and: (int)highValue
{
NSPredicate *fetchPredicate = [NSPredicate predicateWithFormat:@"viewPosition >= %i && viewPosition <= %i", lowValue, highValue];
        return [self itemsUsingFetchPredicate:fetchPredicate];
}

- (int)renumberViewPositionsOfItems:(NSArray *)array startingAt: (int)value
{
        int currentViewPosition = value;
        int count = 0;
        if( array && ([array count] > 0) )
        {
                for( count = 0; count < [array count]; count++ )
                {
AWViewPositionManagedObject *currentObject = [array objectAtIndex:count]; currentObject.viewPosition = [NSNumber numberWithInt:currentViewPosition];
                        currentViewPosition++;
                }
        }
        return currentViewPosition;
}

- (void)renumberViewPositions
{
NSArray *startItems = [self itemsWithViewPosition:AWWiewPositionArrayControllerPostitionValueTop];
        NSArray *existingItems = [self itemsWithNonTemporaryViewPosition];
NSArray *endItems = [self itemsWithViewPosition:AWWiewPositionArrayControllerPostitionValueBottom ];
        
        int currentViewPosition = 0;
        if( startItems && ([startItems count] > 0) )
currentViewPosition = [self renumberViewPositionsOfItems:startItems startingAt:currentViewPosition];
        if( existingItems && ([existingItems count] > 0) )
currentViewPosition = [self renumberViewPositionsOfItems:existingItems startingAt:currentViewPosition];
        if( endItems && ([endItems count] > 0) )
currentViewPosition = [self renumberViewPositionsOfItems:endItems startingAt:currentViewPosition];
}

- (IBAction)add:(id)sender
{
[super add:sender]; [[self managedObjectContext] processPendingChanges];
        [self prepareContent];
        [self fetch:sender];
        [self rearrangeObjects];
        [self renumberViewPositions];
}

- (IBAction)remove:(id)sender
{
        [super remove:sender];
        [self renumberViewPositions];
}

- end ---------------------------------------------------------------------------------



_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to