[Pyobjc-dev] NSTableView and Drag and Drop
Brought to you by:
ronaldoussoren
From: John S. <jo...@sk...> - 2008-01-24 22:51:21
|
Hi PyObjC list, I have a table view that I'd like to add drag and drop support to. I borrowed a lot of code from the bookmarks example and some Objective-C examples I've found across the net (and I used tableView_writeRowsWithIndexes_toPasteboard_ rather than tableView_writeRows_toPasteboard_ since I read writeRows is deprecated). I've also modified it a little since my application is not document-based. Ideally the user would be able to reorder items in the table (I don't anticipate the need for copy and paste). I have it almost working--I can drag an element, but on drop, I get the following error: An unexpected error has occurred (TypeError: 'NoneType' object is not iterable) I've implemented the three methods I believe I'm supposed to implement for DND table support and I've declared a pasteboard type. I don't know if it's because the acceptDrop or validateDrop methods aren't working. Ideas? My code is below: """ ApplicationDelegate.py Controller class for the application """ from Foundation import * from AppKit import * from PyObjCTools import NibClassBuilder import objc from objc import YES, NO, IBOutlet, IBAction from ApplicationModel import * MovedRowsType = u"MOVED_ROWS_TYPE" class ApplicationDelegate(NSObject): # Outlets arrayController = objc.IBOutlet() tableView = objc.IBOutlet() # Class methods def init(self): self = NSObject.init(self) return self def awakeFromNib(self): # register for drag and drop self.tableView.registerForDraggedTypes_([MovedRowsType]) def tableView_writeRowsWithIndexes_toPasteboard_(self, tv, rowIndexes, pboard): typesArray = [MovedRowsType] data = NSKeyedArchiver.archivedDataWithRootObject_(rowIndexes) pboard.declareTypes_owner_(typesArray, self) #pboard.setData_forType_(typesArray, self) NSLog("boo-yeah") return YES def tableView_validateDrop_proposedRow_proposedDropOperation_(self, tv, info, row, op): dragOp = NSDragOperationMove tv.setDropRow_dropOperation_(row, NSTableViewDropAbove) return dragOp def tableView_acceptDrop_row_dropOperation_(self, tv, info, row, op): if row < 0: row = 0 if info.draggingSource() == self.tableView: rows = info.draggingPasteboard().propertyListForType_(MovedRowsType) indexSet = self.indexSetFromRows_(rows) self.moveObjectsInArrangedObjectsFromIndexes_toIndex_(indexSet, row) rowsAbove = self.rowsAboveRow_inIndexSet_(row, indexSet) aRange = NSMakeRange(row - rowsAbove, indexSet.count()) indexSet = NSIndexSet.indexSetWithIndexesInRange_(aRange) self.arrayController.setSelectionIndexes_(indexSet) return YES return NO def moveObjectsInArrangedObjectsFromIndexes_toIndex_(self, indexSet, insertIndex): objects = self.arrayController.arrangedObjects() index = indexSet.lastIndex() aboveInsertIndexCount = 0 removeIndex = 0 while index != NSNotFound: if index >= insertIndex: removeIndex = index + aboveInsertIndexCount aboveInsertIndexCount += 1 else: removeIndex = index insertIndex -= 1 obj = objects.objectAtIndex_(removeIndex) self.arrayController.removeObjectAtArrangedObjectIndex_(removeIndex) self.arrayController.insertObject_atArrangedObjectIndex_(obj, insertIndex) index = indexSet.indexLessThanIndex_(index) def indexSetFromRows_(self, rows): indexSet = NSMutableIndexSet.indexSet() for row in rows: indexSet.addIndex_(row) return indexSet def rowsAboveRow_inIndexSet_(self, row, indexSet): currentIndex = indexSet.firstIndex() i = 0 while currentIndex != NSNotFound: if currentIndex < row: i += 1 currentIndex = indexSet.indexGreaterThanIndex_(currentIndex) return i |