mirror of
https://github.com/SoongNoonien/mpdevil.git
synced 2023-08-10 21:12:44 +03:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fbf6afd358 | ||
![]() |
e72625879c | ||
![]() |
839d13e84a | ||
![]() |
277ddbabaa | ||
![]() |
af25d49119 | ||
![]() |
49b277d38f | ||
![]() |
c950aff51b | ||
![]() |
b7f95b5ca9 | ||
![]() |
981c1b0f30 | ||
![]() |
c388cc7342 | ||
![]() |
36a94350ac | ||
![]() |
c9165cf742 | ||
![]() |
074016a686 | ||
![]() |
3b3ccf1cbd |
@@ -20,7 +20,6 @@ Features
|
|||||||
TODO
|
TODO
|
||||||
----
|
----
|
||||||
1. MPRIS interface
|
1. MPRIS interface
|
||||||
2. connecting to mpd servers with password
|
|
||||||
|
|
||||||
Building and installation
|
Building and installation
|
||||||
-------------------------
|
-------------------------
|
||||||
|
480
bin/mpdevil.py
480
bin/mpdevil.py
@@ -82,11 +82,16 @@ class Client(MPDClient):
|
|||||||
def __init__(self, settings):
|
def __init__(self, settings):
|
||||||
MPDClient.__init__(self)
|
MPDClient.__init__(self)
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
|
self.song_to_delete=""
|
||||||
|
|
||||||
def try_connect_default(self):
|
def try_connect_default(self):
|
||||||
active=self.settings.get_int("active-profile")
|
active=self.settings.get_int("active-profile")
|
||||||
try:
|
try:
|
||||||
self.connect(self.settings.get_value("hosts")[active], self.settings.get_value("ports")[active])
|
self.connect(self.settings.get_value("hosts")[active], self.settings.get_value("ports")[active])
|
||||||
|
if self.settings.get_value("passwords")[active] == "":
|
||||||
|
self.password(None)
|
||||||
|
else:
|
||||||
|
self.password(self.settings.get_value("passwords")[active])
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -97,6 +102,38 @@ class Client(MPDClient):
|
|||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def album_to_playlist(self, album, artist, year, append, force=False):
|
||||||
|
if append:
|
||||||
|
songs=self.find("album", album, "date", year, "albumartist", artist)
|
||||||
|
if not songs == []:
|
||||||
|
for song in songs:
|
||||||
|
self.add(song["file"])
|
||||||
|
else:
|
||||||
|
if self.settings.get_boolean("add-album") and not force and not self.status()["state"] == "stop":
|
||||||
|
status=self.status()
|
||||||
|
self.moveid(status["songid"], 0)
|
||||||
|
self.song_to_delete=self.playlistinfo()[0]["file"]
|
||||||
|
try:
|
||||||
|
self.delete((1,)) # delete all songs, but the first. #bad song index possible
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
songs=self.find("album", album, "date", year, "albumartist", artist)
|
||||||
|
if not songs == []:
|
||||||
|
for song in songs:
|
||||||
|
if not song["file"] == self.song_to_delete:
|
||||||
|
self.add(song["file"])
|
||||||
|
else:
|
||||||
|
self.move(0, (len(self.playlist())-1))
|
||||||
|
self.song_to_delete=""
|
||||||
|
else:
|
||||||
|
songs=self.find("album", album, "date", year, "albumartist", artist)
|
||||||
|
if not songs == []:
|
||||||
|
self.stop()
|
||||||
|
self.clear()
|
||||||
|
for song in songs:
|
||||||
|
self.add(song["file"])
|
||||||
|
self.play()
|
||||||
|
|
||||||
class Settings(Gio.Settings):
|
class Settings(Gio.Settings):
|
||||||
BASE_KEY = "org.mpdevil"
|
BASE_KEY = "org.mpdevil"
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -121,11 +158,14 @@ class Settings(Gio.Settings):
|
|||||||
icon_size=self.get_int(key)
|
icon_size=self.get_int(key)
|
||||||
if icon_size == 16:
|
if icon_size == 16:
|
||||||
return Gtk.IconSize.BUTTON
|
return Gtk.IconSize.BUTTON
|
||||||
|
elif icon_size == 24:
|
||||||
|
return Gtk.IconSize.LARGE_TOOLBAR
|
||||||
elif icon_size == 32:
|
elif icon_size == 32:
|
||||||
return Gtk.IconSize.DND
|
return Gtk.IconSize.DND
|
||||||
elif icon_size == 48:
|
elif icon_size == 48:
|
||||||
return Gtk.IconSize.DIALOG
|
return Gtk.IconSize.DIALOG
|
||||||
else:
|
else:
|
||||||
|
# return Gtk.IconSize.INVALID
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
class AlbumDialog(Gtk.Dialog):
|
class AlbumDialog(Gtk.Dialog):
|
||||||
@@ -247,7 +287,7 @@ class ArtistView(Gtk.ScrolledWindow):
|
|||||||
|
|
||||||
#artistSelection
|
#artistSelection
|
||||||
self.selection = self.treeview.get_selection()
|
self.selection = self.treeview.get_selection()
|
||||||
self.selection.set_mode(Gtk.SelectionMode.SINGLE)
|
self.selection.set_mode(Gtk.SelectionMode.MULTIPLE)
|
||||||
|
|
||||||
#Old Name Column
|
#Old Name Column
|
||||||
renderer_text = Gtk.CellRendererText()
|
renderer_text = Gtk.CellRendererText()
|
||||||
@@ -261,6 +301,10 @@ class ArtistView(Gtk.ScrolledWindow):
|
|||||||
|
|
||||||
self.add(self.treeview)
|
self.add(self.treeview)
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self.store.clear()
|
||||||
|
self.albumartists=[]
|
||||||
|
|
||||||
def refresh(self): #returns True if refresh was actually performed
|
def refresh(self): #returns True if refresh was actually performed
|
||||||
if self.client.connected():
|
if self.client.connected():
|
||||||
if self.albumartists != self.client.list("albumartist"):
|
if self.albumartists != self.client.list("albumartist"):
|
||||||
@@ -272,70 +316,171 @@ class ArtistView(Gtk.ScrolledWindow):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
self.store.clear()
|
self.clear()
|
||||||
self.albumartists=[]
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def get_selected_artists(self):
|
||||||
|
paths=self.selection.get_selected_rows()[1]
|
||||||
|
artists=[]
|
||||||
|
for path in paths:
|
||||||
|
treeiter = self.store.get_iter(path)
|
||||||
|
if not treeiter == None:
|
||||||
|
selected_artist=self.store.get_value(treeiter, 0)
|
||||||
|
artists.append(selected_artist)
|
||||||
|
return artists
|
||||||
|
|
||||||
|
class AlbumIconView(Gtk.IconView):
|
||||||
|
def __init__(self, client, settings, window):
|
||||||
|
Gtk.IconView.__init__(self)
|
||||||
|
|
||||||
|
#adding vars
|
||||||
|
self.settings=settings
|
||||||
|
self.client=client
|
||||||
|
self.window=window
|
||||||
|
|
||||||
|
#cover, display_label, tooltip(titles), album, year, artist
|
||||||
|
self.store = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str, str, str, str)
|
||||||
|
self.store.set_sort_column_id(4, Gtk.SortType.ASCENDING)
|
||||||
|
|
||||||
|
#iconview
|
||||||
|
self.set_model(self.store)
|
||||||
|
self.set_pixbuf_column(0)
|
||||||
|
self.set_text_column(1)
|
||||||
|
self.set_item_width(0)
|
||||||
|
self.tooltip_settings()
|
||||||
|
|
||||||
|
#connect
|
||||||
|
self.album_change=self.connect("selection-changed", self.on_album_selection_change)
|
||||||
|
self.album_item_activated=self.connect("item-activated", self.on_album_item_activated)
|
||||||
|
self.connect("button-press-event", self.on_album_view_button_press_event)
|
||||||
|
self.settings.connect("changed::show-album-view-tooltips", self.tooltip_settings)
|
||||||
|
|
||||||
|
def tooltip_settings(self, *args):
|
||||||
|
if self.settings.get_boolean("show-album-view-tooltips"):
|
||||||
|
self.set_tooltip_column(2)
|
||||||
|
else:
|
||||||
|
self.set_tooltip_column(-1)
|
||||||
|
|
||||||
|
def gen_tooltip(self, album, artist, year):
|
||||||
|
songs=self.client.find("album", album, "date", year, "albumartist", artist)
|
||||||
|
length=float(0)
|
||||||
|
for song in songs:
|
||||||
|
try:
|
||||||
|
dura=float(song["duration"])
|
||||||
|
except:
|
||||||
|
dura=0.0
|
||||||
|
length=length+dura
|
||||||
|
length_human_readable=str(datetime.timedelta(seconds=int(length)))
|
||||||
|
tooltip=(_("%(total_tracks)i titles (%(total_length)s)") % {"total_tracks": len(songs), "total_length": length_human_readable})
|
||||||
|
return tooltip
|
||||||
|
|
||||||
|
def populate(self, artists):
|
||||||
|
for artist in artists:
|
||||||
|
size=self.settings.get_int("album-cover")
|
||||||
|
albums=[]
|
||||||
|
for album in self.client.list("album", "albumartist", artist):
|
||||||
|
albums.append({"album": album, "year": self.client.list("date", "album", album, "albumartist", artist)[0]})
|
||||||
|
albums = sorted(albums, key=lambda k: k['year'])
|
||||||
|
for album in albums:
|
||||||
|
if self.get_visible():
|
||||||
|
songs=self.client.find("album", album["album"], "date", album["year"], "albumartist", artist)
|
||||||
|
if songs == []:
|
||||||
|
song_file=None
|
||||||
|
else:
|
||||||
|
song_file=songs[0]["file"]
|
||||||
|
cover=Cover(client=self.client, lib_path=self.settings.get_value("paths")[self.settings.get_int("active-profile")], song_file=song_file)
|
||||||
|
img=cover.get_pixbuf(size)
|
||||||
|
if album["year"] == "":
|
||||||
|
self.store.append([img, album["album"], self.gen_tooltip(album["album"], artist, album["year"]), album["album"], album["year"], artist])
|
||||||
|
else:
|
||||||
|
self.store.append([img, album["album"]+" ("+album["year"]+")", self.gen_tooltip(album["album"], artist, album["year"]), album["album"], album["year"], artist])
|
||||||
|
while Gtk.events_pending():
|
||||||
|
Gtk.main_iteration_do(True)
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
def scroll_to_selected_album(self, first_run):
|
||||||
|
songid=self.client.status()["songid"]
|
||||||
|
song=self.client.playlistid(songid)[0]
|
||||||
|
if not self.settings.get_boolean("add-album") or first_run:
|
||||||
|
self.handler_block(self.album_change)
|
||||||
|
self.unselect_all()
|
||||||
|
row_num=len(self.store)
|
||||||
|
for i in range(0, row_num):
|
||||||
|
path=Gtk.TreePath(i)
|
||||||
|
treeiter = self.store.get_iter(path)
|
||||||
|
if self.store.get_value(treeiter, 3) == song["album"]:
|
||||||
|
self.select_path(path)
|
||||||
|
self.scroll_to_path(path, True, 0, 0)
|
||||||
|
break
|
||||||
|
if not self.settings.get_boolean("add-album") or first_run:
|
||||||
|
self.handler_unblock(self.album_change)
|
||||||
|
|
||||||
|
def on_album_view_button_press_event(self, widget, event):
|
||||||
|
path = widget.get_path_at_pos(int(event.x), int(event.y))
|
||||||
|
if not path == None:
|
||||||
|
if not event.button == 1:
|
||||||
|
treeiter=self.store.get_iter(path)
|
||||||
|
selected_album=self.store.get_value(treeiter, 3)
|
||||||
|
selected_album_year=self.store.get_value(treeiter, 4)
|
||||||
|
selected_artist=self.store.get_value(treeiter, 5)
|
||||||
|
if event.button == 2:
|
||||||
|
self.client.album_to_playlist(selected_album, selected_artist, selected_album_year, True)
|
||||||
|
elif event.button == 3:
|
||||||
|
if self.client.connected():
|
||||||
|
album = AlbumDialog(self.window, self.client, selected_album, selected_artist, selected_album_year)
|
||||||
|
response = album.run()
|
||||||
|
if response == Gtk.ResponseType.OK:
|
||||||
|
self.select_path(path)
|
||||||
|
elif response == Gtk.ResponseType.ACCEPT:
|
||||||
|
self.client.album_to_playlist(selected_album, selected_artist, selected_album_year, True)
|
||||||
|
elif response == Gtk.ResponseType.YES:
|
||||||
|
self.client.album_to_playlist(selected_album, selected_artist, selected_album_year, False, True)
|
||||||
|
album.destroy()
|
||||||
|
|
||||||
|
def on_album_selection_change(self, widget):
|
||||||
|
paths=widget.get_selected_items()
|
||||||
|
if not len(paths) == 0:
|
||||||
|
treeiter=self.store.get_iter(paths[0])
|
||||||
|
selected_album=self.store.get_value(treeiter, 3)
|
||||||
|
selected_album_year=self.store.get_value(treeiter, 4)
|
||||||
|
selected_artist=self.store.get_value(treeiter, 5)
|
||||||
|
self.client.album_to_playlist(selected_album, selected_artist, selected_album_year, False)
|
||||||
|
|
||||||
|
def on_album_item_activated(self, widget, path):
|
||||||
|
treeiter=self.store.get_iter(path)
|
||||||
|
selected_album=self.store.get_value(treeiter, 3)
|
||||||
|
selected_album_year=self.store.get_value(treeiter, 4)
|
||||||
|
selected_artist=self.store.get_value(treeiter, 5)
|
||||||
|
self.client.album_to_playlist(selected_album, selected_artist, selected_album_year, False, True)
|
||||||
|
|
||||||
class AlbumView(Gtk.ScrolledWindow):
|
class AlbumView(Gtk.ScrolledWindow):
|
||||||
def __init__(self, client, settings):
|
def __init__(self, client, settings, window):
|
||||||
Gtk.ScrolledWindow.__init__(self)
|
Gtk.ScrolledWindow.__init__(self)
|
||||||
self.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
self.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
||||||
|
|
||||||
#adding vars
|
#adding vars
|
||||||
self.settings=settings
|
self.settings=settings
|
||||||
self.client=client
|
self.client=client
|
||||||
|
self.window=window
|
||||||
|
|
||||||
#cover, display_label, tooltip(titles), album, year
|
self.iconview=None
|
||||||
self.store = Gtk.ListStore(GdkPixbuf.Pixbuf, str, str, str, str)
|
|
||||||
self.store.set_sort_column_id(4, Gtk.SortType.ASCENDING)
|
|
||||||
|
|
||||||
#iconview
|
def clear(self):
|
||||||
self.iconview = Gtk.IconView.new()
|
if self.iconview:
|
||||||
self.iconview.set_model(self.store)
|
self.remove(self.iconview)
|
||||||
self.iconview.set_pixbuf_column(0)
|
self.iconview.destroy()
|
||||||
self.iconview.set_text_column(1)
|
self.iconview=None
|
||||||
self.iconview.set_tooltip_column(2)
|
|
||||||
self.iconview.set_item_width(0)
|
|
||||||
|
|
||||||
|
def refresh(self, artists):
|
||||||
|
self.clear()
|
||||||
|
self.iconview=AlbumIconView(self.client, self.settings, self.window)
|
||||||
self.add(self.iconview)
|
self.add(self.iconview)
|
||||||
|
self.iconview.show_all()
|
||||||
|
self.iconview.populate(artists)
|
||||||
|
|
||||||
def gen_tooltip(self, album, artist, year):
|
def scroll_to_selected_album(self, first_run):
|
||||||
if self.settings.get_boolean("show-album-view-tooltips"):
|
self.iconview.scroll_to_selected_album(first_run)
|
||||||
songs=self.client.find("album", album, "date", year, "albumartist", artist)
|
|
||||||
length=float(0)
|
|
||||||
for song in songs:
|
|
||||||
try:
|
|
||||||
dura=float(song["duration"])
|
|
||||||
except:
|
|
||||||
dura=0.0
|
|
||||||
length=length+dura
|
|
||||||
length_human_readable=str(datetime.timedelta(seconds=int(length)))
|
|
||||||
tooltip=(_("%(total_tracks)i titles (%(total_length)s)") % {"total_tracks": len(songs), "total_length": length_human_readable})
|
|
||||||
return tooltip
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def refresh(self, artist):
|
|
||||||
self.store.clear()
|
|
||||||
size=self.settings.get_int("album-cover")
|
|
||||||
albums=[]
|
|
||||||
for album in self.client.list("album", "albumartist", artist):
|
|
||||||
albums.append({"album": album, "year": self.client.list("date", "album", album, "albumartist", artist)[0]})
|
|
||||||
albums = sorted(albums, key=lambda k: k['year'])
|
|
||||||
for album in albums:
|
|
||||||
songs=self.client.find("album", album["album"], "date", album["year"], "albumartist", artist)
|
|
||||||
if songs == []:
|
|
||||||
song_file=None
|
|
||||||
else:
|
|
||||||
song_file=songs[0]["file"]
|
|
||||||
cover=Cover(client=self.client, lib_path=self.settings.get_value("paths")[self.settings.get_int("active-profile")], song_file=song_file)
|
|
||||||
img=cover.get_pixbuf(size)
|
|
||||||
if album["year"] == "":
|
|
||||||
self.store.append([img, album["album"], self.gen_tooltip(album["album"], artist, album["year"]), album["album"], album["year"]])
|
|
||||||
else:
|
|
||||||
self.store.append([img, album["album"]+" ("+album["year"]+")", self.gen_tooltip(album["album"], artist, album["year"]), album["album"], album["year"]])
|
|
||||||
while Gtk.events_pending():
|
|
||||||
Gtk.main_iteration_do(True)
|
|
||||||
|
|
||||||
class TrackView(Gtk.Box):
|
class TrackView(Gtk.Box):
|
||||||
def __init__(self, client, settings):
|
def __init__(self, client, settings):
|
||||||
@@ -345,7 +490,6 @@ class TrackView(Gtk.Box):
|
|||||||
#adding vars
|
#adding vars
|
||||||
self.client=client
|
self.client=client
|
||||||
self.playlist=[]
|
self.playlist=[]
|
||||||
self.song_to_delete=""
|
|
||||||
self.hovered_songpos=None
|
self.hovered_songpos=None
|
||||||
self.song_file=None
|
self.song_file=None
|
||||||
|
|
||||||
@@ -408,7 +552,6 @@ class TrackView(Gtk.Box):
|
|||||||
status_bar.pack_end(audio, False, False, 0)
|
status_bar.pack_end(audio, False, False, 0)
|
||||||
|
|
||||||
#timeouts
|
#timeouts
|
||||||
GLib.timeout_add(1000, self.update_cover)
|
|
||||||
GLib.timeout_add(100, self.refresh)
|
GLib.timeout_add(100, self.refresh)
|
||||||
|
|
||||||
#connect
|
#connect
|
||||||
@@ -423,7 +566,13 @@ class TrackView(Gtk.Box):
|
|||||||
self.pack_start(scroll, True, True, 0)
|
self.pack_start(scroll, True, True, 0)
|
||||||
self.pack_end(status_bar, False, False, 0)
|
self.pack_end(status_bar, False, False, 0)
|
||||||
|
|
||||||
def update_cover(self):
|
def scroll_to_selected_title(self):
|
||||||
|
treeview, treeiter=self.selection.get_selected()
|
||||||
|
if not treeiter == None:
|
||||||
|
path=treeview.get_path(treeiter)
|
||||||
|
self.treeview.scroll_to_cell(path)
|
||||||
|
|
||||||
|
def refresh_cover(self):
|
||||||
try:
|
try:
|
||||||
song_file=self.client.currentsong()["file"]
|
song_file=self.client.currentsong()["file"]
|
||||||
except:
|
except:
|
||||||
@@ -433,39 +582,29 @@ class TrackView(Gtk.Box):
|
|||||||
self.song_file=song_file
|
self.song_file=song_file
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def album_to_playlist(self, album, artist, year, append, force=False):
|
def refresh_playlist_info(self):
|
||||||
if append:
|
songs=self.client.playlistinfo()
|
||||||
songs=self.client.find("album", album, "date", year, "albumartist", artist)
|
if not songs == []:
|
||||||
if not songs == []:
|
whole_length=float(0)
|
||||||
for song in songs:
|
for song in songs:
|
||||||
self.client.add(song["file"])
|
|
||||||
else:
|
|
||||||
if self.settings.get_boolean("add-album") and not force and not self.client.status()["state"] == "stop":
|
|
||||||
self.selection.handler_block(self.title_change)
|
|
||||||
status=self.client.status()
|
|
||||||
self.client.moveid(status["songid"], 0)
|
|
||||||
self.song_to_delete=self.client.playlistinfo()[0]["file"]
|
|
||||||
self.selection.handler_unblock(self.title_change)
|
|
||||||
try:
|
try:
|
||||||
self.client.delete((1,)) # delete all songs, but the first. #bad song index possible
|
dura=float(song["duration"])
|
||||||
except:
|
except:
|
||||||
pass
|
dura=0.0
|
||||||
songs=self.client.find("album", album, "date", year, "albumartist", artist)
|
whole_length=whole_length+dura
|
||||||
if not songs == []:
|
whole_length_human_readable=str(datetime.timedelta(seconds=int(whole_length)))
|
||||||
for song in songs:
|
self.playlist_info.set_text(_("%(total_tracks)i titles (%(total_length)s)") % {"total_tracks": len(songs), "total_length": whole_length_human_readable})
|
||||||
if not song["file"] == self.song_to_delete:
|
else:
|
||||||
self.client.add(song["file"])
|
self.playlist_info.set_text("")
|
||||||
else:
|
|
||||||
self.client.move(0, (len(self.client.playlist())-1))
|
def refresh_selection(self):
|
||||||
self.song_to_delete=""
|
try:
|
||||||
else:
|
song=self.client.status()["song"]
|
||||||
songs=self.client.find("album", album, "date", year, "albumartist", artist)
|
path = Gtk.TreePath(int(song))
|
||||||
if not songs == []:
|
self.selection.select_path(path)
|
||||||
self.client.stop()
|
except:
|
||||||
self.client.clear()
|
self.selection.unselect_all()
|
||||||
for song in songs:
|
self.refresh_cover()
|
||||||
self.client.add(song["file"])
|
|
||||||
self.client.play()
|
|
||||||
|
|
||||||
def refresh(self):
|
def refresh(self):
|
||||||
self.selection.handler_block(self.title_change)
|
self.selection.handler_block(self.title_change)
|
||||||
@@ -475,7 +614,6 @@ class TrackView(Gtk.Box):
|
|||||||
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"]
|
||||||
@@ -497,31 +635,28 @@ 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.refresh_playlist_info()
|
||||||
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()
|
||||||
|
self.refresh_selection()
|
||||||
|
self.scroll_to_selected_title()
|
||||||
else:
|
else:
|
||||||
if not self.song_to_delete == "":
|
if not self.client.song_to_delete == "":
|
||||||
status=self.client.status()
|
status=self.client.status()
|
||||||
if not status["song"] == "0":
|
if not status["song"] == "0":
|
||||||
if self.client.playlistinfo()[0]["file"] == self.song_to_delete:
|
if self.client.playlistinfo()[0]["file"] == self.client.song_to_delete:
|
||||||
self.client.delete(0)
|
self.client.delete(0)
|
||||||
self.playlist=self.client.playlist()
|
self.playlist=self.client.playlist()
|
||||||
self.store.remove(self.store.get_iter_first())
|
self.store.remove(self.store.get_iter_first())
|
||||||
self.song_to_delete=""
|
self.refresh_playlist_info()
|
||||||
try:
|
self.client.song_to_delete=""
|
||||||
song=self.client.status()["song"]
|
self.refresh_selection()
|
||||||
path = Gtk.TreePath(int(song))
|
|
||||||
self.selection.select_path(path)
|
|
||||||
except:
|
|
||||||
self.selection.unselect_all()
|
|
||||||
else:
|
else:
|
||||||
self.playlist_info.set_text("")
|
self.playlist_info.set_text("")
|
||||||
self.store.clear()
|
self.store.clear()
|
||||||
self.playlist=[]
|
self.playlist=[]
|
||||||
|
self.refresh_cover()
|
||||||
self.selection.handler_unblock(self.title_change)
|
self.selection.handler_unblock(self.title_change)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -534,18 +669,21 @@ class TrackView(Gtk.Box):
|
|||||||
self.client.delete(self.hovered_songpos) #bad song index possible
|
self.client.delete(self.hovered_songpos) #bad song index possible
|
||||||
self.playlist=self.client.playlist()
|
self.playlist=self.client.playlist()
|
||||||
self.store.remove(self.store.get_iter(self.hovered_songpos))
|
self.store.remove(self.store.get_iter(self.hovered_songpos))
|
||||||
|
self.refresh_playlist_info()
|
||||||
except:
|
except:
|
||||||
self.hovered_songpos == None
|
self.hovered_songpos == None
|
||||||
self.selection.handler_unblock(self.title_change)
|
self.selection.handler_unblock(self.title_change)
|
||||||
self.treeview.handler_unblock(self.key_press_event)
|
self.treeview.handler_unblock(self.key_press_event)
|
||||||
|
|
||||||
def on_move_event(self, widget, event):
|
def on_move_event(self, widget, event):
|
||||||
self.treeview.grab_focus()
|
treeiter=self.selection.get_selected()[1]
|
||||||
return_tuple = self.treeview.get_path_at_pos(int(event.x), int(event.y))
|
if not treeiter == None:
|
||||||
if not return_tuple == None:
|
self.treeview.grab_focus()
|
||||||
self.hovered_songpos=return_tuple[0]
|
return_tuple = self.treeview.get_path_at_pos(int(event.x), int(event.y))
|
||||||
else:
|
if not return_tuple == None:
|
||||||
self.hovered_songpos=None
|
self.hovered_songpos=return_tuple[0]
|
||||||
|
else:
|
||||||
|
self.hovered_songpos=None
|
||||||
|
|
||||||
def on_leave_event(self, widget, event):
|
def on_leave_event(self, widget, event):
|
||||||
self.hovered_songpos=None
|
self.hovered_songpos=None
|
||||||
@@ -555,6 +693,7 @@ class TrackView(Gtk.Box):
|
|||||||
if not treeiter == None:
|
if not treeiter == None:
|
||||||
selected_title=self.store.get_path(treeiter)
|
selected_title=self.store.get_path(treeiter)
|
||||||
self.client.play(selected_title)
|
self.client.play(selected_title)
|
||||||
|
self.refresh_cover()
|
||||||
|
|
||||||
def on_row_activated(self, widget, path, view_column):
|
def on_row_activated(self, widget, path, view_column):
|
||||||
treeiter=self.store.get_iter(path)
|
treeiter=self.store.get_iter(path)
|
||||||
@@ -572,20 +711,15 @@ class Browser(Gtk.Box):
|
|||||||
|
|
||||||
#widgets
|
#widgets
|
||||||
self.artist_list=ArtistView(self.client)
|
self.artist_list=ArtistView(self.client)
|
||||||
self.album_list=AlbumView(self.client, self.settings)
|
self.album_list=AlbumView(self.client, self.settings, self.window)
|
||||||
self.title_list=TrackView(self.client, self.settings)
|
self.title_list=TrackView(self.client, self.settings)
|
||||||
|
|
||||||
#connect
|
#connect
|
||||||
self.artist_change=self.artist_list.selection.connect("changed", self.on_artist_selection_change)
|
self.artist_change=self.artist_list.selection.connect("changed", self.on_artist_selection_change)
|
||||||
self.album_change=self.album_list.iconview.connect("selection-changed", self.on_album_selection_change)
|
|
||||||
self.album_item_activated=self.album_list.iconview.connect("item-activated", self.on_album_item_activated)
|
|
||||||
self.album_list.iconview.connect("button-press-event", self.on_album_view_button_press_event)
|
|
||||||
|
|
||||||
#timeouts
|
#timeouts
|
||||||
GLib.timeout_add(1000, self.refresh)
|
GLib.timeout_add(1000, self.refresh)
|
||||||
|
|
||||||
self.go_home(self, first_run=True)
|
|
||||||
|
|
||||||
#packing
|
#packing
|
||||||
self.paned1=Gtk.Paned.new(Gtk.Orientation.HORIZONTAL)
|
self.paned1=Gtk.Paned.new(Gtk.Orientation.HORIZONTAL)
|
||||||
self.paned2=Gtk.Paned.new(Gtk.Orientation.HORIZONTAL)
|
self.paned2=Gtk.Paned.new(Gtk.Orientation.HORIZONTAL)
|
||||||
@@ -604,103 +738,42 @@ class Browser(Gtk.Box):
|
|||||||
self.paned1.set_position(self.settings.get_int("paned1"))
|
self.paned1.set_position(self.settings.get_int("paned1"))
|
||||||
self.paned2.set_position(self.settings.get_int("paned2"))
|
self.paned2.set_position(self.settings.get_int("paned2"))
|
||||||
|
|
||||||
def refresh(self):
|
def refresh(self, *args):
|
||||||
self.artist_list.selection.handler_block(self.artist_change)
|
if self.client.connected():
|
||||||
return_val=self.artist_list.refresh()
|
self.artist_list.selection.handler_block(self.artist_change)
|
||||||
self.artist_list.selection.handler_unblock(self.artist_change)
|
return_val=self.artist_list.refresh()
|
||||||
if return_val:
|
self.artist_list.selection.handler_unblock(self.artist_change)
|
||||||
self.go_home(self, first_run=True)
|
if return_val:
|
||||||
|
self.go_home(self, first_run=True)
|
||||||
|
else:
|
||||||
|
self.artist_list.selection.handler_block(self.artist_change)
|
||||||
|
self.artist_list.clear()
|
||||||
|
self.artist_list.selection.handler_unblock(self.artist_change)
|
||||||
|
self.album_list.clear()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def go_home(self, widget, first_run=False): #TODO
|
def go_home(self, widget, first_run=False): #TODO
|
||||||
try:
|
try:
|
||||||
songid=self.client.status()["songid"]
|
songid=self.client.status()["songid"]
|
||||||
song=self.client.playlistid(songid)[0]
|
song=self.client.playlistid(songid)[0]
|
||||||
|
|
||||||
row_num=len(self.artist_list.store)
|
row_num=len(self.artist_list.store)
|
||||||
for i in range(0, row_num):
|
for i in range(0, row_num):
|
||||||
path=Gtk.TreePath(i)
|
path=Gtk.TreePath(i)
|
||||||
treeiter = self.artist_list.store.get_iter(path)
|
treeiter = self.artist_list.store.get_iter(path)
|
||||||
if self.artist_list.store.get_value(treeiter, 0) == song["albumartist"]:
|
if self.artist_list.store.get_value(treeiter, 0) == song["albumartist"]:
|
||||||
self.artist_list.selection.select_iter(treeiter)
|
if not self.artist_list.selection.iter_is_selected(treeiter):
|
||||||
|
self.artist_list.selection.unselect_all()
|
||||||
|
self.artist_list.selection.select_iter(treeiter)
|
||||||
self.artist_list.treeview.scroll_to_cell(path)
|
self.artist_list.treeview.scroll_to_cell(path)
|
||||||
break
|
break
|
||||||
if not self.settings.get_boolean("add-album") or first_run:
|
self.album_list.scroll_to_selected_album(first_run)
|
||||||
self.album_list.iconview.handler_block(self.album_change)
|
|
||||||
self.album_list.iconview.unselect_all()
|
|
||||||
row_num=len(self.album_list.store)
|
|
||||||
for i in range(0, row_num):
|
|
||||||
path=Gtk.TreePath(i)
|
|
||||||
treeiter = self.album_list.store.get_iter(path)
|
|
||||||
if self.album_list.store.get_value(treeiter, 3) == song["album"]:
|
|
||||||
self.album_list.iconview.select_path(path)
|
|
||||||
self.album_list.iconview.scroll_to_path(path, True, 0, 0)
|
|
||||||
break
|
|
||||||
if not self.settings.get_boolean("add-album") or first_run:
|
|
||||||
self.album_list.iconview.handler_unblock(self.album_change)
|
|
||||||
except:
|
except:
|
||||||
self.artist_list.selection.unselect_all()
|
pass
|
||||||
self.album_list.store.clear()
|
self.title_list.scroll_to_selected_title()
|
||||||
treeview, treeiter=self.title_list.selection.get_selected()
|
|
||||||
if not treeiter == None:
|
|
||||||
path=treeview.get_path(treeiter)
|
|
||||||
self.title_list.treeview.scroll_to_cell(path) #TODO multiple home-button presses needed
|
|
||||||
|
|
||||||
def on_album_view_button_press_event(self, widget, event):
|
def on_artist_selection_change(self, *args):
|
||||||
path = widget.get_path_at_pos(int(event.x), int(event.y))
|
artists=self.artist_list.get_selected_artists()
|
||||||
if not path == None:
|
self.album_list.refresh(artists)
|
||||||
if not event.button == 1:
|
|
||||||
treeiter=self.album_list.store.get_iter(path)
|
|
||||||
selected_album=self.album_list.store.get_value(treeiter, 3)
|
|
||||||
selected_album_year=self.album_list.store.get_value(treeiter, 4)
|
|
||||||
treeiter=self.artist_list.selection.get_selected()[1]
|
|
||||||
selected_artist=self.artist_list.store.get_value(treeiter, 0)
|
|
||||||
if event.button == 2:
|
|
||||||
self.title_list.album_to_playlist(selected_album, selected_artist, selected_album_year, True)
|
|
||||||
elif event.button == 3:
|
|
||||||
if self.client.connected():
|
|
||||||
album = AlbumDialog(self.window, self.client, selected_album, selected_artist, selected_album_year)
|
|
||||||
response = album.run()
|
|
||||||
if response == Gtk.ResponseType.OK:
|
|
||||||
self.album_list.iconview.select_path(path)
|
|
||||||
elif response == Gtk.ResponseType.ACCEPT:
|
|
||||||
self.title_list.album_to_playlist(selected_album, selected_artist, selected_album_year, True)
|
|
||||||
elif response == Gtk.ResponseType.YES:
|
|
||||||
self.title_list.album_to_playlist(selected_album, selected_artist, selected_album_year, False, True)
|
|
||||||
album.destroy()
|
|
||||||
|
|
||||||
def on_album_selection_change(self, widget):
|
|
||||||
paths=widget.get_selected_items()
|
|
||||||
if not len(paths) == 0:
|
|
||||||
treeiter=self.album_list.store.get_iter(paths[0])
|
|
||||||
selected_album=self.album_list.store.get_value(treeiter, 3)
|
|
||||||
selected_album_year=self.album_list.store.get_value(treeiter, 4)
|
|
||||||
treeiter=self.artist_list.selection.get_selected()[1]
|
|
||||||
selected_artist=self.artist_list.store.get_value(treeiter, 0)
|
|
||||||
self.title_list.album_to_playlist(selected_album, selected_artist, selected_album_year, False)
|
|
||||||
|
|
||||||
def on_album_item_activated(self, widget, path):
|
|
||||||
treeiter=self.album_list.store.get_iter(path)
|
|
||||||
selected_album=self.album_list.store.get_value(treeiter, 3)
|
|
||||||
selected_album_year=self.album_list.store.get_value(treeiter, 4)
|
|
||||||
treeiter=self.artist_list.selection.get_selected()[1]
|
|
||||||
selected_artist=self.artist_list.store.get_value(treeiter, 0)
|
|
||||||
self.title_list.album_to_playlist(selected_album, selected_artist, selected_album_year, False, True)
|
|
||||||
|
|
||||||
def on_artist_selection_change(self, widget):
|
|
||||||
treeiter=widget.get_selected()[1]
|
|
||||||
if not treeiter == None:
|
|
||||||
def test(*args):
|
|
||||||
return False
|
|
||||||
selected_artist=self.artist_list.store.get_value(treeiter, 0)
|
|
||||||
self.artist_list.selection.handler_block(self.artist_change)
|
|
||||||
self.artist_list.selection.set_select_function(test)
|
|
||||||
self.album_list.refresh(selected_artist)
|
|
||||||
self.artist_list.selection.set_select_function(None)
|
|
||||||
self.artist_list.selection.select_iter(treeiter)
|
|
||||||
self.artist_list.selection.handler_unblock(self.artist_change)
|
|
||||||
else:
|
|
||||||
self.album_list.refresh(None)
|
|
||||||
|
|
||||||
class ProfileSettings(Gtk.Grid):
|
class ProfileSettings(Gtk.Grid):
|
||||||
def __init__(self, parent, settings):
|
def __init__(self, parent, settings):
|
||||||
@@ -722,6 +795,8 @@ class ProfileSettings(Gtk.Grid):
|
|||||||
self.profile_entry=Gtk.Entry()
|
self.profile_entry=Gtk.Entry()
|
||||||
self.host_entry=Gtk.Entry()
|
self.host_entry=Gtk.Entry()
|
||||||
self.port_entry=IntEntry(0, 0, 65535)
|
self.port_entry=IntEntry(0, 0, 65535)
|
||||||
|
self.password_entry=Gtk.Entry()
|
||||||
|
self.password_entry.set_visibility(False)
|
||||||
self.path_select_button=Gtk.Button(label=_("Select"), image=Gtk.Image(stock=Gtk.STOCK_OPEN))
|
self.path_select_button=Gtk.Button(label=_("Select"), image=Gtk.Image(stock=Gtk.STOCK_OPEN))
|
||||||
|
|
||||||
profiles_label=Gtk.Label(label=_("Profile:"))
|
profiles_label=Gtk.Label(label=_("Profile:"))
|
||||||
@@ -732,13 +807,16 @@ class ProfileSettings(Gtk.Grid):
|
|||||||
host_label.set_xalign(1)
|
host_label.set_xalign(1)
|
||||||
port_label=Gtk.Label(label=_("Port:"))
|
port_label=Gtk.Label(label=_("Port:"))
|
||||||
port_label.set_xalign(1)
|
port_label.set_xalign(1)
|
||||||
|
password_label=Gtk.Label(label=_("Password:"))
|
||||||
|
password_label.set_xalign(1)
|
||||||
path_label=Gtk.Label(label=_("Music lib:"))
|
path_label=Gtk.Label(label=_("Music lib:"))
|
||||||
path_label.set_xalign(1)
|
path_label.set_xalign(1)
|
||||||
|
|
||||||
#connect
|
#connect
|
||||||
self.profile_entry_changed=self.profile_entry.connect("activate", self.on_profile_entry_changed)
|
self.profile_entry_changed=self.profile_entry.connect("changed", self.on_profile_entry_changed)
|
||||||
self.host_entry_changed=self.host_entry.connect("activate", self.on_host_entry_changed)
|
self.host_entry_changed=self.host_entry.connect("changed", self.on_host_entry_changed)
|
||||||
self.port_entry_changed=self.port_entry.connect("value-changed", self.on_port_entry_changed)
|
self.port_entry_changed=self.port_entry.connect("value-changed", self.on_port_entry_changed)
|
||||||
|
self.password_entry_changed=self.password_entry.connect("changed", self.on_password_entry_changed)
|
||||||
self.path_select_button.connect("clicked", self.on_path_select_button_clicked, parent)
|
self.path_select_button.connect("clicked", self.on_path_select_button_clicked, parent)
|
||||||
add_button.connect("clicked", self.on_add_button_clicked)
|
add_button.connect("clicked", self.on_add_button_clicked)
|
||||||
delete_button.connect("clicked", self.on_delete_button_clicked)
|
delete_button.connect("clicked", self.on_delete_button_clicked)
|
||||||
@@ -752,13 +830,15 @@ class ProfileSettings(Gtk.Grid):
|
|||||||
self.attach_next_to(profile_label, profiles_label, Gtk.PositionType.BOTTOM, 1, 1)
|
self.attach_next_to(profile_label, profiles_label, Gtk.PositionType.BOTTOM, 1, 1)
|
||||||
self.attach_next_to(host_label, profile_label, Gtk.PositionType.BOTTOM, 1, 1)
|
self.attach_next_to(host_label, profile_label, Gtk.PositionType.BOTTOM, 1, 1)
|
||||||
self.attach_next_to(port_label, host_label, Gtk.PositionType.BOTTOM, 1, 1)
|
self.attach_next_to(port_label, host_label, Gtk.PositionType.BOTTOM, 1, 1)
|
||||||
self.attach_next_to(path_label, port_label, Gtk.PositionType.BOTTOM, 1, 1)
|
self.attach_next_to(password_label, port_label, Gtk.PositionType.BOTTOM, 1, 1)
|
||||||
|
self.attach_next_to(path_label, password_label, Gtk.PositionType.BOTTOM, 1, 1)
|
||||||
self.attach_next_to(self.profiles_combo, profiles_label, Gtk.PositionType.RIGHT, 1, 1)
|
self.attach_next_to(self.profiles_combo, profiles_label, Gtk.PositionType.RIGHT, 1, 1)
|
||||||
self.attach_next_to(add_button, self.profiles_combo, Gtk.PositionType.RIGHT, 1, 1)
|
self.attach_next_to(add_button, self.profiles_combo, Gtk.PositionType.RIGHT, 1, 1)
|
||||||
self.attach_next_to(delete_button, add_button, Gtk.PositionType.RIGHT, 1, 1)
|
self.attach_next_to(delete_button, add_button, Gtk.PositionType.RIGHT, 1, 1)
|
||||||
self.attach_next_to(self.profile_entry, profile_label, Gtk.PositionType.RIGHT, 1, 1)
|
self.attach_next_to(self.profile_entry, profile_label, Gtk.PositionType.RIGHT, 1, 1)
|
||||||
self.attach_next_to(self.host_entry, host_label, Gtk.PositionType.RIGHT, 1, 1)
|
self.attach_next_to(self.host_entry, host_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.port_entry, port_label, Gtk.PositionType.RIGHT, 1, 1)
|
||||||
|
self.attach_next_to(self.password_entry, password_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 profiles_combo_reload(self, *args):
|
def profiles_combo_reload(self, *args):
|
||||||
@@ -806,6 +886,9 @@ class ProfileSettings(Gtk.Grid):
|
|||||||
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_password_entry_changed(self, *args):
|
||||||
|
self.settings.array_modify('as', "passwords", self.profiles_combo.get_active(), self.password_entry.get_text())
|
||||||
|
|
||||||
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)
|
||||||
dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
|
dialog.add_buttons(Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL)
|
||||||
@@ -822,15 +905,18 @@ class ProfileSettings(Gtk.Grid):
|
|||||||
self.profile_entry.handler_block(self.profile_entry_changed)
|
self.profile_entry.handler_block(self.profile_entry_changed)
|
||||||
self.host_entry.handler_block(self.host_entry_changed)
|
self.host_entry.handler_block(self.host_entry_changed)
|
||||||
self.port_entry.handler_block(self.port_entry_changed)
|
self.port_entry.handler_block(self.port_entry_changed)
|
||||||
|
self.password_entry.handler_block(self.password_entry_changed)
|
||||||
|
|
||||||
self.profile_entry.set_text(self.settings.get_value("profiles")[active])
|
self.profile_entry.set_text(self.settings.get_value("profiles")[active])
|
||||||
self.host_entry.set_text(self.settings.get_value("hosts")[active])
|
self.host_entry.set_text(self.settings.get_value("hosts")[active])
|
||||||
self.port_entry.set_int(self.settings.get_value("ports")[active])
|
self.port_entry.set_int(self.settings.get_value("ports")[active])
|
||||||
|
self.password_entry.set_text(self.settings.get_value("passwords")[active])
|
||||||
self.path_select_button.set_tooltip_text(self.settings.get_value("paths")[active])
|
self.path_select_button.set_tooltip_text(self.settings.get_value("paths")[active])
|
||||||
|
|
||||||
self.profile_entry.handler_unblock(self.profile_entry_changed)
|
self.profile_entry.handler_unblock(self.profile_entry_changed)
|
||||||
self.host_entry.handler_unblock(self.host_entry_changed)
|
self.host_entry.handler_unblock(self.host_entry_changed)
|
||||||
self.port_entry.handler_unblock(self.port_entry_changed)
|
self.port_entry.handler_unblock(self.port_entry_changed)
|
||||||
|
self.password_entry.handler_unblock(self.password_entry_changed)
|
||||||
|
|
||||||
class GeneralSettings(Gtk.Grid):
|
class GeneralSettings(Gtk.Grid):
|
||||||
def __init__(self, settings):
|
def __init__(self, settings):
|
||||||
@@ -855,7 +941,7 @@ class GeneralSettings(Gtk.Grid):
|
|||||||
icon_size_label.set_xalign(1)
|
icon_size_label.set_xalign(1)
|
||||||
icon_size_combo=Gtk.ComboBoxText()
|
icon_size_combo=Gtk.ComboBoxText()
|
||||||
icon_size_combo.set_entry_text_column(0)
|
icon_size_combo.set_entry_text_column(0)
|
||||||
sizes=[16, 32, 48]
|
sizes=[16, 24, 32, 48]
|
||||||
for i in sizes:
|
for i in sizes:
|
||||||
icon_size_combo.append_text(str(i))
|
icon_size_combo.append_text(str(i))
|
||||||
icon_size_combo.set_active(sizes.index(self.settings.get_int("icon-size")))
|
icon_size_combo.set_active(sizes.index(self.settings.get_int("icon-size")))
|
||||||
@@ -1267,6 +1353,7 @@ class ProfileSelect(Gtk.ComboBoxText):
|
|||||||
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::passwords", 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.reload()
|
||||||
@@ -1758,6 +1845,7 @@ class mpdevil(Gtk.Application):
|
|||||||
dialog.set_comments(_("A small MPD client written in python"))
|
dialog.set_comments(_("A small MPD client written in python"))
|
||||||
dialog.set_authors(["Martin Wagner"])
|
dialog.set_authors(["Martin Wagner"])
|
||||||
dialog.set_website("https://github.com/SoongNoonien/mpdevil")
|
dialog.set_website("https://github.com/SoongNoonien/mpdevil")
|
||||||
|
dialog.set_copyright("\xa9 2020 Martin Wagner")
|
||||||
dialog.set_logo_icon_name(PACKAGE)
|
dialog.set_logo_icon_name(PACKAGE)
|
||||||
dialog.run()
|
dialog.run()
|
||||||
dialog.destroy()
|
dialog.destroy()
|
||||||
|
@@ -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.2])
|
AC_INIT([mpdevil], [0.4.3])
|
||||||
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])
|
||||||
|
@@ -81,6 +81,11 @@
|
|||||||
<summary>List of ports</summary>
|
<summary>List of ports</summary>
|
||||||
<description></description>
|
<description></description>
|
||||||
</key>
|
</key>
|
||||||
|
<key type="as" name="passwords">
|
||||||
|
<default>[""]</default>
|
||||||
|
<summary>List of passwords</summary>
|
||||||
|
<description></description>
|
||||||
|
</key>
|
||||||
<key type="as" name="paths">
|
<key type="as" name="paths">
|
||||||
<default>[""]</default>
|
<default>[""]</default>
|
||||||
<summary>List of library paths</summary>
|
<summary>List of library paths</summary>
|
||||||
|
120
po/de.po
120
po/de.po
@@ -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-28 19:56+0100\n"
|
"POT-Creation-Date: 2020-02-01 15:50+0100\n"
|
||||||
"PO-Revision-Date: 2020-01-28 19:58+0100\n"
|
"PO-Revision-Date: 2020-02-01 15:50+0100\n"
|
||||||
"Last-Translator: \n"
|
"Last-Translator: \n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"Language: de\n"
|
"Language: de\n"
|
||||||
@@ -18,144 +18,148 @@ 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:159 mpdevil.py:368 mpdevil.py:1366
|
#: mpdevil.py:199 mpdevil.py:512 mpdevil.py:1453
|
||||||
msgid "No"
|
msgid "No"
|
||||||
msgstr "Nr."
|
msgstr "Nr."
|
||||||
|
|
||||||
#: mpdevil.py:164 mpdevil.py:373 mpdevil.py:1372
|
#: mpdevil.py:204 mpdevil.py:517 mpdevil.py:1459
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr "Titel"
|
msgstr "Titel"
|
||||||
|
|
||||||
#: mpdevil.py:169 mpdevil.py:378 mpdevil.py:1378
|
#: mpdevil.py:209 mpdevil.py:522 mpdevil.py:1465
|
||||||
msgid "Artist"
|
msgid "Artist"
|
||||||
msgstr "Interpret"
|
msgstr "Interpret"
|
||||||
|
|
||||||
#: mpdevil.py:174 mpdevil.py:383 mpdevil.py:1390
|
#: mpdevil.py:214 mpdevil.py:527 mpdevil.py:1477
|
||||||
msgid "Length"
|
msgid "Length"
|
||||||
msgstr "Länge"
|
msgstr "Länge"
|
||||||
|
|
||||||
#: mpdevil.py:214 mpdevil.py:483 mpdevil.py:1427
|
#: mpdevil.py:254 mpdevil.py:621 mpdevil.py:1514
|
||||||
msgid "Unknown Title"
|
msgid "Unknown Title"
|
||||||
msgstr "Unbekannter Titel"
|
msgstr "Unbekannter Titel"
|
||||||
|
|
||||||
#: mpdevil.py:218 mpdevil.py:491 mpdevil.py:1435
|
#: mpdevil.py:258 mpdevil.py:629 mpdevil.py:1522
|
||||||
msgid "Unknown Artist"
|
msgid "Unknown Artist"
|
||||||
msgstr "Unbekannter Künstler"
|
msgstr "Unbekannter Künstler"
|
||||||
|
|
||||||
#: mpdevil.py:254
|
#: mpdevil.py:294
|
||||||
msgid "Album Artist"
|
msgid "Album Artist"
|
||||||
msgstr "Albuminterpret"
|
msgstr "Albuminterpret"
|
||||||
|
|
||||||
#: mpdevil.py:313 mpdevil.py:504
|
#: mpdevil.py:374 mpdevil.py:596
|
||||||
#, 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:495 mpdevil.py:1439
|
#: mpdevil.py:633 mpdevil.py:1526
|
||||||
msgid "Unknown Album"
|
msgid "Unknown Album"
|
||||||
msgstr "Unbekanntes Album"
|
msgstr "Unbekanntes Album"
|
||||||
|
|
||||||
#: mpdevil.py:725
|
#: mpdevil.py:800
|
||||||
msgid "Select"
|
msgid "Select"
|
||||||
msgstr "Auswählen"
|
msgstr "Auswählen"
|
||||||
|
|
||||||
#: mpdevil.py:727
|
#: mpdevil.py:802
|
||||||
msgid "Profile:"
|
msgid "Profile:"
|
||||||
msgstr "Profil:"
|
msgstr "Profil:"
|
||||||
|
|
||||||
#: mpdevil.py:729
|
#: mpdevil.py:804
|
||||||
msgid "Name:"
|
msgid "Name:"
|
||||||
msgstr "Name:"
|
msgstr "Name:"
|
||||||
|
|
||||||
#: mpdevil.py:731
|
#: mpdevil.py:806
|
||||||
msgid "Host:"
|
msgid "Host:"
|
||||||
msgstr "Host:"
|
msgstr "Host:"
|
||||||
|
|
||||||
#: mpdevil.py:733
|
#: mpdevil.py:808
|
||||||
msgid "Port:"
|
msgid "Port:"
|
||||||
msgstr "Port:"
|
msgstr "Port:"
|
||||||
|
|
||||||
#: mpdevil.py:735
|
#: mpdevil.py:810
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr "Passwort:"
|
||||||
|
|
||||||
|
#: mpdevil.py:812
|
||||||
msgid "Music lib:"
|
msgid "Music lib:"
|
||||||
msgstr "Musikverzeichnis:"
|
msgstr "Musikverzeichnis:"
|
||||||
|
|
||||||
#: mpdevil.py:810
|
#: mpdevil.py:893
|
||||||
msgid "Choose directory"
|
msgid "Choose directory"
|
||||||
msgstr "Verzeichnis Wählen"
|
msgstr "Verzeichnis Wählen"
|
||||||
|
|
||||||
#: mpdevil.py:846
|
#: mpdevil.py:932
|
||||||
msgid "Main cover size:"
|
msgid "Main cover size:"
|
||||||
msgstr "Größe des Haupt-Covers:"
|
msgstr "Größe des Haupt-Covers:"
|
||||||
|
|
||||||
#: mpdevil.py:848
|
#: mpdevil.py:934
|
||||||
msgid "Album-view cover size:"
|
msgid "Album-view cover size:"
|
||||||
msgstr "Covergröße in Albumansicht:"
|
msgstr "Covergröße in Albumansicht:"
|
||||||
|
|
||||||
#: mpdevil.py:854
|
#: mpdevil.py:940
|
||||||
msgid "Button icon size (restart required):"
|
msgid "Button icon size (restart required):"
|
||||||
msgstr "Symbolgröße der Knöpfe (Neustart erforderlich):"
|
msgstr "Symbolgröße der Knöpfe (Neustart erforderlich):"
|
||||||
|
|
||||||
#: mpdevil.py:863
|
#: mpdevil.py:949
|
||||||
msgid "Show stop button"
|
msgid "Show stop button"
|
||||||
msgstr "Zeige Stopp-Knopf"
|
msgstr "Zeige Stopp-Knopf"
|
||||||
|
|
||||||
#: mpdevil.py:866
|
#: mpdevil.py:952
|
||||||
msgid "Show tooltips in album view"
|
msgid "Show tooltips in album view"
|
||||||
msgstr "Zeige Tooltips in Albumansicht"
|
msgstr "Zeige Tooltips in Albumansicht"
|
||||||
|
|
||||||
#: mpdevil.py:869
|
#: mpdevil.py:955
|
||||||
msgid "Send notification on title change"
|
msgid "Send notification on title change"
|
||||||
msgstr "Sende Benachrichtigung bei Titelwechsel"
|
msgstr "Sende Benachrichtigung bei Titelwechsel"
|
||||||
|
|
||||||
#: mpdevil.py:872
|
#: mpdevil.py:958
|
||||||
msgid "Stop playback on quit"
|
msgid "Stop playback on quit"
|
||||||
msgstr "Wiedergabe beim Beenden stoppen"
|
msgstr "Wiedergabe beim Beenden stoppen"
|
||||||
|
|
||||||
#: mpdevil.py:875
|
#: mpdevil.py:961
|
||||||
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:913 mpdevil.py:1596
|
#: mpdevil.py:999 mpdevil.py:1683
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Einstellungen"
|
msgstr "Einstellungen"
|
||||||
|
|
||||||
#: mpdevil.py:926
|
#: mpdevil.py:1012
|
||||||
msgid "General"
|
msgid "General"
|
||||||
msgstr "Allgemein"
|
msgstr "Allgemein"
|
||||||
|
|
||||||
#: mpdevil.py:927
|
#: mpdevil.py:1013
|
||||||
msgid "Profiles"
|
msgid "Profiles"
|
||||||
msgstr "Profile"
|
msgstr "Profile"
|
||||||
|
|
||||||
#: mpdevil.py:1081
|
#: mpdevil.py:1167
|
||||||
msgid "Random mode"
|
msgid "Random mode"
|
||||||
msgstr "Zufallsmodus"
|
msgstr "Zufallsmodus"
|
||||||
|
|
||||||
#: mpdevil.py:1083
|
#: mpdevil.py:1169
|
||||||
msgid "Repeat mode"
|
msgid "Repeat mode"
|
||||||
msgstr "Dauerschleife"
|
msgstr "Dauerschleife"
|
||||||
|
|
||||||
#: mpdevil.py:1085
|
#: mpdevil.py:1171
|
||||||
msgid "Single mode"
|
msgid "Single mode"
|
||||||
msgstr "Einzelstückmodus"
|
msgstr "Einzelstückmodus"
|
||||||
|
|
||||||
#: mpdevil.py:1087
|
#: mpdevil.py:1173
|
||||||
msgid "Consume mode"
|
msgid "Consume mode"
|
||||||
msgstr "Playliste verbrauchen"
|
msgstr "Playliste verbrauchen"
|
||||||
|
|
||||||
#: mpdevil.py:1182
|
#: mpdevil.py:1268
|
||||||
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:1206
|
#: mpdevil.py:1292
|
||||||
msgid "MPD-Tag"
|
msgid "MPD-Tag"
|
||||||
msgstr "MPD-Tag"
|
msgstr "MPD-Tag"
|
||||||
|
|
||||||
#: mpdevil.py:1209 mpdevil.py:1316
|
#: mpdevil.py:1295 mpdevil.py:1403
|
||||||
msgid "Value"
|
msgid "Value"
|
||||||
msgstr "Wert"
|
msgstr "Wert"
|
||||||
|
|
||||||
#: mpdevil.py:1230
|
#: mpdevil.py:1316
|
||||||
#, 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 "
|
||||||
@@ -164,88 +168,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:1295
|
#: mpdevil.py:1382
|
||||||
msgid "Stats"
|
msgid "Stats"
|
||||||
msgstr "Statistik"
|
msgstr "Statistik"
|
||||||
|
|
||||||
#: mpdevil.py:1313
|
#: mpdevil.py:1400
|
||||||
msgid "Tag"
|
msgid "Tag"
|
||||||
msgstr "Tag"
|
msgstr "Tag"
|
||||||
|
|
||||||
#: mpdevil.py:1333
|
#: mpdevil.py:1420
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Suche"
|
msgstr "Suche"
|
||||||
|
|
||||||
#: mpdevil.py:1384
|
#: mpdevil.py:1471
|
||||||
msgid "Album"
|
msgid "Album"
|
||||||
msgstr "Album"
|
msgstr "Album"
|
||||||
|
|
||||||
#: mpdevil.py:1446
|
#: mpdevil.py:1533
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Hits: %i"
|
msgid "Hits: %i"
|
||||||
msgstr "Treffer: %i"
|
msgstr "Treffer: %i"
|
||||||
|
|
||||||
#: mpdevil.py:1450
|
#: mpdevil.py:1537
|
||||||
msgid "Lyrics"
|
msgid "Lyrics"
|
||||||
msgstr "Liedtext"
|
msgstr "Liedtext"
|
||||||
|
|
||||||
#: mpdevil.py:1490
|
#: mpdevil.py:1577
|
||||||
msgid "searching..."
|
msgid "searching..."
|
||||||
msgstr "suche..."
|
msgstr "suche..."
|
||||||
|
|
||||||
#: mpdevil.py:1494
|
#: mpdevil.py:1581
|
||||||
msgid "not found"
|
msgid "not found"
|
||||||
msgstr "nicht gefunden"
|
msgstr "nicht gefunden"
|
||||||
|
|
||||||
#: mpdevil.py:1499
|
#: mpdevil.py:1586
|
||||||
msgid "not connected"
|
msgid "not connected"
|
||||||
msgstr "nicht verbunden"
|
msgstr "nicht verbunden"
|
||||||
|
|
||||||
#: mpdevil.py:1576
|
#: mpdevil.py:1663
|
||||||
msgid "Select profile"
|
msgid "Select profile"
|
||||||
msgstr "Profil auswählen"
|
msgstr "Profil auswählen"
|
||||||
|
|
||||||
#: mpdevil.py:1580
|
#: mpdevil.py:1667
|
||||||
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:1582
|
#: mpdevil.py:1669
|
||||||
msgid "Title search"
|
msgid "Title search"
|
||||||
msgstr "Titelsuche"
|
msgstr "Titelsuche"
|
||||||
|
|
||||||
#: mpdevil.py:1584
|
#: mpdevil.py:1671
|
||||||
msgid "Show lyrics"
|
msgid "Show lyrics"
|
||||||
msgstr "Zeige Liedtext"
|
msgstr "Zeige Liedtext"
|
||||||
|
|
||||||
#: mpdevil.py:1591
|
#: mpdevil.py:1678
|
||||||
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:1595
|
#: mpdevil.py:1682
|
||||||
msgid "Save window size"
|
msgid "Save window size"
|
||||||
msgstr "Fenstergröße speichern"
|
msgstr "Fenstergröße speichern"
|
||||||
|
|
||||||
#: mpdevil.py:1597
|
#: mpdevil.py:1684
|
||||||
msgid "Update database"
|
msgid "Update database"
|
||||||
msgstr "Datenbank aktualisieren"
|
msgstr "Datenbank aktualisieren"
|
||||||
|
|
||||||
#: mpdevil.py:1598
|
#: mpdevil.py:1685
|
||||||
msgid "Server stats"
|
msgid "Server stats"
|
||||||
msgstr "Serverstatistik"
|
msgstr "Serverstatistik"
|
||||||
|
|
||||||
#: mpdevil.py:1599
|
#: mpdevil.py:1686
|
||||||
msgid "About"
|
msgid "About"
|
||||||
msgstr "Über"
|
msgstr "Über"
|
||||||
|
|
||||||
#: mpdevil.py:1600
|
#: mpdevil.py:1687
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "Beenden"
|
msgstr "Beenden"
|
||||||
|
|
||||||
#: mpdevil.py:1605
|
#: mpdevil.py:1692
|
||||||
msgid "Main menu"
|
msgid "Main menu"
|
||||||
msgstr "Hauptmenu"
|
msgstr "Hauptmenu"
|
||||||
|
|
||||||
#: mpdevil.py:1758
|
#: mpdevil.py:1845
|
||||||
msgid "A small MPD client written in python"
|
msgid "A small MPD client written in python"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
118
po/mpdevil.pot
118
po/mpdevil.pot
@@ -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-28 19:56+0100\n"
|
"POT-Creation-Date: 2020-02-01 15:50+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,231 +17,235 @@ 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:159 mpdevil.py:368 mpdevil.py:1366
|
#: mpdevil.py:199 mpdevil.py:512 mpdevil.py:1453
|
||||||
msgid "No"
|
msgid "No"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:164 mpdevil.py:373 mpdevil.py:1372
|
#: mpdevil.py:204 mpdevil.py:517 mpdevil.py:1459
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:169 mpdevil.py:378 mpdevil.py:1378
|
#: mpdevil.py:209 mpdevil.py:522 mpdevil.py:1465
|
||||||
msgid "Artist"
|
msgid "Artist"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:174 mpdevil.py:383 mpdevil.py:1390
|
#: mpdevil.py:214 mpdevil.py:527 mpdevil.py:1477
|
||||||
msgid "Length"
|
msgid "Length"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:214 mpdevil.py:483 mpdevil.py:1427
|
#: mpdevil.py:254 mpdevil.py:621 mpdevil.py:1514
|
||||||
msgid "Unknown Title"
|
msgid "Unknown Title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:218 mpdevil.py:491 mpdevil.py:1435
|
#: mpdevil.py:258 mpdevil.py:629 mpdevil.py:1522
|
||||||
msgid "Unknown Artist"
|
msgid "Unknown Artist"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:254
|
#: mpdevil.py:294
|
||||||
msgid "Album Artist"
|
msgid "Album Artist"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:313 mpdevil.py:504
|
#: mpdevil.py:374 mpdevil.py:596
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "%(total_tracks)i titles (%(total_length)s)"
|
msgid "%(total_tracks)i titles (%(total_length)s)"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:495 mpdevil.py:1439
|
#: mpdevil.py:633 mpdevil.py:1526
|
||||||
msgid "Unknown Album"
|
msgid "Unknown Album"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:725
|
#: mpdevil.py:800
|
||||||
msgid "Select"
|
msgid "Select"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:727
|
#: mpdevil.py:802
|
||||||
msgid "Profile:"
|
msgid "Profile:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:729
|
#: mpdevil.py:804
|
||||||
msgid "Name:"
|
msgid "Name:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:731
|
#: mpdevil.py:806
|
||||||
msgid "Host:"
|
msgid "Host:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:733
|
#: mpdevil.py:808
|
||||||
msgid "Port:"
|
msgid "Port:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:735
|
#: mpdevil.py:810
|
||||||
|
msgid "Password:"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: mpdevil.py:812
|
||||||
msgid "Music lib:"
|
msgid "Music lib:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:810
|
#: mpdevil.py:893
|
||||||
msgid "Choose directory"
|
msgid "Choose directory"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:846
|
#: mpdevil.py:932
|
||||||
msgid "Main cover size:"
|
msgid "Main cover size:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:848
|
#: mpdevil.py:934
|
||||||
msgid "Album-view cover size:"
|
msgid "Album-view cover size:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:854
|
#: mpdevil.py:940
|
||||||
msgid "Button icon size (restart required):"
|
msgid "Button icon size (restart required):"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:863
|
#: mpdevil.py:949
|
||||||
msgid "Show stop button"
|
msgid "Show stop button"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:866
|
#: mpdevil.py:952
|
||||||
msgid "Show tooltips in album view"
|
msgid "Show tooltips in album view"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:869
|
#: mpdevil.py:955
|
||||||
msgid "Send notification on title change"
|
msgid "Send notification on title change"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:872
|
#: mpdevil.py:958
|
||||||
msgid "Stop playback on quit"
|
msgid "Stop playback on quit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:875
|
#: mpdevil.py:961
|
||||||
msgid "Play selected album after current title"
|
msgid "Play selected album after current title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:913 mpdevil.py:1596
|
#: mpdevil.py:999 mpdevil.py:1683
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:926
|
#: mpdevil.py:1012
|
||||||
msgid "General"
|
msgid "General"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:927
|
#: mpdevil.py:1013
|
||||||
msgid "Profiles"
|
msgid "Profiles"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1081
|
#: mpdevil.py:1167
|
||||||
msgid "Random mode"
|
msgid "Random mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1083
|
#: mpdevil.py:1169
|
||||||
msgid "Repeat mode"
|
msgid "Repeat mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1085
|
#: mpdevil.py:1171
|
||||||
msgid "Single mode"
|
msgid "Single mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1087
|
#: mpdevil.py:1173
|
||||||
msgid "Consume mode"
|
msgid "Consume mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1182
|
#: mpdevil.py:1268
|
||||||
msgid "Right click to show additional information"
|
msgid "Right click to show additional information"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1206
|
#: mpdevil.py:1292
|
||||||
msgid "MPD-Tag"
|
msgid "MPD-Tag"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1209 mpdevil.py:1316
|
#: mpdevil.py:1295 mpdevil.py:1403
|
||||||
msgid "Value"
|
msgid "Value"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1230
|
#: mpdevil.py:1316
|
||||||
#, 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:1295
|
#: mpdevil.py:1382
|
||||||
msgid "Stats"
|
msgid "Stats"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1313
|
#: mpdevil.py:1400
|
||||||
msgid "Tag"
|
msgid "Tag"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1333
|
#: mpdevil.py:1420
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1384
|
#: mpdevil.py:1471
|
||||||
msgid "Album"
|
msgid "Album"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1446
|
#: mpdevil.py:1533
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Hits: %i"
|
msgid "Hits: %i"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1450
|
#: mpdevil.py:1537
|
||||||
msgid "Lyrics"
|
msgid "Lyrics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1490
|
#: mpdevil.py:1577
|
||||||
msgid "searching..."
|
msgid "searching..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1494
|
#: mpdevil.py:1581
|
||||||
msgid "not found"
|
msgid "not found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1499
|
#: mpdevil.py:1586
|
||||||
msgid "not connected"
|
msgid "not connected"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1576
|
#: mpdevil.py:1663
|
||||||
msgid "Select profile"
|
msgid "Select profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1580
|
#: mpdevil.py:1667
|
||||||
msgid "Return to album of current title"
|
msgid "Return to album of current title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1582
|
#: mpdevil.py:1669
|
||||||
msgid "Title search"
|
msgid "Title search"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1584
|
#: mpdevil.py:1671
|
||||||
msgid "Show lyrics"
|
msgid "Show lyrics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1591
|
#: mpdevil.py:1678
|
||||||
msgid "Not connected to MPD-server. Reconnect?"
|
msgid "Not connected to MPD-server. Reconnect?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1595
|
#: mpdevil.py:1682
|
||||||
msgid "Save window size"
|
msgid "Save window size"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1597
|
#: mpdevil.py:1684
|
||||||
msgid "Update database"
|
msgid "Update database"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1598
|
#: mpdevil.py:1685
|
||||||
msgid "Server stats"
|
msgid "Server stats"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1599
|
#: mpdevil.py:1686
|
||||||
msgid "About"
|
msgid "About"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1600
|
#: mpdevil.py:1687
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1605
|
#: mpdevil.py:1692
|
||||||
msgid "Main menu"
|
msgid "Main menu"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1758
|
#: mpdevil.py:1845
|
||||||
msgid "A small MPD client written in python"
|
msgid "A small MPD client written in python"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 1005 KiB After Width: | Height: | Size: 1002 KiB |
Reference in New Issue
Block a user