Implemented saving of the sortorder to the .wbz.m3u
This commit is contained in:
parent
894b3d213a
commit
78b60dba02
3 changed files with 68 additions and 4 deletions
|
@ -134,7 +134,63 @@ class Playlist:
|
||||||
self.app.gui.on_background_job_stop(process_title)
|
self.app.gui.on_background_job_stop(process_title)
|
||||||
|
|
||||||
def load_from_wbz(self, path):
|
def load_from_wbz(self, path):
|
||||||
self.load_from_m3u(path) # placeholder
|
file = open(path, "r")
|
||||||
|
m3u = file.read()
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
lines = m3u.split("\n") # m3u entries are separated by newlines
|
||||||
|
lines = lines[:-1] # remove last entry because it is just an empty string
|
||||||
|
|
||||||
|
num_lines = len(lines)
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
|
||||||
|
process_title = f'Loading Playlist "{self.title}"'
|
||||||
|
|
||||||
|
self.app.gui.on_background_job_start(
|
||||||
|
process_title,
|
||||||
|
f'Loading the tracks of "{self.title}".',
|
||||||
|
num_lines,
|
||||||
|
lambda: i
|
||||||
|
)
|
||||||
|
|
||||||
|
while i < num_lines:
|
||||||
|
line = lines[i]
|
||||||
|
|
||||||
|
if line.startswith("#"): # comments and EXTM3U/WOBUZZM3U
|
||||||
|
if line.startswith("#SORT: "): # sort
|
||||||
|
sort_line = line[6:] # delete "#SORT: " from the line
|
||||||
|
|
||||||
|
sorting = sort_line.split(", ") # split into the sort column specifier and the sort order
|
||||||
|
# e.g. ["0", "True"]
|
||||||
|
|
||||||
|
del self.sorting[0] # delete first sort so the length stays at 6
|
||||||
|
|
||||||
|
# convert these from strings back to int and bool and append them to the sorting
|
||||||
|
self.sorting.append((int(sorting[0]), sorting[1] == "True"))
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
elif line.startswith("http"): # filter out urls
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
continue
|
||||||
|
|
||||||
|
self.append_track(Track(self.app, line, cache=i == 0)) # first track is cached
|
||||||
|
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
# set current track to the first track if there is no currently playing track
|
||||||
|
if self.current_track is None and self.has_tracks():
|
||||||
|
self.current_track = self.tracks[0]
|
||||||
|
|
||||||
|
list(self.views.values())[0].sort() # execute sort() on the first view
|
||||||
|
|
||||||
|
self.loaded = True
|
||||||
|
|
||||||
|
self.app.gui.on_background_job_stop(process_title)
|
||||||
|
|
||||||
def sync(self, view, user_sort: bool=False):
|
def sync(self, view, user_sort: bool=False):
|
||||||
num_tracks = view.topLevelItemCount()
|
num_tracks = view.topLevelItemCount()
|
||||||
|
@ -206,7 +262,10 @@ class Playlist:
|
||||||
first_view.sortItems(4, Qt.SortOrder.AscendingOrder)
|
first_view.sortItems(4, Qt.SortOrder.AscendingOrder)
|
||||||
self.sync(first_view)
|
self.sync(first_view)
|
||||||
|
|
||||||
wbz_data = "#WOBUZZM3U\n"
|
wbz_data = "#WOBUZZM3U\n" # header
|
||||||
|
|
||||||
|
for sort_column, order in self.sorting:
|
||||||
|
wbz_data += f"#SORT: {sort_column}, {order}\n"
|
||||||
|
|
||||||
for track in self.tracks:
|
for track in self.tracks:
|
||||||
wbz_data += f"{track.path}\n"
|
wbz_data += f"{track.path}\n"
|
||||||
|
|
|
@ -67,7 +67,7 @@ class Track:
|
||||||
|
|
||||||
self.duration = len(self.audio) # track duration in milliseconds
|
self.duration = len(self.audio) # track duration in milliseconds
|
||||||
|
|
||||||
self.tags = TinyTag.get(self.path, ignore_errors=True, duration=False, image=True) # metadata with images
|
self.tags = TinyTag.get(self.path, ignore_errors=True, duration=False, image=True) # metadata with images
|
||||||
|
|
||||||
self.cached = True
|
self.cached = True
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ from .track import TrackItem
|
||||||
|
|
||||||
class PlaylistView(QTreeWidget):
|
class PlaylistView(QTreeWidget):
|
||||||
itemDropped = pyqtSignal(QTreeWidget, list)
|
itemDropped = pyqtSignal(QTreeWidget, list)
|
||||||
|
sort_signal = pyqtSignal(int, Qt.SortOrder)
|
||||||
|
|
||||||
playing_mark = QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackStart)
|
playing_mark = QIcon.fromTheme(QIcon.ThemeIcon.MediaPlaybackStart)
|
||||||
|
|
||||||
|
@ -42,6 +43,7 @@ class PlaylistView(QTreeWidget):
|
||||||
|
|
||||||
self.itemActivated.connect(self.on_track_activation)
|
self.itemActivated.connect(self.on_track_activation)
|
||||||
self.header.sectionClicked.connect(self.on_header_click)
|
self.header.sectionClicked.connect(self.on_header_click)
|
||||||
|
self.sort_signal.connect(self.sortItems)
|
||||||
|
|
||||||
def on_header_click(self, section_index: int):
|
def on_header_click(self, section_index: int):
|
||||||
if section_index == 0: # this would just invert the current sorting
|
if section_index == 0: # this would just invert the current sorting
|
||||||
|
@ -73,7 +75,10 @@ class PlaylistView(QTreeWidget):
|
||||||
# convert True/False to Qt.SortOrder.AscendingOrder/Qt.SortOrder.DescendingOrder
|
# convert True/False to Qt.SortOrder.AscendingOrder/Qt.SortOrder.DescendingOrder
|
||||||
qorder = Qt.SortOrder.AscendingOrder if order else Qt.SortOrder.DescendingOrder
|
qorder = Qt.SortOrder.AscendingOrder if order else Qt.SortOrder.DescendingOrder
|
||||||
|
|
||||||
self.sortItems(index, qorder)
|
# somehow, QTreeWidget.sortItems() cant be called from a thread, so we have to use a signal to execute it
|
||||||
|
# in the main thread
|
||||||
|
self.sort_signal.emit(index, qorder)
|
||||||
|
# self.sortItems(index, qorder)
|
||||||
|
|
||||||
self.on_sort()
|
self.on_sort()
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue