This commit is contained in:
Benjamin Schaaf
2022-01-09 19:24:03 +11:00
parent 6a68cd1c99
commit 5ce4f1c944
2 changed files with 91 additions and 86 deletions

View File

@@ -802,7 +802,7 @@ class SublimeMusicApp(Gtk.Application):
def go_to_playlist(self, playlist_id: str):
self.app_config.state.current_tab = "playlists"
self.app_config.state.selected_playlist_id = playlist_id
self.app_config.state.selected_playlist_id = playlist_id or None
self.update_window()
def on_go_online(self, *args):

View File

@@ -8,77 +8,124 @@ from gi.repository import Gdk, Gio, GLib, GObject, Gtk, Pango, Handy
from ..adapters import AdapterManager, api_objects as API
from ..config import AppConfiguration
from ..ui import util
from ..ui.common import (
from . import util
from .common import (
IconButton,
LoadError,
SongListColumn,
SpinnerImage,
Sizer,
)
from .actions import run_action
class EditPlaylistDialog(Gtk.Dialog):
def __init__(self, parent: Any, playlist: API.Playlist):
Gtk.Dialog.__init__(self, transient_for=parent, flags=Gtk.DialogFlags.MODAL)
class EditPlaylistWindow(Handy.Window):
def __init__(self, main_window: Any, playlist: API.Playlist):
Handy.Window.__init__(
self,
modal=True,
window_position=Gtk.WindowPosition.CENTER_ON_PARENT,
destroy_with_parent=True,
type_hint=Gdk.WindowTypeHint.DIALOG,
default_width=640,
default_height=576)
self.main_window = main_window
self.playlist = playlist
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
# HEADER
self.header = Gtk.HeaderBar()
self.header_bar = Handy.HeaderBar()
self._set_title(playlist.name)
cancel_button = Gtk.Button(label="Cancel")
cancel_button.connect("clicked", lambda _: self.close())
self.header.pack_start(cancel_button)
self.header_bar.pack_start(cancel_button)
self.edit_button = Gtk.Button(label="Edit")
self.edit_button.get_style_context().add_class("suggested-action")
self.edit_button.connect(
"clicked", lambda *a: self.response(Gtk.ResponseType.APPLY)
)
self.header.pack_end(self.edit_button)
self.save_button = Gtk.Button(label="Save")
self.save_button.get_style_context().add_class("suggested-action")
self.save_button.connect("clicked", self._on_save_clicked)
self.header_bar.pack_end(self.save_button)
self.set_titlebar(self.header)
box.add(self.header_bar)
content_area = self.get_content_area()
content_grid = Gtk.Grid(column_spacing=10, row_spacing=10, margin=10)
clamp = Handy.Clamp(margin=12)
make_label = lambda label_text: Gtk.Label(label_text, halign=Gtk.Align.END)
inner_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
content_grid.attach(make_label("Playlist Name"), 0, 0, 1, 1)
self.name_entry = Gtk.Entry(text=playlist.name, hexpand=True)
list_box = Gtk.ListBox()
list_box.get_style_context().add_class('content')
row = Handy.ActionRow(title="Playlist Name")
self.name_entry = Gtk.Entry(valign=Gtk.Align.CENTER, text=(playlist.name or ''))
self.name_entry.connect("changed", self._on_name_change)
content_grid.attach(self.name_entry, 1, 0, 1, 1)
row.add(self.name_entry)
list_box.add(row)
content_grid.attach(make_label("Comment"), 0, 1, 1, 1)
self.comment_entry = Gtk.Entry(text=playlist.comment, hexpand=True)
content_grid.attach(self.comment_entry, 1, 1, 1, 1)
row = Handy.ActionRow(title="Comment")
self.comment_entry = Gtk.Entry(valign=Gtk.Align.CENTER, text=(playlist.comment or ''))
row.add(self.comment_entry)
list_box.add(row)
content_grid.attach(make_label("Public"), 0, 2, 1, 1)
self.public_switch = Gtk.Switch(active=playlist.public, halign=Gtk.Align.START)
content_grid.attach(self.public_switch, 1, 2, 1, 1)
row = Handy.ActionRow(title="Public")
self.public_switch = Gtk.Switch(valign=Gtk.Align.CENTER, active=playlist.public)
row.add(self.public_switch)
list_box.add(row)
delete_button = Gtk.Button(label="Delete")
delete_button.connect("clicked", lambda *a: self.response(Gtk.ResponseType.NO))
content_grid.attach(delete_button, 0, 3, 1, 2)
inner_box.add(list_box)
content_area.add(content_grid)
self.show_all()
delete_button = IconButton(label="Delete", icon_name="user-trash-symbolic", relief=True, halign=Gtk.Align.END)
delete_button.get_style_context().add_class('destructive-action')
delete_button.connect('clicked', self._on_delete_clicked)
inner_box.pack_start(delete_button, False, False, 10)
clamp.add(inner_box)
box.add(clamp)
self.add(box)
def _on_delete_clicked(self, *_):
# Confirm
confirm_dialog = Gtk.MessageDialog(
transient_for=self,
message_type=Gtk.MessageType.WARNING,
buttons=Gtk.ButtonsType.NONE,
text="Confirm deletion",
)
confirm_dialog.add_buttons(
Gtk.STOCK_CANCEL,
Gtk.ResponseType.CANCEL,
Gtk.STOCK_DELETE,
Gtk.ResponseType.YES,
)
confirm_dialog.format_secondary_markup(
f'Are you sure you want to delete the "{self.playlist.name}" playlist?'
)
result = confirm_dialog.run()
confirm_dialog.destroy()
if result == Gtk.ResponseType.YES:
AdapterManager.delete_playlist(self.playlist.id)
run_action(self.main_window, 'app.go-to-playlist', '')
self.close()
def _on_save_clicked(self, *_):
AdapterManager.update_playlist(
self.playlist.id,
name=self.name_entry.get_text(),
comment=self.comment_entry.get_text(),
public=self.public_switch.get_active())
run_action(self.main_window, 'app.refresh')
self.close()
def _on_name_change(self, entry: Gtk.Entry):
text = entry.get_text()
if len(text) > 0:
self._set_title(text)
self.edit_button.set_sensitive(len(text) > 0)
self.save_button.set_sensitive(len(text) > 0)
def _set_title(self, playlist_name: str):
self.header.props.title = f"Edit {playlist_name}"
def get_data(self) -> Dict[str, Any]:
return {
"name": self.name_entry.get_text(),
"comment": self.comment_entry.get_text(),
"public": self.public_switch.get_active(),
}
self.header_bar.props.title = f"Edit {playlist_name}"
class PlaylistsPanel(Handy.Leaflet):
@@ -702,52 +749,10 @@ class PlaylistDetailPanel(Gtk.Overlay):
def on_playlist_edit_button_click(self, _):
assert self.playlist_id
playlist = AdapterManager.get_playlist_details(self.playlist_id).result()
dialog = EditPlaylistDialog(self.get_toplevel(), playlist)
playlist_deleted = False
window = EditPlaylistWindow(self.get_toplevel(), playlist)
result = dialog.run()
# Using ResponseType.NO as the delete event.
if result not in (Gtk.ResponseType.APPLY, Gtk.ResponseType.NO):
dialog.destroy()
return
if result == Gtk.ResponseType.APPLY:
AdapterManager.update_playlist(self.playlist_id, **dialog.get_data())
elif result == Gtk.ResponseType.NO:
# Delete the playlist.
confirm_dialog = Gtk.MessageDialog(
transient_for=self.get_toplevel(),
message_type=Gtk.MessageType.WARNING,
buttons=Gtk.ButtonsType.NONE,
text="Confirm deletion",
)
confirm_dialog.add_buttons(
Gtk.STOCK_DELETE,
Gtk.ResponseType.YES,
Gtk.STOCK_CANCEL,
Gtk.ResponseType.CANCEL,
)
confirm_dialog.format_secondary_markup(
f'Are you sure you want to delete the "{playlist.name}" playlist?'
)
result = confirm_dialog.run()
confirm_dialog.destroy()
if result == Gtk.ResponseType.YES:
AdapterManager.delete_playlist(self.playlist_id)
playlist_deleted = True
else:
# In this case, we don't want to do any invalidation of
# anything.
dialog.destroy()
return
# Force a re-fresh of the view
self.emit(
"refresh-window",
{"selected_playlist_id": None if playlist_deleted else self.playlist_id},
True,
)
dialog.destroy()
window.set_transient_for(self.get_toplevel())
window.show_all()
def on_playlist_list_download_all_button_click(self, _):
def download_state_change(song_id: str):