-
Notifications
You must be signed in to change notification settings - Fork 182
/
Copy pathDNDArrayController.m
executable file
·141 lines (106 loc) · 3.72 KB
/
DNDArrayController.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// This is all addapted from mmalc's freely distributed DNDArrayController on his site.
#import "DNDArrayController.h"
NSString *MovedRowsType = @"MOVED_ROWS_TYPE";
@implementation DNDArrayController
- (void)awakeFromNib
{
// register for drag and drop
[tableView registerForDraggedTypes:[NSArray arrayWithObject:MovedRowsType]];
[super awakeFromNib];
}
- (BOOL)tableView:(NSTableView *)tv writeRows:(NSArray *)rows toPasteboard:(NSPasteboard *)pboard
{
// declare our own pasteboard types
NSArray *typesArray = [NSArray arrayWithObjects:MovedRowsType, nil];
[pboard declareTypes:typesArray owner:self];
// add rows array for local move
[pboard setPropertyList:rows forType:MovedRowsType];
return YES;
}
- (NSDragOperation)tableView:(NSTableView *)tv
validateDrop:(id <NSDraggingInfo>)info
proposedRow:(int)row
proposedDropOperation:(NSTableViewDropOperation)op
{
// Only support internal drags (i.e. moves)
if ([info draggingSource] != tableView)
return NSDragOperationNone;
[tv setDropRow:row dropOperation:NSTableViewDropAbove];
return NSDragOperationMove;
}
- (BOOL)tableView:(NSTableView *)tv
acceptDrop:(id <NSDraggingInfo>)info
row:(int)row
dropOperation:(NSTableViewDropOperation)op
{
if (row < 0)
row = 0;
// Only support internal drags (i.e. moves)
if ([info draggingSource] != tableView)
return NO;
NSArray *rows = [[info draggingPasteboard] propertyListForType: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...
NSUInteger rowsAbove = [self rowsAboveRow:row inIndexSet:indexSet];
NSRange range = NSMakeRange(row - rowsAbove, [indexSet count]);
indexSet = [NSIndexSet indexSetWithIndexesInRange:range];
[self setSelectionIndexes:indexSet];
return YES;
}
- (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
{
if ([aCell class] != [NSTextFieldCell class])
return;
BOOL drawInGrey = NO;
NSDictionary *thisRow = [[self arrangedObjects] objectAtIndex:rowIndex];
NSNumber *enabled;
if ((enabled = [thisRow objectForKey:@"enabled"]) && ![enabled boolValue])
drawInGrey = YES;
if (drawInGrey)
[aCell setTextColor:[NSColor colorWithDeviceWhite:0.5 alpha:1.0]];
else
[aCell setTextColor:[NSColor colorWithDeviceWhite:0 alpha:1.0]];
}
#pragma mark -
- (void)moveObjectsInArrangedObjectsFromIndexes:(NSIndexSet *)indexSet toIndex:(NSUInteger)insertIndex
{
NSArray *objects = [self arrangedObjects];
NSUInteger index = [indexSet lastIndex];
NSUInteger aboveInsertIndexCount = 0, removeIndex;
id object;
while (index != NSNotFound) {
if (index >= insertIndex) {
removeIndex = index + aboveInsertIndexCount;
aboveInsertIndexCount += 1;
} else {
removeIndex = index;
insertIndex -= 1;
}
object = [objects objectAtIndex:removeIndex];
[self removeObjectAtArrangedObjectIndex:removeIndex];
[self insertObject:object atArrangedObjectIndex:insertIndex];
index = [indexSet indexLessThanIndex:index];
}
}
- (NSIndexSet *)indexSetFromRows:(NSArray *)rows
{
NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSet];
NSEnumerator *rowEnumerator = [rows objectEnumerator];
NSNumber *idx;
while ((idx = [rowEnumerator nextObject]))
[indexSet addIndex:[idx intValue]];
return indexSet;
}
- (NSUInteger)rowsAboveRow:(NSUInteger)row inIndexSet:(NSIndexSet *)indexSet
{
NSUInteger currentIndex = [indexSet firstIndex], i = 0;
while (currentIndex != NSNotFound) {
if (currentIndex < row)
i++;
currentIndex = [indexSet indexGreaterThanIndex:currentIndex];
}
return i;
}
@end