8 Commits

Author SHA1 Message Date
Martin Wagner
7037628af9 added icon size setting 2020-01-28 19:59:14 +01:00
Martin Wagner
26ee51fb18 reworked Gio.Settings handling 2020-01-28 18:39:18 +01:00
Martin Wagner
9625bd9cf3 reworked search dialog 2020-01-27 21:03:13 +01:00
Martin Wagner
75d8ff21c6 added playlist length information 2020-01-27 20:27:35 +01:00
Martin Wagner
36b023f04c connect to server after showing window 2020-01-26 23:51:50 +01:00
Martin Wagner
177bd27aa5 reworked connection 2020-01-26 22:23:21 +01:00
Martin Wagner
e07cce7ea6 fixed some play inconsistencies 2020-01-26 21:32:12 +01:00
Martin Wagner
0332fe75b7 fixed shebang 2020-01-19 20:48:49 +01:00
5 changed files with 269 additions and 199 deletions

View File

@@ -1,4 +1,4 @@
#!/usr/bin/python #!/usr/bin/python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# mpdevil - MPD Client. # mpdevil - MPD Client.
@@ -20,7 +20,7 @@
import gi #python-gobject dev-python/pygobject:3[${PYTHON_USEDEP}] import gi #python-gobject dev-python/pygobject:3[${PYTHON_USEDEP}]
gi.require_version('Gtk', '3.0') gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gio, Gdk, GdkPixbuf, GObject, GLib from gi.repository import Gtk, Gio, Gdk, GdkPixbuf, Pango, GObject, GLib
from mpd import MPDClient from mpd import MPDClient
import requests #dev-python/requests import requests #dev-python/requests
from bs4 import BeautifulSoup, Comment #, NavigableString #dev-python/beautifulsoup from bs4 import BeautifulSoup, Comment #, NavigableString #dev-python/beautifulsoup
@@ -79,8 +79,16 @@ class Cover(object):
return GdkPixbuf.Pixbuf.new_from_file_at_size(self.path, size, size) return GdkPixbuf.Pixbuf.new_from_file_at_size(self.path, size, size)
class Client(MPDClient): class Client(MPDClient):
def __init__(self): def __init__(self, settings):
MPDClient.__init__(self) MPDClient.__init__(self)
self.settings = settings
def try_connect_default(self):
active=self.settings.get_int("active-profile")
try:
self.connect(self.settings.get_value("hosts")[active], self.settings.get_value("ports")[active])
except:
pass
def connected(self): def connected(self):
try: try:
@@ -89,6 +97,37 @@ class Client(MPDClient):
except: except:
return False return False
class Settings(Gio.Settings):
BASE_KEY = "org.mpdevil"
def __init__(self):
super().__init__(schema=self.BASE_KEY)
def array_append(self, vtype, key, value): #append to Gio.Settings (self.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 (self.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 (self.settings) array
array=self.get_value(key).unpack()
array[pos]=value
self.set_value(key, GLib.Variant(vtype, array))
def get_gtk_icon_size(self, key):
icon_size=self.get_int(key)
if icon_size == 16:
return Gtk.IconSize.BUTTON
elif icon_size == 32:
return Gtk.IconSize.DND
elif icon_size == 48:
return Gtk.IconSize.DIALOG
else:
raise ValueError
class AlbumDialog(Gtk.Dialog): class AlbumDialog(Gtk.Dialog):
def __init__(self, parent, client, album, artist, year): def __init__(self, parent, client, album, artist, year):
Gtk.Dialog.__init__(self, title=(artist+" - "+album+" ("+year+")"), transient_for=parent) Gtk.Dialog.__init__(self, title=(artist+" - "+album+" ("+year+")"), transient_for=parent)
@@ -157,7 +196,7 @@ class AlbumDialog(Gtk.Dialog):
selected_title=self.store.get_value(treeiter, 4) selected_title=self.store.get_value(treeiter, 4)
self.client.clear() self.client.clear()
self.client.add(selected_title) self.client.add(selected_title)
self.client.play(0) self.client.play()
def on_selection_change(self, widget): def on_selection_change(self, widget):
treeiter=widget.get_selected()[1] treeiter=widget.get_selected()[1]
@@ -358,6 +397,16 @@ class TrackView(Gtk.Box):
#audio infos #audio infos
audio=AudioType(self.client) audio=AudioType(self.client)
#playlist info
self.playlist_info=Gtk.Label()
self.playlist_info.set_xalign(0)
self.playlist_info.set_ellipsize(Pango.EllipsizeMode.END)
#status bar
status_bar=Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10)
status_bar.pack_start(self.playlist_info, True, True, 0)
status_bar.pack_end(audio, False, False, 0)
#timeouts #timeouts
GLib.timeout_add(1000, self.update_cover) GLib.timeout_add(1000, self.update_cover)
GLib.timeout_add(100, self.refresh) GLib.timeout_add(100, self.refresh)
@@ -372,7 +421,7 @@ class TrackView(Gtk.Box):
#packing #packing
self.pack_start(self.cover, False, False, 0) self.pack_start(self.cover, False, False, 0)
self.pack_start(scroll, True, True, 0) self.pack_start(scroll, True, True, 0)
self.pack_end(audio, False, False, 0) self.pack_end(status_bar, False, False, 0)
def update_cover(self): def update_cover(self):
try: try:
@@ -416,15 +465,17 @@ class TrackView(Gtk.Box):
self.client.clear() self.client.clear()
for song in songs: for song in songs:
self.client.add(song["file"]) self.client.add(song["file"])
self.client.play(0) self.client.play()
def refresh(self): def refresh(self):
self.selection.handler_block(self.title_change) self.selection.handler_block(self.title_change)
if self.client.connected(): if self.client.connected():
if self.client.playlist() != self.playlist: if self.client.playlist() != self.playlist:
self.playlist_info.set_text("")
self.store.clear() self.store.clear()
songs=self.client.playlistinfo() songs=self.client.playlistinfo()
if not songs == []: if not songs == []:
whole_length=float(0)
for song in songs: for song in songs:
try: try:
title=song["title"] title=song["title"]
@@ -446,8 +497,11 @@ class TrackView(Gtk.Box):
dura=float(song["duration"]) dura=float(song["duration"])
except: except:
dura=0.0 dura=0.0
whole_length=whole_length+dura
duration=str(datetime.timedelta(seconds=int(dura ))) duration=str(datetime.timedelta(seconds=int(dura )))
self.store.append([track, title, artist, album, duration, song["file"].replace("&", "")]) self.store.append([track, title, artist, album, duration, song["file"].replace("&", "")])
whole_length_human_readable=str(datetime.timedelta(seconds=int(whole_length)))
self.playlist_info.set_text(_("%(total_tracks)i titles (%(total_length)s)") % {"total_tracks": len(songs), "total_length": whole_length_human_readable})
self.playlist=self.client.playlist() self.playlist=self.client.playlist()
else: else:
if not self.song_to_delete == "": if not self.song_to_delete == "":
@@ -463,8 +517,9 @@ class TrackView(Gtk.Box):
path = Gtk.TreePath(int(song)) path = Gtk.TreePath(int(song))
self.selection.select_path(path) self.selection.select_path(path)
except: except:
self.selection.select_path(Gtk.TreePath(0)) self.selection.unselect_all()
else: else:
self.playlist_info.set_text("")
self.store.clear() self.store.clear()
self.playlist=[] self.playlist=[]
self.selection.handler_unblock(self.title_change) self.selection.handler_unblock(self.title_change)
@@ -706,21 +761,6 @@ class ProfileSettings(Gtk.Grid):
self.attach_next_to(self.port_entry, port_label, Gtk.PositionType.RIGHT, 1, 1) self.attach_next_to(self.port_entry, port_label, Gtk.PositionType.RIGHT, 1, 1)
self.attach_next_to(self.path_select_button, path_label, Gtk.PositionType.RIGHT, 1, 1) self.attach_next_to(self.path_select_button, path_label, Gtk.PositionType.RIGHT, 1, 1)
def settings_array_append(self, vtype, key, value): #append to Gio.Settings (self.settings) array
array=self.settings.get_value(key).unpack()
array.append(value)
self.settings.set_value(key, GLib.Variant(vtype, array))
def settings_array_delete(self, vtype, key, pos): #delete entry of Gio.Settings (self.settings) array
array=self.settings.get_value(key).unpack()
array.pop(pos)
self.settings.set_value(key, GLib.Variant(vtype, array))
def settings_array_modify(self, vtype, key, pos, value): #modify entry of Gio.Settings (self.settings) array
array=self.settings.get_value(key).unpack()
array[pos]=value
self.settings.set_value(key, GLib.Variant(vtype, array))
def profiles_combo_reload(self, *args): def profiles_combo_reload(self, *args):
self.profiles_combo.handler_block(self.profiles_combo_changed) self.profiles_combo.handler_block(self.profiles_combo_changed)
self.profile_entry.handler_block(self.profile_entry_changed) self.profile_entry.handler_block(self.profile_entry_changed)
@@ -738,33 +778,33 @@ class ProfileSettings(Gtk.Grid):
def on_add_button_clicked(self, *args): def on_add_button_clicked(self, *args):
pos=self.profiles_combo.get_active() pos=self.profiles_combo.get_active()
self.settings_array_append('as', "profiles", "new profile") self.settings.array_append('as', "profiles", "new profile")
self.settings_array_append('as', "hosts", "localhost") self.settings.array_append('as', "hosts", "localhost")
self.settings_array_append('ai', "ports", 6600) self.settings.array_append('ai', "ports", 6600)
self.settings_array_append('as', "paths", "") self.settings.array_append('as', "paths", "")
self.profiles_combo_reload() self.profiles_combo_reload()
self.profiles_combo.set_active(pos) self.profiles_combo.set_active(pos)
def on_delete_button_clicked(self, *args): def on_delete_button_clicked(self, *args):
pos=self.profiles_combo.get_active() pos=self.profiles_combo.get_active()
self.settings_array_delete('as', "profiles", pos) self.settings.array_delete('as', "profiles", pos)
self.settings_array_delete('as', "hosts", pos) self.settings.array_delete('as', "hosts", pos)
self.settings_array_delete('ai', "ports", pos) self.settings.array_delete('ai', "ports", pos)
self.settings_array_delete('as', "paths", pos) self.settings.array_delete('as', "paths", pos)
self.profiles_combo_reload() self.profiles_combo_reload()
self.profiles_combo.set_active(0) self.profiles_combo.set_active(0)
def on_profile_entry_changed(self, *args): def on_profile_entry_changed(self, *args):
pos=self.profiles_combo.get_active() pos=self.profiles_combo.get_active()
self.settings_array_modify('as', "profiles", pos, self.profile_entry.get_text()) self.settings.array_modify('as', "profiles", pos, self.profile_entry.get_text())
self.profiles_combo_reload() self.profiles_combo_reload()
self.profiles_combo.set_active(pos) self.profiles_combo.set_active(pos)
def on_host_entry_changed(self, *args): def on_host_entry_changed(self, *args):
self.settings_array_modify('as', "hosts", self.profiles_combo.get_active(), self.host_entry.get_text()) self.settings.array_modify('as', "hosts", self.profiles_combo.get_active(), self.host_entry.get_text())
def on_port_entry_changed(self, *args): def on_port_entry_changed(self, *args):
self.settings_array_modify('ai', "ports", self.profiles_combo.get_active(), self.port_entry.get_int()) self.settings.array_modify('ai', "ports", self.profiles_combo.get_active(), self.port_entry.get_int())
def on_path_select_button_clicked(self, widget, parent): def on_path_select_button_clicked(self, widget, parent):
dialog = Gtk.FileChooserDialog(title=_("Choose directory"), transient_for=parent, action=Gtk.FileChooserAction.SELECT_FOLDER) dialog = Gtk.FileChooserDialog(title=_("Choose directory"), transient_for=parent, action=Gtk.FileChooserAction.SELECT_FOLDER)
@@ -774,7 +814,7 @@ class ProfileSettings(Gtk.Grid):
dialog.set_current_folder(self.settings.get_value("paths")[self.profiles_combo.get_active()]) dialog.set_current_folder(self.settings.get_value("paths")[self.profiles_combo.get_active()])
response = dialog.run() response = dialog.run()
if response == Gtk.ResponseType.OK: if response == Gtk.ResponseType.OK:
self.settings_array_modify('as', "paths", self.profiles_combo.get_active(), dialog.get_filename()) self.settings.array_modify('as', "paths", self.profiles_combo.get_active(), dialog.get_filename())
dialog.destroy() dialog.destroy()
def on_profiles_changed(self, *args): def on_profiles_changed(self, *args):
@@ -811,6 +851,15 @@ class GeneralSettings(Gtk.Grid):
track_cover_size=IntEntry(self.settings.get_int("track-cover"), 100, 1200) track_cover_size=IntEntry(self.settings.get_int("track-cover"), 100, 1200)
album_cover_size=IntEntry(self.settings.get_int("album-cover"), 50, 600) album_cover_size=IntEntry(self.settings.get_int("album-cover"), 50, 600)
icon_size_label=Gtk.Label(label=_("Button icon size (restart required):"))
icon_size_label.set_xalign(1)
icon_size_combo=Gtk.ComboBoxText()
icon_size_combo.set_entry_text_column(0)
sizes=[16, 32, 48]
for i in sizes:
icon_size_combo.append_text(str(i))
icon_size_combo.set_active(sizes.index(self.settings.get_int("icon-size")))
show_stop=Gtk.CheckButton(label=_("Show stop button")) show_stop=Gtk.CheckButton(label=_("Show stop button"))
show_stop.set_active(self.settings.get_boolean("show-stop")) show_stop.set_active(self.settings.get_boolean("show-stop"))
@@ -829,6 +878,7 @@ class GeneralSettings(Gtk.Grid):
#connect #connect
track_cover_size.connect("value-changed", self.on_int_changed, "track-cover") track_cover_size.connect("value-changed", self.on_int_changed, "track-cover")
album_cover_size.connect("value-changed", self.on_int_changed, "album-cover") album_cover_size.connect("value-changed", self.on_int_changed, "album-cover")
icon_size_combo.connect("changed", self.on_icon_size_changed)
show_stop.connect("toggled", self.on_toggled, "show-stop") show_stop.connect("toggled", self.on_toggled, "show-stop")
show_album_view_tooltips.connect("toggled", self.on_toggled, "show-album-view-tooltips") show_album_view_tooltips.connect("toggled", self.on_toggled, "show-album-view-tooltips")
send_notify.connect("toggled", self.on_toggled, "send-notify") send_notify.connect("toggled", self.on_toggled, "send-notify")
@@ -838,9 +888,11 @@ class GeneralSettings(Gtk.Grid):
#packing #packing
self.add(track_cover_label) self.add(track_cover_label)
self.attach_next_to(album_cover_label, track_cover_label, Gtk.PositionType.BOTTOM, 1, 1) self.attach_next_to(album_cover_label, track_cover_label, Gtk.PositionType.BOTTOM, 1, 1)
self.attach_next_to(icon_size_label, album_cover_label, Gtk.PositionType.BOTTOM, 1, 1)
self.attach_next_to(track_cover_size, track_cover_label, Gtk.PositionType.RIGHT, 1, 1) self.attach_next_to(track_cover_size, track_cover_label, Gtk.PositionType.RIGHT, 1, 1)
self.attach_next_to(album_cover_size, album_cover_label, Gtk.PositionType.RIGHT, 1, 1) self.attach_next_to(album_cover_size, album_cover_label, Gtk.PositionType.RIGHT, 1, 1)
self.attach_next_to(show_stop, album_cover_label, Gtk.PositionType.BOTTOM, 2, 1) self.attach_next_to(icon_size_combo, icon_size_label, Gtk.PositionType.RIGHT, 1, 1)
self.attach_next_to(show_stop, icon_size_label, Gtk.PositionType.BOTTOM, 2, 1)
self.attach_next_to(show_album_view_tooltips, show_stop, Gtk.PositionType.BOTTOM, 2, 1) self.attach_next_to(show_album_view_tooltips, show_stop, Gtk.PositionType.BOTTOM, 2, 1)
self.attach_next_to(send_notify, show_album_view_tooltips, Gtk.PositionType.BOTTOM, 2, 1) self.attach_next_to(send_notify, show_album_view_tooltips, Gtk.PositionType.BOTTOM, 2, 1)
self.attach_next_to(add_album, send_notify, Gtk.PositionType.BOTTOM, 2, 1) self.attach_next_to(add_album, send_notify, Gtk.PositionType.BOTTOM, 2, 1)
@@ -852,6 +904,10 @@ class GeneralSettings(Gtk.Grid):
def on_toggled(self, widget, key): def on_toggled(self, widget, key):
self.settings.set_boolean(key, widget.get_active()) self.settings.set_boolean(key, widget.get_active())
def on_icon_size_changed(self, box):
active_size=int(box.get_active_text())
self.settings.set_int("icon-size", active_size)
class SettingsDialog(Gtk.Dialog): class SettingsDialog(Gtk.Dialog):
def __init__(self, parent, settings): def __init__(self, parent, settings):
Gtk.Dialog.__init__(self, title=_("Settings"), transient_for=parent) Gtk.Dialog.__init__(self, title=_("Settings"), transient_for=parent)
@@ -881,12 +937,13 @@ class ClientControl(Gtk.ButtonBox):
#adding vars #adding vars
self.client=client self.client=client
self.settings=settings self.settings=settings
self.icon_size=self.settings.get_gtk_icon_size("icon-size")
#widgets #widgets
self.play_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-playback-start-symbolic", Gtk.IconSize.DND)) self.play_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-playback-start-symbolic", self.icon_size))
self.stop_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-playback-stop-symbolic", Gtk.IconSize.DND)) self.stop_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-playback-stop-symbolic", self.icon_size))
self.prev_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-skip-backward-symbolic", Gtk.IconSize.DND)) self.prev_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-skip-backward-symbolic", self.icon_size))
self.next_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-skip-forward-symbolic", Gtk.IconSize.DND)) self.next_button = Gtk.Button(image=Gtk.Image.new_from_icon_name("media-skip-forward-symbolic", self.icon_size))
#connect #connect
self.play_button.connect("clicked", self.on_play_clicked) self.play_button.connect("clicked", self.on_play_clicked)
@@ -909,15 +966,15 @@ class ClientControl(Gtk.ButtonBox):
if self.client.connected(): if self.client.connected():
status=self.client.status() status=self.client.status()
if status["state"] == "play": if status["state"] == "play":
self.play_button.set_image(Gtk.Image.new_from_icon_name("media-playback-pause-symbolic", Gtk.IconSize.DND)) self.play_button.set_image(Gtk.Image.new_from_icon_name("media-playback-pause-symbolic", self.icon_size))
self.prev_button.set_sensitive(True) self.prev_button.set_sensitive(True)
self.next_button.set_sensitive(True) self.next_button.set_sensitive(True)
elif status["state"] == "pause": elif status["state"] == "pause":
self.play_button.set_image(Gtk.Image.new_from_icon_name("media-playback-start-symbolic", Gtk.IconSize.DND)) self.play_button.set_image(Gtk.Image.new_from_icon_name("media-playback-start-symbolic", self.icon_size))
self.prev_button.set_sensitive(True) self.prev_button.set_sensitive(True)
self.next_button.set_sensitive(True) self.next_button.set_sensitive(True)
else: else:
self.play_button.set_image(Gtk.Image.new_from_icon_name("media-playback-start-symbolic", Gtk.IconSize.DND)) self.play_button.set_image(Gtk.Image.new_from_icon_name("media-playback-start-symbolic", self.icon_size))
self.prev_button.set_sensitive(False) self.prev_button.set_sensitive(False)
self.next_button.set_sensitive(False) self.next_button.set_sensitive(False)
return True return True
@@ -934,7 +991,7 @@ class ClientControl(Gtk.ButtonBox):
self.client.play(status["song"]) self.client.play(status["song"])
except: except:
try: try:
self.client.play(0) #bad song index possible self.client.play()
except: except:
pass pass
self.update() self.update()
@@ -1011,22 +1068,25 @@ class SeekBar(Gtk.Box):
return True return True
class PlaybackOptions(Gtk.Box): class PlaybackOptions(Gtk.Box):
def __init__(self, client): def __init__(self, client, settings):
Gtk.Box.__init__(self) Gtk.Box.__init__(self)
#adding vars #adding vars
self.client=client self.client=client
self.settings=settings
self.icon_size=self.settings.get_gtk_icon_size("icon-size")
#widgets #widgets
self.random=Gtk.ToggleButton(image=Gtk.Image.new_from_icon_name("media-playlist-shuffle-symbolic", Gtk.IconSize.DND)) self.random=Gtk.ToggleButton(image=Gtk.Image.new_from_icon_name("media-playlist-shuffle-symbolic", self.icon_size))
self.random.set_tooltip_text(_("Random mode")) self.random.set_tooltip_text(_("Random mode"))
self.repeat=Gtk.ToggleButton(image=Gtk.Image.new_from_icon_name("media-playlist-repeat-symbolic", Gtk.IconSize.DND)) self.repeat=Gtk.ToggleButton(image=Gtk.Image.new_from_icon_name("media-playlist-repeat-symbolic", self.icon_size))
self.repeat.set_tooltip_text(_("Repeat mode")) self.repeat.set_tooltip_text(_("Repeat mode"))
self.single=Gtk.ToggleButton(image=Gtk.Image.new_from_icon_name("zoom-original-symbolic", Gtk.IconSize.DND)) self.single=Gtk.ToggleButton(image=Gtk.Image.new_from_icon_name("zoom-original-symbolic", self.icon_size))
self.single.set_tooltip_text(_("Single mode")) self.single.set_tooltip_text(_("Single mode"))
self.consume=Gtk.ToggleButton(image=Gtk.Image.new_from_icon_name("edit-cut-symbolic", Gtk.IconSize.DND)) self.consume=Gtk.ToggleButton(image=Gtk.Image.new_from_icon_name("edit-cut-symbolic", self.icon_size))
self.consume.set_tooltip_text(_("Consume mode")) self.consume.set_tooltip_text(_("Consume mode"))
self.volume=Gtk.VolumeButton() self.volume=Gtk.VolumeButton()
self.volume.set_property("size", self.icon_size)
#connect #connect
self.random_toggled=self.random.connect("toggled", self.set_random) self.random_toggled=self.random.connect("toggled", self.set_random)
@@ -1127,6 +1187,7 @@ class AudioType(Gtk.EventBox):
#widgets #widgets
self.label=Gtk.Label() self.label=Gtk.Label()
self.label.set_xalign(1) self.label.set_xalign(1)
self.label.set_ellipsize(Pango.EllipsizeMode.END)
self.popover=Gtk.Popover() self.popover=Gtk.Popover()
#Store #Store
@@ -1201,16 +1262,18 @@ class ProfileSelect(Gtk.ComboBoxText):
self.client=client self.client=client
self.settings=settings self.settings=settings
#connect
self.changed=self.connect("changed", self.on_changed) self.changed=self.connect("changed", self.on_changed)
self.reload()
self.set_active(self.settings.get_int("active-profile"))
self.settings.connect("changed::profiles", self.on_settings_changed) self.settings.connect("changed::profiles", self.on_settings_changed)
self.settings.connect("changed::hosts", self.on_settings_changed) self.settings.connect("changed::hosts", self.on_settings_changed)
self.settings.connect("changed::ports", self.on_settings_changed) self.settings.connect("changed::ports", self.on_settings_changed)
self.settings.connect("changed::paths", self.on_settings_changed) self.settings.connect("changed::paths", self.on_settings_changed)
self.reload()
self.handler_block(self.changed)
self.set_active(self.settings.get_int("active-profile"))
self.handler_unblock(self.changed)
def reload(self, *args): def reload(self, *args):
self.handler_block(self.changed) self.handler_block(self.changed)
self.remove_all() self.remove_all()
@@ -1224,11 +1287,8 @@ class ProfileSelect(Gtk.ComboBoxText):
def on_changed(self, *args): def on_changed(self, *args):
active=self.get_active() active=self.get_active()
self.settings.set_int("active-profile", active) self.settings.set_int("active-profile", active)
try: self.client.disconnect()
self.client.disconnect() self.client.try_connect_default()
self.client.connect(self.settings.get_value("hosts")[active], self.settings.get_value("ports")[active])
except:
pass
class ServerStats(Gtk.Dialog): class ServerStats(Gtk.Dialog):
def __init__(self, parent, client): def __init__(self, parent, client):
@@ -1306,26 +1366,31 @@ class Search(Gtk.Dialog):
self.column_track = Gtk.TreeViewColumn(_("No"), renderer_text, text=0) self.column_track = Gtk.TreeViewColumn(_("No"), renderer_text, text=0)
self.column_track.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.column_track.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
self.column_track.set_property("resizable", False) self.column_track.set_property("resizable", False)
self.column_track.set_sort_column_id(0)
self.treeview.append_column(self.column_track) self.treeview.append_column(self.column_track)
self.column_title = Gtk.TreeViewColumn(_("Title"), renderer_text, text=1) self.column_title = Gtk.TreeViewColumn(_("Title"), renderer_text, text=1)
self.column_title.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.column_title.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
self.column_title.set_property("resizable", False) self.column_title.set_property("resizable", False)
self.column_title.set_sort_column_id(1)
self.treeview.append_column(self.column_title) self.treeview.append_column(self.column_title)
self.column_artist = Gtk.TreeViewColumn(_("Artist"), renderer_text, text=2) self.column_artist = Gtk.TreeViewColumn(_("Artist"), renderer_text, text=2)
self.column_artist.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.column_artist.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
self.column_artist.set_property("resizable", False) self.column_artist.set_property("resizable", False)
self.column_artist.set_sort_column_id(2)
self.treeview.append_column(self.column_artist) self.treeview.append_column(self.column_artist)
self.column_album = Gtk.TreeViewColumn(_("Album"), renderer_text, text=3) self.column_album = Gtk.TreeViewColumn(_("Album"), renderer_text, text=3)
self.column_album.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.column_album.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
self.column_album.set_property("resizable", False) self.column_album.set_property("resizable", False)
self.column_album.set_sort_column_id(3)
self.treeview.append_column(self.column_album) self.treeview.append_column(self.column_album)
self.column_time = Gtk.TreeViewColumn(_("Length"), renderer_text, text=4) self.column_time = Gtk.TreeViewColumn(_("Length"), renderer_text, text=4)
self.column_time.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE) self.column_time.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
self.column_time.set_property("resizable", False) self.column_time.set_property("resizable", False)
self.column_time.set_sort_column_id(4)
self.treeview.append_column(self.column_time) self.treeview.append_column(self.column_time)
#connect #connect
@@ -1345,7 +1410,7 @@ class Search(Gtk.Dialog):
selected_title=self.store.get_value(treeiter, 5) selected_title=self.store.get_value(treeiter, 5)
self.client.clear() self.client.clear()
self.client.add(selected_title) self.client.add(selected_title)
self.client.play(0) self.client.play()
def on_selection_change(self, widget): def on_selection_change(self, widget):
treeiter=widget.get_selected()[1] treeiter=widget.get_selected()[1]
@@ -1355,7 +1420,7 @@ class Search(Gtk.Dialog):
def on_search_changed(self, widget): def on_search_changed(self, widget):
self.store.clear() self.store.clear()
for song in self.client.search("title", self.search_entry.get_text()): for song in self.client.search("any", self.search_entry.get_text()):
try: try:
title=song["title"] title=song["title"]
except: except:
@@ -1387,15 +1452,11 @@ class LyricsWindow(Gtk.Window): #Lyrics view with own client because MPDClient i
self.set_default_size(450, 800) self.set_default_size(450, 800)
#adding vars #adding vars
self.client=Client()
self.settings=settings self.settings=settings
self.client=Client(self.settings)
#connect client #connect client
active=self.settings.get_int("active-profile") self.client.try_connect_default()
try:
self.client.connect(self.settings.get_value("hosts")[active], self.settings.get_value("ports")[active])
except:
pass
self.current_song={} self.current_song={}
#widgets #widgets
@@ -1422,7 +1483,7 @@ class LyricsWindow(Gtk.Window): #Lyrics view with own client because MPDClient i
def update_loop(): def update_loop():
while not self.stop: while not self.stop:
try: if self.client.connected():
cs=self.client.currentsong() cs=self.client.currentsong()
cs.pop("pos") #avoid unnecessary reloads caused by position change of current title cs.pop("pos") #avoid unnecessary reloads caused by position change of current title
if cs != self.current_song: if cs != self.current_song:
@@ -1433,7 +1494,7 @@ class LyricsWindow(Gtk.Window): #Lyrics view with own client because MPDClient i
text=_("not found") text=_("not found")
GLib.idle_add(update_label, text) GLib.idle_add(update_label, text)
self.current_song=cs self.current_song=cs
except: else:
self.current_song={} self.current_song={}
GLib.idle_add(update_label, _("not connected")) GLib.idle_add(update_label, _("not connected"))
time.sleep(1) time.sleep(1)
@@ -1477,12 +1538,8 @@ class LyricsWindow(Gtk.Window): #Lyrics view with own client because MPDClient i
return output.encode('utf-8') return output.encode('utf-8')
def on_settings_changed(self, *args): def on_settings_changed(self, *args):
active=self.settings.get_int("active-profile") self.client.disconnect()
try: self.client.try_connect_default()
self.client.disconnect()
self.client.connect(self.settings.get_value("hosts")[active], self.settings.get_value("ports")[active])
except:
pass
class MainWindow(Gtk.ApplicationWindow): class MainWindow(Gtk.ApplicationWindow):
def __init__(self, app, client, settings): def __init__(self, app, client, settings):
@@ -1494,6 +1551,7 @@ class MainWindow(Gtk.ApplicationWindow):
#adding vars #adding vars
self.client=client self.client=client
self.songid_playing=None self.songid_playing=None
self.icon_size=self.settings.get_gtk_icon_size("icon-size")
#actions #actions
save_action = Gio.SimpleAction.new("save", None) save_action = Gio.SimpleAction.new("save", None)
@@ -1518,13 +1576,13 @@ class MainWindow(Gtk.ApplicationWindow):
self.profiles.set_tooltip_text(_("Select profile")) self.profiles.set_tooltip_text(_("Select profile"))
self.control=ClientControl(self.client, self.settings) self.control=ClientControl(self.client, self.settings)
self.progress=SeekBar(self.client) self.progress=SeekBar(self.client)
self.go_home_button=Gtk.Button(image=Gtk.Image.new_from_icon_name("go-home-symbolic", Gtk.IconSize.DND)) self.go_home_button=Gtk.Button(image=Gtk.Image.new_from_icon_name("go-home-symbolic", self.icon_size))
self.go_home_button.set_tooltip_text(_("Return to album of current title")) self.go_home_button.set_tooltip_text(_("Return to album of current title"))
self.search_button=Gtk.Button(image=Gtk.Image.new_from_icon_name("system-search-symbolic", Gtk.IconSize.DND)) self.search_button=Gtk.Button(image=Gtk.Image.new_from_icon_name("system-search-symbolic", self.icon_size))
self.search_button.set_tooltip_text(_("Title search")) self.search_button.set_tooltip_text(_("Title search"))
self.lyrics_button=Gtk.ToggleButton(image=Gtk.Image.new_from_icon_name("media-view-subtitles-symbolic", Gtk.IconSize.DND)) self.lyrics_button=Gtk.ToggleButton(image=Gtk.Image.new_from_icon_name("media-view-subtitles-symbolic", self.icon_size))
self.lyrics_button.set_tooltip_text(_("Show lyrics")) self.lyrics_button.set_tooltip_text(_("Show lyrics"))
self.play_opts=PlaybackOptions(self.client) self.play_opts=PlaybackOptions(self.client, self.settings)
#info bar #info bar
self.info_bar=Gtk.InfoBar.new() self.info_bar=Gtk.InfoBar.new()
@@ -1576,6 +1634,10 @@ class MainWindow(Gtk.ApplicationWindow):
self.hbox.pack_end(menu_button, False, False, 0) self.hbox.pack_end(menu_button, False, False, 0)
self.add(self.vbox) self.add(self.vbox)
#connect client
self.client.try_connect_default()
self.show_all() self.show_all()
def update(self, app): #update title and send notify def update(self, app): #update title and send notify
@@ -1616,11 +1678,7 @@ class MainWindow(Gtk.ApplicationWindow):
def on_info_bar_response(self, info_bar, response_id): def on_info_bar_response(self, info_bar, response_id):
if response_id == Gtk.ResponseType.OK: if response_id == Gtk.ResponseType.OK:
active=self.settings.get_int("active-profile") self.client.try_connect_default()
try:
self.client.connect(self.settings.get_value("hosts")[active], self.settings.get_value("ports")[active])
except:
pass
info_bar.set_revealed(False) info_bar.set_revealed(False)
def on_search_clicked(self, widget): def on_search_clicked(self, widget):
@@ -1665,11 +1723,10 @@ class MainWindow(Gtk.ApplicationWindow):
self.client.update() self.client.update()
class mpdevil(Gtk.Application): class mpdevil(Gtk.Application):
BASE_KEY = "org.mpdevil"
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, application_id="org.mpdevil", flags=Gio.ApplicationFlags.FLAGS_NONE, **kwargs) super().__init__(*args, application_id="org.mpdevil", flags=Gio.ApplicationFlags.FLAGS_NONE, **kwargs)
self.client=Client() self.settings = Settings()
self.settings = Gio.Settings.new(self.BASE_KEY) self.client=Client(self.settings)
self.window=None self.window=None
def do_activate(self): def do_activate(self):

