2005-06-02 18:16:43 +00:00
|
|
|
|
|
|
|
#import "DNDArrayController.h"
|
|
|
|
|
|
|
|
@implementation DNDArrayController
|
|
|
|
|
|
|
|
NSString *MovedRowsType = @"MOVED_ROWS_TYPE";
|
2008-02-13 17:14:19 +00:00
|
|
|
NSString *CogUrlsPboardType = @"COG_URLS_TYPE";
|
2005-06-02 18:16:43 +00:00
|
|
|
|
2007-02-17 15:58:39 +00:00
|
|
|
// @"CorePasteboardFlavorType 0x6974756E" is the "itun" type representing an iTunes plist
|
|
|
|
NSString *iTunesDropType = @"CorePasteboardFlavorType 0x6974756E";
|
2005-06-02 18:16:43 +00:00
|
|
|
|
|
|
|
- (void)awakeFromNib
|
|
|
|
{
|
|
|
|
// register for drag and drop
|
2008-02-13 17:14:19 +00:00
|
|
|
[tableView registerForDraggedTypes:[NSArray arrayWithObjects:MovedRowsType, CogUrlsPboardType, NSFilenamesPboardType, iTunesDropType, nil]];
|
2005-06-02 18:16:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (BOOL)tableView:(NSTableView *)tv
|
|
|
|
writeRows:(NSArray*)rows
|
|
|
|
toPasteboard:(NSPasteboard*)pboard
|
|
|
|
{
|
|
|
|
NSData *data;
|
|
|
|
data = [NSKeyedArchiver archivedDataWithRootObject:rows];
|
|
|
|
|
|
|
|
[pboard declareTypes: [NSArray arrayWithObjects:MovedRowsType, nil] owner:self];
|
|
|
|
[pboard setData: data forType: MovedRowsType];
|
|
|
|
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (NSDragOperation)tableView:(NSTableView*)tv
|
|
|
|
validateDrop:(id <NSDraggingInfo>)info
|
|
|
|
proposedRow:(int)row
|
|
|
|
proposedDropOperation:(NSTableViewDropOperation)op
|
|
|
|
{
|
|
|
|
NSDragOperation dragOp = NSDragOperationCopy;
|
|
|
|
|
|
|
|
if ([info draggingSource] == tv)
|
|
|
|
dragOp = NSDragOperationMove;
|
|
|
|
|
|
|
|
// we want to put the object at, not over,
|
|
|
|
// the current row (contrast NSTableViewDropOn)
|
|
|
|
[tv setDropRow:row dropOperation:NSTableViewDropAbove];
|
|
|
|
|
|
|
|
return dragOp;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
- (BOOL)tableView:(NSTableView*)tv
|
|
|
|
acceptDrop:(id <NSDraggingInfo>)info
|
|
|
|
row:(int)row
|
|
|
|
dropOperation:(NSTableViewDropOperation)op
|
|
|
|
{
|
|
|
|
if (row < 0)
|
|
|
|
{
|
|
|
|
row = 0;
|
|
|
|
}
|
2007-03-09 01:16:06 +00:00
|
|
|
|
2005-06-02 18:16:43 +00:00
|
|
|
// if drag source is self, it's a move
|
|
|
|
if ([info draggingSource] == tableView)
|
|
|
|
{
|
|
|
|
NSArray *rows = [NSKeyedUnarchiver unarchiveObjectWithData:[[info draggingPasteboard] dataForType: MovedRowsType]];
|
|
|
|
|
|
|
|
NSIndexSet *indexSet = [self indexSetFromRows:rows];
|
|
|
|
|
|
|
|
[self moveObjectsInArrangedObjectsFromIndexes:indexSet toIndex:row];
|
|
|
|
|
|
|
|
// set selected rows to those that were just moved
|
|
|
|
// Need to work out what moved where to determine proper selection...
|
|
|
|
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-02-10 19:35:58 +00:00
|
|
|
-(void)moveObjectsFromArrangedObjectIndexes:(NSArray *) sources toIndexes:(NSArray *)destinations;
|
2005-06-02 18:16:43 +00:00
|
|
|
{
|
2008-02-10 19:35:58 +00:00
|
|
|
//We expect [sources count] == [destinations count].
|
|
|
|
NSMutableArray *selectedObjects = [[NSMutableArray alloc] init];
|
2005-06-02 18:16:43 +00:00
|
|
|
|
2008-02-10 19:35:58 +00:00
|
|
|
NSUInteger i = 0;
|
|
|
|
for (i = 0; i < [sources count]; i++) {
|
|
|
|
NSUInteger source = [[sources objectAtIndex:i] unsignedIntegerValue];
|
|
|
|
NSUInteger dest = [[destinations objectAtIndex:i] unsignedIntegerValue];
|
|
|
|
|
|
|
|
id object = [[self arrangedObjects] objectAtIndex:source];
|
|
|
|
|
|
|
|
[object retain];
|
|
|
|
|
|
|
|
[self removeObjectAtArrangedObjectIndex:source];
|
|
|
|
[self insertObject:object atArrangedObjectIndex:dest];
|
|
|
|
|
|
|
|
[selectedObjects addObject: object];
|
|
|
|
|
|
|
|
[object release];
|
|
|
|
}
|
2005-06-02 18:16:43 +00:00
|
|
|
|
2008-02-10 19:35:58 +00:00
|
|
|
[self setSelectedObjects:selectedObjects];
|
|
|
|
|
|
|
|
[selectedObjects release];
|
|
|
|
}
|
|
|
|
|
|
|
|
-(void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet*)indexSet
|
|
|
|
toIndex:(unsigned int)insertIndex
|
|
|
|
{
|
|
|
|
int index = [indexSet lastIndex];
|
2005-06-02 18:16:43 +00:00
|
|
|
int aboveInsertIndexCount = 0;
|
|
|
|
int removeIndex;
|
2008-02-10 19:35:58 +00:00
|
|
|
|
|
|
|
NSMutableArray *sources = [NSMutableArray array];
|
|
|
|
NSMutableArray *destinations = [NSMutableArray array];
|
2005-06-02 18:16:43 +00:00
|
|
|
|
|
|
|
while (NSNotFound != index)
|
|
|
|
{
|
|
|
|
if (index >= insertIndex) {
|
|
|
|
removeIndex = index + aboveInsertIndexCount;
|
|
|
|
aboveInsertIndexCount += 1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
removeIndex = index;
|
|
|
|
insertIndex -= 1;
|
|
|
|
}
|
2008-02-10 19:35:58 +00:00
|
|
|
|
|
|
|
[sources addObject:[NSNumber numberWithUnsignedInteger:removeIndex]];
|
|
|
|
[destinations addObject: [NSNumber numberWithUnsignedInteger:insertIndex]];
|
2005-06-02 18:16:43 +00:00
|
|
|
|
|
|
|
index = [indexSet indexLessThanIndex:index];
|
|
|
|
}
|
2008-02-10 19:35:58 +00:00
|
|
|
|
|
|
|
[self moveObjectsFromArrangedObjectIndexes:sources toIndexes:destinations];
|
2005-06-02 18:16:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSIndexSet *)indexSetFromRows:(NSArray *)rows
|
|
|
|
{
|
|
|
|
NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
|
|
|
|
NSEnumerator *rowEnumerator = [rows objectEnumerator];
|
|
|
|
NSNumber *idx;
|
|
|
|
while (idx = [rowEnumerator nextObject])
|
|
|
|
{
|
|
|
|
[indexSet addIndex:[idx unsignedIntValue]];
|
|
|
|
}
|
|
|
|
return indexSet;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|