fix: correct playlist creation on iPod (real db_track_id, metadata fallback, Settings hover fix)

This commit is contained in:
Maksim Totmin
2026-06-01 21:05:39 +07:00
parent 8861e55f32
commit b7367e63c4
4 changed files with 279 additions and 6 deletions
+60 -2
View File
@@ -27,6 +27,14 @@ class PlaylistDropListWidget(QListWidget):
self.setAcceptDrops(True)
self._hovered_item = None
def mimeData(self, items):
mime = super().mimeData(items)
if items:
playlist_id = items[0].data(Qt.ItemDataRole.UserRole)
if playlist_id:
mime.setData("application/x-neopod-playlist", playlist_id.encode())
return mime
def dragEnterEvent(self, event: QDragEnterEvent):
if event.source() is not self and event.mimeData().hasUrls():
event.acceptProposedAction()
@@ -83,6 +91,7 @@ class PlaylistDropListWidget(QListWidget):
class NavDropListWidget(QListWidget):
"""QListWidget that accepts external track drops on the iPod nav item."""
tracks_dropped_for_transfer = pyqtSignal(list)
playlist_dropped_for_transfer = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
@@ -95,7 +104,19 @@ class NavDropListWidget(QListWidget):
return item
return None
def _repolish(self):
self.style().unpolish(self)
self.style().polish(self)
def dragEnterEvent(self, event: QDragEnterEvent):
if event.mimeData().hasFormat("application/x-neopod-playlist"):
self.setProperty("dndActive", True)
self._repolish()
pos = event.position().toPoint()
if self._target_item_at(pos):
event.acceptProposedAction()
return
# Let default handler accept so dragMoveEvent still fires
if event.source() is not self and event.mimeData().hasUrls():
pos = event.position().toPoint()
if self._target_item_at(pos):
@@ -104,6 +125,7 @@ class NavDropListWidget(QListWidget):
super().dragEnterEvent(event)
def dragMoveEvent(self, event: QDragMoveEvent):
accept = False
if event.source() is not self and event.mimeData().hasUrls():
pos = event.position().toPoint()
item = self._target_item_at(pos)
@@ -115,15 +137,34 @@ class NavDropListWidget(QListWidget):
item.setBackground(bg)
if item:
event.acceptProposedAction()
return
super().dragMoveEvent(event)
accept = True
if not accept and event.mimeData().hasFormat("application/x-neopod-playlist"):
pos = event.position().toPoint()
item = self._target_item_at(pos)
if item != self._hovered_item:
self._clear_hover()
if item:
self._hovered_item = item
bg = self.palette().color(self.palette().ColorRole.Highlight)
item.setBackground(bg)
if item:
event.acceptProposedAction()
accept = True
if not accept:
event.ignore()
def dragLeaveEvent(self, event: QDragLeaveEvent):
self._clear_hover()
if self.property("dndActive"):
self.setProperty("dndActive", False)
self._repolish()
super().dragLeaveEvent(event)
def dropEvent(self, event: QDropEvent):
self._clear_hover()
if self.property("dndActive"):
self.setProperty("dndActive", False)
self._repolish()
if event.source() is not self and event.mimeData().hasUrls():
pos = event.position().toPoint()
if self._target_item_at(pos):
@@ -133,6 +174,14 @@ class NavDropListWidget(QListWidget):
self.tracks_dropped_for_transfer.emit(paths)
event.acceptProposedAction()
return
if event.mimeData().hasFormat("application/x-neopod-playlist"):
pos = event.position().toPoint()
if self._target_item_at(pos):
playlist_id = bytes(event.mimeData().data("application/x-neopod-playlist")).decode()
if playlist_id:
self.playlist_dropped_for_transfer.emit(playlist_id)
event.acceptProposedAction()
return
super().dropEvent(event)
def _clear_hover(self):
@@ -146,6 +195,7 @@ class SidebarWidget(QWidget):
playlist_selected = pyqtSignal(str)
tracks_dropped_on_playlist = pyqtSignal(str, list)
tracks_dropped_for_nav_transfer = pyqtSignal(list)
playlist_dropped_for_nav_transfer = pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
@@ -205,6 +255,9 @@ class SidebarWidget(QWidget):
QListWidget::item:hover:!selected {{
background: {hl_light_name};
}}
#navList[dndActive="true"]::item:hover:!selected {{
background: transparent;
}}
""")
def _build_ui(self):
@@ -292,6 +345,7 @@ class SidebarWidget(QWidget):
layout.addWidget(line2)
self._nav_list = NavDropListWidget()
self._nav_list.setObjectName("navList")
items = [
("🎸 iPod", "ipod"),
("⚙️ Settings", "settings"),
@@ -303,6 +357,7 @@ class SidebarWidget(QWidget):
self._nav_list.addItem(item)
self._nav_list.itemClicked.connect(self._on_nav_item_clicked)
self._nav_list.tracks_dropped_for_transfer.connect(self._on_tracks_dropped_for_nav_transfer)
self._nav_list.playlist_dropped_for_transfer.connect(self._on_playlist_dropped_for_transfer)
layout.addWidget(self._nav_list)
self._playlist_items: dict = {}
@@ -396,6 +451,9 @@ class SidebarWidget(QWidget):
def _on_tracks_dropped_for_nav_transfer(self, paths: list):
self.tracks_dropped_for_nav_transfer.emit(paths)
def _on_playlist_dropped_for_transfer(self, playlist_id: str):
self.playlist_dropped_for_nav_transfer.emit(playlist_id)
def _on_playlists_reordered(self):
order = self.get_playlist_order_ids()
self.item_selected.emit("playlist_reorder", "|".join(order))