WIP
This commit is contained in:
@@ -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):
|
||||
|
@@ -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):
|
||||
|
Reference in New Issue
Block a user