#!/usr/bin/python3 from PyQt6.QtCore import pyqtSignal from PyQt6.QtGui import QDropEvent, QIcon, QFont from PyQt6.QtWidgets import QTreeWidget, QAbstractItemView, QFrame from .track import TrackItem class PlaylistView(QTreeWidget): itemDropped = pyqtSignal(QTreeWidget, list) normal_font = QFont() bold_font = QFont() bold_font.setBold(True) def __init__(self, playlist, dock, parent=None): super().__init__(parent) self.playlist = playlist self.library_dock = dock self.app = playlist.app playlist.views[id(dock)] = self self.setDragDropMode(QAbstractItemView.DragDropMode.InternalMove) self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) self.setColumnCount(4) self.playing_mark = QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackStart) headers = [ "#", "Title", "Artist", "Album", "# Custom Sorting" ] self.setHeaderLabels(headers) self.itemActivated.connect(self.on_track_activation) def on_user_sort(self): num_tracks = self.topLevelItemCount() i = 0 while i < num_tracks: track_item = self.topLevelItem(i) track = track_item.track track_item.index_user_sort = i track_item.index = i track_item.setText(5, str(i + 1)) self.playlist.tracks[i] = track track.set_occurrences() i += 1 if self.app.player.current_playlist.has_tracks(): self.app.player.cache_next_track() def dropEvent(self, event: QDropEvent): # receive items that were dropped and create new items from its tracks (new items bc. widgets can only have # one parent) if event.source() == self: items = self.selectedItems() # dragged items are always selected items self.itemDropped.emit(self, items) else: items = self.app.gui.dropped i = 0 for item in items: track = item.track self.playlist.tracks.append(track) track_item = TrackItem(track, i, self) i += 1 super().dropEvent(event) event.accept() self.on_user_sort() def dragEnterEvent(self, event): # store dragged items in gui.dropped, so the other playlist can receive it if event.source() == self: items = self.selectedItems() self.app.gui.dropped = items super().dragEnterEvent(event) event.accept() def load_tracks(self): i = 0 for track in self.playlist.tracks: track_item = TrackItem(track, i, self) i += 1 def on_track_activation(self, item, column): if not self.app.player.current_playlist == self.playlist: self.app.player.current_playlist = self.playlist index = self.indexOfTopLevelItem(item) self.app.player.play_track_in_playlist(index) def on_track_change(self, previous_track, track): # unmark the previous track and playlist and mark the current track and playlist as playing playlist_tabs = self.parent().parent() index = playlist_tabs.indexOf(self) # tab index of this playlist if previous_track: # unmark all playlists by looping through the tabs for i in range(playlist_tabs.count()): playlist_tabs.setTabIcon(i, QIcon(None)) # unmark the previous track in all playlists for item in previous_track.items: item.setIcon(0, QIcon(None)) item.setFont(1, self.normal_font) item.setFont(2, self.normal_font) item.setFont(3, self.normal_font) if track: playlist_tabs.setTabIcon(index, self.playing_mark) # mark this playlist # mark the current track in this playlist item = self.topLevelItem(self.app.player.current_playlist.current_track_index) item.setIcon(0, self.playing_mark) item.setFont(1, self.bold_font) item.setFont(2, self.bold_font) item.setFont(3, self.normal_font) def append_track(self, track): TrackItem(track, self.topLevelItemCount() - 1, self)