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) self.resizeRowsToContents)
# Drag and drop setup # Drag and drop setup
# TODO: fix drag and drop for qt6 self.setAcceptDrops(True)
self.setAcceptDrops(False)
self.viewport().setAcceptDrops(True) self.viewport().setAcceptDrops(True)
self.setDragDropOverwriteMode(False) self.setDragDropOverwriteMode(False)
self.setDropIndicatorShown(True) self.setDropIndicatorShown(True)
@ -232,41 +231,37 @@ class PlaylistTab(QTableWidget):
if not event.source() == self: if not event.source() == self:
return # We don't accept external drops return # We don't accept external drops
drop_row: int = self._drop_on(event) row_set = set([mi.row() for mi in self.selectedIndexes()])
targetRow = self.indexAt(event.position().toPoint()).row()
rows: List = sorted(set(item.row() for item in self.selectedItems())) row_set.discard(targetRow)
rows_to_move = [ rows = list(sorted(row_set))
[QTableWidgetItem( if not rows:
self.item(row_index, column_index) # type: ignore return
) for if targetRow == -1:
column_index in range(self.columnCount())] targetRow = self.rowCount()
for row_index in rows for _ in range(len(rows)):
] self.insertRow(targetRow)
for row_index in reversed(rows): rowMapping = dict() # Src row to target row.
self.removeRow(row_index) for idx, row in enumerate(rows):
if row_index < drop_row: if row < targetRow:
drop_row -= 1 rowMapping[row] = targetRow + idx
else:
for row_index, data in enumerate(rows_to_move): rowMapping[row + len(rows)] = targetRow + idx
row_index += drop_row colCount = self.columnCount()
self.insertRow(row_index) for srcRow, tgtRow in sorted(rowMapping.items()):
for column_index, column_data in enumerate(data): for col in range(0, colCount):
self.setItem(row_index, column_index, column_data) self.setItem(tgtRow, col, self.takeItem(srcRow, col))
for row in reversed(sorted(rowMapping.keys())):
self.removeRow(row)
event.accept() 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 # 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 # Reset drag mode to allow row selection by dragging
self.setDragEnabled(False) self.setDragEnabled(False)
super().dropEvent(event)
with Session() as session: with Session() as session:
self.save_playlist(session) self.save_playlist(session)
self._update_start_end_times(session) self._update_start_end_times(session)
@ -291,8 +286,7 @@ class PlaylistTab(QTableWidget):
""" """
if self.selectedItems(): if self.selectedItems():
# TODO: fix drag and drop self.setDragEnabled(True)
self.setDragEnabled(False)
else: else:
self.setDragEnabled(False) self.setDragEnabled(False)
super().mouseReleaseEvent(event) super().mouseReleaseEvent(event)
@ -1152,19 +1146,6 @@ class PlaylistTab(QTableWidget):
self._update_start_end_times(session) 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, def _find_next_track_row(self, session: scoped_session,
starting_row: Optional[int] = None) \ starting_row: Optional[int] = None) \
-> Optional[int]: -> Optional[int]:
@ -1416,23 +1397,6 @@ class PlaylistTab(QTableWidget):
info.setDefaultButton(QMessageBox.StandardButton.Cancel) info.setDefaultButton(QMessageBox.StandardButton.Cancel)
info.exec() 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: def _look_up_row(self, website: str) -> None:
""" """
If there is a selected row and it is a track row, If there is a selected row and it is a track row,