On 26/10/2010, at 8:54 AM, Paul Johnson wrote:
> I am trying to drag and drop from one text view
^^ you mean TABLE view, right?
> to another. I can write an
> index set of copied rows to the pasteboard using:
>
>
> - (BOOL)tableView:(NSTableView *)tv
>
> writeRowsWithIndexes:(NSIndexSet *)rowIndexes
>
> toPasteboard:(NSPasteboard*)pboard {
>
> // Copy the row numbers to the pasteboard.
>
> NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes];
>
> [pboard declareTypes:[NSArray arrayWithObject:NSDragPboard] owner:self];
>
> [pboard setData:data forType:NSDragPboard];
>
> return YES;
>
> }
This is totally confused and broken.
The rowIndexes just tell you which rows to copy; they do not contain those
row's data. You can use the indexes in the index set to find out which data
items in your data model you want to copy to the pasteboard. You are archiving
the rowIndexes themselves, which information is unlikely to be of much interest
to the destination.
Once you have the actual data, you write it to the dragging pasteboard using an
appropriate type. For private data of your own, you need to make up something
suitable for the type - NSDragPBoard is NOT a type name, it is a pasteboard
name and should not be used here.
> In the array controller for the destination text view, I have
>
>
> - (BOOL)tableView:(NSTableView *)aTableView
>
> acceptDrop:(id <NSDraggingInfo>)info
>
> row:(NSInteger)row
>
> dropOperation:(NSTableViewDropOperation)operation
>
> {
>
> NSPasteboard* pboard = [info draggingPasteboard];
>
> NSData* rowData = [pboard dataForType:NSDragPboard];
Same error here, NSDragPBoard is NOT a type name. This should be whatever you
used in the write method, and for private data is a name you made up. Note that
for some kinds of data there are suitable predefined type names but if you use
those you have to ensure that the data is written in the appropriate format.
>
> NSIndexSet* rowIndexes = [NSKeyedUnarchiver unarchiveObjectWithData
> :rowData];
>
> NSInteger dragRow = [rowIndexes firstIndex];
>
>
>
> // Move the specified row to its new location...
>
> NSLog(@"count = %i", [rowIndexes count]);
>
> while(dragRow != NSNotFound)
>
> {
>
> NSLog(@" %i", dragRow);
>
> dragRow = [rowIndexes indexGreaterThanIndex:dragRow];
>
> // **** Copy a row here. ****
>
> }
>
> return YES;
>
> }
>
>
> I'm having trouble figuring out the correct code in the while-loop where I
> need to copy a row.
Because you archived the source table's row indexes rather than the data they
index, that's what you get back. At this point that information only makes
sense in the context of the source table. While that can be made to work (as a
private transaction between data models in your app, you could have the second
table ask for the data from the source here, but it's more conventional to pass
the data itself, so you have it already here, where it's needed).
If you can fix up these issues, putting the data into the destination is a case
of inserting the data items at the row you're given and calling -reloadData on
the table so that it draws the updated table.
I should factor out the data movement or copy into methods on your data model,
e.g. [myDataModel dataForIndexes:(NSIndexSet*) indexes] and [myDataModel
insertData:(NSData*) data atIndex:(NSUInteger) index]; so that you have a pair
of simple methods you can call from the table's drag/drop handling methods.
Since they are views they should not be making too many assumptions about the
data they are displaying.
I assume you have also registered the destination table view to receive drags
of the desired type? Since you have not used a correct type name I suspect that
step is also missing.
--Graham
_______________________________________________
Cocoa-dev mailing list ([email protected])
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 [email protected]