mirror of
https://github.com/SoongNoonien/mpdevil.git
synced 2023-08-10 21:12:44 +03:00
Compare commits
20 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7037628af9 | ||
![]() |
26ee51fb18 | ||
![]() |
9625bd9cf3 | ||
![]() |
75d8ff21c6 | ||
![]() |
36b023f04c | ||
![]() |
177bd27aa5 | ||
![]() |
e07cce7ea6 | ||
![]() |
0332fe75b7 | ||
![]() |
e62f4824c2 | ||
![]() |
b9b1ba989a | ||
![]() |
f1831a5569 | ||
![]() |
b904907f6f | ||
![]() |
54673a9840 | ||
![]() |
89ffc03cb2 | ||
![]() |
d04c84e5d0 | ||
![]() |
6990d59f72 | ||
![]() |
421f685b58 | ||
![]() |
6238df4d21 | ||
![]() |
b8d1f9aafc | ||
![]() |
3414212173 |
@@ -12,9 +12,10 @@ Features
|
|||||||
3. fetching lyrics form the web (based on PyLyrics 1.1.0)
|
3. fetching lyrics form the web (based on PyLyrics 1.1.0)
|
||||||
4. searching songs in your music library
|
4. searching songs in your music library
|
||||||
5. removing single tracks form playlist by hovering and pressing del
|
5. removing single tracks form playlist by hovering and pressing del
|
||||||
6. appending albums by rightclick
|
6. appending albums by middleclick
|
||||||
7. sending notifications on title change
|
7. query albums by rightclick
|
||||||
8. managing multiple mpd servers
|
8. sending notifications on title change
|
||||||
|
9. managing multiple mpd servers
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
----
|
----
|
||||||
|
385
bin/mpdevil.py
385
bin/mpdevil.py
@@ -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,136 @@ 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):
|
||||||
|
def __init__(self, parent, client, album, artist, year):
|
||||||
|
Gtk.Dialog.__init__(self, title=(artist+" - "+album+" ("+year+")"), transient_for=parent)
|
||||||
|
self.add_buttons(Gtk.STOCK_ADD, Gtk.ResponseType.ACCEPT, Gtk.STOCK_MEDIA_PLAY, Gtk.ResponseType.YES, Gtk.STOCK_OPEN, Gtk.ResponseType.OK, Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
|
||||||
|
self.set_default_size(800, 600)
|
||||||
|
|
||||||
|
#adding vars
|
||||||
|
self.client=client
|
||||||
|
|
||||||
|
#scroll
|
||||||
|
scroll=Gtk.ScrolledWindow()
|
||||||
|
scroll.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
|
||||||
|
|
||||||
|
#Store
|
||||||
|
#(track, title, artist, duration, file)
|
||||||
|
self.store = Gtk.ListStore(str, str, str, str, str)
|
||||||
|
|
||||||
|
#TreeView
|
||||||
|
self.treeview = Gtk.TreeView(model=self.store)
|
||||||
|
self.treeview.set_search_column(-1)
|
||||||
|
self.treeview.columns_autosize()
|
||||||
|
|
||||||
|
self.selection = self.treeview.get_selection()
|
||||||
|
self.selection.set_mode(Gtk.SelectionMode.SINGLE)
|
||||||
|
|
||||||
|
#Column
|
||||||
|
renderer_text = Gtk.CellRendererText()
|
||||||
|
|
||||||
|
self.column_track = Gtk.TreeViewColumn(_("No"), renderer_text, text=0)
|
||||||
|
self.column_track.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
|
||||||
|
self.column_track.set_property("resizable", False)
|
||||||
|
self.treeview.append_column(self.column_track)
|
||||||
|
|
||||||
|
self.column_title = Gtk.TreeViewColumn(_("Title"), renderer_text, text=1)
|
||||||
|
self.column_title.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
|
||||||
|
self.column_title.set_property("resizable", False)
|
||||||
|
self.treeview.append_column(self.column_title)
|
||||||
|
|
||||||
|
self.column_artist = Gtk.TreeViewColumn(_("Artist"), renderer_text, text=2)
|
||||||
|
self.column_artist.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
|
||||||
|
self.column_artist.set_property("resizable", False)
|
||||||
|
self.treeview.append_column(self.column_artist)
|
||||||
|
|
||||||
|
self.column_time = Gtk.TreeViewColumn(_("Length"), renderer_text, text=3)
|
||||||
|
self.column_time.set_sizing(Gtk.TreeViewColumnSizing.AUTOSIZE)
|
||||||
|
self.column_time.set_property("resizable", False)
|
||||||
|
self.treeview.append_column(self.column_time)
|
||||||
|
|
||||||
|
self.populate_treeview(album, artist, year)
|
||||||
|
|
||||||
|
#connect
|
||||||
|
self.title_activated=self.treeview.connect("row-activated", self.on_row_activated)
|
||||||
|
|
||||||
|
#packing
|
||||||
|
scroll.add(self.treeview)
|
||||||
|
self.vbox.pack_start(scroll, True, True, 0) #vbox default widget of dialogs
|
||||||
|
self.vbox.set_spacing(6)
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
|
#selection workaround
|
||||||
|
self.selection.unselect_all()
|
||||||
|
self.title_change=self.selection.connect("changed", self.on_selection_change)
|
||||||
|
|
||||||
|
def on_row_activated(self, widget, path, view_column):
|
||||||
|
treeiter=self.store.get_iter(path)
|
||||||
|
selected_title=self.store.get_value(treeiter, 4)
|
||||||
|
self.client.clear()
|
||||||
|
self.client.add(selected_title)
|
||||||
|
self.client.play()
|
||||||
|
|
||||||
|
def on_selection_change(self, widget):
|
||||||
|
treeiter=widget.get_selected()[1]
|
||||||
|
if not treeiter == None:
|
||||||
|
selected_title=self.store.get_value(treeiter, 4)
|
||||||
|
self.client.add(selected_title)
|
||||||
|
|
||||||
|
def populate_treeview(self, album, artist, year):
|
||||||
|
songs=self.client.find("album", album, "date", year, "albumartist", artist)
|
||||||
|
if not songs == []:
|
||||||
|
for song in songs:
|
||||||
|
try:
|
||||||
|
title=song["title"]
|
||||||
|
except:
|
||||||
|
title=_("Unknown Title")
|
||||||
|
try:
|
||||||
|
artist=song["artist"]
|
||||||
|
except:
|
||||||
|
artist=_("Unknown Artist")
|
||||||
|
try:
|
||||||
|
track=song["track"].zfill(2)
|
||||||
|
except:
|
||||||
|
track="00"
|
||||||
|
try:
|
||||||
|
dura=float(song["duration"])
|
||||||
|
except:
|
||||||
|
dura=0.0
|
||||||
|
duration=str(datetime.timedelta(seconds=int(dura)))
|
||||||
|
self.store.append([track, title, artist, duration, song["file"]] )
|
||||||
|
|
||||||
class ArtistView(Gtk.ScrolledWindow):
|
class ArtistView(Gtk.ScrolledWindow):
|
||||||
def __init__(self, client):
|
def __init__(self, client):
|
||||||
Gtk.ScrolledWindow.__init__(self)
|
Gtk.ScrolledWindow.__init__(self)
|
||||||
@@ -161,32 +299,19 @@ class AlbumView(Gtk.ScrolledWindow):
|
|||||||
|
|
||||||
self.add(self.iconview)
|
self.add(self.iconview)
|
||||||
|
|
||||||
def gen_title_list(self, album, artist, year): #needed for tooltips
|
def gen_tooltip(self, album, artist, year):
|
||||||
if self.settings.get_boolean("show-album-view-tooltips"):
|
if self.settings.get_boolean("show-album-view-tooltips"):
|
||||||
songs=self.client.find("album", album, "date", year, "albumartist", artist)
|
songs=self.client.find("album", album, "date", year, "albumartist", artist)
|
||||||
length=float(0)
|
length=float(0)
|
||||||
title_list=""
|
|
||||||
for song in songs:
|
for song in songs:
|
||||||
try:
|
|
||||||
title=song["title"]
|
|
||||||
except:
|
|
||||||
title=_("Unknown Title")
|
|
||||||
try:
|
|
||||||
track=song["track"].zfill(2)
|
|
||||||
except:
|
|
||||||
track="00"
|
|
||||||
try:
|
try:
|
||||||
dura=float(song["duration"])
|
dura=float(song["duration"])
|
||||||
except:
|
except:
|
||||||
dura=0.0
|
dura=0.0
|
||||||
length=length+dura
|
length=length+dura
|
||||||
duration=str(datetime.timedelta(seconds=int(dura)))
|
|
||||||
title_list=title_list+"\n"+(track+" - "+title+" ("+duration+")")
|
|
||||||
if not year == "":
|
|
||||||
year=" ("+year+")"
|
|
||||||
length_human_readable=str(datetime.timedelta(seconds=int(length)))
|
length_human_readable=str(datetime.timedelta(seconds=int(length)))
|
||||||
title_list=(_("%(album)s%(year)s (tracks: %(total_tracks)i) (%(total_length)s):") % {"album": album, "year": year, "total_tracks": len(songs), "total_length": length_human_readable})+title_list
|
tooltip=(_("%(total_tracks)i titles (%(total_length)s)") % {"total_tracks": len(songs), "total_length": length_human_readable})
|
||||||
return title_list.replace("&", "") #& must not be in tooltips
|
return tooltip
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -206,9 +331,9 @@ class AlbumView(Gtk.ScrolledWindow):
|
|||||||
cover=Cover(client=self.client, lib_path=self.settings.get_value("paths")[self.settings.get_int("active-profile")], song_file=song_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)
|
img=cover.get_pixbuf(size)
|
||||||
if album["year"] == "":
|
if album["year"] == "":
|
||||||
self.store.append([img, album["album"], self.gen_title_list(album["album"], artist, album["year"]), album["album"], album["year"]])
|
self.store.append([img, album["album"], self.gen_tooltip(album["album"], artist, album["year"]), album["album"], album["year"]])
|
||||||
else:
|
else:
|
||||||
self.store.append([img, album["album"]+" ("+album["year"]+")", self.gen_title_list(album["album"], artist, album["year"]), album["album"], album["year"]])
|
self.store.append([img, album["album"]+" ("+album["year"]+")", self.gen_tooltip(album["album"], artist, album["year"]), album["album"], album["year"]])
|
||||||
while Gtk.events_pending():
|
while Gtk.events_pending():
|
||||||
Gtk.main_iteration_do(True)
|
Gtk.main_iteration_do(True)
|
||||||
|
|
||||||
@@ -231,7 +356,6 @@ class TrackView(Gtk.Box):
|
|||||||
#TreeView
|
#TreeView
|
||||||
self.treeview = Gtk.TreeView(model=self.store)
|
self.treeview = Gtk.TreeView(model=self.store)
|
||||||
self.treeview.set_search_column(-1)
|
self.treeview.set_search_column(-1)
|
||||||
self.treeview.set_tooltip_column(5)
|
|
||||||
self.treeview.columns_autosize()
|
self.treeview.columns_autosize()
|
||||||
|
|
||||||
#selection
|
#selection
|
||||||
@@ -273,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)
|
||||||
@@ -287,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:
|
||||||
@@ -306,14 +440,11 @@ class TrackView(Gtk.Box):
|
|||||||
for song in songs:
|
for song in songs:
|
||||||
self.client.add(song["file"])
|
self.client.add(song["file"])
|
||||||
else:
|
else:
|
||||||
if self.settings.get_boolean("add-album") and not force:
|
if self.settings.get_boolean("add-album") and not force and not self.client.status()["state"] == "stop":
|
||||||
self.selection.handler_block(self.title_change)
|
self.selection.handler_block(self.title_change)
|
||||||
status=self.client.status()
|
status=self.client.status()
|
||||||
try:
|
self.client.moveid(status["songid"], 0)
|
||||||
self.client.moveid(status["songid"], 0) #bad song index possible
|
|
||||||
self.song_to_delete=self.client.playlistinfo()[0]["file"]
|
self.song_to_delete=self.client.playlistinfo()[0]["file"]
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self.selection.handler_unblock(self.title_change)
|
self.selection.handler_unblock(self.title_change)
|
||||||
try:
|
try:
|
||||||
self.client.delete((1,)) # delete all songs, but the first. #bad song index possible
|
self.client.delete((1,)) # delete all songs, but the first. #bad song index possible
|
||||||
@@ -334,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"]
|
||||||
@@ -364,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 == "":
|
||||||
@@ -381,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)
|
||||||
@@ -425,12 +562,13 @@ class TrackView(Gtk.Box):
|
|||||||
self.client.play(selected_title)
|
self.client.play(selected_title)
|
||||||
|
|
||||||
class Browser(Gtk.Box):
|
class Browser(Gtk.Box):
|
||||||
def __init__(self, client, settings):
|
def __init__(self, client, settings, window):
|
||||||
Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL, spacing=3)
|
Gtk.Box.__init__(self, orientation=Gtk.Orientation.HORIZONTAL, spacing=3)
|
||||||
|
|
||||||
#adding vars
|
#adding vars
|
||||||
self.client=client
|
self.client=client
|
||||||
self.settings=settings
|
self.settings=settings
|
||||||
|
self.window=window
|
||||||
|
|
||||||
#widgets
|
#widgets
|
||||||
self.artist_list=ArtistView(self.client)
|
self.artist_list=ArtistView(self.client)
|
||||||
@@ -510,14 +648,26 @@ class Browser(Gtk.Box):
|
|||||||
|
|
||||||
def on_album_view_button_press_event(self, widget, event):
|
def on_album_view_button_press_event(self, widget, event):
|
||||||
path = widget.get_path_at_pos(int(event.x), int(event.y))
|
path = widget.get_path_at_pos(int(event.x), int(event.y))
|
||||||
if event.button == 3:
|
|
||||||
if not path == None:
|
if not path == None:
|
||||||
|
if not event.button == 1:
|
||||||
treeiter=self.album_list.store.get_iter(path)
|
treeiter=self.album_list.store.get_iter(path)
|
||||||
selected_album=self.album_list.store.get_value(treeiter, 3)
|
selected_album=self.album_list.store.get_value(treeiter, 3)
|
||||||
selected_album_year=self.album_list.store.get_value(treeiter, 4)
|
selected_album_year=self.album_list.store.get_value(treeiter, 4)
|
||||||
treeiter=self.artist_list.selection.get_selected()[1]
|
treeiter=self.artist_list.selection.get_selected()[1]
|
||||||
selected_artist=self.artist_list.store.get_value(treeiter, 0)
|
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)
|
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):
|
def on_album_selection_change(self, widget):
|
||||||
paths=widget.get_selected_items()
|
paths=widget.get_selected_items()
|
||||||
@@ -611,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)
|
||||||
@@ -643,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)
|
||||||
@@ -679,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):
|
||||||
@@ -716,10 +851,19 @@ 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"))
|
||||||
|
|
||||||
show_album_view_tooltips=Gtk.CheckButton(label=_("Show title list as tooltip in album view"))
|
show_album_view_tooltips=Gtk.CheckButton(label=_("Show tooltips in album view"))
|
||||||
show_album_view_tooltips.set_active(self.settings.get_boolean("show-album-view-tooltips"))
|
show_album_view_tooltips.set_active(self.settings.get_boolean("show-album-view-tooltips"))
|
||||||
|
|
||||||
send_notify=Gtk.CheckButton(label=_("Send notification on title change"))
|
send_notify=Gtk.CheckButton(label=_("Send notification on title change"))
|
||||||
@@ -734,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")
|
||||||
@@ -743,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)
|
||||||
@@ -757,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)
|
||||||
@@ -775,6 +926,7 @@ class SettingsDialog(Gtk.Dialog):
|
|||||||
tabs.append_page(general, Gtk.Label(label=_("General")))
|
tabs.append_page(general, Gtk.Label(label=_("General")))
|
||||||
tabs.append_page(profiles, Gtk.Label(label=_("Profiles")))
|
tabs.append_page(profiles, Gtk.Label(label=_("Profiles")))
|
||||||
self.vbox.pack_start(tabs, True, True, 0) #vbox default widget of dialogs
|
self.vbox.pack_start(tabs, True, True, 0) #vbox default widget of dialogs
|
||||||
|
self.vbox.set_spacing(6)
|
||||||
|
|
||||||
self.show_all()
|
self.show_all()
|
||||||
|
|
||||||
@@ -785,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", 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", 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", 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", 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)
|
||||||
@@ -813,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", 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", 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", 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
|
||||||
@@ -838,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()
|
||||||
@@ -873,7 +1026,9 @@ class SeekBar(Gtk.Box):
|
|||||||
|
|
||||||
#widgets
|
#widgets
|
||||||
self.elapsed=Gtk.Label()
|
self.elapsed=Gtk.Label()
|
||||||
|
self.elapsed.set_width_chars(7)
|
||||||
self.rest=Gtk.Label()
|
self.rest=Gtk.Label()
|
||||||
|
self.rest.set_width_chars(8)
|
||||||
self.scale=Gtk.Scale.new_with_range(orientation=Gtk.Orientation.HORIZONTAL, min=0, max=100, step=0.001)
|
self.scale=Gtk.Scale.new_with_range(orientation=Gtk.Orientation.HORIZONTAL, min=0, max=100, step=0.001)
|
||||||
self.scale.set_draw_value(False)
|
self.scale.set_draw_value(False)
|
||||||
|
|
||||||
@@ -913,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)
|
||||||
@@ -1029,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
|
||||||
@@ -1103,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()
|
||||||
@@ -1126,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.connect(self.settings.get_value("hosts")[active], self.settings.get_value("ports")[active])
|
self.client.try_connect_default()
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class ServerStats(Gtk.Dialog):
|
class ServerStats(Gtk.Dialog):
|
||||||
def __init__(self, parent, client):
|
def __init__(self, parent, client):
|
||||||
@@ -1173,7 +1331,7 @@ class ServerStats(Gtk.Dialog):
|
|||||||
class Search(Gtk.Dialog):
|
class Search(Gtk.Dialog):
|
||||||
def __init__(self, parent, client):
|
def __init__(self, parent, client):
|
||||||
Gtk.Dialog.__init__(self, title=_("Search"), transient_for=parent)
|
Gtk.Dialog.__init__(self, title=_("Search"), transient_for=parent)
|
||||||
self.add_button(Gtk.STOCK_OK, Gtk.ResponseType.OK)
|
self.add_button(Gtk.STOCK_CLOSE, Gtk.ResponseType.CLOSE)
|
||||||
self.set_default_size(800, 600)
|
self.set_default_size(800, 600)
|
||||||
|
|
||||||
#adding vars
|
#adding vars
|
||||||
@@ -1185,7 +1343,6 @@ class Search(Gtk.Dialog):
|
|||||||
|
|
||||||
#search entry
|
#search entry
|
||||||
self.search_entry=Gtk.SearchEntry()
|
self.search_entry=Gtk.SearchEntry()
|
||||||
self.search_entry.connect("search-changed", self.on_search_changed)
|
|
||||||
|
|
||||||
#label
|
#label
|
||||||
self.label=Gtk.Label()
|
self.label=Gtk.Label()
|
||||||
@@ -1198,7 +1355,6 @@ class Search(Gtk.Dialog):
|
|||||||
#TreeView
|
#TreeView
|
||||||
self.treeview = Gtk.TreeView(model=self.store)
|
self.treeview = Gtk.TreeView(model=self.store)
|
||||||
self.treeview.set_search_column(-1)
|
self.treeview.set_search_column(-1)
|
||||||
self.treeview.set_tooltip_column(5)
|
|
||||||
self.treeview.columns_autosize()
|
self.treeview.columns_autosize()
|
||||||
|
|
||||||
self.selection = self.treeview.get_selection()
|
self.selection = self.treeview.get_selection()
|
||||||
@@ -1210,31 +1366,37 @@ 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
|
||||||
self.title_activated=self.treeview.connect("row-activated", self.on_row_activated)
|
self.title_activated=self.treeview.connect("row-activated", self.on_row_activated)
|
||||||
self.title_change=self.selection.connect("changed", self.on_selection_change)
|
self.title_change=self.selection.connect("changed", self.on_selection_change)
|
||||||
|
self.search_entry.connect("search-changed", self.on_search_changed)
|
||||||
|
|
||||||
#packing
|
#packing
|
||||||
scroll.add(self.treeview)
|
scroll.add(self.treeview)
|
||||||
@@ -1248,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]
|
||||||
@@ -1258,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:
|
||||||
@@ -1290,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
|
||||||
@@ -1325,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:
|
||||||
@@ -1336,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)
|
||||||
@@ -1380,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")
|
|
||||||
try:
|
|
||||||
self.client.disconnect()
|
self.client.disconnect()
|
||||||
self.client.connect(self.settings.get_value("hosts")[active], self.settings.get_value("ports")[active])
|
self.client.try_connect_default()
|
||||||
except:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class MainWindow(Gtk.ApplicationWindow):
|
class MainWindow(Gtk.ApplicationWindow):
|
||||||
def __init__(self, app, client, settings):
|
def __init__(self, app, client, settings):
|
||||||
@@ -1397,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)
|
||||||
@@ -1416,18 +1571,18 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||||||
self.add_action(update_action)
|
self.add_action(update_action)
|
||||||
|
|
||||||
#widgets
|
#widgets
|
||||||
self.browser=Browser(self.client, self.settings)
|
self.browser=Browser(self.client, self.settings, self)
|
||||||
self.profiles=ProfileSelect(self.client, self.settings)
|
self.profiles=ProfileSelect(self.client, self.settings)
|
||||||
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", 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", 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", 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()
|
||||||
@@ -1480,6 +1635,11 @@ class MainWindow(Gtk.ApplicationWindow):
|
|||||||
|
|
||||||
self.add(self.vbox)
|
self.add(self.vbox)
|
||||||
|
|
||||||
|
#connect client
|
||||||
|
self.client.try_connect_default()
|
||||||
|
|
||||||
|
self.show_all()
|
||||||
|
|
||||||
def update(self, app): #update title and send notify
|
def update(self, app): #update title and send notify
|
||||||
if self.client.connected():
|
if self.client.connected():
|
||||||
self.info_bar.set_revealed(False)
|
self.info_bar.set_revealed(False)
|
||||||
@@ -1518,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):
|
||||||
@@ -1567,18 +1723,17 @@ 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)
|
||||||
#Gtk.window_set_default_icon_name("mpdevil")
|
self.settings = Settings()
|
||||||
self.client=Client()
|
self.client=Client(self.settings)
|
||||||
self.settings = Gio.Settings.new(self.BASE_KEY)
|
|
||||||
self.window=None
|
self.window=None
|
||||||
|
|
||||||
def do_activate(self):
|
def do_activate(self):
|
||||||
|
if not self.window: #allow just one instance
|
||||||
self.window = MainWindow(self, self.client, self.settings)
|
self.window = MainWindow(self, self.client, self.settings)
|
||||||
self.window.connect("delete-event", self.on_delete_event)
|
self.window.connect("delete-event", self.on_delete_event)
|
||||||
self.window.show_all()
|
self.window.present()
|
||||||
|
|
||||||
def do_startup(self):
|
def do_startup(self):
|
||||||
Gtk.Application.do_startup(self)
|
Gtk.Application.do_startup(self)
|
||||||
|
@@ -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.3.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])
|
||||||
|
@@ -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>
|
||||||
|
142
po/de.po
142
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-12 16:18+0100\n"
|
"POT-Creation-Date: 2020-01-28 19:56+0100\n"
|
||||||
"PO-Revision-Date: 2020-01-12 16:18+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:116
|
#: mpdevil.py:159 mpdevil.py:368 mpdevil.py:1366
|
||||||
msgid "Album Artist"
|
|
||||||
msgstr "Albuminterpret"
|
|
||||||
|
|
||||||
#: mpdevil.py:173 mpdevil.py:350 mpdevil.py:1265
|
|
||||||
msgid "Unknown Title"
|
|
||||||
msgstr "Unbekannter Titel"
|
|
||||||
|
|
||||||
#: mpdevil.py:188
|
|
||||||
#, python-format
|
|
||||||
msgid "%(album)s%(year)s (tracks: %(total_tracks)i) (%(total_length)s):"
|
|
||||||
msgstr "%(album)s%(year)s (Titel: %(total_tracks)i) (%(total_length)s):"
|
|
||||||
|
|
||||||
#: mpdevil.py:244 mpdevil.py:1210
|
|
||||||
msgid "No"
|
msgid "No"
|
||||||
msgstr "Nr."
|
msgstr "Nr."
|
||||||
|
|
||||||
#: mpdevil.py:249 mpdevil.py:1215
|
#: mpdevil.py:164 mpdevil.py:373 mpdevil.py:1372
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr "Titel"
|
msgstr "Titel"
|
||||||
|
|
||||||
#: mpdevil.py:254 mpdevil.py:1220
|
#: mpdevil.py:169 mpdevil.py:378 mpdevil.py:1378
|
||||||
msgid "Artist"
|
msgid "Artist"
|
||||||
msgstr "Interpret"
|
msgstr "Interpret"
|
||||||
|
|
||||||
#: mpdevil.py:259 mpdevil.py:1230
|
#: mpdevil.py:174 mpdevil.py:383 mpdevil.py:1390
|
||||||
msgid "Length"
|
msgid "Length"
|
||||||
msgstr "Länge"
|
msgstr "Länge"
|
||||||
|
|
||||||
#: mpdevil.py:358 mpdevil.py:1273
|
#: mpdevil.py:214 mpdevil.py:483 mpdevil.py:1427
|
||||||
|
msgid "Unknown Title"
|
||||||
|
msgstr "Unbekannter Titel"
|
||||||
|
|
||||||
|
#: 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:362 mpdevil.py:1277
|
#: mpdevil.py:254
|
||||||
|
msgid "Album Artist"
|
||||||
|
msgstr "Albuminterpret"
|
||||||
|
|
||||||
|
#: mpdevil.py:313 mpdevil.py:504
|
||||||
|
#, python-format
|
||||||
|
msgid "%(total_tracks)i titles (%(total_length)s)"
|
||||||
|
msgstr "%(total_tracks)i Titel (%(total_length)s)"
|
||||||
|
|
||||||
|
#: mpdevil.py:495 mpdevil.py:1439
|
||||||
msgid "Unknown Album"
|
msgid "Unknown Album"
|
||||||
msgstr "Unbekanntes Album"
|
msgstr "Unbekanntes Album"
|
||||||
|
|
||||||
#: mpdevil.py:575
|
#: mpdevil.py:725
|
||||||
msgid "Select"
|
msgid "Select"
|
||||||
msgstr "Auswählen"
|
msgstr "Auswählen"
|
||||||
|
|
||||||
#: mpdevil.py:577
|
#: mpdevil.py:727
|
||||||
msgid "Profile:"
|
msgid "Profile:"
|
||||||
msgstr "Profil:"
|
msgstr "Profil:"
|
||||||
|
|
||||||
#: mpdevil.py:579
|
#: mpdevil.py:729
|
||||||
msgid "Name:"
|
msgid "Name:"
|
||||||
msgstr "Name:"
|
msgstr "Name:"
|
||||||
|
|
||||||
#: mpdevil.py:581
|
#: mpdevil.py:731
|
||||||
msgid "Host:"
|
msgid "Host:"
|
||||||
msgstr "Host:"
|
msgstr "Host:"
|
||||||
|
|
||||||
#: mpdevil.py:583
|
#: mpdevil.py:733
|
||||||
msgid "Port:"
|
msgid "Port:"
|
||||||
msgstr "Port:"
|
msgstr "Port:"
|
||||||
|
|
||||||
#: mpdevil.py:585
|
#: mpdevil.py:735
|
||||||
msgid "Music lib:"
|
msgid "Music lib:"
|
||||||
msgstr "Musikverzeichnis:"
|
msgstr "Musikverzeichnis:"
|
||||||
|
|
||||||
#: mpdevil.py:675
|
#: mpdevil.py:810
|
||||||
msgid "Choose directory"
|
msgid "Choose directory"
|
||||||
msgstr "Verzeichnis Wählen"
|
msgstr "Verzeichnis Wählen"
|
||||||
|
|
||||||
#: mpdevil.py:711
|
#: 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:713
|
#: 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:719
|
#: 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:722
|
#: mpdevil.py:866
|
||||||
msgid "Show title list as tooltip in album view"
|
msgid "Show tooltips in album view"
|
||||||
msgstr "Zeige Titellisten als Tooltips in Albumansicht"
|
msgstr "Zeige Tooltips in Albumansicht"
|
||||||
|
|
||||||
#: mpdevil.py:725
|
#: 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:728
|
#: 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:731
|
#: 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:762 mpdevil.py:1441
|
#: mpdevil.py:913 mpdevil.py:1596
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr "Einstellungen"
|
msgstr "Einstellungen"
|
||||||
|
|
||||||
#: mpdevil.py:775
|
#: mpdevil.py:926
|
||||||
msgid "General"
|
msgid "General"
|
||||||
msgstr "Allgemein"
|
msgstr "Allgemein"
|
||||||
|
|
||||||
#: mpdevil.py:776
|
#: mpdevil.py:927
|
||||||
msgid "Profiles"
|
msgid "Profiles"
|
||||||
msgstr "Profile"
|
msgstr "Profile"
|
||||||
|
|
||||||
#: mpdevil.py:924
|
#: mpdevil.py:1081
|
||||||
msgid "Random mode"
|
msgid "Random mode"
|
||||||
msgstr "Zufallsmodus"
|
msgstr "Zufallsmodus"
|
||||||
|
|
||||||
#: mpdevil.py:926
|
#: mpdevil.py:1083
|
||||||
msgid "Repeat mode"
|
msgid "Repeat mode"
|
||||||
msgstr "Dauerschleife"
|
msgstr "Dauerschleife"
|
||||||
|
|
||||||
#: mpdevil.py:928
|
#: mpdevil.py:1085
|
||||||
msgid "Single mode"
|
msgid "Single mode"
|
||||||
msgstr "Einzelstückmodus"
|
msgstr "Einzelstückmodus"
|
||||||
|
|
||||||
#: mpdevil.py:930
|
#: mpdevil.py:1087
|
||||||
msgid "Consume mode"
|
msgid "Consume mode"
|
||||||
msgstr "Playliste verbrauchen"
|
msgstr "Playliste verbrauchen"
|
||||||
|
|
||||||
#: mpdevil.py:1024
|
#: 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:1047
|
#: mpdevil.py:1206
|
||||||
msgid "MPD-Tag"
|
msgid "MPD-Tag"
|
||||||
msgstr "MPD-Tag"
|
msgstr "MPD-Tag"
|
||||||
|
|
||||||
#: mpdevil.py:1050 mpdevil.py:1158
|
#: mpdevil.py:1209 mpdevil.py:1316
|
||||||
msgid "Value"
|
msgid "Value"
|
||||||
msgstr "Wert"
|
msgstr "Wert"
|
||||||
|
|
||||||
#: mpdevil.py:1071
|
#: 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:1137
|
#: mpdevil.py:1295
|
||||||
msgid "Stats"
|
msgid "Stats"
|
||||||
msgstr "Statistik"
|
msgstr "Statistik"
|
||||||
|
|
||||||
#: mpdevil.py:1155
|
#: mpdevil.py:1313
|
||||||
msgid "Tag"
|
msgid "Tag"
|
||||||
msgstr "Tag"
|
msgstr "Tag"
|
||||||
|
|
||||||
#: mpdevil.py:1175
|
#: mpdevil.py:1333
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Suche"
|
msgstr "Suche"
|
||||||
|
|
||||||
#: mpdevil.py:1225
|
#: mpdevil.py:1384
|
||||||
msgid "Album"
|
msgid "Album"
|
||||||
msgstr "Album"
|
msgstr "Album"
|
||||||
|
|
||||||
#: mpdevil.py:1284
|
#: mpdevil.py:1446
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Hits: %i"
|
msgid "Hits: %i"
|
||||||
msgstr "Treffer: %i"
|
msgstr "Treffer: %i"
|
||||||
|
|
||||||
#: mpdevil.py:1288
|
#: mpdevil.py:1450
|
||||||
msgid "Lyrics"
|
msgid "Lyrics"
|
||||||
msgstr "Liedtext"
|
msgstr "Liedtext"
|
||||||
|
|
||||||
#: mpdevil.py:1332
|
#: mpdevil.py:1490
|
||||||
msgid "searching..."
|
msgid "searching..."
|
||||||
msgstr "suche..."
|
msgstr "suche..."
|
||||||
|
|
||||||
#: mpdevil.py:1336
|
#: mpdevil.py:1494
|
||||||
msgid "not found"
|
msgid "not found"
|
||||||
msgstr "nicht gefunden"
|
msgstr "nicht gefunden"
|
||||||
|
|
||||||
#: mpdevil.py:1341
|
#: mpdevil.py:1499
|
||||||
msgid "not connected"
|
msgid "not connected"
|
||||||
msgstr "nicht verbunden"
|
msgstr "nicht verbunden"
|
||||||
|
|
||||||
#: mpdevil.py:1421
|
#: mpdevil.py:1576
|
||||||
msgid "Select profile"
|
msgid "Select profile"
|
||||||
msgstr "Profil auswählen"
|
msgstr "Profil auswählen"
|
||||||
|
|
||||||
#: mpdevil.py:1425
|
#: 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:1427
|
#: mpdevil.py:1582
|
||||||
msgid "Title search"
|
msgid "Title search"
|
||||||
msgstr "Titelsuche"
|
msgstr "Titelsuche"
|
||||||
|
|
||||||
#: mpdevil.py:1429
|
#: mpdevil.py:1584
|
||||||
msgid "Show lyrics"
|
msgid "Show lyrics"
|
||||||
msgstr "Zeige Liedtext"
|
msgstr "Zeige Liedtext"
|
||||||
|
|
||||||
#: mpdevil.py:1436
|
#: 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:1440
|
#: mpdevil.py:1595
|
||||||
msgid "Save window size"
|
msgid "Save window size"
|
||||||
msgstr "Fenstergröße speichern"
|
msgstr "Fenstergröße speichern"
|
||||||
|
|
||||||
#: mpdevil.py:1442
|
#: mpdevil.py:1597
|
||||||
msgid "Update database"
|
msgid "Update database"
|
||||||
msgstr "Datenbank aktualisieren"
|
msgstr "Datenbank aktualisieren"
|
||||||
|
|
||||||
#: mpdevil.py:1443
|
#: mpdevil.py:1598
|
||||||
msgid "Server stats"
|
msgid "Server stats"
|
||||||
msgstr "Serverstatistik"
|
msgstr "Serverstatistik"
|
||||||
|
|
||||||
#: mpdevil.py:1444
|
#: mpdevil.py:1599
|
||||||
msgid "About"
|
msgid "About"
|
||||||
msgstr "Über"
|
msgstr "Über"
|
||||||
|
|
||||||
#: mpdevil.py:1445
|
#: mpdevil.py:1600
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr "Beenden"
|
msgstr "Beenden"
|
||||||
|
|
||||||
#: mpdevil.py:1450
|
#: mpdevil.py:1605
|
||||||
msgid "Main menu"
|
msgid "Main menu"
|
||||||
msgstr "Hauptmenu"
|
msgstr "Hauptmenu"
|
||||||
|
|
||||||
#: mpdevil.py:1603
|
#: mpdevil.py:1758
|
||||||
msgid "A small MPD client written in python"
|
msgid "A small MPD client written in python"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
138
po/mpdevil.pot
138
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-12 16:18+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:116
|
#: mpdevil.py:159 mpdevil.py:368 mpdevil.py:1366
|
||||||
msgid "Album Artist"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: mpdevil.py:173 mpdevil.py:350 mpdevil.py:1265
|
|
||||||
msgid "Unknown Title"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: mpdevil.py:188
|
|
||||||
#, python-format
|
|
||||||
msgid "%(album)s%(year)s (tracks: %(total_tracks)i) (%(total_length)s):"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: mpdevil.py:244 mpdevil.py:1210
|
|
||||||
msgid "No"
|
msgid "No"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:249 mpdevil.py:1215
|
#: mpdevil.py:164 mpdevil.py:373 mpdevil.py:1372
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:254 mpdevil.py:1220
|
#: mpdevil.py:169 mpdevil.py:378 mpdevil.py:1378
|
||||||
msgid "Artist"
|
msgid "Artist"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:259 mpdevil.py:1230
|
#: mpdevil.py:174 mpdevil.py:383 mpdevil.py:1390
|
||||||
msgid "Length"
|
msgid "Length"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:358 mpdevil.py:1273
|
#: mpdevil.py:214 mpdevil.py:483 mpdevil.py:1427
|
||||||
|
msgid "Unknown Title"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: mpdevil.py:218 mpdevil.py:491 mpdevil.py:1435
|
||||||
msgid "Unknown Artist"
|
msgid "Unknown Artist"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:362 mpdevil.py:1277
|
#: mpdevil.py:254
|
||||||
|
msgid "Album Artist"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: mpdevil.py:313 mpdevil.py:504
|
||||||
|
#, python-format
|
||||||
|
msgid "%(total_tracks)i titles (%(total_length)s)"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: mpdevil.py:495 mpdevil.py:1439
|
||||||
msgid "Unknown Album"
|
msgid "Unknown Album"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:575
|
#: mpdevil.py:725
|
||||||
msgid "Select"
|
msgid "Select"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:577
|
#: mpdevil.py:727
|
||||||
msgid "Profile:"
|
msgid "Profile:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:579
|
#: mpdevil.py:729
|
||||||
msgid "Name:"
|
msgid "Name:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:581
|
#: mpdevil.py:731
|
||||||
msgid "Host:"
|
msgid "Host:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:583
|
#: mpdevil.py:733
|
||||||
msgid "Port:"
|
msgid "Port:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:585
|
#: mpdevil.py:735
|
||||||
msgid "Music lib:"
|
msgid "Music lib:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:675
|
#: mpdevil.py:810
|
||||||
msgid "Choose directory"
|
msgid "Choose directory"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:711
|
#: mpdevil.py:846
|
||||||
msgid "Main cover size:"
|
msgid "Main cover size:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:713
|
#: mpdevil.py:848
|
||||||
msgid "Album-view cover size:"
|
msgid "Album-view cover size:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:719
|
#: 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:722
|
#: mpdevil.py:866
|
||||||
msgid "Show title list as tooltip in album view"
|
msgid "Show tooltips in album view"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:725
|
#: mpdevil.py:869
|
||||||
msgid "Send notification on title change"
|
msgid "Send notification on title change"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:728
|
#: mpdevil.py:872
|
||||||
msgid "Stop playback on quit"
|
msgid "Stop playback on quit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:731
|
#: mpdevil.py:875
|
||||||
msgid "Play selected album after current title"
|
msgid "Play selected album after current title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:762 mpdevil.py:1441
|
#: mpdevil.py:913 mpdevil.py:1596
|
||||||
msgid "Settings"
|
msgid "Settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:775
|
#: mpdevil.py:926
|
||||||
msgid "General"
|
msgid "General"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:776
|
#: mpdevil.py:927
|
||||||
msgid "Profiles"
|
msgid "Profiles"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:924
|
#: mpdevil.py:1081
|
||||||
msgid "Random mode"
|
msgid "Random mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:926
|
#: mpdevil.py:1083
|
||||||
msgid "Repeat mode"
|
msgid "Repeat mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:928
|
#: mpdevil.py:1085
|
||||||
msgid "Single mode"
|
msgid "Single mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:930
|
#: mpdevil.py:1087
|
||||||
msgid "Consume mode"
|
msgid "Consume mode"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1024
|
#: mpdevil.py:1182
|
||||||
msgid "Right click to show additional information"
|
msgid "Right click to show additional information"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1047
|
#: mpdevil.py:1206
|
||||||
msgid "MPD-Tag"
|
msgid "MPD-Tag"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1050 mpdevil.py:1158
|
#: mpdevil.py:1209 mpdevil.py:1316
|
||||||
msgid "Value"
|
msgid "Value"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1071
|
#: 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:1137
|
#: mpdevil.py:1295
|
||||||
msgid "Stats"
|
msgid "Stats"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1155
|
#: mpdevil.py:1313
|
||||||
msgid "Tag"
|
msgid "Tag"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1175
|
#: mpdevil.py:1333
|
||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1225
|
#: mpdevil.py:1384
|
||||||
msgid "Album"
|
msgid "Album"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1284
|
#: mpdevil.py:1446
|
||||||
#, python-format
|
#, python-format
|
||||||
msgid "Hits: %i"
|
msgid "Hits: %i"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1288
|
#: mpdevil.py:1450
|
||||||
msgid "Lyrics"
|
msgid "Lyrics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1332
|
#: mpdevil.py:1490
|
||||||
msgid "searching..."
|
msgid "searching..."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1336
|
#: mpdevil.py:1494
|
||||||
msgid "not found"
|
msgid "not found"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1341
|
#: mpdevil.py:1499
|
||||||
msgid "not connected"
|
msgid "not connected"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1421
|
#: mpdevil.py:1576
|
||||||
msgid "Select profile"
|
msgid "Select profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1425
|
#: mpdevil.py:1580
|
||||||
msgid "Return to album of current title"
|
msgid "Return to album of current title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1427
|
#: mpdevil.py:1582
|
||||||
msgid "Title search"
|
msgid "Title search"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1429
|
#: mpdevil.py:1584
|
||||||
msgid "Show lyrics"
|
msgid "Show lyrics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1436
|
#: mpdevil.py:1591
|
||||||
msgid "Not connected to MPD-server. Reconnect?"
|
msgid "Not connected to MPD-server. Reconnect?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1440
|
#: mpdevil.py:1595
|
||||||
msgid "Save window size"
|
msgid "Save window size"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1442
|
#: mpdevil.py:1597
|
||||||
msgid "Update database"
|
msgid "Update database"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1443
|
#: mpdevil.py:1598
|
||||||
msgid "Server stats"
|
msgid "Server stats"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1444
|
#: mpdevil.py:1599
|
||||||
msgid "About"
|
msgid "About"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1445
|
#: mpdevil.py:1600
|
||||||
msgid "Quit"
|
msgid "Quit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1450
|
#: mpdevil.py:1605
|
||||||
msgid "Main menu"
|
msgid "Main menu"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: mpdevil.py:1603
|
#: mpdevil.py:1758
|
||||||
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: 1021 KiB After Width: | Height: | Size: 1005 KiB |
Reference in New Issue
Block a user