Greatly simplifed drag and drop code

This commit is contained in:
Keith Edmunds 2023-04-13 17:29:58 +01:00
parent 32cc0468e8
commit 8a6812e405

View File

@ -189,8 +189,7 @@ class PlaylistTab(QTableWidget):
self.resizeRowsToContents)
# Drag and drop setup
# TODO: fix drag and drop for qt6
self.setAcceptDrops(False)
self.setAcceptDrops(True)
self.viewport().setAcceptDrops(True)
self.setDragDropOverwriteMode(False)
self.setDropIndicatorShown(True)
@ -232,41 +231,37 @@ class PlaylistTab(QTableWidget):
if not event.source() == self:
return # We don't accept external drops
drop_row: int = self._drop_on(event)
rows: List = sorted(set(item.row() for item in self.selectedItems()))
rows_to_move = [
[QTableWidgetItem(
self.item(row_index, column_index) # type: ignore
) for
column_index in range(self.columnCount())]
for row_index in rows
]
for row_index in reversed(rows):
self.removeRow(row_index)
if row_index < drop_row:
drop_row -= 1
for row_index, data in enumerate(rows_to_move):
row_index += drop_row
self.insertRow(row_index)
for column_index, column_data in enumerate(data):
self.setItem(row_index, column_index, column_data)
row_set = set([mi.row() for mi in self.selectedIndexes()])
targetRow = self.indexAt(event.position().toPoint()).row()
row_set.discard(targetRow)
rows = list(sorted(row_set))
if not rows:
return
if targetRow == -1:
targetRow = self.rowCount()
for _ in range(len(rows)):
self.insertRow(targetRow)
rowMapping = dict() # Src row to target row.
for idx, row in enumerate(rows):
if row < targetRow:
rowMapping[row] = targetRow + idx
else:
rowMapping[row + len(rows)] = targetRow + idx
colCount = self.columnCount()
for srcRow, tgtRow in sorted(rowMapping.items()):
for col in range(0, colCount):
self.setItem(tgtRow, col, self.takeItem(srcRow, col))
for row in reversed(sorted(rowMapping.keys())):
self.removeRow(row)
event.accept()
# The above doesn't handle column spans, which we use in note
# rows. Check and fix:
for row in range(drop_row, drop_row + len(rows_to_move)):
if not self._get_row_track_id(row):
self.setSpan(row, HEADER_NOTES_COLUMN, 1, len(columns))
# Scroll to drop zone
self.scrollToItem(self.item(row, 1))
self.scrollToItem(self.item(targetRow, 1),
QAbstractItemView.ScrollHint.PositionAtCenter)
# Reset drag mode to allow row selection by dragging
self.setDragEnabled(False)
super().dropEvent(event)
with Session() as session:
self.save_playlist(session)
self._update_start_end_times(session)
@ -291,8 +286,7 @@ class PlaylistTab(QTableWidget):
"""
if self.selectedItems():
# TODO: fix drag and drop
self.setDragEnabled(False)
self.setDragEnabled(True)
else:
self.setDragEnabled(False)
super().mouseReleaseEvent(event)
@ -1152,19 +1146,6 @@ class PlaylistTab(QTableWidget):
self._update_start_end_times(session)
def _drop_on(self, event):
"""
https://stackoverflow.com/questions/26227885/drag-and-drop-rows-within-qtablewidget
"""
position = event.position().toPoint()
index = self.indexAt(position)
if not index.isValid():
return self.rowCount()
return (index.row() + 1 if self._is_below(position, index)
else index.row())
def _find_next_track_row(self, session: scoped_session,
starting_row: Optional[int] = None) \
-> Optional[int]:
@ -1416,23 +1397,6 @@ class PlaylistTab(QTableWidget):
info.setDefaultButton(QMessageBox.StandardButton.Cancel)
info.exec()
def _is_below(self, pos, index): # review
"""
https://stackoverflow.com/questions/26227885/drag-and-drop-rows-within-qtablewidget
"""
rect = self.visualRect(index)
margin = 2
if pos.y() - rect.top() < margin:
return False
elif rect.bottom() - pos.y() < margin:
return True
return (
rect.contains(pos, True) and not
(int(self.model().flags(index)) & Qt.ItemIsDropEnabled)
and pos.y() >= rect.center().y() # noqa W503
)
def _look_up_row(self, website: str) -> None:
"""
If there is a selected row and it is a track row,