From a9f07f071679a51447f89520a862d6c8aa1740d8 Mon Sep 17 00:00:00 2001 From: The Wobbler Date: Fri, 28 Feb 2025 17:28:14 +0100 Subject: [PATCH] Implemented loading of tracks via the window's top menubar. --- wobuzz/command_line.py | 14 ++--------- wobuzz/gui.py | 24 +++++++++++++++--- wobuzz/library/library.py | 28 +++++++++++++++++++-- wobuzz/player/playlist.py | 17 ++++++++++--- wobuzz/ui/main_window.py | 8 +++++- wobuzz/ui/playlist.py | 2 +- wobuzz/ui/playlist_tabs/tab_context_menu.py | 2 -- wobuzz/ui/playlist_tabs/tab_widget.py | 6 ++--- 8 files changed, 73 insertions(+), 28 deletions(-) diff --git a/wobuzz/command_line.py b/wobuzz/command_line.py index 5b97b3a..71925fc 100644 --- a/wobuzz/command_line.py +++ b/wobuzz/command_line.py @@ -24,20 +24,10 @@ def main(): if arguments.playlist: playlist = Playlist(app, "Temporary Playlist", arguments.playlist) - app.library.playlists.append(playlist) - - if app.library.temporary_playlist in app.library.playlists: - app.library.playlists.remove(app.library.temporary_playlist) - app.library.temporary_playlist = playlist + app.library.replace_temporary_playlist(playlist) if arguments.track: - playlist = Playlist(app, "Temporary Playlist", arguments.track) - - app.library.playlists.append(playlist) - - if app.library.temporary_playlist in app.library.playlists: - app.library.playlists.remove(app.library.temporary_playlist) - app.library.temporary_playlist = playlist + app.library.open_tracks(arguments.track) app.library.load_playlist_views() diff --git a/wobuzz/gui.py b/wobuzz/gui.py index 4ab74ae..8712c61 100644 --- a/wobuzz/gui.py +++ b/wobuzz/gui.py @@ -1,7 +1,7 @@ #!/usr/bin/python3 from PyQt6.QtCore import Qt -from PyQt6.QtWidgets import QDockWidget +from PyQt6.QtWidgets import QDockWidget, QFileDialog from .ui.main_window import MainWindow @@ -11,7 +11,7 @@ class GUI: self.dropped = [] - self.window = MainWindow(app) + self.window = MainWindow(app, self) self.settings = self.window.settings self.track_control = self.window.track_control self.process_dock = self.window.process_dock @@ -27,9 +27,14 @@ class GUI: if self.app.settings.window_maximized: self.window.showMaximized() - elif not self.app.settings.window_size is None: + elif self.app.settings.window_size is not None: self.window.resize(*self.app.settings.window_size) + self.audio_file_selector = QFileDialog(self.window, "Select Audio File") + self.audio_file_selector.setFileMode(QFileDialog.FileMode.ExistingFiles) + self.audio_file_selector.setNameFilters(["Audio Files (*.flac *.wav *.mp3 *.ogg *.opus)", "Any (*)"]) + self.audio_file_selector.setViewMode(QFileDialog.ViewMode.List) + self.connect() self.window.show() @@ -67,3 +72,16 @@ class GUI: self.track_control.on_playstate_update() self.track_info.update_info() + def select_audio_files(self): + if self.audio_file_selector.exec(): + return self.audio_file_selector.selectedFiles() + + def open_tracks(self): + files = self.select_audio_files() + + if files is not None and not files == []: + self.app.library.open_tracks(files) + + def import_tracks(self): + self.open_tracks() # placeholder + diff --git a/wobuzz/library/library.py b/wobuzz/library/library.py index 9bc3c9b..549bdce 100644 --- a/wobuzz/library/library.py +++ b/wobuzz/library/library.py @@ -47,12 +47,16 @@ class Library: self.temporary_playlist = playlist def load_playlist_views(self): + # create views for each dock and playlist + for library_dock in self.library_docks: playlist_tabs: QTabWidget = library_dock.library_widget.playlist_tabs - playlist_tabs.playlists = {} - + # create view for each playlist for playlist in self.playlists: + if id(library_dock) in playlist.views: # view already exists + continue + playlist_view = PlaylistView(playlist, library_dock) playlist_tabs.addTab(playlist_view, playlist.title) @@ -87,3 +91,23 @@ class Library: playlist_tabs.addTab(playlist_view, playlist.title) + def replace_temporary_playlist(self, replace: Playlist): + self.temporary_playlist.delete() + + if self.temporary_playlist in self.playlists: + self.playlists.remove(self.temporary_playlist) + + if not replace in self.playlists: + self.playlists.append(replace) + + self.temporary_playlist = replace + + def open_tracks(self, tracks: list[str]): + playlist = Playlist(self.app, "Temporary Playlist", tracks) + + self.replace_temporary_playlist(playlist) + + self.load_playlist_views() + + playlist.load() + diff --git a/wobuzz/player/playlist.py b/wobuzz/player/playlist.py index c2ca4c7..f52af29 100644 --- a/wobuzz/player/playlist.py +++ b/wobuzz/player/playlist.py @@ -36,6 +36,7 @@ class Playlist: self.current_track: Track | None = None self.views = {} # dict of id(LibraryDock): PlaylistView self.loaded = False + self.loading = False self.path = os.path.expanduser( f"{app.settings.library_path}/playlists/{self.title.replace(" ", "_")}.wbz.m3u" @@ -78,9 +79,11 @@ class Playlist: loading_thread.start() def loading_thread(self): - if self.loaded: + if self.loaded or self.loading: return + self.loading = True + if self.load_from is None: # if the playlist is in the library self.load_from_wbz(self.path) @@ -90,6 +93,8 @@ class Playlist: elif isinstance(self.load_from, list): # if it's created from tracks self.load_from_paths(self.load_from) + self.loading = False + for dock_id in self.views: # enable drag and drop on every view view = self.views[dock_id] @@ -297,13 +302,16 @@ class Playlist: if os.path.exists(self.path): os.remove(self.path) - self.app.utils.unique_names.remove(self.title) - self.app.library.playlists.remove(self) - if self.app.player.current_playlist == self: # stop if this is the current playlist self.app.player.stop() self.app.player.current_playlist = None + for view in self.views.values(): # close views (and PyQt automatically closes the corresponding tabs) + view.deleteLater() + + self.app.utils.unique_names.remove(self.title) + self.app.library.playlists.remove(self) + def append_track(self, track): for dock_id in self.views: view = self.views[dock_id] @@ -316,3 +324,4 @@ class Playlist: if len(self.tracks) > 1: return self.tracks[-2] + diff --git a/wobuzz/ui/main_window.py b/wobuzz/ui/main_window.py index a430be0..53b5be6 100644 --- a/wobuzz/ui/main_window.py +++ b/wobuzz/ui/main_window.py @@ -10,10 +10,11 @@ from .track_info import TrackInfo class MainWindow(QMainWindow): - def __init__(self, app, parent=None): + def __init__(self, app, gui, parent=None): super().__init__(parent) self.app = app + self.gui = gui self.icon = QIcon(f"{self.app.utils.wobuzz_location}/icon.svg") @@ -25,6 +26,9 @@ class MainWindow(QMainWindow): self.file_menu = QMenu("&File", self.menu_bar) self.menu_bar.addMenu(self.file_menu) + self.open_track_action = self.file_menu.addAction("&Open Tracks") + self.import_track_action = self.file_menu.addAction("&Import Track") + self.edit_menu = QMenu("&Edit", self.menu_bar) self.menu_bar.addMenu(self.edit_menu) @@ -51,4 +55,6 @@ class MainWindow(QMainWindow): self.settings_action.triggered.connect(self.settings.show) self.processes_action.triggered.connect(self.process_dock.show) + self.open_track_action.triggered.connect(self.gui.open_tracks) + self.import_track_action.triggered.connect(self.gui.import_tracks) diff --git a/wobuzz/ui/playlist.py b/wobuzz/ui/playlist.py index 7484215..76ff343 100644 --- a/wobuzz/ui/playlist.py +++ b/wobuzz/ui/playlist.py @@ -25,7 +25,7 @@ class PlaylistView(QTreeWidget): self.header.setSectionsClickable(True) self.header.setSortIndicatorShown(True) - playlist.views[id(dock)] = self + playlist.views[id(dock)] = self # let the playlist know that this view exists self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection) diff --git a/wobuzz/ui/playlist_tabs/tab_context_menu.py b/wobuzz/ui/playlist_tabs/tab_context_menu.py index 6e285a2..12ec0df 100644 --- a/wobuzz/ui/playlist_tabs/tab_context_menu.py +++ b/wobuzz/ui/playlist_tabs/tab_context_menu.py @@ -36,5 +36,3 @@ class PlaylistContextMenu(QMenu): def delete(self): self.playlist_title.playlist_view.playlist.delete() - self.playlist_title.playlist_view.deleteLater() - diff --git a/wobuzz/ui/playlist_tabs/tab_widget.py b/wobuzz/ui/playlist_tabs/tab_widget.py index 9eb286e..afdb04b 100644 --- a/wobuzz/ui/playlist_tabs/tab_widget.py +++ b/wobuzz/ui/playlist_tabs/tab_widget.py @@ -20,12 +20,12 @@ class PlaylistTabs(QTabWidget): self.setMovable(True) self.setAcceptDrops(True) - def addTab(self, widget, label): - super().addTab(widget, None) + def addTab(self, playlist_view, label): + super().addTab(playlist_view, None) index = self.tab_bar.count() - 1 - title = TabTitle(self.app, label, self.tab_bar, index, widget) + title = TabTitle(self.app, label, self.tab_bar, index, playlist_view) self.tab_bar.setTabButton(index, QTabBar.ButtonPosition.RightSide, title)