mirror of
https://github.com/SoongNoonien/mpdevil.git
synced 2023-08-10 21:12:44 +03:00
reworked playlist
This commit is contained in:
parent
e72ccd6c9a
commit
532e93bf8b
|
@ -92,18 +92,6 @@
|
||||||
<default>false</default>
|
<default>false</default>
|
||||||
<summary>Classic previous button behavior</summary>
|
<summary>Classic previous button behavior</summary>
|
||||||
</key>
|
</key>
|
||||||
<key type="ai" name="column-permutation">
|
|
||||||
<default>[0, 1, 2, 3, 4, 5, 6, 7]</default>
|
|
||||||
<summary>Column order in playlist</summary>
|
|
||||||
</key>
|
|
||||||
<key type="ab" name="column-visibilities">
|
|
||||||
<default>[true, false, true, true, true, true, false, false]</default>
|
|
||||||
<summary>Visibility of columns in playlist</summary>
|
|
||||||
</key>
|
|
||||||
<key type="ai" name="column-sizes">
|
|
||||||
<default>[33, 0, 217, 173, 186, 0, 0, 0]</default>
|
|
||||||
<summary>Sizes of columns in playlist</summary>
|
|
||||||
</key>
|
|
||||||
<key type="b" name="playlist-right">
|
<key type="b" name="playlist-right">
|
||||||
<default>false</default>
|
<default>false</default>
|
||||||
<summary>Move playlist to the right</summary>
|
<summary>Move playlist to the right</summary>
|
||||||
|
|
231
src/mpdevil.py
231
src/mpdevil.py
|
@ -969,21 +969,6 @@ class Settings(Gio.Settings):
|
||||||
super().__init__(schema=self.BASE_KEY)
|
super().__init__(schema=self.BASE_KEY)
|
||||||
self._profiles=(self.get_child("profile1"), self.get_child("profile2"), self.get_child("profile3"))
|
self._profiles=(self.get_child("profile1"), self.get_child("profile2"), self.get_child("profile3"))
|
||||||
|
|
||||||
def array_append(self, vtype, key, value): # append to Gio.Settings array
|
|
||||||
array=self.get_value(key).unpack()
|
|
||||||
array.append(value)
|
|
||||||
self.set_value(key, GLib.Variant(vtype, array))
|
|
||||||
|
|
||||||
def array_delete(self, vtype, key, pos): # delete entry of Gio.Settings array
|
|
||||||
array=self.get_value(key).unpack()
|
|
||||||
array.pop(pos)
|
|
||||||
self.set_value(key, GLib.Variant(vtype, array))
|
|
||||||
|
|
||||||
def array_modify(self, vtype, key, pos, value): # modify entry of Gio.Settings array
|
|
||||||
array=self.get_value(key).unpack()
|
|
||||||
array[pos]=value
|
|
||||||
self.set_value(key, GLib.Variant(vtype, array))
|
|
||||||
|
|
||||||
def get_profile(self, num):
|
def get_profile(self, num):
|
||||||
return self._profiles[num]
|
return self._profiles[num]
|
||||||
|
|
||||||
|
@ -1197,109 +1182,6 @@ class ProfileSettings(Gtk.Box):
|
||||||
else:
|
else:
|
||||||
self._settings.set_int("active-profile", selected)
|
self._settings.set_int("active-profile", selected)
|
||||||
|
|
||||||
class PlaylistSettings(Gtk.Box):
|
|
||||||
def __init__(self, settings):
|
|
||||||
super().__init__(orientation=Gtk.Orientation.VERTICAL, spacing=6, border_width=18)
|
|
||||||
self._settings=settings
|
|
||||||
|
|
||||||
# label
|
|
||||||
label=Gtk.Label(label=_("Choose the order of information to appear in the playlist:"), wrap=True, xalign=0)
|
|
||||||
|
|
||||||
# treeview
|
|
||||||
# (toggle, header, actual_index)
|
|
||||||
self._store=Gtk.ListStore(bool, str, int)
|
|
||||||
treeview=Gtk.TreeView(model=self._store, reorderable=True, headers_visible=False, search_column=-1)
|
|
||||||
self._selection=treeview.get_selection()
|
|
||||||
|
|
||||||
# columns
|
|
||||||
renderer_text=Gtk.CellRendererText()
|
|
||||||
renderer_toggle=Gtk.CellRendererToggle()
|
|
||||||
column_toggle=Gtk.TreeViewColumn("", renderer_toggle, active=0)
|
|
||||||
treeview.append_column(column_toggle)
|
|
||||||
column_text=Gtk.TreeViewColumn("", renderer_text, text=1)
|
|
||||||
treeview.append_column(column_text)
|
|
||||||
|
|
||||||
# fill store
|
|
||||||
self._headers=[_("No"), _("Disc"), _("Title"), _("Artist"), _("Album"), _("Length"), _("Year"), _("Genre")]
|
|
||||||
self._fill()
|
|
||||||
|
|
||||||
# scroll
|
|
||||||
scroll=Gtk.ScrolledWindow(child=treeview)
|
|
||||||
|
|
||||||
# toolbar
|
|
||||||
toolbar=Gtk.Toolbar(icon_size=Gtk.IconSize.SMALL_TOOLBAR)
|
|
||||||
toolbar.get_style_context().add_class("inline-toolbar")
|
|
||||||
self._up_button=Gtk.ToolButton(icon_name="go-up-symbolic", sensitive=False)
|
|
||||||
self._down_button=Gtk.ToolButton(icon_name="go-down-symbolic", sensitive=False)
|
|
||||||
toolbar.insert(self._up_button, 0)
|
|
||||||
toolbar.insert(self._down_button, 1)
|
|
||||||
|
|
||||||
# column chooser
|
|
||||||
frame=Gtk.Frame(child=scroll)
|
|
||||||
column_chooser=Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
|
||||||
column_chooser.pack_start(frame, True, True, 0)
|
|
||||||
column_chooser.pack_start(toolbar, False, False, 0)
|
|
||||||
|
|
||||||
# connect
|
|
||||||
self._row_deleted=self._store.connect("row-deleted", self._save_permutation)
|
|
||||||
renderer_toggle.connect("toggled", self._on_cell_toggled)
|
|
||||||
self._up_button.connect("clicked", self._on_up_button_clicked)
|
|
||||||
self._down_button.connect("clicked", self._on_down_button_clicked)
|
|
||||||
self._selection.connect("changed", self._set_button_sensitivity)
|
|
||||||
|
|
||||||
# packing
|
|
||||||
self.pack_start(label, False, False, 0)
|
|
||||||
self.pack_start(column_chooser, True, True, 0)
|
|
||||||
|
|
||||||
def _fill(self, *args):
|
|
||||||
visibilities=self._settings.get_value("column-visibilities").unpack()
|
|
||||||
for actual_index in self._settings.get_value("column-permutation"):
|
|
||||||
self._store.append([visibilities[actual_index], self._headers[actual_index], actual_index])
|
|
||||||
|
|
||||||
def _save_permutation(self, *args):
|
|
||||||
permutation=[]
|
|
||||||
for row in self._store:
|
|
||||||
permutation.append(row[2])
|
|
||||||
self._settings.set_value("column-permutation", GLib.Variant("ai", permutation))
|
|
||||||
|
|
||||||
def _set_button_sensitivity(self, *args):
|
|
||||||
treeiter=self._selection.get_selected()[1]
|
|
||||||
if treeiter is None:
|
|
||||||
self._up_button.set_sensitive(False)
|
|
||||||
self._down_button.set_sensitive(False)
|
|
||||||
else:
|
|
||||||
path=self._store.get_path(treeiter)
|
|
||||||
if self._store.iter_next(treeiter) is None:
|
|
||||||
self._up_button.set_sensitive(True)
|
|
||||||
self._down_button.set_sensitive(False)
|
|
||||||
elif not path.prev():
|
|
||||||
self._up_button.set_sensitive(False)
|
|
||||||
self._down_button.set_sensitive(True)
|
|
||||||
else:
|
|
||||||
self._up_button.set_sensitive(True)
|
|
||||||
self._down_button.set_sensitive(True)
|
|
||||||
|
|
||||||
def _on_cell_toggled(self, widget, path):
|
|
||||||
self._store[path][0]=not self._store[path][0]
|
|
||||||
self._settings.array_modify("ab", "column-visibilities", self._store[path][2], self._store[path][0])
|
|
||||||
|
|
||||||
def _on_up_button_clicked(self, *args):
|
|
||||||
treeiter=self._selection.get_selected()[1]
|
|
||||||
path=self._store.get_path(treeiter)
|
|
||||||
path.prev()
|
|
||||||
prev=self._store.get_iter(path)
|
|
||||||
self._store.move_before(treeiter, prev)
|
|
||||||
self._set_button_sensitivity()
|
|
||||||
self._save_permutation()
|
|
||||||
|
|
||||||
def _on_down_button_clicked(self, *args):
|
|
||||||
treeiter=self._selection.get_selected()[1]
|
|
||||||
path=self._store.get_path(treeiter)
|
|
||||||
next=self._store.iter_next(treeiter)
|
|
||||||
self._store.move_after(treeiter, next)
|
|
||||||
self._set_button_sensitivity()
|
|
||||||
self._save_permutation()
|
|
||||||
|
|
||||||
class SettingsDialog(Gtk.Dialog):
|
class SettingsDialog(Gtk.Dialog):
|
||||||
def __init__(self, parent, client, settings, tab="view"):
|
def __init__(self, parent, client, settings, tab="view"):
|
||||||
use_csd=settings.get_boolean("use-csd")
|
use_csd=settings.get_boolean("use-csd")
|
||||||
|
@ -1314,7 +1196,6 @@ class SettingsDialog(Gtk.Dialog):
|
||||||
view=ViewSettings(settings)
|
view=ViewSettings(settings)
|
||||||
behavior=BehaviorSettings(settings)
|
behavior=BehaviorSettings(settings)
|
||||||
profiles=ProfileSettings(parent, client, settings)
|
profiles=ProfileSettings(parent, client, settings)
|
||||||
playlist=PlaylistSettings(settings)
|
|
||||||
|
|
||||||
# packing
|
# packing
|
||||||
vbox=self.get_content_area()
|
vbox=self.get_content_area()
|
||||||
|
@ -1322,7 +1203,6 @@ class SettingsDialog(Gtk.Dialog):
|
||||||
stack=Gtk.Stack(transition_type=Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
|
stack=Gtk.Stack(transition_type=Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
|
||||||
stack.add_titled(view, "view", _("View"))
|
stack.add_titled(view, "view", _("View"))
|
||||||
stack.add_titled(behavior, "behavior", _("Behavior"))
|
stack.add_titled(behavior, "behavior", _("Behavior"))
|
||||||
stack.add_titled(playlist, "playlist", _("Playlist"))
|
|
||||||
stack.add_titled(profiles, "profiles", _("Profiles"))
|
stack.add_titled(profiles, "profiles", _("Profiles"))
|
||||||
stack_switcher=Gtk.StackSwitcher(stack=stack)
|
stack_switcher=Gtk.StackSwitcher(stack=stack)
|
||||||
vbox.set_property("border-width", 0)
|
vbox.set_property("border-width", 0)
|
||||||
|
@ -1333,7 +1213,6 @@ class SettingsDialog(Gtk.Dialog):
|
||||||
tabs=Gtk.Notebook()
|
tabs=Gtk.Notebook()
|
||||||
tabs.append_page(view, Gtk.Label(label=_("View")))
|
tabs.append_page(view, Gtk.Label(label=_("View")))
|
||||||
tabs.append_page(behavior, Gtk.Label(label=_("Behavior")))
|
tabs.append_page(behavior, Gtk.Label(label=_("Behavior")))
|
||||||
tabs.append_page(playlist, Gtk.Label(label=_("Playlist")))
|
|
||||||
tabs.append_page(profiles, Gtk.Label(label=_("Profiles")))
|
tabs.append_page(profiles, Gtk.Label(label=_("Profiles")))
|
||||||
vbox.set_property("spacing", 6)
|
vbox.set_property("spacing", 6)
|
||||||
vbox.set_property("border-width", 6)
|
vbox.set_property("border-width", 6)
|
||||||
|
@ -1342,7 +1221,7 @@ class SettingsDialog(Gtk.Dialog):
|
||||||
if use_csd:
|
if use_csd:
|
||||||
stack.set_visible_child_name(tab)
|
stack.set_visible_child_name(tab)
|
||||||
else:
|
else:
|
||||||
tabs.set_current_page({"view": 0, "behavior": 1, "playlist": 2, "profiles": 3}[tab])
|
tabs.set_current_page({"view": 0, "behavior": 1, "profiles": 2}[tab])
|
||||||
|
|
||||||
#################
|
#################
|
||||||
# other dialogs #
|
# other dialogs #
|
||||||
|
@ -2450,7 +2329,7 @@ class Browser(Gtk.Paned):
|
||||||
class PlaylistView(TreeView):
|
class PlaylistView(TreeView):
|
||||||
selected_path=GObject.Property(type=Gtk.TreePath, default=None) # currently marked song (bold text)
|
selected_path=GObject.Property(type=Gtk.TreePath, default=None) # currently marked song (bold text)
|
||||||
def __init__(self, client, settings):
|
def __init__(self, client, settings):
|
||||||
super().__init__(activate_on_single_click=True, reorderable=True, search_column=2, fixed_height_mode=True)
|
super().__init__(activate_on_single_click=True, reorderable=True, search_column=5)
|
||||||
self._client=client
|
self._client=client
|
||||||
self._settings=settings
|
self._settings=settings
|
||||||
self._playlist_version=None
|
self._playlist_version=None
|
||||||
|
@ -2458,33 +2337,28 @@ class PlaylistView(TreeView):
|
||||||
self._selection=self.get_selection()
|
self._selection=self.get_selection()
|
||||||
|
|
||||||
# store
|
# store
|
||||||
# (track, disc, title, artist, album, human duration, date, genre, file, weight, duration)
|
# (track, title, human duration, file, duration, search, weight, weight_set)
|
||||||
self._store=Gtk.ListStore(str, str, str, str, str, str, str, str, str, Pango.Weight, float)
|
self._store=Gtk.ListStore(str, str, str, str, float, str, Pango.Weight, bool)
|
||||||
self.set_model(self._store)
|
self.set_model(self._store)
|
||||||
|
|
||||||
# columns
|
# columns
|
||||||
renderer_text=Gtk.CellRendererText(ellipsize=Pango.EllipsizeMode.END, ellipsize_set=True)
|
renderer_text=Gtk.CellRendererText(ellipsize=Pango.EllipsizeMode.END, ellipsize_set=True)
|
||||||
renderer_text_ralign=Gtk.CellRendererText(xalign=1.0)
|
|
||||||
attrs=Pango.AttrList()
|
attrs=Pango.AttrList()
|
||||||
attrs.insert(Pango.AttrFontFeatures.new("tnum 1"))
|
attrs.insert(Pango.AttrFontFeatures.new("tnum 1"))
|
||||||
renderer_text_tnum=Gtk.CellRendererText(ellipsize=Pango.EllipsizeMode.END, ellipsize_set=True, attributes=attrs)
|
renderer_text_tnum=Gtk.CellRendererText(attributes=attrs)
|
||||||
renderer_text_ralign_tnum=Gtk.CellRendererText(xalign=1.0, attributes=attrs)
|
renderer_text_centered_tnum=Gtk.CellRendererText(xalign=0.5, attributes=attrs)
|
||||||
self._columns=(
|
columns=(
|
||||||
Gtk.TreeViewColumn(_("No"), renderer_text_ralign_tnum, text=0, weight=9),
|
Gtk.TreeViewColumn(_("No"), renderer_text_centered_tnum, text=0, weight=6),
|
||||||
Gtk.TreeViewColumn(_("Disc"), renderer_text_ralign, text=1, weight=9),
|
# the order of weight_set and weight seems to be important here
|
||||||
Gtk.TreeViewColumn(_("Title"), renderer_text, text=2, weight=9),
|
Gtk.TreeViewColumn(_("Title"), renderer_text, markup=1, weight_set=7, weight=6),
|
||||||
Gtk.TreeViewColumn(_("Artist"), renderer_text, text=3, weight=9),
|
Gtk.TreeViewColumn(_("Length"), renderer_text_tnum, text=2, weight=6)
|
||||||
Gtk.TreeViewColumn(_("Album"), renderer_text, text=4, weight=9),
|
|
||||||
Gtk.TreeViewColumn(_("Length"), renderer_text_tnum, text=5, weight=9),
|
|
||||||
Gtk.TreeViewColumn(_("Year"), renderer_text_tnum, text=6, weight=9),
|
|
||||||
Gtk.TreeViewColumn(_("Genre"), renderer_text, text=7, weight=9)
|
|
||||||
)
|
)
|
||||||
for i, column in enumerate(self._columns):
|
for column in columns:
|
||||||
column.set_property("resizable", True)
|
column.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
|
||||||
column.set_property("sizing", Gtk.TreeViewColumnSizing.FIXED)
|
column.set_property("resizable", False)
|
||||||
column.set_min_width(30)
|
self.append_column(column)
|
||||||
column.connect("notify::fixed-width", self._on_column_width, i)
|
self._column_title=columns[1]
|
||||||
self._load_settings()
|
self._column_title.set_property("expand", True)
|
||||||
|
|
||||||
# song popover
|
# song popover
|
||||||
self._song_popover=SongPopover(self._client, show_buttons=False)
|
self._song_popover=SongPopover(self._client, show_buttons=False)
|
||||||
|
@ -2501,24 +2375,6 @@ class PlaylistView(TreeView):
|
||||||
self._client.emitter.connect("disconnected", self._on_disconnected)
|
self._client.emitter.connect("disconnected", self._on_disconnected)
|
||||||
self._client.emitter.connect("reconnected", self._on_reconnected)
|
self._client.emitter.connect("reconnected", self._on_reconnected)
|
||||||
|
|
||||||
self._settings.connect("changed::column-visibilities", self._load_settings)
|
|
||||||
self._settings.connect("changed::column-permutation", self._load_settings)
|
|
||||||
|
|
||||||
def _on_column_width(self, obj, typestring, pos):
|
|
||||||
self._settings.array_modify("ai", "column-sizes", pos, obj.get_property("fixed-width"))
|
|
||||||
|
|
||||||
def _load_settings(self, *args):
|
|
||||||
columns=self.get_columns()
|
|
||||||
for column in columns:
|
|
||||||
self.remove_column(column)
|
|
||||||
sizes=self._settings.get_value("column-sizes").unpack()
|
|
||||||
visibilities=self._settings.get_value("column-visibilities").unpack()
|
|
||||||
for i in self._settings.get_value("column-permutation"):
|
|
||||||
if sizes[i] > 0:
|
|
||||||
self._columns[i].set_fixed_width(sizes[i])
|
|
||||||
self._columns[i].set_visible(visibilities[i])
|
|
||||||
self.append_column(self._columns[i])
|
|
||||||
|
|
||||||
def _clear(self, *args):
|
def _clear(self, *args):
|
||||||
self._song_popover.popdown()
|
self._song_popover.popdown()
|
||||||
self._set_playlist_info("")
|
self._set_playlist_info("")
|
||||||
|
@ -2533,7 +2389,8 @@ class PlaylistView(TreeView):
|
||||||
def _select(self, path):
|
def _select(self, path):
|
||||||
self._unselect()
|
self._unselect()
|
||||||
try:
|
try:
|
||||||
self._store[path][9]=Pango.Weight.BOLD
|
self._store[path][6]=Pango.Weight.BOLD
|
||||||
|
self._store[path][7]=True
|
||||||
self.set_property("selected-path", path)
|
self.set_property("selected-path", path)
|
||||||
except IndexError: # invalid path
|
except IndexError: # invalid path
|
||||||
pass
|
pass
|
||||||
|
@ -2541,7 +2398,8 @@ class PlaylistView(TreeView):
|
||||||
def _unselect(self):
|
def _unselect(self):
|
||||||
if self.get_property("selected-path") is not None:
|
if self.get_property("selected-path") is not None:
|
||||||
try:
|
try:
|
||||||
self._store[self.get_property("selected-path")][9]=Pango.Weight.BOOK
|
self._store[self.get_property("selected-path")][6]=Pango.Weight.BOOK
|
||||||
|
self._store[self.get_property("selected-path")][7]=False
|
||||||
self.set_property("selected-path", None)
|
self.set_property("selected-path", None)
|
||||||
except IndexError: # invalid path
|
except IndexError: # invalid path
|
||||||
self.set_property("selected-path", None)
|
self.set_property("selected-path", None)
|
||||||
|
@ -2565,9 +2423,9 @@ class PlaylistView(TreeView):
|
||||||
|
|
||||||
def _set_playlist_info(self, text):
|
def _set_playlist_info(self, text):
|
||||||
if text:
|
if text:
|
||||||
self._columns[2].set_title(" • ".join([_("Title"), text]))
|
self._column_title.set_title(" • ".join([_("Title"), text]))
|
||||||
else:
|
else:
|
||||||
self._columns[2].set_title(_("Title"))
|
self._column_title.set_title(_("Title"))
|
||||||
|
|
||||||
def _on_button_press_event(self, widget, event):
|
def _on_button_press_event(self, widget, event):
|
||||||
path_re=widget.get_path_at_pos(int(event.x), int(event.y))
|
path_re=widget.get_path_at_pos(int(event.x), int(event.y))
|
||||||
|
@ -2577,7 +2435,7 @@ class PlaylistView(TreeView):
|
||||||
self._store.remove(self._store.get_iter(path))
|
self._store.remove(self._store.get_iter(path))
|
||||||
elif event.button == 3 and event.type == Gdk.EventType.BUTTON_PRESS:
|
elif event.button == 3 and event.type == Gdk.EventType.BUTTON_PRESS:
|
||||||
point=self.convert_bin_window_to_widget_coords(event.x,event.y)
|
point=self.convert_bin_window_to_widget_coords(event.x,event.y)
|
||||||
self._song_popover.open(self._store[path][8], widget, *point)
|
self._song_popover.open(self._store[path][3], widget, *point)
|
||||||
|
|
||||||
def _on_key_release_event(self, widget, event):
|
def _on_key_release_event(self, widget, event):
|
||||||
if event.keyval == Gdk.keyval_from_name("Delete"):
|
if event.keyval == Gdk.keyval_from_name("Delete"):
|
||||||
|
@ -2628,29 +2486,32 @@ class PlaylistView(TreeView):
|
||||||
self.freeze_child_notify()
|
self.freeze_child_notify()
|
||||||
self._set_playlist_info("")
|
self._set_playlist_info("")
|
||||||
for song in songs:
|
for song in songs:
|
||||||
|
if "date" in song:
|
||||||
|
date=f"({song['date']})"
|
||||||
|
else:
|
||||||
|
date=""
|
||||||
|
album_with_date=" ".join(filter(None, ((song["album"][0], date))))
|
||||||
|
title=(f"<b>{GLib.markup_escape_text(song['title'][0])}</b>"
|
||||||
|
f" • {GLib.markup_escape_text(str(song['artist']))}\n"
|
||||||
|
f"<small>{GLib.markup_escape_text(album_with_date)}</small>")
|
||||||
try:
|
try:
|
||||||
treeiter=self._store.get_iter(song["pos"])
|
treeiter=self._store.get_iter(song["pos"])
|
||||||
self._store.set(treeiter,
|
self._store.set(treeiter,
|
||||||
0, song["track"][0],
|
0, song["track"][0],
|
||||||
1, song["disc"][0],
|
1, title,
|
||||||
2, song["title"][0],
|
2, str(song["duration"]),
|
||||||
3, str(song["artist"]),
|
3, song["file"],
|
||||||
4, song["album"][0],
|
4, float(song["duration"]),
|
||||||
5, str(song["duration"]),
|
5, song["title"][0],
|
||||||
6, song["date"][0],
|
6, Pango.Weight.BOOK,
|
||||||
7, str(song["genre"]),
|
7, False
|
||||||
8, song["file"],
|
|
||||||
9, Pango.Weight.BOOK,
|
|
||||||
10, float(song["duration"])
|
|
||||||
)
|
)
|
||||||
except:
|
except:
|
||||||
self._store.insert_with_valuesv(-1, range(11), [
|
self._store.insert_with_valuesv(-1, range(8), [
|
||||||
song["track"][0], song["disc"][0],
|
song["track"][0], title,
|
||||||
song["title"][0], str(song["artist"]),
|
str(song["duration"]), song["file"],
|
||||||
song["album"][0], str(song["duration"]),
|
float(song["duration"]), song["title"][0],
|
||||||
song["date"][0], str(song["genre"]),
|
Pango.Weight.BOOK, False
|
||||||
song["file"], Pango.Weight.BOOK,
|
|
||||||
float(song["duration"])
|
|
||||||
])
|
])
|
||||||
self.thaw_child_notify()
|
self.thaw_child_notify()
|
||||||
for i in reversed(range(int(self._client.status()["playlistlength"]), len(self._store))):
|
for i in reversed(range(int(self._client.status()["playlistlength"]), len(self._store))):
|
||||||
|
@ -2660,7 +2521,7 @@ class PlaylistView(TreeView):
|
||||||
if playlist_length == 0:
|
if playlist_length == 0:
|
||||||
self._set_playlist_info("")
|
self._set_playlist_info("")
|
||||||
else:
|
else:
|
||||||
duration=Duration(sum([row[10] for row in self._store]))
|
duration=Duration(sum([row[4] for row in self._store]))
|
||||||
translated_string=ngettext("{number} song ({duration})", "{number} songs ({duration})", playlist_length)
|
translated_string=ngettext("{number} song ({duration})", "{number} songs ({duration})", playlist_length)
|
||||||
self._set_playlist_info(translated_string.format(number=playlist_length, duration=duration))
|
self._set_playlist_info(translated_string.format(number=playlist_length, duration=duration))
|
||||||
self._refresh_selection()
|
self._refresh_selection()
|
||||||
|
@ -2686,7 +2547,7 @@ class PlaylistView(TreeView):
|
||||||
treeview, treeiter=self._selection.get_selected()
|
treeview, treeiter=self._selection.get_selected()
|
||||||
if treeiter is not None:
|
if treeiter is not None:
|
||||||
path=self._store.get_path(treeiter)
|
path=self._store.get_path(treeiter)
|
||||||
self._song_popover.open(self._store[path][8], self, *self.get_popover_point(path))
|
self._song_popover.open(self._store[path][3], self, *self.get_popover_point(path))
|
||||||
|
|
||||||
class PlaylistWindow(Gtk.Overlay):
|
class PlaylistWindow(Gtk.Overlay):
|
||||||
def __init__(self, client, settings):
|
def __init__(self, client, settings):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user