[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 |