View File

@@ -1,7 +1,7 @@
dnl -*- Mode: autoconf -*- dnl -*- Mode: autoconf -*-
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_PREREQ([2.68]) AC_PREREQ([2.68])
AC_INIT([mpdevil], [0.4.1]) AC_INIT([mpdevil], [0.4.2])
AC_CONFIG_SRCDIR([bin/mpdevil.py]) AC_CONFIG_SRCDIR([bin/mpdevil.py])
AM_INIT_AUTOMAKE AM_INIT_AUTOMAKE
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])

View File

@@ -31,6 +31,11 @@
<summary>Size of main cover</summary> <summary>Size of main cover</summary>
<description></description> <description></description>
</key> </key>
<key type="i" name="icon-size">
<default>16</default>
<summary>Size of button icons in control bar</summary>
<description></description>
</key>
<key type="b" name="show-stop"> <key type="b" name="show-stop">
<default>false</default> <default>false</default>
<summary>Show stop button</summary> <summary>Show stop button</summary>

118
po/de.po
View File

@@ -7,8 +7,8 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: \n" "Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-01-17 22:33+0100\n" "POT-Creation-Date: 2020-01-28 19:56+0100\n"
"PO-Revision-Date: 2020-01-17 22:34+0100\n" "PO-Revision-Date: 2020-01-28 19:58+0100\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"Language: de\n" "Language: de\n"
@@ -18,140 +18,144 @@ msgstr ""
"X-Generator: Poedit 2.2.4\n" "X-Generator: Poedit 2.2.4\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: mpdevil.py:120 mpdevil.py:328 mpdevil.py:1302 #: mpdevil.py:159 mpdevil.py:368 mpdevil.py:1366
msgid "No" msgid "No"
msgstr "Nr." msgstr "Nr."
#: mpdevil.py:125 mpdevil.py:333 mpdevil.py:1307 #: mpdevil.py:164 mpdevil.py:373 mpdevil.py:1372
msgid "Title" msgid "Title"
msgstr "Titel" msgstr "Titel"
#: mpdevil.py:130 mpdevil.py:338 mpdevil.py:1312 #: mpdevil.py:169 mpdevil.py:378 mpdevil.py:1378
msgid "Artist" msgid "Artist"
msgstr "Interpret" msgstr "Interpret"
#: mpdevil.py:135 mpdevil.py:343 mpdevil.py:1322 #: mpdevil.py:174 mpdevil.py:383 mpdevil.py:1390
msgid "Length" msgid "Length"
msgstr "Länge" msgstr "Länge"
#: mpdevil.py:174 mpdevil.py:431 mpdevil.py:1358 #: mpdevil.py:214 mpdevil.py:483 mpdevil.py:1427
msgid "Unknown Title" msgid "Unknown Title"
msgstr "Unbekannter Titel" msgstr "Unbekannter Titel"
#: mpdevil.py:178 mpdevil.py:439 mpdevil.py:1366 #: mpdevil.py:218 mpdevil.py:491 mpdevil.py:1435
msgid "Unknown Artist" msgid "Unknown Artist"
msgstr "Unbekannter Künstler" msgstr "Unbekannter Künstler"
#: mpdevil.py:214 #: mpdevil.py:254
msgid "Album Artist" msgid "Album Artist"
msgstr "Albuminterpret" msgstr "Albuminterpret"
#: mpdevil.py:273 #: mpdevil.py:313 mpdevil.py:504
#, python-format #, python-format
msgid "%(total_tracks)i titles (%(total_length)s)" msgid "%(total_tracks)i titles (%(total_length)s)"
msgstr "%(total_tracks)i Titel (%(total_length)s)" msgstr "%(total_tracks)i Titel (%(total_length)s)"
#: mpdevil.py:443 mpdevil.py:1370 #: mpdevil.py:495 mpdevil.py:1439
msgid "Unknown Album" msgid "Unknown Album"
msgstr "Unbekanntes Album" msgstr "Unbekanntes Album"
#: mpdevil.py:669 #: mpdevil.py:725
msgid "Select" msgid "Select"
msgstr "Auswählen" msgstr "Auswählen"
#: mpdevil.py:671 #: mpdevil.py:727
msgid "Profile:" msgid "Profile:"
msgstr "Profil:" msgstr "Profil:"
#: mpdevil.py:673 #: mpdevil.py:729
msgid "Name:" msgid "Name:"
msgstr "Name:" msgstr "Name:"
#: mpdevil.py:675 #: mpdevil.py:731
msgid "Host:" msgid "Host:"
msgstr "Host:" msgstr "Host:"
#: mpdevil.py:677 #: mpdevil.py:733
msgid "Port:" msgid "Port:"
msgstr "Port:" msgstr "Port:"
#: mpdevil.py:679 #: mpdevil.py:735
msgid "Music lib:" msgid "Music lib:"
msgstr "Musikverzeichnis:" msgstr "Musikverzeichnis:"
#: mpdevil.py:769 #: mpdevil.py:810
msgid "Choose directory" msgid "Choose directory"
msgstr "Verzeichnis Wählen" msgstr "Verzeichnis Wählen"
#: mpdevil.py:805 #: mpdevil.py:846
msgid "Main cover size:" msgid "Main cover size:"
msgstr "Größe des Haupt-Covers:" msgstr "Größe des Haupt-Covers:"
#: mpdevil.py:807 #: mpdevil.py:848
msgid "Album-view cover size:" msgid "Album-view cover size:"
msgstr "Covergröße in Albumansicht:" msgstr "Covergröße in Albumansicht:"
#: mpdevil.py:813 #: mpdevil.py:854
msgid "Button icon size (restart required):"
msgstr "Symbolgröße der Knöpfe (Neustart erforderlich):"
#: mpdevil.py:863
msgid "Show stop button" msgid "Show stop button"
msgstr "Zeige Stopp-Knopf" msgstr "Zeige Stopp-Knopf"
#: mpdevil.py:816 #: mpdevil.py:866
msgid "Show tooltips in album view" msgid "Show tooltips in album view"
msgstr "Zeige Tooltips in Albumansicht" msgstr "Zeige Tooltips in Albumansicht"
#: mpdevil.py:819 #: mpdevil.py:869
msgid "Send notification on title change" msgid "Send notification on title change"
msgstr "Sende Benachrichtigung bei Titelwechsel" msgstr "Sende Benachrichtigung bei Titelwechsel"
#: mpdevil.py:822 #: mpdevil.py:872
msgid "Stop playback on quit" msgid "Stop playback on quit"
msgstr "Wiedergabe beim Beenden stoppen" msgstr "Wiedergabe beim Beenden stoppen"
#: mpdevil.py:825 #: mpdevil.py:875
msgid "Play selected album after current title" msgid "Play selected album after current title"
msgstr "Ausgewähltes Album hinter aktuellem Titel einreihen" msgstr "Ausgewähltes Album hinter aktuellem Titel einreihen"
#: mpdevil.py:856 mpdevil.py:1534 #: mpdevil.py:913 mpdevil.py:1596
msgid "Settings" msgid "Settings"
msgstr "Einstellungen" msgstr "Einstellungen"
#: mpdevil.py:869 #: mpdevil.py:926
msgid "General" msgid "General"
msgstr "Allgemein" msgstr "Allgemein"
#: mpdevil.py:870 #: mpdevil.py:927
msgid "Profiles" msgid "Profiles"
msgstr "Profile" msgstr "Profile"
#: mpdevil.py:1018 #: mpdevil.py:1081
msgid "Random mode" msgid "Random mode"
msgstr "Zufallsmodus" msgstr "Zufallsmodus"
#: mpdevil.py:1020 #: mpdevil.py:1083
msgid "Repeat mode" msgid "Repeat mode"
msgstr "Dauerschleife" msgstr "Dauerschleife"
#: mpdevil.py:1022 #: mpdevil.py:1085
msgid "Single mode" msgid "Single mode"
msgstr "Einzelstückmodus" msgstr "Einzelstückmodus"
#: mpdevil.py:1024 #: mpdevil.py:1087
msgid "Consume mode" msgid "Consume mode"
msgstr "Playliste verbrauchen" msgstr "Playliste verbrauchen"
#: mpdevil.py:1118 #: mpdevil.py:1182
msgid "Right click to show additional information" msgid "Right click to show additional information"
msgstr "Rechtsclick für weitere Informationen" msgstr "Rechtsclick für weitere Informationen"
#: mpdevil.py:1141 #: mpdevil.py:1206
msgid "MPD-Tag" msgid "MPD-Tag"
msgstr "MPD-Tag" msgstr "MPD-Tag"
#: mpdevil.py:1144 mpdevil.py:1252 #: mpdevil.py:1209 mpdevil.py:1316
msgid "Value" msgid "Value"
msgstr "Wert" msgstr "Wert"
#: mpdevil.py:1165 #: mpdevil.py:1230
#, python-format #, python-format
msgid "" msgid ""
"%(bitrate)s kb/s, %(frequency)s kHz, %(resolution)s bit, %(channels)s " "%(bitrate)s kb/s, %(frequency)s kHz, %(resolution)s bit, %(channels)s "
@@ -160,88 +164,88 @@ msgstr ""
"%(bitrate)s kb/s, %(frequency)s kHz, %(resolution)s bit, %(channels)s " "%(bitrate)s kb/s, %(frequency)s kHz, %(resolution)s bit, %(channels)s "
"Kanäle, %(file_type)s" "Kanäle, %(file_type)s"
#: mpdevil.py:1231 #: mpdevil.py:1295
msgid "Stats" msgid "Stats"
msgstr "Statistik" msgstr "Statistik"
#: mpdevil.py:1249 #: mpdevil.py:1313
msgid "Tag" msgid "Tag"
msgstr "Tag" msgstr "Tag"
#: mpdevil.py:1269 #: mpdevil.py:1333
msgid "Search" msgid "Search"
msgstr "Suche" msgstr "Suche"
#: mpdevil.py:1317 #: mpdevil.py:1384
msgid "Album" msgid "Album"
msgstr "Album" msgstr "Album"
#: mpdevil.py:1377 #: mpdevil.py:1446
#, python-format #, python-format
msgid "Hits: %i" msgid "Hits: %i"
msgstr "Treffer: %i" msgstr "Treffer: %i"
#: mpdevil.py:1381 #: mpdevil.py:1450
msgid "Lyrics" msgid "Lyrics"
msgstr "Liedtext" msgstr "Liedtext"
#: mpdevil.py:1425 #: mpdevil.py:1490
msgid "searching..." msgid "searching..."
msgstr "suche..." msgstr "suche..."
#: mpdevil.py:1429 #: mpdevil.py:1494
msgid "not found" msgid "not found"
msgstr "nicht gefunden" msgstr "nicht gefunden"
#: mpdevil.py:1434 #: mpdevil.py:1499
msgid "not connected" msgid "not connected"
msgstr "nicht verbunden" msgstr "nicht verbunden"
#: mpdevil.py:1514 #: mpdevil.py:1576
msgid "Select profile" msgid "Select profile"
msgstr "Profil auswählen" msgstr "Profil auswählen"
#: mpdevil.py:1518 #: mpdevil.py:1580
msgid "Return to album of current title" msgid "Return to album of current title"
msgstr "Zu Album des aktuellen Titels zurückkehren" msgstr "Zu Album des aktuellen Titels zurückkehren"
#: mpdevil.py:1520 #: mpdevil.py:1582
msgid "Title search" msgid "Title search"
msgstr "Titelsuche" msgstr "Titelsuche"
#: mpdevil.py:1522 #: mpdevil.py:1584
msgid "Show lyrics" msgid "Show lyrics"
msgstr "Zeige Liedtext" msgstr "Zeige Liedtext"
#: mpdevil.py:1529 #: mpdevil.py:1591
msgid "Not connected to MPD-server. Reconnect?" msgid "Not connected to MPD-server. Reconnect?"
msgstr "Nicht mit MPD-Server verbunden. Verbindung wiederherstellen?" msgstr "Nicht mit MPD-Server verbunden. Verbindung wiederherstellen?"
#: mpdevil.py:1533 #: mpdevil.py:1595
msgid "Save window size" msgid "Save window size"
msgstr "Fenstergröße speichern" msgstr "Fenstergröße speichern"
#: mpdevil.py:1535 #: mpdevil.py:1597
msgid "Update database" msgid "Update database"
msgstr "Datenbank aktualisieren" msgstr "Datenbank aktualisieren"
#: mpdevil.py:1536 #: mpdevil.py:1598
msgid "Server stats" msgid "Server stats"
msgstr "Serverstatistik" msgstr "Serverstatistik"
#: mpdevil.py:1537 #: mpdevil.py:1599
msgid "About" msgid "About"
msgstr "Über" msgstr "Über"
#: mpdevil.py:1538 #: mpdevil.py:1600
msgid "Quit" msgid "Quit"
msgstr "Beenden" msgstr "Beenden"
#: mpdevil.py:1543 #: mpdevil.py:1605
msgid "Main menu" msgid "Main menu"
msgstr "Hauptmenu" msgstr "Hauptmenu"
#: mpdevil.py:1696 #: mpdevil.py:1758
msgid "A small MPD client written in python" msgid "A small MPD client written in python"
msgstr "" msgstr ""

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2020-01-17 22:33+0100\n" "POT-Creation-Date: 2020-01-28 19:56+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,227 +17,231 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n" "Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
#: mpdevil.py:120 mpdevil.py:328 mpdevil.py:1302 #: mpdevil.py:159 mpdevil.py:368 mpdevil.py:1366
msgid "No" msgid "No"
msgstr "" msgstr ""
#: mpdevil.py:125 mpdevil.py:333 mpdevil.py:1307 #: mpdevil.py:164 mpdevil.py:373 mpdevil.py:1372
msgid "Title" msgid "Title"
msgstr "" msgstr ""
#: mpdevil.py:130 mpdevil.py:338 mpdevil.py:1312 #: mpdevil.py:169 mpdevil.py:378 mpdevil.py:1378
msgid "Artist" msgid "Artist"
msgstr "" msgstr ""
#: mpdevil.py:135 mpdevil.py:343 mpdevil.py:1322 #: mpdevil.py:174 mpdevil.py:383 mpdevil.py:1390
msgid "Length" msgid "Length"
msgstr "" msgstr ""
#: mpdevil.py:174 mpdevil.py:431 mpdevil.py:1358 #: mpdevil.py:214 mpdevil.py:483 mpdevil.py:1427
msgid "Unknown Title" msgid "Unknown Title"
msgstr "" msgstr ""
#: mpdevil.py:178 mpdevil.py:439 mpdevil.py:1366 #: mpdevil.py:218 mpdevil.py:491 mpdevil.py:1435
msgid "Unknown Artist" msgid "Unknown Artist"
msgstr "" msgstr ""
#: mpdevil.py:214 #: mpdevil.py:254
msgid "Album Artist" msgid "Album Artist"
msgstr "" msgstr ""
#: mpdevil.py:273 #: mpdevil.py:313 mpdevil.py:504
#, python-format #, python-format
msgid "%(total_tracks)i titles (%(total_length)s)" msgid "%(total_tracks)i titles (%(total_length)s)"
msgstr "" msgstr ""
#: mpdevil.py:443 mpdevil.py:1370 #: mpdevil.py:495 mpdevil.py:1439
msgid "Unknown Album" msgid "Unknown Album"
msgstr "" msgstr ""
#: mpdevil.py:669 #: mpdevil.py:725
msgid "Select" msgid "Select"
msgstr "" msgstr ""
#: mpdevil.py:671 #: mpdevil.py:727
msgid "Profile:" msgid "Profile:"
msgstr "" msgstr ""
#: mpdevil.py:673 #: mpdevil.py:729
msgid "Name:" msgid "Name:"
msgstr "" msgstr ""
#: mpdevil.py:675 #: mpdevil.py:731
msgid "Host:" msgid "Host:"
msgstr "" msgstr ""
#: mpdevil.py:677 #: mpdevil.py:733
msgid "Port:" msgid "Port:"
msgstr "" msgstr ""
#: mpdevil.py:679 #: mpdevil.py:735
msgid "Music lib:" msgid "Music lib:"
msgstr "" msgstr ""
#: mpdevil.py:769 #: mpdevil.py:810
msgid "Choose directory" msgid "Choose directory"
msgstr "" msgstr ""
#: mpdevil.py:805 #: mpdevil.py:846
msgid "Main cover size:" msgid "Main cover size:"
msgstr "" msgstr ""
#: mpdevil.py:807 #: mpdevil.py:848
msgid "Album-view cover size:" msgid "Album-view cover size:"
msgstr "" msgstr ""
#: mpdevil.py:813 #: mpdevil.py:854
msgid "Button icon size (restart required):"
msgstr ""
#: mpdevil.py:863
msgid "Show stop button" msgid "Show stop button"
msgstr "" msgstr ""
#: mpdevil.py:816 #: mpdevil.py:866
msgid "Show tooltips in album view" msgid "Show tooltips in album view"
msgstr "" msgstr ""
#: mpdevil.py:819 #: mpdevil.py:869
msgid "Send notification on title change" msgid "Send notification on title change"
msgstr "" msgstr ""
#: mpdevil.py:822 #: mpdevil.py:872
msgid "Stop playback on quit" msgid "Stop playback on quit"
msgstr "" msgstr ""
#: mpdevil.py:825 #: mpdevil.py:875
msgid "Play selected album after current title" msgid "Play selected album after current title"
msgstr "" msgstr ""
#: mpdevil.py:856 mpdevil.py:1534 #: mpdevil.py:913 mpdevil.py:1596
msgid "Settings" msgid "Settings"
msgstr "" msgstr ""
#: mpdevil.py:869 #: mpdevil.py:926
msgid "General" msgid "General"
msgstr "" msgstr ""
#: mpdevil.py:870 #: mpdevil.py:927
msgid "Profiles" msgid "Profiles"
msgstr "" msgstr ""
#: mpdevil.py:1018 #: mpdevil.py:1081
msgid "Random mode" msgid "Random mode"
msgstr "" msgstr ""
#: mpdevil.py:1020 #: mpdevil.py:1083
msgid "Repeat mode" msgid "Repeat mode"
msgstr "" msgstr ""
#: mpdevil.py:1022 #: mpdevil.py:1085
msgid "Single mode" msgid "Single mode"
msgstr "" msgstr ""
#: mpdevil.py:1024 #: mpdevil.py:1087
msgid "Consume mode" msgid "Consume mode"
msgstr "" msgstr ""
#: mpdevil.py:1118 #: mpdevil.py:1182
msgid "Right click to show additional information" msgid "Right click to show additional information"
msgstr "" msgstr ""
#: mpdevil.py:1141 #: mpdevil.py:1206
msgid "MPD-Tag" msgid "MPD-Tag"
msgstr "" msgstr ""
#: mpdevil.py:1144 mpdevil.py:1252 #: mpdevil.py:1209 mpdevil.py:1316
msgid "Value" msgid "Value"
msgstr "" msgstr ""
#: mpdevil.py:1165 #: mpdevil.py:1230
#, python-format #, python-format
msgid "" msgid ""
"%(bitrate)s kb/s, %(frequency)s kHz, %(resolution)s bit, %(channels)s " "%(bitrate)s kb/s, %(frequency)s kHz, %(resolution)s bit, %(channels)s "
"channels, %(file_type)s" "channels, %(file_type)s"
msgstr "" msgstr ""
#: mpdevil.py:1231 #: mpdevil.py:1295
msgid "Stats" msgid "Stats"
msgstr "" msgstr ""
#: mpdevil.py:1249 #: mpdevil.py:1313
msgid "Tag" msgid "Tag"
msgstr "" msgstr ""
#: mpdevil.py:1269 #: mpdevil.py:1333
msgid "Search" msgid "Search"
msgstr "" msgstr ""
#: mpdevil.py:1317 #: mpdevil.py:1384
msgid "Album" msgid "Album"
msgstr "" msgstr ""
#: mpdevil.py:1377 #: mpdevil.py:1446
#, python-format #, python-format
msgid "Hits: %i" msgid "Hits: %i"
msgstr "" msgstr ""
#: mpdevil.py:1381 #: mpdevil.py:1450
msgid "Lyrics" msgid "Lyrics"
msgstr "" msgstr ""
#: mpdevil.py:1425 #: mpdevil.py:1490
msgid "searching..." msgid "searching..."
msgstr "" msgstr ""
#: mpdevil.py:1429 #: mpdevil.py:1494
msgid "not found" msgid "not found"
msgstr "" msgstr ""
#: mpdevil.py:1434 #: mpdevil.py:1499
msgid "not connected" msgid "not connected"
msgstr "" msgstr ""
#: mpdevil.py:1514 #: mpdevil.py:1576
msgid "Select profile" msgid "Select profile"
msgstr "" msgstr ""
#: mpdevil.py:1518 #: mpdevil.py:1580
msgid "Return to album of current title" msgid "Return to album of current title"
msgstr "" msgstr ""
#: mpdevil.py:1520 #: mpdevil.py:1582
msgid "Title search" msgid "Title search"
msgstr "" msgstr ""
#: mpdevil.py:1522 #: mpdevil.py:1584
msgid "Show lyrics" msgid "Show lyrics"
msgstr "" msgstr ""
#: mpdevil.py:1529 #: mpdevil.py:1591
msgid "Not connected to MPD-server. Reconnect?" msgid "Not connected to MPD-server. Reconnect?"
msgstr "" msgstr ""
#: mpdevil.py:1533 #: mpdevil.py:1595
msgid "Save window size" msgid "Save window size"
msgstr "" msgstr ""
#: mpdevil.py:1535 #: mpdevil.py:1597
msgid "Update database" msgid "Update database"
msgstr "" msgstr ""
#: mpdevil.py:1536 #: mpdevil.py:1598
msgid "Server stats" msgid "Server stats"
msgstr "" msgstr ""
#: mpdevil.py:1537 #: mpdevil.py:1599
msgid "About" msgid "About"
msgstr "" msgstr ""
#: mpdevil.py:1538 #: mpdevil.py:1600
msgid "Quit" msgid "Quit"
msgstr "" msgstr ""
#: mpdevil.py:1543 #: mpdevil.py:1605
msgid "Main menu" msgid "Main menu"
msgstr "" msgstr ""
#: mpdevil.py:1696 #: mpdevil.py:1758
msgid "A small MPD client written in python" msgid "A small MPD client written in python"
msgstr "" msgstr ""