summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <smcv@debian.org>2020-09-18 09:10:05 +0100
committerSimon McVittie <smcv@debian.org>2020-09-18 09:10:05 +0100
commit394bfdcf06d34d836d0991ce79ab2f9e48c8bcc7 (patch)
tree15276ec0f4ad5f44ddeaeafd98011ce803efbc59
parent53af09494d1c7b1dca4d98662380383bf84ad7a7 (diff)
parent9214c96178439e8c02fcaa4d81c5a8a1fbeaaf6e (diff)
New upstream version 3.38.0
-rw-r--r--NEWS149
-rw-r--r--README.md14
-rw-r--r--data/org.gnome.Music.appdata.xml.in.in35
-rw-r--r--data/org.gnome.Music.css3
-rw-r--r--data/org.gnome.Music.gresource.xml5
-rw-r--r--data/ui/AboutDialog.ui.in9
-rw-r--r--data/ui/AlbumCover.ui2
-rw-r--r--data/ui/AlbumWidget.ui13
-rw-r--r--data/ui/ArtistAlbumWidget.ui4
-rw-r--r--data/ui/ArtistSearchTile.ui2
-rw-r--r--data/ui/ArtistTile.ui31
-rw-r--r--data/ui/ArtistsView.ui37
-rw-r--r--data/ui/DiscBox.ui1
-rw-r--r--data/ui/EmptyView.ui2
-rw-r--r--data/ui/HeaderBar.ui1
-rw-r--r--data/ui/LoadingNotification.ui20
-rw-r--r--data/ui/NotificationsPopup.ui24
-rw-r--r--data/ui/PlayerToolbar.ui3
-rw-r--r--data/ui/PlaylistControls.ui1
-rw-r--r--data/ui/PlaylistNotification.ui39
-rw-r--r--data/ui/PlaylistsView.ui25
-rw-r--r--data/ui/PlaylistsWidget.ui1
-rw-r--r--data/ui/SearchHeaderBar.ui1
-rw-r--r--data/ui/SearchView.ui3
-rw-r--r--data/ui/SongWidget.ui3
-rw-r--r--data/ui/SongsView.ui123
-rw-r--r--data/ui/Window.ui11
-rwxr-xr-xgnome-music.in12
-rw-r--r--gnomemusic/albumart.py72
-rw-r--r--gnomemusic/albumartcache.py678
-rw-r--r--gnomemusic/application.py40
-rw-r--r--gnomemusic/artcache.py267
-rw-r--r--gnomemusic/artistart.py299
-rw-r--r--gnomemusic/corealbum.py53
-rw-r--r--gnomemusic/coreartist.py58
-rw-r--r--gnomemusic/coredisc.py42
-rw-r--r--gnomemusic/coregrilo.py175
-rw-r--r--gnomemusic/coremodel.py227
-rw-r--r--gnomemusic/coreselection.py14
-rw-r--r--gnomemusic/coresong.py46
-rw-r--r--gnomemusic/embeddedart.py181
-rw-r--r--gnomemusic/grilowrappers/grlsearchwrapper.py15
-rw-r--r--gnomemusic/grilowrappers/grltrackerplaylists.py568
-rw-r--r--gnomemusic/grilowrappers/grltrackerwrapper.py1082
-rw-r--r--gnomemusic/gstplayer.py58
-rw-r--r--gnomemusic/mpris.py116
-rw-r--r--gnomemusic/notificationmanager.py61
-rw-r--r--gnomemusic/player.py42
-rw-r--r--gnomemusic/scrobbler.py20
-rw-r--r--gnomemusic/songart.py72
-rw-r--r--gnomemusic/storeart.py162
-rw-r--r--gnomemusic/trackerwrapper.py244
-rw-r--r--gnomemusic/utils.py51
-rw-r--r--gnomemusic/views/albumsview.py13
-rw-r--r--gnomemusic/views/artistsview.py125
-rw-r--r--gnomemusic/views/baseview.py77
-rw-r--r--gnomemusic/views/emptyview.py9
-rw-r--r--gnomemusic/views/playlistsview.py26
-rw-r--r--gnomemusic/views/searchview.py29
-rw-r--r--gnomemusic/views/songsview.py180
-rw-r--r--gnomemusic/widgets/albumcover.py19
-rw-r--r--gnomemusic/widgets/albumwidget.py26
-rw-r--r--gnomemusic/widgets/artistalbumswidget.py23
-rw-r--r--gnomemusic/widgets/artistalbumwidget.py47
-rw-r--r--gnomemusic/widgets/artistartstack.py162
-rw-r--r--gnomemusic/widgets/artistsearchtile.py10
-rw-r--r--gnomemusic/widgets/artisttile.py12
-rw-r--r--gnomemusic/widgets/artstack.py129
-rw-r--r--gnomemusic/widgets/coverstack.py147
-rw-r--r--gnomemusic/widgets/disclistboxwidget.py59
-rw-r--r--gnomemusic/widgets/headerbar.py32
-rw-r--r--gnomemusic/widgets/notificationspopup.py70
-rw-r--r--gnomemusic/widgets/playertoolbar.py9
-rw-r--r--gnomemusic/widgets/playlistcontrols.py3
-rw-r--r--gnomemusic/widgets/playlistdialog.py17
-rw-r--r--gnomemusic/widgets/playlistswidget.py11
-rw-r--r--gnomemusic/widgets/searchheaderbar.py14
-rw-r--r--gnomemusic/widgets/selectiontoolbar.py10
-rw-r--r--gnomemusic/widgets/songwidget.py60
-rw-r--r--gnomemusic/widgets/starimage.py2
-rw-r--r--gnomemusic/window.py78
-rw-r--r--meson.build13
-rw-r--r--org.gnome.Music.json41
-rw-r--r--po/POTFILES.in3
-rw-r--r--po/ca.po143
-rw-r--r--po/cs.po129
-rw-r--r--po/da.po126
-rw-r--r--po/de.po135
-rw-r--r--po/el.po201
-rw-r--r--po/es.po129
-rw-r--r--po/eu.po128
-rw-r--r--po/fa.po124
-rw-r--r--po/fi.po126
-rw-r--r--po/fr.po132
-rw-r--r--po/fur.po171
-rw-r--r--po/gl.po138
-rw-r--r--po/hr.po130
-rw-r--r--po/hu.po129
-rw-r--r--po/id.po126
-rw-r--r--po/it.po126
-rw-r--r--po/ja.po209
-rw-r--r--po/kk.po124
-rw-r--r--po/ko.po126
-rw-r--r--po/lt.po131
-rw-r--r--po/lv.po255
-rw-r--r--po/nl.po122
-rw-r--r--po/pl.po126
-rw-r--r--po/pt.po855
-rw-r--r--po/pt_BR.po132
-rw-r--r--po/ro.po26
-rw-r--r--po/sk.po126
-rw-r--r--po/sl.po134
-rw-r--r--po/sr.po134
-rw-r--r--po/sv.po126
-rw-r--r--po/tr.po246
-rw-r--r--po/uk.po143
-rw-r--r--po/zh_CN.po136
-rw-r--r--po/zh_TW.po30
-rw-r--r--subprojects/shared-modules/CODEOWNERS3
-rw-r--r--subprojects/shared-modules/README.md9
-rw-r--r--subprojects/shared-modules/glew/glew.json4
-rw-r--r--subprojects/shared-modules/gtk2/arc-gtk2-theme-Replace-Inkscape-dependency-with-rsvg-convert.patch180
-rw-r--r--subprojects/shared-modules/gtk2/gtk2-common-themes.json226
-rw-r--r--subprojects/shared-modules/gtk2/gtk2-use-adwaita-theme.patch2
-rw-r--r--subprojects/shared-modules/gtk2/gtk2.json9
-rw-r--r--subprojects/shared-modules/gtk2/murrine-engine-fix-crash.patch12
-rw-r--r--subprojects/shared-modules/libappindicator/libappindicator-fix-crash-from-incorrect-signal-emission.patch74
-rw-r--r--subprojects/shared-modules/libappindicator/libappindicator-fix-crash-iterating-icon-themes.patch11
-rw-r--r--subprojects/shared-modules/libappindicator/libappindicator-gtk2-12.10.json8
-rw-r--r--subprojects/shared-modules/libappindicator/libappindicator-gtk3-12.10.json8
-rw-r--r--subprojects/shared-modules/libappindicator/libappindicator-gtk3-introspection-12.10.json8
-rw-r--r--subprojects/shared-modules/libappindicator/libappindicator.json.in8
-rw-r--r--subprojects/shared-modules/libsecret/libsecret-init-gcrypt-for-file-collection.patch21
-rw-r--r--subprojects/shared-modules/libsecret/libsecret.json8
-rw-r--r--subprojects/shared-modules/libusb/libusb.json19
-rw-r--r--subprojects/shared-modules/linux-audio/dssi.json29
-rw-r--r--subprojects/shared-modules/linux-audio/fftw3f-static.json41
-rw-r--r--subprojects/shared-modules/linux-audio/fftw3f.json36
-rw-r--r--subprojects/shared-modules/linux-audio/fluidsynth2-static.json29
-rw-r--r--subprojects/shared-modules/linux-audio/fluidsynth2.json21
-rw-r--r--subprojects/shared-modules/linux-audio/jack2.json21
-rw-r--r--subprojects/shared-modules/linux-audio/ladspa.json17
-rw-r--r--subprojects/shared-modules/linux-audio/lash.json41
-rw-r--r--subprojects/shared-modules/linux-audio/libinstpatch.json17
-rw-r--r--subprojects/shared-modules/linux-audio/liblo-static.json27
-rw-r--r--subprojects/shared-modules/linux-audio/liblo.json17
-rw-r--r--subprojects/shared-modules/linux-audio/lilv.json100
-rw-r--r--subprojects/shared-modules/linux-audio/lrdf.json44
-rw-r--r--subprojects/shared-modules/linux-audio/lv2.json26
-rw-r--r--subprojects/shared-modules/linux-audio/patches/lash-0.5.3-no-static-lib.patch10
-rw-r--r--subprojects/shared-modules/linux-audio/patches/lash-configure.patch11
-rw-r--r--subprojects/shared-modules/linux-audio/patches/lash-gcc47.patch11
-rw-r--r--subprojects/shared-modules/linux-audio/patches/lash-linking.patch90
-rw-r--r--subprojects/shared-modules/linux-audio/patches/stk-install.sh54
-rw-r--r--subprojects/shared-modules/linux-audio/stk.json28
-rw-r--r--subprojects/shared-modules/lua5.1/lua-5.1.5-so.patch43
-rw-r--r--subprojects/shared-modules/lua5.1/lua-5.1.5.json38
-rw-r--r--subprojects/shared-modules/lua5.3/lua-5.3.0-autotoolize.patch192
-rw-r--r--subprojects/shared-modules/lua5.3/lua-5.3.0-configure-compat-module.patch35
-rw-r--r--subprojects/shared-modules/lua5.3/lua-5.3.0-idsize.patch12
-rw-r--r--subprojects/shared-modules/lua5.3/lua-5.3.5.json42
-rw-r--r--subprojects/shared-modules/lua5.3/lua.pc.in8
-rw-r--r--subprojects/shared-modules/lua5.3/makefile-add-liblua.so-rule.patch47
-rw-r--r--subprojects/shared-modules/python2.7/python-2.7.json4
-rw-r--r--subprojects/shared-modules/qt4/fixgcc9.patch31
-rw-r--r--subprojects/shared-modules/qt4/qt4-4.8.7-minimal.json4
166 files changed, 6708 insertions, 7075 deletions
diff --git a/NEWS b/NEWS
index 8013d4f7..cd477b01 100644
--- a/NEWS
+++ b/NEWS
@@ -1,90 +1,133 @@
-Overview of changes in 3.36.4.1
-===============================
+Overview of changes in 3.38.0
+=============================
-• Fix a showstopper bug in 3.36.4.1
+Updated translations:
+ Danish
+ Greek
+ Hungarian
+ Italian
+ Latvian
+ Portuguese
-Packagers should use this version and remove 3.36.4 as it is non-functional.
+Overview of changes in 3.37.92
+==============================
-Overview of changes in 3.36.4
-=============================
+* Port to Tracker 3
+* Art retrieval complete rework
+* Flatpak cleanups and updates
Bugs fixed:
- pauseonsuspend: Fix calls to MusicLogger.warning() (!724)
- Duplication of menu bar (#387)
+ gnome-music gets stuck when next button is pressed when current song is about to finish (#375)
+ Selection mode search doesn't work (#405)
+ Selecting an album in albums view in selection mode randomly deselects other albums (#406)
+ Selection mode only works for artists during search (#407)
+ Music crashed if gnome-online-accounts is unavailable (#410)
+ MPRIS playlist fixes (!741)
+ Gracefully handle locale.{bind,}textdomain not being available (!735)
Thanks to our contributors this release:
- Evan Nehring
- Nils Reuße
+ Adam Blanchet
+ Carlos Garnacho
+ Chinmay Gurjar
+ Jean Felder
+ Marinus Schrall
+ Piotr DrÄ…g
+ Rasmus Thomsen
+ Sam Thursfield
+ Simon McVittie
Updated translation:
+ Basque
+ Brazilian Portuguese
+ Catalan
+ Chinese (China)
+ Croatian
+ Czech
+ Dutch
+ Finnish
+ French
+ Friulian
+ Galician
+ German
+ Indonesian
+ Japanese
Kazakh
+ Korean
+ Lithuanian
+ Persian
+ Polish
+ Serbian
+ Slovak
+ Slovenian
+ Spanish
+ Swedish
+ Turkish
+ Ukrainian
-Overview of changes in 3.36.3
-=============================
-
-* Fix a crash in SearchView
-* Handle missing change notification case
-
-Bugs fixed:
- searchview: Fix incorrect object use (!708)
- grltrackerwrapper: Handle missing change notification case (!716)
-
-Thanks to our contributors this release:
- Atharva Veer
- Marinus Schraal
-
-* Fix a crash in SearchView
-* Handle missing change notification case
-
-Updated translations:
- Romanian
-
-Overview of changes in 3.36.2
+Overview of changes in 3.37.3
=============================
-• Fix two crashers
-
Bugs fixed:
- Crash on playlist change check (#382)
- Rare crash on some music files (!701)
+ pauseonsuspend: Fix calls to MusicLogger.warning() (!724)
+ Duplication of menu bar (#387)
+ High CPU usage (#360)
+ Bind more SongWidget properties (!663)
Thanks to our contributors this release:
+ Evan Nehring
+ Jean Felder
Marinus Schraal
+ Nils Reuße
-Translation added:
- Ukranian
-
-Updated translations:
- Hebrew
- Slovak
- Russian
- Slovenian
- Chinese (China)
+Updated translation:
+ Kazakh
-Overview of changes in 3.36.1
+Overview of changes in 3.37.2
=============================
-• Fix crash when Pango 1.44 is not available
-• Do not change python module search path
-• Various CoreModel and Playlist binding optimizations
-• Various crash and bugfixes
+* Use Gtk.Template for all the Views and remove BaseView
+* Prefer Albumartist field for artist search
+* Change Artist view selection from artist to song
+* Extend Gtk.Template usage for Window
+* Deinitialize Grilo on shutdown
+* Music now explicitly depends on Pango 1.44 or above
+* Flatpak cleanups and updates
+* Various widgets style and code cleanups
Bugs fixed:
+ Artist view should support music selection (#26)
+ In-app notifications need to be dismissable (#259)
+ Stop using show_all (#320)
Crash while searching due to bugs in searchview.py (#372)
- Do not change the module search path (#377)
+ Crash on start: object 'AttrFontFeatures' has no attribute 'new' (#374)
Wrong song count in favourite playlist (#376)
- First song selected displays selected count as 2 (#379)
- App crashing on start: type object 'AttrFontFeatures' has no attribute 'new' (#374)
+ Please stop changing the module search path (#377)
+ Use libsoup for art retrieval (#378)
+ Music crashes on 'check_smart_playlist_change' call (#382)
Thanks to our contributors this release:
Ashwani Singh Tanwar
+ Atharva Veer
+ Chinmay Gurjar
+ Erik Inkinen
+ Evan Nehring
Jean Felder
Marinus Schraal
- Weifeng Lai
+ Weifang Lai
+
+Added translations:
+ Ukrainian
Updated translations:
Catalan
+ Chinese (China)
+ Chinese (Taiwan)
+ Hebrew
Norwegian Bokmål
+ Romanian
+ Russian
+ Slovak
+ Slovenian
Ukrainian
Overview of changes in 3.36.0
diff --git a/README.md b/README.md
index eab51d89..7af1e256 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ You can join the developers on IRC: [#gnome-music](irc://irc.gnome.org/gnome-mus
Follow the [GNOME Newcomers guide](https://wiki.gnome.org/Newcomers/) and choose Music as your project. There are bugs labeled for newcomers, which should provide an easy entry point. Of course, feel free to pick something more challenging. Pick bugs if you can, not feature requests. The goal is to make the current Music experience sound & stable and only then extend it's functionality.
-### Build Music
+## Build Music
Music uses the [meson](http://mesonbuild.com/) build system. Use the following commands to build Music from the source directory:
@@ -33,6 +33,14 @@ You can also install Music system-wide by running:
$ ninja install
```
+## Debugging
+
+GNOME Music uses [GLib logging facilities](https://developer.gnome.org/glib/stable/glib-running.html) to print debug messages. It can be activated by setting the `G_MESSAGES_DEBUG` environment variable:
+
+```sh
+G_MESSAGES_DEBUG=org.gnome.Music gnome-music
+```
+
## Coding style
GNOME Music is written in Python and adheres to the coding style described in the python style guide [PEP-8](https://www.python.org/dev/peps/pep-0008/).
@@ -145,10 +153,10 @@ Recent PyGObject (3.29.1 and up) allows template usage and Music is [starting to
The basic usage in Python is as follows, with the `widget.ui` file being a regular GTK template:
```python
-@Gtk.Template(resource_path='/org/gnome/Music/widget.ui')
+@Gtk.Template(resource_path="/org/gnome/Music/widget.ui")
class Widget(Gtk.Widget):
- __gtype_name__ = 'Widget'
+ __gtype_name__ = "Widget"
_button = Gtk.Template.Child()
diff --git a/data/org.gnome.Music.appdata.xml.in.in b/data/org.gnome.Music.appdata.xml.in.in
index c5816da2..db89e06b 100644
--- a/data/org.gnome.Music.appdata.xml.in.in
+++ b/data/org.gnome.Music.appdata.xml.in.in
@@ -28,33 +28,20 @@
</screenshot>
</screenshots>
<releases>
- <release version="3.36.4.1" date="2020-07-08">
+ <release version="3.38.0" date="2020-09-14">
<description>
<p>
- Fix a showstopper bug in 3.36.4.
+ First stable release for GNOME 3.38. This version does not rely on
+ Tracker running on the host. There are also some notable
+ improvements:
</p>
- </description>
- </release>
- <release version="3.36.4" date="2020-07-04">
- <description>
- <p>
- Bugfixes and translation updates.
- </p>
- </description>
- </release>
- <release version="3.36.3" date="2020-05-30">
- <description>
- <p>
- This updates fixes one crasher and updates translations.
- </p>
- </description>
- </release>
- <release version="3.36.2" date="2020-04-25">
- <description>
- <p>
- Two possible crashers fixed.
- </p>
- <p>This release also updates and adds translations.</p>
+ <ul>
+ <li>Port to Tracker version 3</li>
+ <li>Prefer Albumartist field for artist search</li>
+ <li>Change Artist view selection from artist to song</li>
+ <li>Lots of general cleanups and bugfixes</li>
+ </ul>
+ <p>This release also updates translations.</p>
</description>
</release>
<release version="3.36.0" date="2020-03-07">
diff --git a/data/org.gnome.Music.css b/data/org.gnome.Music.css
index 617c8650..00e2ec7a 100644
--- a/data/org.gnome.Music.css
+++ b/data/org.gnome.Music.css
@@ -57,6 +57,9 @@ box#ArtistAlbumsWidget .artist-label {
}
/* ArtistAlbumWidget */
+.artist-albums-widget {
+ margin: 0 0 20px 0;
+}
.artist-albums-widget,
.artist-albums-widget:hover {
background-color: @theme_bg_color;
diff --git a/data/org.gnome.Music.gresource.xml b/data/org.gnome.Music.gresource.xml
index 9d3cceb2..4ef28690 100644
--- a/data/org.gnome.Music.gresource.xml
+++ b/data/org.gnome.Music.gresource.xml
@@ -11,6 +11,7 @@
<file preprocess="xml-stripblanks">ui/ArtistSearchTile.ui</file>
<file preprocess="xml-stripblanks">ui/AppMenu.ui</file>
<file preprocess="xml-stripblanks">ui/ArtistAlbumWidget.ui</file>
+ <file preprocess="xml-stripblanks">ui/ArtistsView.ui</file>
<file preprocess="xml-stripblanks">ui/ArtistTile.ui</file>
<file preprocess="xml-stripblanks">ui/DiscBox.ui</file>
<file preprocess="xml-stripblanks">ui/DropDown.ui</file>
@@ -18,11 +19,14 @@
<file preprocess="xml-stripblanks">ui/FilterView.ui</file>
<file preprocess="xml-stripblanks">ui/HeaderBar.ui</file>
<file preprocess="xml-stripblanks">ui/LastfmDialog.ui</file>
+ <file preprocess="xml-stripblanks">ui/LoadingNotification.ui</file>
+ <file preprocess="xml-stripblanks">ui/NotificationsPopup.ui</file>
<file preprocess="xml-stripblanks">ui/PlayerToolbar.ui</file>
<file preprocess="xml-stripblanks">ui/PlaylistContextMenu.ui</file>
<file preprocess="xml-stripblanks">ui/PlaylistControls.ui</file>
<file preprocess="xml-stripblanks">ui/PlaylistDialog.ui</file>
<file preprocess="xml-stripblanks">ui/PlaylistDialogRow.ui</file>
+ <file preprocess="xml-stripblanks">ui/PlaylistNotification.ui</file>
<file preprocess="xml-stripblanks">ui/PlaylistsView.ui</file>
<file preprocess="xml-stripblanks">ui/PlaylistsWidget.ui</file>
<file preprocess="xml-stripblanks">ui/PlaylistTile.ui</file>
@@ -30,6 +34,7 @@
<file preprocess="xml-stripblanks">ui/SearchView.ui</file>
<file preprocess="xml-stripblanks">ui/SelectionBarMenuButton.ui</file>
<file preprocess="xml-stripblanks">ui/SelectionToolbar.ui</file>
+ <file preprocess="xml-stripblanks">ui/SongsView.ui</file>
<file preprocess="xml-stripblanks">ui/SongWidget.ui</file>
<file preprocess="xml-stripblanks">ui/TwoLineTip.ui</file>
<file preprocess="xml-stripblanks">ui/Window.ui</file>
diff --git a/data/ui/AboutDialog.ui.in b/data/ui/AboutDialog.ui.in
index 7e878871..38ff9ad5 100644
--- a/data/ui/AboutDialog.ui.in
+++ b/data/ui/AboutDialog.ui.in
@@ -20,6 +20,7 @@ The GNOME Music authors hereby grant permission for non-GPL compatible GStreamer
“Magic of the vinyl†by Sami Pyylampi image is licensed by CC-BY-SA 2.0 https://www.flickr.com/photos/_spy_/12270839403</property>
<property name="authors">Abhinav Singh
+Adam Blanchet
Adrian Solom
Alberto Fanjul
Alexander Mikhaylenko
@@ -43,6 +44,7 @@ Clayton G. Hobbs
Divyanshu Vishwakarma
Eslam Mostafa
Elias Entrup
+Erik Inkinen
Evan Nehring
Evandro Giovanini
Fabiano Fidêncio
@@ -81,6 +83,7 @@ Phil Dawson
Piotr DrÄ…g
Prashant Tyagi
Rashi Sah
+Rasmus Thomsen
Reuben Dsouza
Robert Greener
Sabri Ãœnal
@@ -92,6 +95,7 @@ Sambhav Kothari
Seif Lotfy
Shivani Poddar
Shivansh Handa
+Simon McVittie
Subhadip Jana
Sumaid Syed
Suyash Garg
@@ -100,7 +104,7 @@ Taylor Garcia
Tjipke van der Heide
Vadim Rutkovsky
Veerasamy Sevagen
-Weifeng Lai
+Weifang Lai
Yash Singh
</property>
<property name="artists">Allan Day
@@ -123,6 +127,7 @@ Balázs Meskó
Balázs Úr
Baurzhan Muftakhidinov
Bruce Cowan
+Boyuan Yang
Carmen Bianca Bakker
Cédric Valmary
Chao-Hsiung Liao
@@ -147,11 +152,13 @@ Gábor Kelemen
Gil Forcada Codinachs
Goran Vidović
Guillaume Bernard
+Henrique Machado Campos
Inaki Larranaga Murgoitio
Jiri Grönroos
Joe Hansen
Jor Teron
Jordi Mas
+Juliano Camargo
Julien Humbert
Justin van Steijn
Kjartan Maraas
diff --git a/data/ui/AlbumCover.ui b/data/ui/AlbumCover.ui
index d825c1cc..7ac403c2 100644
--- a/data/ui/AlbumCover.ui
+++ b/data/ui/AlbumCover.ui
@@ -16,7 +16,7 @@
<property name="can_focus">False</property>
<property name="margin_bottom">4</property>
<child>
- <object class="CoverStack" id="_cover_stack">
+ <object class="ArtStack" id="_art_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="vexpand">True</property>
diff --git a/data/ui/AlbumWidget.ui b/data/ui/AlbumWidget.ui
index 75d649ac..e5848709 100644
--- a/data/ui/AlbumWidget.ui
+++ b/data/ui/AlbumWidget.ui
@@ -19,7 +19,7 @@
<property name="halign">end</property>
<property name="margin_start">32</property>
<property name="margin_end">32</property>
- <property name="margin_top">64</property>
+ <property name="margin_top">48</property>
<property name="margin_bottom">32</property>
<property name="vexpand">True</property>
<property name="hexpand">True</property>
@@ -32,13 +32,15 @@
<property name="orientation">vertical</property>
<property name="spacing">18</property>
<child>
- <object class="CoverStack" id="_cover_stack">
+ <object class="ArtStack" id="_art_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">start</property>
<property name="margin_start">1</property>
<property name="margin_end">1</property>
+ <property name="hhomogeneous">False</property>
+ <property name="vhomogeneous">False</property>
</object>
<packing>
<property name="position">0</property>
@@ -159,7 +161,6 @@
<object class="GtkLabel" id="_composer_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="no_show_all">True</property>
<property name="halign">end</property>
<property name="margin_top">2</property>
<property name="margin_bottom">2</property>
@@ -178,7 +179,6 @@
<object class="GtkLabel" id="_composer_info_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="no_show_all">True</property>
<property name="halign">start</property>
<property name="margin_top">2</property>
<property name="margin_bottom">2</property>
@@ -222,11 +222,10 @@
<child>
<object class="DiscListBox" id="_disc_list_box">
<property name="can_focus">False</property>
- <property name="margin_top">64</property>
- <property name="margin_bottom">64</property>
+ <property name="margin_top">48</property>
+ <property name="margin_bottom">48</property>
<property name="margin_end">32</property>
<property name="selection_mode">0</property>
- <property name="selection_mode_allowed">True</property>
<property name="visible">True</property>
</object>
</child>
diff --git a/data/ui/ArtistAlbumWidget.ui b/data/ui/ArtistAlbumWidget.ui
index 54ccb83f..e25083ce 100644
--- a/data/ui/ArtistAlbumWidget.ui
+++ b/data/ui/ArtistAlbumWidget.ui
@@ -3,11 +3,11 @@
<interface>
<requires lib="gtk+" version="3.12"/>
<template parent="GtkBox" class="ArtistAlbumWidget">
- <property name="margin_top">30</property>
+ <property name="margin_top">20</property>
<property name="margin_right">120</property>
<property name="visible">True</property>
<child>
- <object class="CoverStack" id="_cover_stack">
+ <object class="ArtStack" id="_art_stack">
<property name="visible">True</property>
<property name="margin_top">20</property>
<property name="margin_right">30</property>
diff --git a/data/ui/ArtistSearchTile.ui b/data/ui/ArtistSearchTile.ui
index 50ab0a38..c62feaf4 100644
--- a/data/ui/ArtistSearchTile.ui
+++ b/data/ui/ArtistSearchTile.ui
@@ -21,7 +21,7 @@
<property name="can_focus">False</property>
<signal name="button-release-event" handler="_on_artist_event" swapped="no"/>
<child>
- <object class="ArtistArtStack" id="_artistart_stack">
+ <object class="ArtStack" id="_art_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="vexpand">True</property>
diff --git a/data/ui/ArtistTile.ui b/data/ui/ArtistTile.ui
index 2745fc3e..c4d854a8 100644
--- a/data/ui/ArtistTile.ui
+++ b/data/ui/ArtistTile.ui
@@ -4,36 +4,13 @@
<property name="can_focus">False</property>
<property name="visible">True</property>
<child>
- <object class="GtkBox">
+ <object class="GtkLabel" id="_label">
<property name="can_focus">False</property>
+ <property name="ellipsize">end</property>
+ <property name="halign">start</property>
<property name="hexpand">False</property>
- <property name="orientation">horizontal</property>
+ <property name="margin">16</property>
<property name="visible">True</property>
- <child>
- <object class="GtkRevealer" id="_revealer">
- <property name="halign">fill</property>
- <property name="hexpand">False</property>
- <property name="reveal-child">False</property>
- <property name="transition-type">slide-right</property>
- <property name="visible">True</property>
- <child>
- <object class="GtkCheckButton" id="_check">
- <property name="margin-start">12</property>
- <property name="visible">True</property>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkLabel" id="_label">
- <property name="can_focus">False</property>
- <property name="ellipsize">end</property>
- <property name="halign">start</property>
- <property name="hexpand">True</property>
- <property name="margin">16</property>
- <property name="visible">True</property>
- </object>
- </child>
</object>
</child>
</template>
diff --git a/data/ui/ArtistsView.ui b/data/ui/ArtistsView.ui
new file mode 100644
index 00000000..cce0e7be
--- /dev/null
+++ b/data/ui/ArtistsView.ui
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.18"/>
+ <template class="ArtistsView" parent="GtkBox">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="width_request">220</property>
+ <style>
+ <class name="sidebar"/>
+ </style>
+ <child>
+ <object class="GtkListBox" id="_sidebar">
+ <property name="selection_mode">single</property>
+ <property name="visible">True</property>
+ <signal name="row-activated" handler="_on_artist_activated" swapped="no"/>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkScrolledWindow" id="_artist_container">
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkStack" id="_artist_view">
+ <property name="transition-type">crossfade</property>
+ <property name="vhomogeneous">False</property>
+ <property name="visible">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/data/ui/DiscBox.ui b/data/ui/DiscBox.ui
index a769b65c..5d2ce0bf 100644
--- a/data/ui/DiscBox.ui
+++ b/data/ui/DiscBox.ui
@@ -17,7 +17,6 @@
<property name="can_focus">False</property>
<property name="halign">fill</property>
<!-- <property name="hexpand">True</property> -->
- <property name="no_show_all">True</property>
<property name="xalign">0.0</property>
<style>
<class name="disc-label"/>
diff --git a/data/ui/EmptyView.ui b/data/ui/EmptyView.ui
index 66f71f54..cc7ae76c 100644
--- a/data/ui/EmptyView.ui
+++ b/data/ui/EmptyView.ui
@@ -3,6 +3,7 @@
<!-- interface-requires gtk+ 3.0 -->
<template class="EmptyView" parent="GtkStack">
<property name="transition_type">crossfade</property>
+ <property name="visible">True</property>
<child>
<object class="GtkBox" id="_container">
<property name="visible">True</property>
@@ -32,6 +33,7 @@
<child>
<object class="GtkBox" id="box">
<property name="orientation">vertical</property>
+ <property name="visible">True</property>
<child>
<object class="GtkLabel" id="_main_label">
<property name="visible">True</property>
diff --git a/data/ui/HeaderBar.ui b/data/ui/HeaderBar.ui
index d24359f8..c0e8578a 100644
--- a/data/ui/HeaderBar.ui
+++ b/data/ui/HeaderBar.ui
@@ -56,7 +56,6 @@
<child>
<object class="GtkButton" id="_cancel_button">
<property name="visible">False</property>
- <property name="no_show_all">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Cancel</property>
<property name="use_underline">True</property>
diff --git a/data/ui/LoadingNotification.ui b/data/ui/LoadingNotification.ui
new file mode 100644
index 00000000..3af3a1ac
--- /dev/null
+++ b/data/ui/LoadingNotification.ui
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="LoadingNotification" parent="GtkGrid">
+ <property name="column_spacing">18</property>
+ <child>
+ <object class="GtkSpinner">
+ <property name="visible">True</property>
+ <property name="active">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes">Loading</property>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/data/ui/NotificationsPopup.ui b/data/ui/NotificationsPopup.ui
new file mode 100644
index 00000000..ae2d3007
--- /dev/null
+++ b/data/ui/NotificationsPopup.ui
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <template class="NotificationsPopup" parent="GtkRevealer">
+ <property name="visible">True</property>
+ <property name="halign">center</property>
+ <property name="valign">start</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="shadow_type">none</property>
+ <child>
+ <object class="GtkGrid" id="_grid">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="row_spacing">6</property>
+ </object>
+ </child>
+ <style>
+ <class name="app-notification"/>
+ </style>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/data/ui/PlayerToolbar.ui b/data/ui/PlayerToolbar.ui
index 78888f6e..79c37bbc 100644
--- a/data/ui/PlayerToolbar.ui
+++ b/data/ui/PlayerToolbar.ui
@@ -53,7 +53,6 @@
</object>
<template class="PlayerToolbar" parent="GtkActionBar">
<property name="can_focus">False</property>
- <property name="no_show_all">True</property>
<child>
<object class="GtkBox" id="buttons">
<property name="visible">True</property>
@@ -121,7 +120,7 @@
<property name="spacing">8</property>
<signal name="query-tooltip" handler="_on_tooltip_query"/>
<child>
- <object class="CoverStack" id="_cover_stack">
+ <object class="ArtStack" id="_art_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
diff --git a/data/ui/PlaylistControls.ui b/data/ui/PlaylistControls.ui
index d0db94b0..0c52d1b8 100644
--- a/data/ui/PlaylistControls.ui
+++ b/data/ui/PlaylistControls.ui
@@ -68,7 +68,6 @@
<child>
<object class="GtkButton" id="_rename_done_button">
<property name="visible">True</property>
- <property name="no_show_all">True</property>
<property name="can_focus">True</property>
<property name="has_focus">True</property>
<property name="receives_default">True</property>
diff --git a/data/ui/PlaylistNotification.ui b/data/ui/PlaylistNotification.ui
new file mode 100644
index 00000000..b10ee723
--- /dev/null
+++ b/data/ui/PlaylistNotification.ui
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <object class="GtkImage" id="close_notification_window">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">window-close-symbolic</property>
+ <property name="icon_size">1</property>
+ </object>
+ <template class="PlaylistNotification" parent="GtkGrid">
+ <property name="visible">True</property>
+ <property name="column_spacing">18</property>
+ <child>
+ <object class="GtkLabel" id="_label">
+ <property name="visible">True</property>
+ <property name="halign">start</property>
+ <property name="hexpand">True</property>
+ <property name="label" translatable="yes"></property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="label" translatable="yes">_Undo</property>
+ <property name="use_underline">True</property>
+ <property name="visible">True</property>
+ <signal name="clicked" handler="_undo_deletion" swapped="no"/>
+ </object>
+ </child>
+ <child>
+ <object class="GtkButton">
+ <property name="always_show_image">True</property>
+ <property name="image">close_notification_window</property>
+ <property name="image_position">right</property>
+ <property name="relief">none</property>
+ <property name="visible">True</property>
+ <signal name="clicked" handler="_close_notification" swapped="no"/>
+ </object>
+ </child>
+ </template>
+</interface>
diff --git a/data/ui/PlaylistsView.ui b/data/ui/PlaylistsView.ui
index f1714731..4fffcc2d 100644
--- a/data/ui/PlaylistsView.ui
+++ b/data/ui/PlaylistsView.ui
@@ -1,29 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<requires lib="gtk+" version="3.18"/>
- <template class="PlaylistsView" parent="GtkStack">
+ <template class="PlaylistsView" parent="GtkBox">
<property name="visible">True</property>
<child>
- <object class="GtkBox" id="_main_container">
+ <object class="GtkScrolledWindow">
<property name="visible">True</property>
+ <property name="width-request">220</property>
+ <style>
+ <class name="sidebar"/>
+ </style>
<child>
- <object class="GtkScrolledWindow" id="all_playlists">
+ <object class="GtkListBox" id="_sidebar">
+ <property name="selection-mode">single</property>
<property name="visible">True</property>
- <property name="width-request">220</property>
- <style>
- <class name="sidebar"/>
- </style>
- <child>
- <object class="GtkListBox" id="_sidebar">
- <property name="selection-mode">single</property>
- <property name="visible">True</property>
- <signal name="row-activated" handler="_on_playlist_activated" swapped="no"/>
- </object>
- </child>
+ <signal name="row-activated" handler="_on_playlist_activated" swapped="no"/>
</object>
</child>
- <child>
- </child>
</object>
</child>
</template>
diff --git a/data/ui/PlaylistsWidget.ui b/data/ui/PlaylistsWidget.ui
index 02a0c801..fbc7882b 100644
--- a/data/ui/PlaylistsWidget.ui
+++ b/data/ui/PlaylistsWidget.ui
@@ -17,6 +17,7 @@
<property name="margin-left">80</property>
<property name="margin-right">80</property>
<property name="margin-top">20</property>
+ <property name="margin-bottom">20</property>
<property name="valign">start</property>
<property name="visible">True</property>
<style>
diff --git a/data/ui/SearchHeaderBar.ui b/data/ui/SearchHeaderBar.ui
index b894dbf2..48bd0795 100644
--- a/data/ui/SearchHeaderBar.ui
+++ b/data/ui/SearchHeaderBar.ui
@@ -33,7 +33,6 @@
<child>
<object class="GtkButton" id="_cancel_button">
<property name="visible">False</property>
- <property name="no_show_all">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">_Cancel</property>
<property name="use_underline">True</property>
diff --git a/data/ui/SearchView.ui b/data/ui/SearchView.ui
index e67e85a7..944fa420 100644
--- a/data/ui/SearchView.ui
+++ b/data/ui/SearchView.ui
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
- <requires lib="gtk+" version="3.18"/>
<object class="GtkImage" id="view_all_image_artist">
<property name="visible">True</property>
<property name="can_focus">False</property>
@@ -224,6 +223,6 @@
</object>
</child>
</object>
- </child>h
+ </child>
</template>
</interface>
diff --git a/data/ui/SongWidget.ui b/data/ui/SongWidget.ui
index 63cfc100..240a707e 100644
--- a/data/ui/SongWidget.ui
+++ b/data/ui/SongWidget.ui
@@ -20,7 +20,6 @@
<signal name="drag-begin" handler="_on_drag_begin"/>
<signal name="drag-end" handler="_on_drag_end"/>
<signal name="drag_data_get" handler="_on_drag_data_get"/>
- <property name="no_show_all">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
@@ -55,7 +54,6 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
- <property name="no_show_all">True</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="_on_select_button_toggled"/>
</object>
@@ -144,7 +142,6 @@
<object class="GtkLabel" id="_duration_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="no_show_all">True</property>
<property name="halign">end</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
diff --git a/data/ui/SongsView.ui b/data/ui/SongsView.ui
new file mode 100644
index 00000000..223df375
--- /dev/null
+++ b/data/ui/SongsView.ui
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+ <requires lib="gtk+" version="3.18"/>
+ <template class="SongsView" parent="GtkScrolledWindow">
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkTreeView" id="_songs_view">
+ <property name="activate-on-single-click">True</property>
+ <property name="headers_visible">False</property>
+ <property name="valign">start</property>
+ <property name="visible">True</property>
+ <signal name="row-activated" handler="_on_item_activated" swapped="no"/>
+ <style>
+ <class name="songs-list-old"/>
+ </style>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection">
+ <property name="mode">single</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="_now_playing_column">
+ <property name="fixed_width">48</property>
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkCellRendererPixbuf" id="_now_playing_cell">
+ <property name="xalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="yalign">0.5</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="_selection_column">
+ <property name="fixed_width">48</property>
+ <property name="visible">False</property>
+ <child>
+ <object class="GtkCellRendererToggle">
+ </object>
+ <attributes>
+ <attribute name="active">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="_title_column">
+ <property name="expand">True</property>
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkCellRendererText">
+ <property name="ellipsize">end</property>
+ <property name="height">48</property>
+ <property name="xalign">0</property>
+ <property name="xpad">0</property>
+ <property name="yalign">0.5</property>
+ </object>
+ <attributes>
+ <attribute name="text">2</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="_artist_column">
+ <property name="expand">True</property>
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkCellRendererText">
+ <property name="ellipsize">end</property>
+ <property name="xpad">32</property>
+ </object>
+ <attributes>
+ <attribute name="text">3</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="_album_column">
+ <property name="expand">True</property>
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkCellRendererText">
+ <property name="ellipsize">end</property>
+ <property name="xpad">32</property>
+ </object>
+ <attributes>
+ <attribute name="text">4</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="_duration_column">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkCellRendererText" id="_duration_renderer">
+ <property name="xalign">1</property>
+ </object>
+ <attributes>
+ <attribute name="text">5</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="_star_column">
+ <property name="visible">True</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+ <object class="GtkGestureMultiPress" id="_songs_ctrlr">
+ <property name="widget">_songs_view</property>
+ <property name="propagation-phase">capture</property>
+ <signal name="released" handler="_on_view_clicked" swapped="no"/>
+ </object>
+</interface>
diff --git a/data/ui/Window.ui b/data/ui/Window.ui
index 161b3059..19e7dc85 100644
--- a/data/ui/Window.ui
+++ b/data/ui/Window.ui
@@ -3,8 +3,14 @@
<template class="Window" parent="GtkApplicationWindow">
<property name="default-height">500</property>
<property name="default-width">300</property>
+ <child type="titlebar">
+ <object class="GtkStack" id="_headerbar_stack">
+ <property name="transition-type">crossfade</property>
+ <property name="visible">True</property>
+ </object>
+ </child>
<child>
- <object class="GtkBox" id="_box">
+ <object class="GtkBox">
<property name="orientation">vertical</property>
<property name="visible">True</property>
<child>
@@ -32,6 +38,9 @@
<child>
<object class="SelectionToolbar" id="_selection_toolbar"/>
</child>
+ <child>
+ <object class="PlayerToolbar" id="_player_toolbar"/>
+ </child>
</object>
</child>
</template>
diff --git a/gnome-music.in b/gnome-music.in
index 908df023..35ea2c4d 100755
--- a/gnome-music.in
+++ b/gnome-music.in
@@ -87,8 +87,16 @@ def set_exception_hook():
def set_internationalization():
"""Sets application internationalization."""
- locale.bindtextdomain('@application_id@', LOCALE_DIR)
- locale.textdomain('@application_id@')
+ try:
+ locale.bindtextdomain('@application_id@', LOCALE_DIR)
+ locale.textdomain('@application_id@')
+ except AttributeError as e:
+ # Python built without gettext support does not have
+ # bindtextdomain() and textdomain().
+ print(
+ "Could not bind the gettext translation domain. Some"
+ " translations will not work. Error:\n{}".format(e))
+
gettext.bindtextdomain('@application_id@', LOCALE_DIR)
gettext.textdomain('@application_id@')
diff --git a/gnomemusic/albumart.py b/gnomemusic/albumart.py
new file mode 100644
index 00000000..2d3f14eb
--- /dev/null
+++ b/gnomemusic/albumart.py
@@ -0,0 +1,72 @@
+# Copyright 2020 The GNOME Music developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music. This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered. If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so. If you do not wish to do so,
+# delete this exception statement from your version.
+
+import gi
+gi.require_version("MediaArt", "2.0")
+from gi.repository import GObject, MediaArt
+
+from gnomemusic.embeddedart import EmbeddedArt
+
+
+class AlbumArt(GObject.GObject):
+ """AlbumArt retrieval object
+ """
+
+ def __init__(self, application, corealbum):
+ """Initialize AlbumArt
+
+ :param Application application: The application object
+ :param CoreAlbum corealbum: The corealbum to use
+ """
+ super().__init__()
+
+ self._application = application
+ self._corealbum = corealbum
+ self._album = self._corealbum.props.title
+ self._artist = self._corealbum.props.artist
+
+ if self._in_cache():
+ return
+
+ embedded = EmbeddedArt()
+ embedded.connect("art-found", self._on_embedded_art_found)
+ embedded.query(corealbum, self._album)
+
+ def _on_embedded_art_found(self, embeddedart, found):
+ if found:
+ self._in_cache()
+ else:
+ self._application.props.coregrilo.get_album_art(self._corealbum)
+
+ def _in_cache(self):
+ success, thumb_file = MediaArt.get_file(
+ self._artist, self._album, "album")
+ if (not success
+ or not thumb_file.query_exists()):
+ self._corealbum.props.thumbnail = "loading"
+ return False
+
+ self._corealbum.props.thumbnail = thumb_file.get_uri()
+
+ return True
diff --git a/gnomemusic/albumartcache.py b/gnomemusic/albumartcache.py
deleted file mode 100644
index e737d038..00000000
--- a/gnomemusic/albumartcache.py
+++ /dev/null
@@ -1,678 +0,0 @@
-# Copyright © 2018 The GNOME Music developers
-#
-# GNOME Music is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# GNOME Music is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# The GNOME Music authors hereby grant permission for non-GPL compatible
-# GStreamer plugins to be used and distributed together with GStreamer
-# and GNOME Music. This permission is above and beyond the permissions
-# granted by the GPL license by which GNOME Music is covered. If you
-# modify this code, you may extend this exception to your version of the
-# code, but you are not obligated to do so. If you do not wish to do so,
-# delete this exception statement from your version.
-
-from enum import Enum
-from math import pi
-import os
-
-import cairo
-import gi
-gi.require_version('GstTag', '1.0')
-gi.require_version('MediaArt', '2.0')
-from gi.repository import (Gdk, GdkPixbuf, Gio, GLib, GObject, Gtk, MediaArt,
- Gst, GstTag, GstPbutils)
-
-from gnomemusic.musiclogger import MusicLogger
-
-
-def lookup_art_file_from_cache(coresong):
- """Lookup MediaArt cache art of an album or song.
-
- :param CoreSong coresong: song or album
- :returns: a cache file
- :rtype: Gio.File
- """
- try:
- album = coresong.props.album
- except AttributeError:
- album = coresong.props.title
- artist = coresong.props.artist
-
- success, thumb_file = MediaArt.get_file(artist, album, "album")
- if (not success
- or not thumb_file.query_exists()):
- return None
-
- return thumb_file
-
-
-def _make_icon_frame(icon_surface, art_size=None, scale=1, default_icon=False):
- border = 3
- degrees = pi / 180
- radius = 3
-
- icon_w = icon_surface.get_width()
- icon_h = icon_surface.get_height()
- ratio = icon_h / icon_w
-
- # Scale down the image according to the biggest axis
- if ratio > 1:
- w = int(art_size.width / ratio)
- h = art_size.height
- else:
- w = art_size.width
- h = int(art_size.height * ratio)
-
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w * scale, h * scale)
- surface.set_device_scale(scale, scale)
- ctx = cairo.Context(surface)
-
- # draw outline
- ctx.new_sub_path()
- ctx.arc(w - radius, radius, radius - 0.5, -90 * degrees, 0 * degrees)
- ctx.arc(w - radius, h - radius, radius - 0.5, 0 * degrees, 90 * degrees)
- ctx.arc(radius, h - radius, radius - 0.5, 90 * degrees, 180 * degrees)
- ctx.arc(radius, radius, radius - 0.5, 180 * degrees, 270 * degrees)
- ctx.close_path()
- ctx.set_line_width(0.6)
- ctx.set_source_rgba(0, 0, 0, 0.7)
- ctx.stroke_preserve()
-
- matrix = cairo.Matrix()
-
- if default_icon:
- ctx.set_source_rgb(1, 1, 1)
- ctx.fill()
- ctx.set_source_rgba(0, 0, 0, 0.3)
- ctx.mask_surface(icon_surface, w / 3, h / 3)
- ctx.fill()
- else:
- matrix.scale(
- icon_w / ((w - border * 2) * scale),
- icon_h / ((h - border * 2) * scale))
- matrix.translate(-border, -border)
- ctx.set_source_surface(icon_surface, 0, 0)
-
- pattern = ctx.get_source()
- pattern.set_matrix(matrix)
- ctx.fill()
-
- ctx.rectangle(border, border, w - border * 2, h - border * 2)
- ctx.clip()
-
- return surface
-
-
-class DefaultIcon(GObject.GObject):
- """Provides the symbolic fallback and loading icons."""
-
- class Type(Enum):
- LOADING = 'content-loading-symbolic'
- MUSIC = 'folder-music-symbolic'
-
- _cache = {}
- _default_theme = Gtk.IconTheme.get_default()
-
- def __init__(self):
- super().__init__()
-
- def _make_default_icon(self, icon_type, art_size, scale):
- icon_info = self._default_theme.lookup_icon_for_scale(
- icon_type.value, art_size.width / 3, scale, 0)
- icon = icon_info.load_surface()
-
- icon_surface = _make_icon_frame(icon, art_size, scale, True)
-
- return icon_surface
-
- def get(self, icon_type, art_size, scale=1):
- """Returns the requested symbolic icon
-
- Returns a cairo surface of the requested symbolic icon in the
- given size.
-
- :param enum icon_type: The DefaultIcon.Type of the icon
- :param enum art_size: The Art.Size requested
-
- :return: The symbolic icon
- :rtype: cairo.Surface
- """
- if (icon_type, art_size, scale) not in self._cache.keys():
- new_icon = self._make_default_icon(icon_type, art_size, scale)
- self._cache[(icon_type, art_size, scale)] = new_icon
-
- return self._cache[(icon_type, art_size, scale)]
-
-
-class Art(GObject.GObject):
- """Retrieves art for an album or song
-
- This is the control class for retrieving art.
- It looks for art in
- 1. The MediaArt cache
- 2. Embedded or in the directory
- 3. Remotely
- """
-
- __gsignals__ = {
- 'finished': (GObject.SignalFlags.RUN_FIRST, None, ())
- }
-
- _blacklist = {}
-
- class Size(Enum):
- """Enum for icon sizes"""
- XSMALL = (34, 34)
- SMALL = (48, 48)
- MEDIUM = (128, 128)
- LARGE = (256, 256)
- XLARGE = (512, 512)
-
- def __init__(self, width, height):
- """Intialize width and height"""
- self.width = width
- self.height = height
-
- def __init__(self, size, coresong, scale=1):
- super().__init__()
-
- self._size = size
- self._coresong = coresong
- # FIXME: Albums do not have a URL.
- try:
- self._url = self._coresong.props.url
- except AttributeError:
- self._url = None
- self._surface = None
- self._scale = scale
-
- def lookup(self):
- """Starts the art lookup sequence"""
- if self._in_blacklist():
- self._no_art_available()
- return
-
- cache = Cache()
- cache.connect('miss', self._cache_miss)
- cache.connect('hit', self._cache_hit)
- cache.query(self._coresong)
-
- def _cache_miss(self, klass):
- embedded_art = EmbeddedArt()
- embedded_art.connect('found', self._embedded_art_found)
- embedded_art.connect('unavailable', self._embedded_art_unavailable)
- embedded_art.query(self._coresong)
-
- def _cache_hit(self, klass, pixbuf):
- surface = Gdk.cairo_surface_create_from_pixbuf(
- pixbuf, self._scale, None)
- surface = _make_icon_frame(surface, self._size, self._scale)
- self._surface = surface
-
- self.emit('finished')
-
- def _embedded_art_found(self, klass):
- cache = Cache()
- # In case of an error in local art retrieval, there are two
- # options:
- # 1. Go and check for remote art instead
- # 2. Consider it a fail and add it to the blacklist
- # Go with option 1 here, because it gives the user the biggest
- # chance of getting artwork.
- cache.connect('miss', self._embedded_art_unavailable)
- cache.connect('hit', self._cache_hit)
- cache.query(self._coresong)
-
- def _embedded_art_unavailable(self, klass):
- remote_art = RemoteArt()
- remote_art.connect('retrieved', self._remote_art_retrieved)
- remote_art.connect('unavailable', self._remote_art_unavailable)
- remote_art.connect('no-remote-sources', self._remote_art_no_sources)
- remote_art.query(self._coresong)
-
- def _remote_art_retrieved(self, klass):
- cache = Cache()
- cache.connect('miss', self._remote_art_unavailable)
- cache.connect('hit', self._cache_hit)
- cache.query(self._coresong)
-
- def _remote_art_unavailable(self, klass):
- self._add_to_blacklist()
- self._no_art_available()
-
- def _remote_art_no_sources(self, klass):
- self._no_art_available()
-
- def _no_art_available(self):
- self._surface = DefaultIcon().get(
- DefaultIcon.Type.MUSIC, self._size, self._scale)
-
- self.emit('finished')
-
- def _add_to_blacklist(self):
- # FIXME: coresong can be a CoreAlbum
- try:
- album = self._coresong.props.album
- except AttributeError:
- album = self._coresong.props.title
- artist = self._coresong.props.artist
-
- if artist not in self._blacklist:
- self._blacklist[artist] = []
-
- album_stripped = MediaArt.strip_invalid_entities(album)
- self._blacklist[artist].append(album_stripped)
-
- def _in_blacklist(self):
- # FIXME: coresong can be a CoreAlbum
- try:
- album = self._coresong.props.album
- except AttributeError:
- album = self._coresong.props.title
- artist = self._coresong.props.artist
- album_stripped = MediaArt.strip_invalid_entities(album)
-
- if artist in self._blacklist:
- if album_stripped in self._blacklist[artist]:
- return True
-
- return False
-
- @GObject.Property
- def surface(self):
- if self._surface is None:
- self._surface = DefaultIcon().get(
- DefaultIcon.Type.LOADING, self._size, self._scale)
-
- return self._surface
-
-
-class Cache(GObject.GObject):
- """Handles retrieval of MediaArt cache art
-
- Uses signals to indicate success or failure.
- """
-
- __gsignals__ = {
- 'miss': (GObject.SignalFlags.RUN_FIRST, None, ()),
- 'hit': (GObject.SignalFlags.RUN_FIRST, None, (GObject.GObject, ))
- }
-
- def __init__(self):
- super().__init__()
-
- self._log = MusicLogger()
-
- # FIXME: async
- self.cache_dir = os.path.join(GLib.get_user_cache_dir(), 'media-art')
- if not os.path.exists(self.cache_dir):
- try:
- Gio.file_new_for_path(self.cache_dir).make_directory(None)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- return
-
- def query(self, coresong):
- """Start the cache query
-
- :param CoreSong coresong: The CoreSong object to search art for
- """
- thumb_file = lookup_art_file_from_cache(coresong)
- if thumb_file:
- thumb_file.read_async(
- GLib.PRIORITY_LOW, None, self._open_stream, None)
- return
-
- self.emit('miss')
-
- def _open_stream(self, thumb_file, result, arguments):
- try:
- stream = thumb_file.read_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self.emit('miss')
- return
-
- GdkPixbuf.Pixbuf.new_from_stream_async(
- stream, None, self._pixbuf_loaded, None)
-
- def _pixbuf_loaded(self, stream, result, data):
- try:
- pixbuf = GdkPixbuf.Pixbuf.new_from_stream_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self.emit('miss')
- return
-
- stream.close_async(GLib.PRIORITY_LOW, None, self._close_stream, None)
- self.emit('hit', pixbuf)
-
- def _close_stream(self, stream, result, data):
- try:
- stream.close_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
-
-
-class EmbeddedArt(GObject.GObject):
- """Lookup local art
-
- 1. Embedded through Gstreamer
- 2. Available in the directory through MediaArt
- """
-
- __gsignals__ = {
- 'found': (GObject.SignalFlags.RUN_FIRST, None, ()),
- 'unavailable': (GObject.SignalFlags.RUN_FIRST, None, ())
- }
-
- def __repr__(self):
- return '<EmbeddedArt>'
-
- def __init__(self):
- super().__init__()
-
- self._log = MusicLogger()
-
- try:
- Gst.init(None)
- GstPbutils.pb_utils_init()
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- return
-
- self._media_art = MediaArt.Process.new()
-
- self._album = None
- self._artist = None
- self._coresong = None
- self._path = None
-
- def query(self, coresong):
- """Start the local query
-
- :param CoreSong coresong: The CoreSong object to search art for
- """
- try:
- if coresong.props.url is None:
- self.emit('unavailable')
- return
- except AttributeError:
- self.emit('unavailable')
- return
-
- # FIXME: coresong can be a CoreAlbum
- try:
- self._album = coresong.props.album
- except AttributeError:
- self._album = coresong.props.title
- self._artist = coresong.props.artist
- self._coresong = coresong
-
- try:
- discoverer = GstPbutils.Discoverer.new(Gst.SECOND)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self._lookup_cover_in_directory()
- return
-
- discoverer.connect('discovered', self._discovered)
- discoverer.start()
-
- success, path = MediaArt.get_path(self._artist, self._album, "album")
-
- if not success:
- self.emit('unavailable')
- discoverer.stop()
- return
-
- self._path = path
-
- success = discoverer.discover_uri_async(self._coresong.props.url)
-
- if not success:
- self._log.warning("Could not add url to discoverer.")
- self.emit('unavailable')
- discoverer.stop()
- return
-
- def _discovered(self, discoverer, info, error):
- tags = info.get_tags()
- index = 0
-
- if (error is not None
- or tags is None):
- if error:
- self._log.warning("Discoverer error: {}, {}".format(
- Gst.CoreError(error.code), error.message))
- discoverer.stop()
- self.emit('unavailable')
- return
-
- while True:
- success, sample = tags.get_sample_index(Gst.TAG_IMAGE, index)
- if not success:
- break
- index += 1
- struct = sample.get_info()
- if struct is None:
- break
- success, image_type = struct.get_enum(
- 'image-type', GstTag.TagImageType)
- if not success:
- continue
- if image_type != GstTag.TagImageType.FRONT_COVER:
- continue
-
- buf = sample.get_buffer()
- success, map_info = buf.map(Gst.MapFlags.READ)
- if not success:
- continue
-
- try:
- mime = sample.get_caps().get_structure(0).get_name()
- MediaArt.buffer_to_jpeg(map_info.data, mime, self._path)
- self.emit('found')
- discoverer.stop()
- return
- except GLib.Error as error:
- self._log.warning("Error: {}, {}".format(
- MediaArt.Error(error.code), error.message))
-
- discoverer.stop()
-
- self._lookup_cover_in_directory()
-
- def _lookup_cover_in_directory(self):
- # Find local art in cover.jpeg files.
- self._media_art.uri_async(
- MediaArt.Type.ALBUM, MediaArt.ProcessFlags.NONE,
- self._coresong.props.url, self._artist, self._album,
- GLib.PRIORITY_LOW, None, self._uri_async_cb, None)
-
- def _uri_async_cb(self, src, result, data):
- try:
- success = self._media_art.uri_finish(result)
- if success:
- self.emit('found')
- return
- except GLib.Error as error:
- if MediaArt.Error(error.code) == MediaArt.Error.SYMLINK_FAILED:
- # This error indicates that the coverart has already
- # been linked by another concurrent lookup.
- self.emit('found')
- return
- else:
- self._log.warning("Error: {}, {}".format(
- MediaArt.Error(error.code), error.message))
-
- self.emit('unavailable')
-
-
-class RemoteArt(GObject.GObject):
- """Looks for remote art through Grilo
-
- Uses Grilo coverart providers to retrieve art.
- """
-
- __gsignals__ = {
- 'retrieved': (GObject.SignalFlags.RUN_FIRST, None, ()),
- 'unavailable': (GObject.SignalFlags.RUN_FIRST, None, ()),
- 'no-remote-sources': (GObject.SignalFlags.RUN_FIRST, None, ())
- }
-
- def __init__(self):
- super().__init__()
-
- self._log = MusicLogger()
-
- self._artist = None
- self._album = None
- self._coresong = None
- self._grilo = None
-
- def query(self, coresong):
- """Start the remote query
-
- :param CoreSong coresong: The CoreSong object to search art for
- """
- # FIXME: coresong can be a CoreAlbum
- try:
- self._album = coresong.props.album
- except AttributeError:
- self._album = coresong.props.title
- self._artist = coresong.props.artist
- self._coresong = coresong
-
- self.emit('no-remote-sources')
-
- # FIXME: This is a total hack. It gets CoreModel from the
- # CoreAlbum or CoreSong about and then retrieves the CoreGrilo
- # instance.
- try:
- self._grilo = self._coresong._coremodel.props.grilo
- except AttributeError:
- self._grilo = self._coresong._grilo
-
- if not self._grilo.props.cover_sources:
- self.emit('no-remote-sources')
- self._grilo.connect(
- 'notify::cover-sources', self._on_grilo_cover_sources_changed)
- else:
- # FIXME: It seems this Grilo query does not always return,
- # especially on queries with little info.
- self._grilo.get_album_art_for_item(
- self._coresong, self._remote_album_art)
-
- def _on_grilo_cover_sources_changed(self, klass, data):
- if self._grilo.props.cover_sources:
- self._grilo.get_album_art_for_item(
- self._coresong, self._remote_album_art)
-
- def _delete_callback(self, src, result, data):
- try:
- src.delete_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
-
- def _splice_callback(self, src, result, data):
- tmp_file, iostream = data
-
- iostream.close_async(
- GLib.PRIORITY_LOW, None, self._close_iostream_callback, None)
-
- try:
- src.splice_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self.emit('unavailable')
- return
-
- success, cache_path = MediaArt.get_path(
- self._artist, self._album, "album")
-
- if not success:
- self.emit('unavailable')
- return
-
- try:
- # FIXME: I/O blocking
- MediaArt.file_to_jpeg(tmp_file.get_path(), cache_path)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self.emit('unavailable')
- return
-
- self.emit('retrieved')
-
- tmp_file.delete_async(
- GLib.PRIORITY_LOW, None, self._delete_callback, None)
-
- def _close_iostream_callback(self, src, result, data):
- try:
- src.close_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
-
- def _read_callback(self, src, result, data):
- try:
- istream = src.read_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self.emit('unavailable')
- return
-
- try:
- [tmp_file, iostream] = Gio.File.new_tmp()
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self.emit('unavailable')
- return
-
- ostream = iostream.get_output_stream()
- # FIXME: Passing the iostream here, otherwise it gets
- # closed. PyGI specific issue?
- ostream.splice_async(
- istream, Gio.OutputStreamSpliceFlags.CLOSE_SOURCE
- | Gio.OutputStreamSpliceFlags.CLOSE_TARGET, GLib.PRIORITY_LOW,
- None, self._splice_callback, [tmp_file, iostream])
-
- def _remote_album_art(self, source, param, item, count, error):
- if error:
- self._log.warning("Grilo error {}".format(error))
- self.emit('unavailable')
- return
-
- thumb_uri = item.get_thumbnail()
-
- if (thumb_uri is None
- or thumb_uri == ""):
- self.emit('unavailable')
- return
-
- src = Gio.File.new_for_uri(thumb_uri)
- src.read_async(
- GLib.PRIORITY_LOW, None, self._read_callback, None)
diff --git a/gnomemusic/application.py b/gnomemusic/application.py
index 1ec542f6..c92a6aa1 100644
--- a/gnomemusic/application.py
+++ b/gnomemusic/application.py
@@ -34,14 +34,17 @@ from gettext import gettext as _
from gi.repository import Gtk, Gio, GLib, Gdk, GObject
+from gnomemusic.coregrilo import CoreGrilo
from gnomemusic.coremodel import CoreModel
from gnomemusic.coreselection import CoreSelection
from gnomemusic.inhibitsuspend import InhibitSuspend
from gnomemusic.mpris import MPRIS
from gnomemusic.musiclogger import MusicLogger
+from gnomemusic.notificationmanager import NotificationManager
from gnomemusic.pauseonsuspend import PauseOnSuspend
from gnomemusic.player import Player
from gnomemusic.scrobbler import LastFmScrobbler
+from gnomemusic.search import Search
from gnomemusic.widgets.aboutdialog import AboutDialog
from gnomemusic.widgets.lastfmdialog import LastfmDialog
from gnomemusic.window import Window
@@ -62,8 +65,14 @@ class Application(Gtk.Application):
self._window = None
self._log = MusicLogger()
+ self._search = Search()
+
+ self._notificationmanager = NotificationManager(self)
self._coreselection = CoreSelection()
self._coremodel = CoreModel(self)
+ # Order is important: CoreGrilo initializes the Grilo sources,
+ # which in turn use CoreModel & CoreSelection extensively.
+ self._coregrilo = CoreGrilo(self)
self._settings = Gio.Settings.new('org.gnome.Music')
self._lastfm_scrobbler = LastFmScrobbler(self)
@@ -81,6 +90,16 @@ class Application(Gtk.Application):
screen, css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
@GObject.Property(
+ type=CoreGrilo, default=None, flags=GObject.ParamFlags.READABLE)
+ def coregrilo(self):
+ """Get application-wide CoreGrilo instance.
+
+ :returns: The grilo wrapper
+ :rtype: CoreGrilo
+ """
+ return self._coregrilo
+
+ @GObject.Property(
type=MusicLogger, default=None, flags=GObject.ParamFlags.READABLE)
def log(self):
"""Get application-wide logging facility.
@@ -148,6 +167,26 @@ class Application(Gtk.Application):
"""
return self._window
+ @GObject.Property(
+ type=Search, flags=GObject.ParamFlags.READABLE)
+ def search(self):
+ """Get class providing search logic.
+
+ :returns: List model provider class
+ :rtype: Search
+ """
+ return self._search
+
+ @GObject.Property(
+ type=NotificationManager, flags=GObject.ParamFlags.READABLE)
+ def notificationmanager(self):
+ """Get notification manager
+
+ :returns: notification manager
+ :rtype: NotificationManager
+ """
+ return self._notificationmanager
+
def _set_actions(self):
action_entries = [
('about', self._about, None),
@@ -189,6 +228,7 @@ class Application(Gtk.Application):
def do_activate(self):
if not self._window:
self._window = Window(self)
+ self.notify("window")
self._window.set_default_icon_name(self.props.application_id)
if self.props.application_id == "org.gnome.Music.Devel":
self._window.get_style_context().add_class('devel')
diff --git a/gnomemusic/artcache.py b/gnomemusic/artcache.py
new file mode 100644
index 00000000..67cfebc3
--- /dev/null
+++ b/gnomemusic/artcache.py
@@ -0,0 +1,267 @@
+# Copyright 2020 The GNOME Music developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music. This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered. If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so. If you do not wish to do so,
+# delete this exception statement from your version.
+from enum import Enum
+from math import pi
+
+import cairo
+from gi.repository import Gdk, GdkPixbuf, Gio, Gtk, GLib, GObject
+
+from gnomemusic.corealbum import CoreAlbum
+from gnomemusic.coreartist import CoreArtist
+from gnomemusic.coresong import CoreSong
+from gnomemusic.musiclogger import MusicLogger
+
+
+def _make_icon_frame(
+ icon_surface, art_size=None, scale=1, default_icon=False,
+ round_shape=False):
+ """Create an Art frame, square or round.
+
+ :param cairo.Surface icon_surface: The surface to use
+ :param art_size: The size of the art
+ :param int scale: The scale of the art
+ :param bool default_icon: Indicates of this is a default icon
+ :param bool round_shape: Square or round indicator
+
+ :return: The framed surface
+ :rtype: cairo.Surface
+ """
+ border = 3
+ degrees = pi / 180
+ radius = 3
+ icon_w = icon_surface.get_width()
+ icon_h = icon_surface.get_height()
+ ratio = icon_h / icon_w
+
+ # Scale down the image according to the biggest axis
+ if ratio > 1:
+ w = int(art_size.width / ratio)
+ h = art_size.height
+ else:
+ w = art_size.width
+ h = int(art_size.height * ratio)
+
+ surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w * scale, h * scale)
+ surface.set_device_scale(scale, scale)
+ ctx = cairo.Context(surface)
+ matrix = cairo.Matrix()
+
+ if round_shape:
+ line_width = 0.6
+ ctx.new_sub_path()
+ ctx.arc(w / 2, h / 2, (w / 2) - line_width, 0, 2 * pi)
+ ctx.set_source_rgba(0, 0, 0, 0.7)
+ ctx.set_line_width(line_width)
+ ctx.stroke_preserve()
+ else:
+ # draw outline
+ ctx.new_sub_path()
+ ctx.arc(w - radius, radius, radius - 0.5, -90 * degrees, 0 * degrees)
+ ctx.arc(
+ w - radius, h - radius, radius - 0.5, 0 * degrees, 90 * degrees)
+ ctx.arc(radius, h - radius, radius - 0.5, 90 * degrees, 180 * degrees)
+ ctx.arc(radius, radius, radius - 0.5, 180 * degrees, 270 * degrees)
+ ctx.close_path()
+ ctx.set_line_width(0.6)
+ ctx.set_source_rgba(0, 0, 0, 0.7)
+ ctx.stroke_preserve()
+
+ if default_icon:
+ ctx.set_source_rgb(1, 1, 1)
+ ctx.fill()
+ ctx.set_source_rgba(0, 0, 0, 0.3)
+ ctx.mask_surface(icon_surface, w / 3, h / 3)
+ ctx.fill()
+ else:
+ if round_shape:
+ matrix.scale(icon_w / (w * scale), icon_h / (h * scale))
+ else:
+ matrix.scale(
+ icon_w / ((w - border * 2) * scale),
+ icon_h / ((h - border * 2) * scale))
+ matrix.translate(-border, -border)
+
+ ctx.set_source_surface(icon_surface, 0, 0)
+
+ pattern = ctx.get_source()
+ pattern.set_matrix(matrix)
+ ctx.fill()
+
+ if round_shape:
+ ctx.arc(w / 2, h / 2, w / 2, 0, 2 * pi)
+ else:
+ ctx.rectangle(border, border, w - border * 2, h - border * 2)
+
+ ctx.clip()
+
+ return surface
+
+
+class DefaultIcon(GObject.GObject):
+ """Provides the symbolic fallback and loading icons."""
+
+ class Type(Enum):
+ ARTIST = "avatar-default-symbolic"
+ ARTIST_LOADING = "content-loading-symbolic"
+ LOADING = "content-loading-symbolic"
+ MUSIC = "folder-music-symbolic"
+
+ _cache = {}
+ _default_theme = Gtk.IconTheme.get_default()
+
+ def __init__(self):
+ super().__init__()
+
+ def _make_default_icon(self, icon_type, art_size, scale, round_shape):
+ icon_info = self._default_theme.lookup_icon_for_scale(
+ icon_type.value, art_size.width / 3, scale, 0)
+ icon = icon_info.load_surface()
+
+ icon_surface = _make_icon_frame(
+ icon, art_size, scale, True, round_shape=round_shape)
+
+ return icon_surface
+
+ def get(self, icon_type, art_size, scale=1, round_shape=False):
+ """Returns the requested symbolic icon
+
+ Returns a cairo surface of the requested symbolic icon in the
+ given size and shape.
+
+ :param enum icon_type: The DefaultIcon.Type of the icon
+ :param enum art_size: The ArtSize requested
+ :param int scale: The scale
+ :param bool round_shape: Indicates square or round icon shape
+
+ :return: The symbolic icon
+ :rtype: cairo.Surface
+ """
+ if (icon_type, art_size, scale) not in self._cache.keys():
+ new_icon = self._make_default_icon(
+ icon_type, art_size, scale, round_shape)
+ self._cache[(icon_type, art_size, scale, round_shape)] = new_icon
+
+ return self._cache[(icon_type, art_size, scale, round_shape)]
+
+
+class ArtCache(GObject.GObject):
+ """Handles retrieval of MediaArt cache art
+
+ Uses signals to indicate success or failure and always returns a
+ Cairo.Surface.
+ """
+
+ __gtype_name__ = "ArtCache"
+
+ __gsignals__ = {
+ "result": (GObject.SignalFlags.RUN_FIRST, None, (object, ))
+ }
+
+ _log = MusicLogger()
+
+ def __init__(self, size, scale):
+ super().__init__()
+
+ self._size = size
+ self._scale = scale
+
+ self._coreobject = None
+ self._default_icon = None
+ self._loading_icon = None
+
+ def query(self, coreobject):
+ """Start the cache query
+
+ :param coreobject: The object to search art for
+ """
+ self._coreobject = coreobject
+
+ if isinstance(coreobject, CoreArtist):
+ self._loading_icon = DefaultIcon().get(
+ DefaultIcon.Type.ARTIST_LOADING, self._size, self._scale, True)
+ self._default_icon = DefaultIcon().get(
+ DefaultIcon.Type.ARTIST, self._size, self._scale, True)
+ elif (isinstance(coreobject, CoreAlbum)
+ or isinstance(coreobject, CoreSong)):
+ self._loading_icon = DefaultIcon().get(
+ DefaultIcon.Type.LOADING, self._size, self._scale)
+ self._default_icon = DefaultIcon().get(
+ DefaultIcon.Type.MUSIC, self._size, self._scale)
+
+ thumbnail_uri = coreobject.props.thumbnail
+ if thumbnail_uri == "loading":
+ self.emit("result", self._loading_icon)
+ return
+ elif thumbnail_uri == "generic":
+ self.emit("result", self._default_icon)
+ return
+
+ thumb_file = Gio.File.new_for_uri(thumbnail_uri)
+ if thumb_file:
+ thumb_file.read_async(
+ GLib.PRIORITY_LOW, None, self._open_stream, None)
+ return
+
+ self.emit("result", self._default_icon)
+
+ def _open_stream(self, thumb_file, result, arguments):
+ try:
+ stream = thumb_file.read_finish(result)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ self.emit("result", self._default_icon)
+ return
+
+ GdkPixbuf.Pixbuf.new_from_stream_async(
+ stream, None, self._pixbuf_loaded, None)
+
+ def _pixbuf_loaded(self, stream, result, data):
+ try:
+ pixbuf = GdkPixbuf.Pixbuf.new_from_stream_finish(result)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ self.emit("result", self._default_icon)
+ return
+
+ stream.close_async(GLib.PRIORITY_LOW, None, self._close_stream, None)
+
+ surface = Gdk.cairo_surface_create_from_pixbuf(
+ pixbuf, self._scale, None)
+ if isinstance(self._coreobject, CoreArtist):
+ surface = _make_icon_frame(
+ surface, self._size, self._scale, round_shape=True)
+ elif (isinstance(self._coreobject, CoreAlbum)
+ or isinstance(self._coreobject, CoreSong)):
+ surface = _make_icon_frame(surface, self._size, self._scale)
+
+ self.emit("result", surface)
+
+ def _close_stream(self, stream, result, data):
+ try:
+ stream.close_finish(result)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
diff --git a/gnomemusic/artistart.py b/gnomemusic/artistart.py
index c810198b..9cb0e3c6 100644
--- a/gnomemusic/artistart.py
+++ b/gnomemusic/artistart.py
@@ -22,113 +22,20 @@
# code, but you are not obligated to do so. If you do not wish to do so,
# delete this exception statement from your version.
-from enum import Enum
-from math import pi
-
-import cairo
import gi
gi.require_version("MediaArt", "2.0")
-from gi.repository import Gdk, GdkPixbuf, Gio, GLib, GObject, Gtk, MediaArt
-
-from gnomemusic.musiclogger import MusicLogger
-
-
-def _make_icon_frame(icon_surface, art_size=None, scale=1, default_icon=False):
- icon_w = icon_surface.get_width()
- icon_h = icon_surface.get_height()
- ratio = icon_h / icon_w
-
- # Scale down the image according to the biggest axis
- if ratio > 1:
- w = int(art_size.width / ratio)
- h = art_size.height
- else:
- w = art_size.width
- h = int(art_size.height * ratio)
-
- surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, w * scale, h * scale)
- surface.set_device_scale(scale, scale)
- ctx = cairo.Context(surface)
-
- matrix = cairo.Matrix()
-
- line_width = 0.6
- ctx.new_sub_path()
- ctx.arc(w / 2, h / 2, (w / 2) - line_width, 0, 2 * pi)
- ctx.set_source_rgba(0, 0, 0, 0.7)
- ctx.set_line_width(line_width)
- ctx.stroke_preserve()
-
- if default_icon:
- ctx.set_source_rgb(1, 1, 1)
- ctx.fill()
- ctx.set_source_rgba(0, 0, 0, 0.3)
- ctx.mask_surface(icon_surface, w / 3, h / 3)
- ctx.fill()
- else:
- matrix.scale(icon_w / (w * scale), icon_h / (h * scale))
- ctx.set_source_surface(icon_surface, 0, 0)
-
- pattern = ctx.get_source()
- pattern.set_matrix(matrix)
- ctx.fill()
-
- ctx.arc(w / 2, h / 2, w / 2, 0, 2 * pi)
- ctx.clip()
-
- return surface
-
-
-class DefaultIcon(GObject.GObject):
- """Provides the symbolic fallback and loading icons."""
-
- class Type(Enum):
- LOADING = "content-loading-symbolic"
- ARTIST = "avatar-default-symbolic"
-
- _cache = {}
- _default_theme = Gtk.IconTheme.get_default()
-
- def __init__(self):
- super().__init__()
-
- def _make_default_icon(self, icon_type, art_size, scale):
- icon_info = self._default_theme.lookup_icon_for_scale(
- icon_type.value, art_size.width / 3, scale, 0)
- icon = icon_info.load_surface()
-
- icon_surface = _make_icon_frame(icon, art_size, scale, True)
-
- return icon_surface
-
- def get(self, icon_type, art_size, scale=1):
- """Returns the requested symbolic icon
-
- Returns a cairo surface of the requested symbolic icon in the
- given size.
-
- :param enum icon_type: The DefaultIcon.Type of the icon
- :param enum art_size: The Art.Size requested
-
- :return: The symbolic icon
- :rtype: cairo.Surface
- """
- if (icon_type, art_size, scale) not in self._cache.keys():
- new_icon = self._make_default_icon(icon_type, art_size, scale)
- self._cache[(icon_type, art_size, scale)] = new_icon
-
- return self._cache[(icon_type, art_size, scale)]
+from gi.repository import GObject, MediaArt
class ArtistArt(GObject.GObject):
+ """Artist art retrieval object
+ """
- _log = MusicLogger()
-
- def __init__(self, coreartist, coremodel):
- """Initialize the ArtistArt.
+ def __init__(self, application, coreartist):
+ """Initialize.
+ :param Application application: The application object
:param CoreArtist coreartist: The coreartist to use
- :param CoreModel coremodel: The main coremodel
"""
super().__init__()
@@ -138,204 +45,16 @@ class ArtistArt(GObject.GObject):
if self._in_cache():
return
- grilo = coremodel.props.grilo
-
- self._coreartist.connect(
- "notify::thumbnail", self._on_thumbnail_changed)
-
- grilo.get_artist_art(self._coreartist)
+ application.props.coregrilo.get_artist_art(self._coreartist)
def _in_cache(self):
success, thumb_file = MediaArt.get_file(
self._artist, None, "artist")
if (not success
or not thumb_file.query_exists()):
+ self._coreartist.props.thumbnail = "loading"
return False
- self._coreartist.props.cached_thumbnail_uri = thumb_file.get_path()
+ self._coreartist.props.thumbnail = thumb_file.get_uri()
return True
-
- def _on_thumbnail_changed(self, coreartist, thumbnail):
- uri = coreartist.props.thumbnail
-
- if (uri is None
- or uri == ""):
- self._coreartist.props.cached_thumbnail_uri = ""
- return
-
- src = Gio.File.new_for_uri(uri)
- src.read_async(
- GLib.PRIORITY_LOW, None, self._read_callback, None)
-
- def _read_callback(self, src, result, data):
- try:
- istream = src.read_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self._coreartist.props.cached_thumbnail_uri = ""
- return
-
- try:
- [tmp_file, iostream] = Gio.File.new_tmp()
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self._coreartist.props.cached_thumbnail_uri = ""
- return
-
- ostream = iostream.get_output_stream()
- # FIXME: Passing the iostream here, otherwise it gets
- # closed. PyGI specific issue?
- ostream.splice_async(
- istream, Gio.OutputStreamSpliceFlags.CLOSE_SOURCE
- | Gio.OutputStreamSpliceFlags.CLOSE_TARGET, GLib.PRIORITY_LOW,
- None, self._splice_callback, [tmp_file, iostream])
-
- def _delete_callback(self, src, result, data):
- try:
- src.delete_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
-
- def _splice_callback(self, src, result, data):
- tmp_file, iostream = data
-
- iostream.close_async(
- GLib.PRIORITY_LOW, None, self._close_iostream_callback, None)
-
- try:
- src.splice_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self._coreartist.props.cached_thumbnail_uri = ""
- return
-
- success, cache_path = MediaArt.get_path(self._artist, None, "artist")
-
- if not success:
- self._coreartist.props.cached_thumbnail_uri = ""
- return
-
- try:
- # FIXME: I/O blocking
- MediaArt.file_to_jpeg(tmp_file.get_path(), cache_path)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self._coreartist.props.cached_thumbnail_uri = ""
- return
-
- self._in_cache()
-
- tmp_file.delete_async(
- GLib.PRIORITY_LOW, None, self._delete_callback, None)
-
- def _close_iostream_callback(self, src, result, data):
- try:
- src.close_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
-
-
-class ArtistCache(GObject.GObject):
- """Handles retrieval of MediaArt cache art
-
- Uses signals to indicate success or failure.
- """
-
- __gtype_name__ = "ArtistCache"
-
- __gsignals__ = {
- "result": (GObject.SignalFlags.RUN_FIRST, None, (object, ))
- }
-
- _log = MusicLogger()
-
- def __init__(self, size, scale):
- super().__init__()
-
- self._size = size
- self._scale = scale
-
- self._default_icon = DefaultIcon().get(
- DefaultIcon.Type.ARTIST, self._size, self._scale)
-
- cache_dir = GLib.build_filenamev(
- [GLib.get_user_cache_dir(), "media-art"])
- cache_dir_file = Gio.File.new_for_path(cache_dir)
- cache_dir_file.query_info_async(
- Gio.FILE_ATTRIBUTE_ACCESS_CAN_READ, Gio.FileQueryInfoFlags.NONE,
- GLib.PRIORITY_LOW, None, self._cache_dir_info_read, None)
-
- def _cache_dir_info_read(self, cache_dir_file, res, data):
- try:
- cache_dir_file.query_info_finish(res)
- return
- except GLib.Error:
- # directory does not exist yet
- try:
- cache_dir_file.make_directory(None)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
-
- def query(self, coreartist):
- """Start the cache query
-
- :param CoreSong coresong: The CoreSong object to search art for
- """
- thumbnail_uri = coreartist.props.cached_thumbnail_uri
- if thumbnail_uri == "":
- self.emit("result", self._default_icon)
- return
- elif thumbnail_uri is None:
- return
-
- thumb_file = Gio.File.new_for_path(thumbnail_uri)
- if thumb_file:
- thumb_file.read_async(
- GLib.PRIORITY_LOW, None, self._open_stream, None)
- return
-
- self.emit("result", self._default_icon)
-
- def _open_stream(self, thumb_file, result, arguments):
- try:
- stream = thumb_file.read_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self.emit("result", self._default_icon)
- return
-
- GdkPixbuf.Pixbuf.new_from_stream_async(
- stream, None, self._pixbuf_loaded, None)
-
- def _pixbuf_loaded(self, stream, result, data):
- try:
- pixbuf = GdkPixbuf.Pixbuf.new_from_stream_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self.emit("result", self._default_icon)
- return
-
- stream.close_async(GLib.PRIORITY_LOW, None, self._close_stream, None)
-
- surface = Gdk.cairo_surface_create_from_pixbuf(
- pixbuf, self._scale, None)
- surface = _make_icon_frame(surface, self._size, self._scale)
-
- self.emit("result", surface)
-
- def _close_stream(self, stream, result, data):
- try:
- stream.close_finish(result)
- except GLib.Error as error:
- self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
diff --git a/gnomemusic/corealbum.py b/gnomemusic/corealbum.py
index 9084cd82..3be2f5bf 100644
--- a/gnomemusic/corealbum.py
+++ b/gnomemusic/corealbum.py
@@ -23,11 +23,13 @@
# delete this exception statement from your version.
import gi
-gi.require_version("Grl", "0.3")
-from gi.repository import Gio, Grl, GObject
+gi.require_versions({"Gfm": "0.1", "Grl": "0.3"})
+from gi.repository import Gfm, Gio, Grl, GObject
import gnomemusic.utils as utils
+from gnomemusic.albumart import AlbumArt
+
class CoreAlbum(GObject.GObject):
"""Exposes a Grl.Media with relevant data as properties
@@ -41,17 +43,20 @@ class CoreAlbum(GObject.GObject):
url = GObject.Property(type=str)
year = GObject.Property(type=str, default="----")
- def __init__(self, media, coremodel):
+ def __init__(self, application, media):
"""Initiate the CoreAlbum object
+ :param Application application: The application object
:param Grl.Media media: A media object
- :param CoreModel coremodel: The CoreModel to use models from
"""
super().__init__()
- self._coremodel = coremodel
+ self._application = application
+ self._coregrilo = application.props.coregrilo
self._model = None
self._selected = False
+ self._thumbnail = None
+
self.update(media)
def update(self, media):
@@ -66,12 +71,27 @@ class CoreAlbum(GObject.GObject):
self.props.url = media.get_url()
self.props.year = utils.get_media_year(media)
+ def _get_album_model(self):
+ disc_model = Gio.ListStore()
+ disc_model_sort = Gfm.SortListModel.new(disc_model)
+
+ def _disc_order_sort(disc_a, disc_b):
+ return disc_a.props.disc_nr - disc_b.props.disc_nr
+
+ disc_model_sort.set_sort_func(
+ utils.wrap_list_store_sort_func(_disc_order_sort))
+
+ self._coregrilo.get_album_discs(self.props.media, disc_model)
+
+ return disc_model_sort
+
@GObject.Property(
type=Gio.ListModel, default=None, flags=GObject.ParamFlags.READABLE)
def model(self):
if self._model is None:
- self._model = self._coremodel.get_album_model(self.props.media)
+ self._model = self._get_album_model()
self._model.connect("items-changed", self._on_list_items_changed)
+ self._model.items_changed(0, 0, self._model.get_n_items())
return self._model
@@ -111,3 +131,24 @@ class CoreAlbum(GObject.GObject):
# is requested, it will trigger the filled model update as
# well.
self.props.model.items_changed(0, 0, 0)
+
+ @GObject.Property(type=str, default=None)
+ def thumbnail(self):
+ """Album art thumbnail retrieval
+
+ :return: The album art uri or "generic" or "loading"
+ :rtype: string
+ """
+ if self._thumbnail is None:
+ self._thumbnail = "loading"
+ AlbumArt(self._application, self)
+
+ return self._thumbnail
+
+ @thumbnail.setter
+ def thumbnail(self, value):
+ """Album art thumbnail setter
+
+ :param string value: uri, "generic" or "loading"
+ """
+ self._thumbnail = value
diff --git a/gnomemusic/coreartist.py b/gnomemusic/coreartist.py
index 96b8a15f..036f4c17 100644
--- a/gnomemusic/coreartist.py
+++ b/gnomemusic/coreartist.py
@@ -23,8 +23,8 @@
# delete this exception statement from your version.
import gi
-gi.require_version('Grl', '0.3')
-from gi.repository import Gio, Grl, GObject
+gi.require_versions({"Gfm": "0.1", "Grl": "0.3"})
+from gi.repository import Gfm, Gio, Grl, GObject
from gnomemusic.artistart import ArtistArt
import gnomemusic.utils as utils
@@ -37,11 +37,17 @@ class CoreArtist(GObject.GObject):
artist = GObject.Property(type=str)
media = GObject.Property(type=Grl.Media)
- def __init__(self, media, coremodel):
+ def __init__(self, application, media):
+ """Initiate the CoreArtist object
+
+ :param Application application: The application object
+ :param Grl.Media media: A media object
+ """
super().__init__()
- self._cached_thumbnail_uri = None
- self._coremodel = coremodel
+ self._application = application
+ self._coregrilo = application.props.coregrilo
+ self._coremodel = application.props.coremodel
self._model = None
self._selected = False
self._thumbnail = None
@@ -52,11 +58,28 @@ class CoreArtist(GObject.GObject):
self.props.media = media
self.props.artist = utils.get_artist_name(media)
+ def _get_artist_album_model(self):
+ albums_model_filter = Gfm.FilterListModel.new(
+ self._coremodel.props.albums)
+ albums_model_filter.set_filter_func(lambda a: False)
+
+ albums_model_sort = Gfm.SortListModel.new(albums_model_filter)
+
+ self._coregrilo.get_artist_albums(
+ self.props.media, albums_model_filter)
+
+ def _album_sort(album_a, album_b):
+ return album_a.props.year > album_b.props.year
+
+ albums_model_sort.set_sort_func(
+ utils.wrap_list_store_sort_func(_album_sort))
+
+ return albums_model_sort
+
@GObject.Property(type=Gio.ListModel, default=None)
def model(self):
if self._model is None:
- self._model = self._coremodel.get_artist_album_model(
- self.props.media)
+ self._model = self._get_artist_album_model()
self._model.connect("items-changed", self._on_items_changed)
return self._model
@@ -86,20 +109,21 @@ class CoreArtist(GObject.GObject):
@GObject.Property(type=str, default=None)
def thumbnail(self):
+ """Artist art thumbnail retrieval
+
+ :return: The artist art uri or "generic" or "loading"
+ :rtype: string
+ """
if self._thumbnail is None:
- self._thumbnail = ""
- ArtistArt(self, self._coremodel)
+ self._thumbnail = "loading"
+ ArtistArt(self._application, self)
return self._thumbnail
@thumbnail.setter
def thumbnail(self, value):
- self._thumbnail = value
+ """Artist art thumbnail setter
- @GObject.Property(type=str, default=None)
- def cached_thumbnail_uri(self):
- return self._cached_thumbnail_uri
-
- @cached_thumbnail_uri.setter
- def cached_thumbnail_uri(self, value):
- self._cached_thumbnail_uri = value
+ :param string value: uri, "generic" or "loading"
+ """
+ self._thumbnail = value
diff --git a/gnomemusic/coredisc.py b/gnomemusic/coredisc.py
index a7def610..4307f0ed 100644
--- a/gnomemusic/coredisc.py
+++ b/gnomemusic/coredisc.py
@@ -23,7 +23,8 @@
# delete this exception statement from your version.
from gi.repository import GObject, Gio, Gfm, Grl
-from gi._gi import pygobject_new_full
+
+import gnomemusic.utils as utils
class CoreDisc(GObject.GObject):
@@ -32,11 +33,19 @@ class CoreDisc(GObject.GObject):
duration = GObject.Property(type=int, default=None)
media = GObject.Property(type=Grl.Media, default=None)
- def __init__(self, media, nr, coremodel):
+ def __init__(self, application, media, nr):
+ """Initialize a CoreDisc object
+
+ :param Application application: The application object
+ :param Grl.Media media: A media object
+ :param int nr: The disc number to create an object for
+ """
super().__init__()
- self._coremodel = coremodel
+ self._coregrilo = application.props.coregrilo
+ self._coremodel = application.props.coremodel
self._filter_model = None
+ self._log = application.props.log
self._model = None
self._old_album_ids = []
self._selected = False
@@ -49,13 +58,16 @@ class CoreDisc(GObject.GObject):
@GObject.Property(type=Gio.ListModel, default=None)
def model(self):
+ def _disc_sort(song_a, song_b):
+ return song_a.props.track_number - song_b.props.track_number
+
if self._model is None:
self._filter_model = Gfm.FilterListModel.new(
self._coremodel.props.songs)
self._filter_model.set_filter_func(lambda a: False)
self._model = Gfm.SortListModel.new(self._filter_model)
self._model.set_sort_func(
- self._wrap_sort_func(self._disc_sort))
+ utils.wrap_list_store_sort_func(_disc_sort))
self._model.connect("items-changed", self._on_disc_changed)
@@ -73,18 +85,6 @@ class CoreDisc(GObject.GObject):
self.props.duration = duration
- def _disc_sort(self, song_a, song_b):
- return song_a.props.track_number - song_b.props.track_number
-
- def _wrap_sort_func(self, func):
-
- def wrap(a, b, *user_data):
- a = pygobject_new_full(a, False)
- b = pygobject_new_full(b, False)
- return func(a, b, *user_data)
-
- return wrap
-
def _get_album_disc(self, media, discnr, model):
album_ids = []
model_filter = model
@@ -92,10 +92,11 @@ class CoreDisc(GObject.GObject):
def _filter_func(core_song):
return core_song.props.grlid in album_ids
- def _reverse_sort(song_a, song_b, data=None):
- return song_a.props.track_number - song_b.props.track_number
+ def _callback(source, op_id, media, remaining, error):
+ if error:
+ self._log.warning("Error: {}".format(error))
+ return
- def _callback(source, dunno, media, something, something2):
if media is None:
if sorted(album_ids) == sorted(self._old_album_ids):
return
@@ -105,8 +106,7 @@ class CoreDisc(GObject.GObject):
album_ids.append(media.get_source() + media.get_id())
- self._coremodel.props.grilo.populate_album_disc_songs(
- media, discnr, _callback)
+ self._coregrilo.populate_album_disc_songs(media, discnr, _callback)
@GObject.Property(
type=bool, default=False, flags=GObject.BindingFlags.SYNC_CREATE)
diff --git a/gnomemusic/coregrilo.py b/gnomemusic/coregrilo.py
index 4d408acf..d3f9b4e0 100644
--- a/gnomemusic/coregrilo.py
+++ b/gnomemusic/coregrilo.py
@@ -22,6 +22,8 @@
# code, but you are not obligated to do so. If you do not wish to do so,
# delete this exception statement from your version.
+import weakref
+
import gi
gi.require_version('Grl', '0.3')
from gi.repository import Grl, GLib, GObject
@@ -33,13 +35,12 @@ from gnomemusic.trackerwrapper import TrackerState, TrackerWrapper
class CoreGrilo(GObject.GObject):
- _blacklist = [
+ _blocklist = [
'grl-bookmarks',
'grl-filesystem',
'grl-itunes-podcast',
'grl-metadata-store',
- 'grl-podcasts',
- 'grl-spotify-cover'
+ 'grl-podcasts'
]
_grl_plugin_ranks = ("grl-musicbrainz-coverart:3,"
@@ -51,16 +52,15 @@ class CoreGrilo(GObject.GObject):
cover_sources = GObject.Property(type=bool, default=False)
tracker_available = GObject.Property(type=int)
- def __init__(self, coremodel, application):
+ def __init__(self, application):
"""Initiate the CoreGrilo object
- :param CoreModel coremodel: The CoreModel instance to use
:param Application application: The Application instance to use
"""
super().__init__()
self._application = application
- self._coremodel = coremodel
+ self._coremodel = self._application.props.coremodel
self._coreselection = application.props.coreselection
self._log = application.props.log
self._search_wrappers = {}
@@ -68,14 +68,11 @@ class CoreGrilo(GObject.GObject):
self._thumbnail_sources_timeout = None
self._wrappers = {}
- self._tracker_wrapper = TrackerWrapper()
+ self._tracker_wrapper = TrackerWrapper(application)
self._tracker_wrapper.bind_property(
"tracker-available", self, "tracker-available",
GObject.BindingFlags.SYNC_CREATE)
- self._tracker_wrapper.connect(
- "notify::tracker-available", self._on_tracker_available_changed)
-
GLib.setenv("GRL_PLUGIN_RANKS", self._grl_plugin_ranks, True)
Grl.init(None)
@@ -88,16 +85,42 @@ class CoreGrilo(GObject.GObject):
self._registry.connect('source-added', self._on_source_added)
self._registry.connect('source-removed', self._on_source_removed)
- self._registry.load_all_plugins(True)
+ self._registry.load_all_plugins(False)
+
+ tracker_available_state = self._tracker_wrapper.props.tracker_available
+ if tracker_available_state != TrackerState.AVAILABLE:
+ self._tracker_wrapper.connect(
+ "notify::tracker-available",
+ self._on_tracker_available_changed)
+ else:
+ self._on_tracker_available_changed(None, None)
+
+ for plugin in self._registry.get_plugins(False):
+ plugin_id = plugin.get_id()
+ # Activate the Tracker plugin only when TrackerWrapper
+ # is available by listening to the tracker-available
+ # property, so skip it here.
+ if plugin_id != "grl-tracker3":
+ try:
+ self._registry.activate_plugin_by_id(plugin_id)
+ except GLib.GError:
+ self._log.debug(
+ "Failed to activate {} plugin.".format(plugin_id))
+
+ weakref.finalize(self, Grl.deinit)
def _on_tracker_available_changed(self, klass, value):
- new_state = self._tracker_wrapper.props.tracker_available
# FIXME:No removal support yet.
+ new_state = self._tracker_wrapper.props.tracker_available
if new_state == TrackerState.AVAILABLE:
- tracker_plugin = self._registry.lookup_plugin("grl-tracker")
- if tracker_plugin:
- self._registry.unload_plugin("grl-tracker")
- self._registry.activate_plugin_by_id("grl-tracker")
+ config = Grl.Config.new("grl-tracker3", "grl-tracker3-source")
+ config.set_string(
+ "miner-service", self._tracker_wrapper.props.miner_fs_busname)
+ config.set_string(
+ "store-path", self._tracker_wrapper.cache_directory())
+ self._registry.add_config(config)
+
+ self._registry.activate_plugin_by_id("grl-tracker3")
def _on_source_added(self, registry, source):
@@ -109,7 +132,7 @@ class CoreGrilo(GObject.GObject):
return GLib.SOURCE_REMOVE
if ("net:plaintext" in source.get_tags()
- or source.props.source_id in self._blacklist):
+ or source.props.source_id in self._blocklist):
try:
registry.unregister_source(source)
except GLib.GError:
@@ -125,30 +148,20 @@ class CoreGrilo(GObject.GObject):
self._thumbnail_sources_timeout = GLib.timeout_add_seconds(
5, _trigger_art_update)
- new_wrapper = None
-
- new_state = self._tracker_wrapper.props.tracker_available
- if (source.props.source_id == "grl-tracker-source"
- and self._tracker_wrapper.location_filter() is not None
- and new_state == TrackerState.AVAILABLE):
- if source.props.source_id not in self._wrappers.keys():
- new_wrapper = GrlTrackerWrapper(
- source, self._coremodel, self._application, self,
- self._tracker_wrapper)
- self._wrappers[source.props.source_id] = new_wrapper
- self._log.debug("Adding wrapper {}".format(new_wrapper))
- else:
- grl_tracker_wrapper = self._wrappers[source.props.source_id]
- registry.unregister_source(grl_tracker_wrapper.props.source)
- grl_tracker_wrapper.props.source = source
+ if (source.props.source_id == "grl-tracker3-source"
+ and self._tracker_wrapper.location_filter() is not None):
+ new_wrapper = GrlTrackerWrapper(
+ source, self._application, self._tracker_wrapper)
+ self._wrappers[source.props.source_id] = new_wrapper
+ self._log.debug("Adding wrapper {}".format(new_wrapper))
elif (source.props.source_id not in self._search_wrappers.keys()
and source.props.source_id not in self._wrappers.keys()
- and source.props.source_id != "grl-tracker-source"
+ and source.props.source_id != "grl-tracker3-source"
and source.get_supported_media() & Grl.MediaType.AUDIO
and source.supported_operations() & Grl.SupportedOps.SEARCH
and "net:internet" not in source.props.source_tags):
self._search_wrappers[source.props.source_id] = GrlSearchWrapper(
- source, self._coremodel, self._application, self)
+ source, self._application)
self._log.debug("Adding search source {}".format(source))
def _on_source_removed(self, registry, source):
@@ -158,17 +171,34 @@ class CoreGrilo(GObject.GObject):
# FIXME: Only removes search sources atm.
self._search_wrappers.pop(source.props.source_id, None)
- def get_artist_albums(self, artist, filter_model):
- for wrapper in self._wrappers.values():
- wrapper.get_artist_albums(artist, filter_model)
+ def get_artist_albums(self, media, filter_model):
+ """Get all album by an artist
+
+ :param Grl.Media media: A Grilo Media item that represents Artist
+ :param Gfm.FilterListModel filter_model: The model to fill
+ """
+ source = media.get_source()
+ self._wrappers[source].get_artist_albums(media, filter_model)
def get_album_discs(self, media, disc_model):
- for wrapper in self._wrappers.values():
- wrapper.get_album_discs(media, disc_model)
+ """Get all discs from an album
+
+ :param Grl.Media media: A Grilo Media item that represents Album
+ :param Gfm.SortListModel disc_model: The model to fill
+ """
+ source = media.get_source()
+ self._wrappers[source].get_album_discs(media, disc_model)
def populate_album_disc_songs(self, media, discnr, callback):
- for wrapper in self._wrappers.values():
- wrapper.populate_album_disc_songs(media, discnr, callback)
+ """Get all songs from an album disc
+
+ :param Grl.Media media: A Grilo Media item that represents Album
+ :param int discnr: The disc number
+ :param callback: The callback to call for every song added
+ """
+ source = media.get_source()
+ self._wrappers[source].populate_album_disc_songs(
+ media, discnr, callback)
def writeback(self, media, key):
"""Store the values associated with the key.
@@ -190,31 +220,56 @@ class CoreGrilo(GObject.GObject):
None)
break
+ def writeback_tracker(self, media, tag):
+ """Use Tracker queries to update tags.
+
+ The tags are associated with a Tracker resource
+ (song, album, artist or external resource), so they can cannot
+ be updated with grilo writeback support.
+
+ :param Grl.Media media: A Grilo media item
+ :param str tag: tag to update
+ """
+ self._tracker_wrapper.update_tag(media, tag)
+
def search(self, text):
for wrapper in self._wrappers.values():
wrapper.search(text)
for wrapper in self._search_wrappers.values():
wrapper.search(text)
- def get_album_art_for_item(self, coresong, callback):
- # Tracker not (yet) loaded.
- if "grl-tracker-source" in self._wrappers:
- self._wrappers["grl-tracker-source"].get_album_art_for_item(
- coresong, callback)
+ def get_song_art(self, coresong):
+ """Retrieve song art for the given CoreSong
+
+ :param CoreSong coresong: CoreSong to retrieve art for
+ """
+ if "grl-tracker3-source" in self._wrappers:
+ self._wrappers["grl-tracker3-source"].get_song_art(coresong)
+
+ def get_album_art(self, corealbum):
+ """Retrieve album art for the given CoreAlbum
+
+ :param CoreAlbum corealbum: CoreAlbum to retrieve art for
+ """
+ if "grl-tracker3-source" in self._wrappers:
+ self._wrappers["grl-tracker3-source"].get_album_art(corealbum)
def get_artist_art(self, coreartist):
- if "grl-tracker-source" in self._wrappers:
- self._wrappers["grl-tracker-source"].get_artist_art(coreartist)
+ """Retrieve artist art for the given CoreArtist
+
+ :param CoreArtist coreartist: CoreArtist to retrieve art for
+ """
+ if "grl-tracker3-source" in self._wrappers:
+ self._wrappers["grl-tracker3-source"].get_artist_art(coreartist)
def stage_playlist_deletion(self, playlist):
"""Prepares playlist deletion.
:param Playlist playlist: playlist
"""
- for wrapper in self._wrappers.values():
- if wrapper.source.props.source_id == "grl-tracker-source":
- wrapper.stage_playlist_deletion(playlist)
- break
+ if "grl-tracker3-source" in self._wrappers:
+ self._wrappers["grl-tracker3-source"].stage_playlist_deletion(
+ playlist)
def finish_playlist_deletion(self, playlist, deleted):
"""Finishes playlist deletion.
@@ -222,10 +277,9 @@ class CoreGrilo(GObject.GObject):
:param Playlist playlist: playlist
:param bool deleted: indicates if the playlist has been deleted
"""
- for wrapper in self._wrappers.values():
- if wrapper.source.props.source_id == "grl-tracker-source":
- wrapper.finish_playlist_deletion(playlist, deleted)
- break
+ if "grl-tracker3-source" in self._wrappers:
+ self._wrappers["grl-tracker3-source"].finish_playlist_deletion(
+ playlist, deleted)
def create_playlist(self, playlist_title, callback):
"""Creates a new user playlist.
@@ -233,7 +287,6 @@ class CoreGrilo(GObject.GObject):
:param str playlist_title: playlist title
:param callback: function to perform once, the playlist is created
"""
- for wrapper in self._wrappers.values():
- if wrapper.source.props.source_id == "grl-tracker-source":
- wrapper.create_playlist(playlist_title, callback)
- break
+ if "grl-tracker3-source" in self._wrappers:
+ self._wrappers["grl-tracker3-source"].create_playlist(
+ playlist_title, callback)
diff --git a/gnomemusic/coremodel.py b/gnomemusic/coremodel.py
index 185413df..7d8f8173 100644
--- a/gnomemusic/coremodel.py
+++ b/gnomemusic/coremodel.py
@@ -28,8 +28,8 @@ import gi
gi.require_version("Gfm", "0.1")
from gi.repository import GObject, Gio, Gfm, Gtk
+from gnomemusic.corealbum import CoreAlbum
from gnomemusic.coreartist import CoreArtist
-from gnomemusic.coregrilo import CoreGrilo
from gnomemusic.coresong import CoreSong
from gnomemusic.grilowrappers.grltrackerplaylists import Playlist
from gnomemusic.player import PlayerPlaylist
@@ -69,10 +69,10 @@ class CoreModel(GObject.GObject):
"smart-playlist-change": (GObject.SignalFlags.RUN_FIRST, None, ())
}
- active_playlist = GObject.Property(type=Playlist, default=None)
- grilo = GObject.Property(type=CoreGrilo, default=None)
songs_available = GObject.Property(type=bool, default=False)
+ _recent_size = 21
+
def __init__(self, application):
"""Initiate the CoreModel object
@@ -85,40 +85,50 @@ class CoreModel(GObject.GObject):
self._current_playlist_model = None
self._previous_playlist_model = None
- self._model = Gio.ListStore.new(CoreSong)
- self._songliststore = SongListStore(self._model)
+ self._songs_model_proxy = Gio.ListStore.new(Gio.ListModel)
+ self._songs_model = Gfm.FlattenListModel.new(
+ CoreSong, self._songs_model_proxy)
+ self._songliststore = SongListStore(self._songs_model)
+
+ self._application = application
- self._coreselection = application.props.coreselection
- self._album_model = Gio.ListStore()
- self._album_model_sort = Gfm.SortListModel.new(self._album_model)
- self._album_model_sort.set_sort_func(
+ self._albums_model_proxy = Gio.ListStore.new(Gio.ListModel)
+ self._albums_model = Gfm.FlattenListModel.new(
+ CoreAlbum, self._albums_model_proxy)
+ self._albums_model_sort = Gfm.SortListModel.new(self._albums_model)
+ self._albums_model_sort.set_sort_func(
utils.wrap_list_store_sort_func(self._albums_sort))
- self._artist_model = Gio.ListStore.new(CoreArtist)
- self._artist_model_sort = Gfm.SortListModel.new(self._artist_model)
- self._artist_model_sort.set_sort_func(
+ self._artists_model_proxy = Gio.ListStore.new(Gio.ListModel)
+ self._artists_model = Gfm.FlattenListModel.new(
+ CoreArtist, self._artists_model_proxy)
+ self._artists_model_sort = Gfm.SortListModel.new(self._artists_model)
+ self._artists_model_sort.set_sort_func(
utils.wrap_list_store_sort_func(self._artist_sort))
self._playlist_model = Gio.ListStore.new(CoreSong)
self._playlist_model_sort = Gfm.SortListModel.new(self._playlist_model)
+ self._playlist_model_recent = Gfm.SliceListModel.new(
+ self._playlist_model_sort, 0, self._recent_size)
+ self._active_core_object = None
- self._song_search_proxy = Gio.ListStore.new(Gfm.FilterListModel)
- self._song_search_flatten = Gfm.FlattenListModel.new(CoreSong)
- self._song_search_flatten.set_model(self._song_search_proxy)
+ self._songs_search_proxy = Gio.ListStore.new(Gfm.FilterListModel)
+ self._songs_search_flatten = Gfm.FlattenListModel.new(CoreSong)
+ self._songs_search_flatten.set_model(self._songs_search_proxy)
- self._album_search_model = Gfm.FilterListModel.new(
- self._album_model)
- self._album_search_model.set_filter_func(lambda a: False)
+ self._albums_search_model = Gfm.FilterListModel.new(
+ self._albums_model)
+ self._albums_search_model.set_filter_func(lambda a: False)
- self._album_search_filter = Gfm.FilterListModel.new(
- self._album_search_model)
+ self._albums_search_filter = Gfm.FilterListModel.new(
+ self._albums_search_model)
- self._artist_search_model = Gfm.FilterListModel.new(
- self._artist_model)
- self._artist_search_model.set_filter_func(lambda a: False)
+ self._artists_search_model = Gfm.FilterListModel.new(
+ self._artists_model)
+ self._artists_search_model.set_filter_func(lambda a: False)
- self._artist_search_filter = Gfm.FilterListModel.new(
- self._artist_search_model)
+ self._artists_search_filter = Gfm.FilterListModel.new(
+ self._artists_search_model)
self._playlists_model = Gio.ListStore.new(Playlist)
self._playlists_model_filter = Gfm.FilterListModel.new(
@@ -135,12 +145,10 @@ class CoreModel(GObject.GObject):
self._user_playlists_model_sort.set_sort_func(
utils.wrap_list_store_sort_func(self._playlists_sort))
- self.props.grilo = CoreGrilo(self, application)
- # FIXME: Not all instances of internal _grilo use have been
- # fixed.
- self._grilo = self.props.grilo
+ self._search = application.props.search
- self._model.connect("items-changed", self._on_songs_items_changed)
+ self._songs_model.connect(
+ "items-changed", self._on_songs_items_changed)
def _on_songs_items_changed(self, model, position, removed, added):
available = self.props.songs_available
@@ -182,37 +190,7 @@ class CoreModel(GObject.GObject):
playlist_a.props.creation_date)
return math.copysign(1, date_diff)
- def get_album_model(self, media):
- disc_model = Gio.ListStore()
- disc_model_sort = Gfm.SortListModel.new(disc_model)
-
- def _disc_order_sort(disc_a, disc_b):
- return disc_a.props.disc_nr - disc_b.props.disc_nr
-
- disc_model_sort.set_sort_func(
- utils.wrap_list_store_sort_func(_disc_order_sort))
-
- self.props.grilo.get_album_discs(media, disc_model)
-
- return disc_model_sort
-
- def get_artist_album_model(self, media):
- albums_model_filter = Gfm.FilterListModel.new(self._album_model)
- albums_model_filter.set_filter_func(lambda a: False)
-
- albums_model_sort = Gfm.SortListModel.new(albums_model_filter)
-
- self.props.grilo.get_artist_albums(media, albums_model_filter)
-
- def _album_sort(album_a, album_b):
- return album_a.props.year > album_b.props.year
-
- albums_model_sort.set_sort_func(
- utils.wrap_list_store_sort_func(_album_sort))
-
- return albums_model_sort
-
- def set_player_model(self, playlist_type, model):
+ def _set_player_model(self, playlist_type, model):
"""Set the model for PlayerPlaylist to use
This fills playlist model based on the playlist type and model
@@ -241,9 +219,7 @@ class CoreModel(GObject.GObject):
if added > 0:
for i in list(range(added)):
coresong = model[position + i]
- song = CoreSong(
- coresong.props.media, self._coreselection,
- self.props.grilo)
+ song = CoreSong(self._application, coresong.props.media)
_bind_song_properties(coresong, song)
songs_list.append(song)
@@ -259,10 +235,6 @@ class CoreModel(GObject.GObject):
self._player_signal_id = None
self._current_playlist_model = None
- if (playlist_type != PlayerPlaylist.Type.PLAYLIST
- and self.props.active_playlist is not None):
- self.props.active_playlist = None
-
songs_added = []
if playlist_type == PlayerPlaylist.Type.ALBUM:
@@ -276,9 +248,7 @@ class CoreModel(GObject.GObject):
self._current_playlist_model = self._flatten_model
for model_song in self._flatten_model:
- song = CoreSong(
- model_song.props.media, self._coreselection,
- self.props.grilo)
+ song = CoreSong(self._application, model_song.props.media)
_bind_song_properties(model_song, song)
songs_added.append(song)
@@ -294,9 +264,7 @@ class CoreModel(GObject.GObject):
self._current_playlist_model = self._flatten_model
for model_song in self._flatten_model:
- song = CoreSong(
- model_song.props.media, self._coreselection,
- self.props.grilo)
+ song = CoreSong(self._application, model_song.props.media)
_bind_song_properties(model_song, song)
songs_added.append(song)
@@ -310,18 +278,16 @@ class CoreModel(GObject.GObject):
song.props.state = SongWidget.State.PLAYED
elif playlist_type == PlayerPlaylist.Type.SEARCH_RESULT:
- self._current_playlist_model = self._song_search_flatten
+ self._current_playlist_model = self._songs_search_flatten
- for song in self._song_search_flatten:
+ for song in self._songs_search_flatten:
songs_added.append(song)
elif playlist_type == PlayerPlaylist.Type.PLAYLIST:
self._current_playlist_model = model
for model_song in model:
- song = CoreSong(
- model_song.props.media, self._coreselection,
- self.props.grilo)
+ song = CoreSong(self._application, model_song.props.media)
_bind_song_properties(model_song, song)
songs_added.append(song)
@@ -335,46 +301,77 @@ class CoreModel(GObject.GObject):
self.emit("playlist-loaded", playlist_type)
- def stage_playlist_deletion(self, playlist):
- """Prepares playlist deletion.
-
- :param Playlist playlist: playlist
- """
- self.props.grilo.stage_playlist_deletion(playlist)
-
- def finish_playlist_deletion(self, playlist, deleted):
- """Finishes playlist deletion.
+ @GObject.Property(default=None)
+ def active_core_object(self):
+ """Get the current playing core object
+ (album, artist, playlist, search result or song).
- :param Playlist playlist: playlist
- :param bool deleted: indicates if the playlist has been deleted
+ :returns: current media
+ :rtype: CoreObject
"""
- self.props.grilo.finish_playlist_deletion(playlist, deleted)
+ return self._active_core_object
- def create_playlist(self, playlist_title, callback):
- """Creates a new user playlist.
+ @active_core_object.setter
+ def active_core_object(self, value):
+ """Set the current playing core object
+ (album, artist, playlist, search result or song).
- :param str playlist_title: playlist title
- :param callback: function to perform once, the playlist is created
+ :param CoreObject value: new core object to play
"""
- self.props.grilo.create_playlist(playlist_title, callback)
+ self._active_core_object = value
+ if isinstance(value, CoreAlbum):
+ playlist_type = PlayerPlaylist.Type.ALBUM
+ model = value.props.model
+ elif isinstance(value, CoreArtist):
+ playlist_type = PlayerPlaylist.Type.ARTIST
+ model = value.props.model
+ elif isinstance(value, Playlist):
+ playlist_type = PlayerPlaylist.Type.PLAYLIST
+ model = value.props.model
+ # If the search is active, it means that the search view is visible,
+ # so the player playlist is a list of songs from the search result.
+ # Otherwise, it's a list of songs from the songs view.
+ elif self._search.props.search_mode_active:
+ playlist_type = PlayerPlaylist.Type.SEARCH_RESULT
+ model = self._songs_search_flatten
+ else:
+ playlist_type = PlayerPlaylist.Type.SONGS
+ model = self._songs_model
- def search(self, text):
- self.props.grilo.search(text)
+ self._set_player_model(playlist_type, model)
@GObject.Property(
type=Gio.ListStore, default=None, flags=GObject.ParamFlags.READABLE)
def songs(self):
- return self._model
+ return self._songs_model
+
+ @GObject.Property(
+ type=Gfm.FlattenListModel, default=None,
+ flags=GObject.ParamFlags.READABLE)
+ def songs_proxy(self):
+ return self._songs_model_proxy
@GObject.Property(
type=Gio.ListStore, default=None, flags=GObject.ParamFlags.READABLE)
def albums(self):
- return self._album_model
+ return self._albums_model
+
+ @GObject.Property(
+ type=Gfm.FlattenListModel, default=None,
+ flags=GObject.ParamFlags.READABLE)
+ def albums_proxy(self):
+ return self._albums_model_proxy
@GObject.Property(
type=Gio.ListStore, default=None, flags=GObject.ParamFlags.READABLE)
def artists(self):
- return self._artist_model
+ return self._artists_model
+
+ @GObject.Property(
+ type=Gfm.FlattenListModel, default=None,
+ flags=GObject.ParamFlags.READABLE)
+ def artists_proxy(self):
+ return self._artists_model_proxy
@GObject.Property(
type=Gio.ListStore, default=None, flags=GObject.ParamFlags.READABLE)
@@ -385,13 +382,13 @@ class CoreModel(GObject.GObject):
type=Gfm.SortListModel, default=None,
flags=GObject.ParamFlags.READABLE)
def albums_sort(self):
- return self._album_model_sort
+ return self._albums_model_sort
@GObject.Property(
type=Gfm.SortListModel, default=None,
flags=GObject.ParamFlags.READABLE)
def artists_sort(self):
- return self._artist_model_sort
+ return self._artists_model_sort
@GObject.Property(
type=Gfm.SortListModel, default=None,
@@ -400,40 +397,52 @@ class CoreModel(GObject.GObject):
return self._playlist_model_sort
@GObject.Property(
+ type=Gfm.SliceListModel, default=None,
+ flags=GObject.ParamFlags.READABLE)
+ def recent_playlist(self):
+ return self._playlist_model_recent
+
+ @GObject.Property(
+ type=int, default=None,
+ flags=GObject.ParamFlags.READABLE)
+ def recent_playlist_size(self):
+ return self._recent_size // 2
+
+ @GObject.Property(
type=Gfm.FilterListModel, default=None,
flags=GObject.ParamFlags.READABLE)
def songs_search(self):
- return self._song_search_flatten
+ return self._songs_search_flatten
@GObject.Property(
type=Gio.ListStore, default=None,
flags=GObject.ParamFlags.READABLE)
def songs_search_proxy(self):
- return self._song_search_proxy
+ return self._songs_search_proxy
@GObject.Property(
type=Gfm.FilterListModel, default=None,
flags=GObject.ParamFlags.READABLE)
def albums_search(self):
- return self._album_search_model
+ return self._albums_search_model
@GObject.Property(
type=Gfm.FilterListModel, default=None,
flags=GObject.ParamFlags.READABLE)
def albums_search_filter(self):
- return self._album_search_filter
+ return self._albums_search_filter
@GObject.Property(
type=Gfm.FilterListModel, default=None,
flags=GObject.ParamFlags.READABLE)
def artists_search(self):
- return self._artist_search_model
+ return self._artists_search_model
@GObject.Property(
type=Gfm.FilterListModel, default=None,
flags=GObject.ParamFlags.READABLE)
def artists_search_filter(self):
- return self._artist_search_filter
+ return self._artists_search_filter
@GObject.Property(
type=Gtk.ListStore, default=None, flags=GObject.ParamFlags.READABLE)
diff --git a/gnomemusic/coreselection.py b/gnomemusic/coreselection.py
index 848da8bc..de3b1077 100644
--- a/gnomemusic/coreselection.py
+++ b/gnomemusic/coreselection.py
@@ -27,24 +27,24 @@ from gi.repository import GObject
class CoreSelection(GObject.GObject):
- selected_items_count = GObject.Property(type=int, default=0)
+ selected_songs_count = GObject.Property(type=int, default=0)
def __init__(self):
super().__init__()
- self._selected_items = []
+ self._selected_songs = []
def update_selection(self, coresong, value):
if coresong.props.selected:
- self.props.selected_items.append(coresong)
+ self.props.selected_songs.append(coresong)
else:
try:
- self.props.selected_items.remove(coresong)
+ self.props.selected_songs.remove(coresong)
except ValueError:
pass
- self.props.selected_items_count = len(self.props.selected_items)
+ self.props.selected_songs_count = len(self.props.selected_songs)
@GObject.Property
- def selected_items(self):
- return self._selected_items
+ def selected_songs(self):
+ return self._selected_songs
diff --git a/gnomemusic/coresong.py b/gnomemusic/coresong.py
index c2befcb6..6099b3d5 100644
--- a/gnomemusic/coresong.py
+++ b/gnomemusic/coresong.py
@@ -28,6 +28,7 @@ import gi
gi.require_version('Grl', '0.3')
from gi.repository import Grl, GLib, GObject
+from gnomemusic.songart import SongArt
import gnomemusic.utils as utils
@@ -55,16 +56,23 @@ class CoreSong(GObject.GObject):
FAILED = 2
SUCCEEDED = 3
- def __init__(self, media, coreselection, grilo):
+ def __init__(self, application, media):
+ """Initiate the CoreSong object
+
+ :param Application application: The application object
+ :param Grl.Media media: A media object
+ """
super().__init__()
- self._grilo = grilo
- self._coreselection = coreselection
+ self._application = application
+ self._coregrilo = application.props.coregrilo
+ self._coreselection = application.props.coreselection
self._favorite = False
self._selected = False
+ self._thumbnail = None
self.props.grlid = media.get_source() + media.get_id()
- self._is_tracker = media.get_source() == "grl-tracker-source"
+ self._is_tracker = media.get_source() == "grl-tracker3-source"
self.props.validation = CoreSong.Validation.PENDING
self.update(media)
@@ -94,7 +102,8 @@ class CoreSong(GObject.GObject):
return
self.props.media.set_favourite(self._favorite)
- self._grilo.writeback(self.props.media, Grl.METADATA_KEY_FAVOURITE)
+ self._coregrilo.writeback_tracker(
+ self.props.media, "favorite")
@GObject.Property(type=bool, default=False)
def selected(self):
@@ -111,6 +120,27 @@ class CoreSong(GObject.GObject):
self._selected = value
self._coreselection.update_selection(self, self._selected)
+ @GObject.Property(type=str, default=None)
+ def thumbnail(self):
+ """Song art thumbnail retrieval
+
+ :return: The song art uri or "generic" or "loading"
+ :rtype: string
+ """
+ if self._thumbnail is None:
+ self._thumbnail = "loading"
+ SongArt(self._application, self)
+
+ return self._thumbnail
+
+ @thumbnail.setter
+ def thumbnail(self, value):
+ """Song art thumbnail setter
+
+ :param string value: uri, "generic" or "loading"
+ """
+ self._thumbnail = value
+
def update(self, media):
self.props.media = media
self.props.album = utils.get_album_title(media)
@@ -128,11 +158,13 @@ class CoreSong(GObject.GObject):
return
self.props.media.set_play_count(self.props.play_count + 1)
- self._grilo.writeback(self.props.media, Grl.METADATA_KEY_PLAY_COUNT)
+ self._coregrilo.writeback_tracker(
+ self.props.media, "play-count")
def set_last_played(self):
if not self._is_tracker:
return
self.props.media.set_last_played(GLib.DateTime.new_now_utc())
- self._grilo.writeback(self.props.media, Grl.METADATA_KEY_LAST_PLAYED)
+ self._coregrilo.writeback_tracker(
+ self.props.media, "last-played")
diff --git a/gnomemusic/embeddedart.py b/gnomemusic/embeddedart.py
new file mode 100644
index 00000000..7ef4f93d
--- /dev/null
+++ b/gnomemusic/embeddedart.py
@@ -0,0 +1,181 @@
+# Copyright 2020 The GNOME Music developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music. This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered. If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so. If you do not wish to do so,
+# delete this exception statement from your version.
+
+import gi
+gi.require_versions({"GstPbutils": "1.0", "GstTag": "1.0", "MediaArt": "2.0"})
+from gi.repository import GLib, GObject, MediaArt, Gst, GstTag, GstPbutils
+
+from gnomemusic.musiclogger import MusicLogger
+
+
+class EmbeddedArt(GObject.GObject):
+ """Lookup local art
+
+ 1. Embedded art using GStreamer
+ 2. Available in the directory using MediaArt
+ """
+
+ _log = MusicLogger()
+
+ __gsignals__ = {
+ "art-found": (GObject.SignalFlags.RUN_FIRST, None, (bool, ))
+ }
+
+ def __init__(self):
+ """Initialize EmbeddedArt
+ """
+ super().__init__()
+
+ try:
+ Gst.init(None)
+ GstPbutils.pb_utils_init()
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ return
+
+ self._media_art = MediaArt.Process.new()
+
+ self._album = None
+ self._artist = None
+ self._coreobject = None
+ self._path = None
+
+ def query(self, coreobject, title):
+ """Start the local query
+
+ :param coreobject: The CoreAlbum or CoreSong to search art for
+ :param str title: The album title for the CoreAlbum or CoreSong
+ """
+ self._album = title
+ self._artist = coreobject.props.artist
+ self._coreobject = coreobject
+
+ try:
+ if coreobject.props.url is None:
+ self.emit("art-found", False)
+ return
+ except AttributeError:
+ self.emit("art-found", False)
+ return
+
+ try:
+ discoverer = GstPbutils.Discoverer.new(Gst.SECOND)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ self._lookup_cover_in_directory()
+ return
+
+ discoverer.connect("discovered", self._discovered)
+ discoverer.start()
+
+ success, path = MediaArt.get_path(self._artist, self._album, "album")
+
+ if not success:
+ self.emit("art-found", False)
+ discoverer.stop()
+ return
+
+ self._path = path
+
+ success = discoverer.discover_uri_async(self._coreobject.props.url)
+
+ if not success:
+ self._log.warning("Could not add url to discoverer.")
+ self.emit("art-found", False)
+ discoverer.stop()
+ return
+
+ def _discovered(self, discoverer, info, error):
+ tags = info.get_tags()
+ index = 0
+
+ if (error is not None
+ or tags is None):
+ if error:
+ self._log.warning("Discoverer error: {}, {}".format(
+ Gst.CoreError(error.code), error.message))
+ discoverer.stop()
+ self.emit("art-found", False)
+ return
+
+ while True:
+ success, sample = tags.get_sample_index(Gst.TAG_IMAGE, index)
+ if not success:
+ break
+ index += 1
+ struct = sample.get_info()
+ if struct is None:
+ break
+ success, image_type = struct.get_enum(
+ "image-type", GstTag.TagImageType)
+ if not success:
+ continue
+ if image_type != GstTag.TagImageType.FRONT_COVER:
+ continue
+
+ buf = sample.get_buffer()
+ success, map_info = buf.map(Gst.MapFlags.READ)
+ if not success:
+ continue
+
+ try:
+ mime = sample.get_caps().get_structure(0).get_name()
+ MediaArt.buffer_to_jpeg(map_info.data, mime, self._path)
+ discoverer.stop()
+ self.emit("art-found", True)
+ return
+ except GLib.Error as error:
+ self._log.warning("Error: {}, {}".format(
+ MediaArt.Error(error.code), error.message))
+
+ discoverer.stop()
+
+ self._lookup_cover_in_directory()
+
+ def _lookup_cover_in_directory(self):
+ # Find local art in cover.jpeg files.
+ self._media_art.uri_async(
+ MediaArt.Type.ALBUM, MediaArt.ProcessFlags.NONE,
+ self._coreobject.props.url, self._artist, self._album,
+ GLib.PRIORITY_LOW, None, self._uri_async_cb, None)
+
+ def _uri_async_cb(self, src, result, data):
+ try:
+ success = self._media_art.uri_finish(result)
+ if success:
+ self.emit("art-found", True)
+ return
+ except GLib.Error as error:
+ if MediaArt.Error(error.code) == MediaArt.Error.SYMLINK_FAILED:
+ # This error indicates that the coverart has already
+ # been linked by another concurrent lookup.
+ self.emit("art-found", True)
+ return
+ else:
+ self._log.warning("Error: {}, {}".format(
+ MediaArt.Error(error.code), error.message))
+
+ self.emit("art-found", False)
diff --git a/gnomemusic/grilowrappers/grlsearchwrapper.py b/gnomemusic/grilowrappers/grlsearchwrapper.py
index ab263e6c..3910f065 100644
--- a/gnomemusic/grilowrappers/grlsearchwrapper.py
+++ b/gnomemusic/grilowrappers/grlsearchwrapper.py
@@ -23,7 +23,7 @@
# delete this exception statement from your version.
import gi
-gi.require_versions({"Grl": "0.3"})
+gi.require_versions({"Gfm": "0.1", "Grl": "0.3"})
from gi.repository import Gfm, Gio, Grl, GObject
from gnomemusic.coresong import CoreSong
@@ -54,26 +54,23 @@ class GrlSearchWrapper(GObject.GObject):
Grl.METADATA_KEY_URL
]
- def __init__(self, source, coremodel, application, grilo):
+ def __init__(self, source, application):
"""Initialize a search wrapper
Initialize a generic Grilo source search wrapper.
:param Grl.Source source: The Grilo source to wrap
- :param CoreModel coremodel: CoreModel instance to use models
- from
:param Application application: Application instance
- :param CoreGrilo grilo: The CoreGrilo instance
"""
super().__init__()
- self._coremodel = coremodel
+ self._application = application
self._coreselection = application.props.coreselection
- self._grilo = grilo
self._log = application.props.log
self._source = source
- self._song_search_proxy = self._coremodel.props.songs_search_proxy
+ coremodel = application.props.coremodel
+ self._song_search_proxy = coremodel.props.songs_search_proxy
self._song_search_store = Gio.ListStore.new(CoreSong)
# FIXME: Workaround for adding the right list type to the proxy
@@ -104,7 +101,7 @@ class GrlSearchWrapper(GObject.GObject):
if not media:
return
- coresong = CoreSong(media, self._coreselection, self._grilo)
+ coresong = CoreSong(self._application, media)
coresong.props.title = (
coresong.props.title + " (" + source.props.source_name + ")")
diff --git a/gnomemusic/grilowrappers/grltrackerplaylists.py b/gnomemusic/grilowrappers/grltrackerplaylists.py
index 3c32172e..566a6762 100644
--- a/gnomemusic/grilowrappers/grltrackerplaylists.py
+++ b/gnomemusic/grilowrappers/grltrackerplaylists.py
@@ -36,43 +36,26 @@ import gnomemusic.utils as utils
class GrlTrackerPlaylists(GObject.GObject):
- METADATA_KEYS = [
- Grl.METADATA_KEY_ALBUM,
- Grl.METADATA_KEY_ALBUM_ARTIST,
- Grl.METADATA_KEY_ALBUM_DISC_NUMBER,
- Grl.METADATA_KEY_ARTIST,
+ _METADATA_PLAYLIST_KEYS = [
Grl.METADATA_KEY_CHILDCOUNT,
Grl.METADATA_KEY_CREATION_DATE,
- Grl.METADATA_KEY_COMPOSER,
- Grl.METADATA_KEY_DURATION,
- Grl.METADATA_KEY_FAVOURITE,
Grl.METADATA_KEY_ID,
- Grl.METADATA_KEY_PLAY_COUNT,
- Grl.METADATA_KEY_THUMBNAIL,
- Grl.METADATA_KEY_TITLE,
- Grl.METADATA_KEY_TRACK_NUMBER,
- Grl.METADATA_KEY_URL
+ Grl.METADATA_KEY_TITLE
]
- def __init__(
- self, source, coremodel, application, grilo, tracker_wrapper,
- songs_hash):
+ def __init__(self, source, application, tracker_wrapper, songs_hash):
"""Initialize GrlTrackerPlaylists.
:param Grl.TrackerSource source: The Tracker source to wrap
- :param CoreModel coremodel: CoreModel instance to use models
- from
:param Application application: Application instance
- :param CoreGrilo grilo: The CoreGrilo instance
:param TrackerWrapper tracker_wrapper: The TrackerWrapper
instance
+ :param dict songs_hash: The songs hash table
"""
super().__init__()
self._application = application
- self._coremodel = coremodel
- self._coreselection = application.props.coreselection
- self._grilo = grilo
+ self._coremodel = application.props.coremodel
self._log = application.props.log
self._source = source
self._model = self._coremodel.props.playlists
@@ -80,8 +63,9 @@ class GrlTrackerPlaylists(GObject.GObject):
self._user_model_filter = self._coremodel.props.user_playlists_filter
self._pls_todelete = []
self._songs_hash = songs_hash
- self._tracker = tracker_wrapper.props.tracker
+ self._tracker = tracker_wrapper.props.local_db
self._tracker_wrapper = tracker_wrapper
+ self._notificationmanager = application.props.notificationmanager
self._window = application.props.window
self._user_model_filter.set_filter_func(self._user_playlists_filter)
@@ -96,7 +80,6 @@ class GrlTrackerPlaylists(GObject.GObject):
args = {
"source": self._source,
"application": self._application,
- "grilo": self._grilo,
"tracker_wrapper": self._tracker_wrapper,
"songs_hash": self._songs_hash
}
@@ -112,48 +95,39 @@ class GrlTrackerPlaylists(GObject.GObject):
for playlist in smart_playlists.values():
self._model.append(playlist)
- self._window.notifications_popup.push_loading()
+ self._notificationmanager.push_loading()
query = """
SELECT DISTINCT
- rdf:type(?playlist)
- tracker:id(?playlist) AS ?id
+ %(media_type)s AS ?type
+ ?playlist AS ?id
nie:title(?playlist) AS ?title
- tracker:added(?playlist) AS ?creation_date
- nfo:entryCounter(?playlist) AS ?childcount
+ nrl:added(?playlist) AS ?creationDate
+ nfo:entryCounter(?playlist) AS ?childCount
WHERE
{
?playlist a nmm:Playlist .
- OPTIONAL { ?playlist nie:url ?url;
- tracker:available ?available . }
- FILTER ( !STRENDS(LCASE(?url), '.m3u')
- && !STRENDS(LCASE(?url), '.m3u8')
- && !STRENDS(LCASE(?url), '.pls')
- || !BOUND(nfo:belongsToContainer(?playlist)) )
- FILTER ( !BOUND(?tag) )
- OPTIONAL { ?playlist nao:hasTag ?tag }
}
- """.replace('\n', ' ').strip()
-
- options = self._fast_options.copy()
+ """.replace("\n", " ").strip() % {
+ "media_type": int(Grl.MediaType.CONTAINER),
+ }
self._source.query(
- query, self.METADATA_KEYS, options, self._add_user_playlist)
+ query, self._METADATA_PLAYLIST_KEYS, self._fast_options,
+ self._add_user_playlist)
def _add_user_playlist(
self, source, op_id, media, remaining, data=None, error=None):
if error:
self._log.warning("Error: {}".format(error))
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
if not media:
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
playlist = Playlist(
- media=media, source=self._source, coremodel=self._coremodel,
- application=self._application, grilo=self._grilo,
+ media=media, source=self._source, application=self._application,
tracker_wrapper=self._tracker_wrapper, songs_hash=self._songs_hash)
-
self._model.append(playlist)
callback = data
if callback is not None:
@@ -200,9 +174,9 @@ class GrlTrackerPlaylists(GObject.GObject):
break
self._model_filter.set_filter_func(self._playlists_filter)
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
- self._window.notifications_popup.push_loading()
+ self._notificationmanager.push_loading()
query = """
DELETE {
?playlist a rdfs:Resource .
@@ -217,8 +191,7 @@ class GrlTrackerPlaylists(GObject.GObject):
""".replace("\n", " ").strip() % {
"playlist_id": playlist.props.pl_id
}
- self._tracker.update_async(
- query, GLib.PRIORITY_LOW, None, _delete_cb, None)
+ self._tracker.update_async(query, None, _delete_cb, None)
def create_playlist(self, playlist_title, callback):
"""Creates a new user playlist.
@@ -231,24 +204,25 @@ class GrlTrackerPlaylists(GObject.GObject):
playlist_urn = result[0][0]['playlist']
query = """
SELECT
- rdf:type(?playlist)
- tracker:id(?playlist) AS ?id
+ %(media_type)s AS ?type
+ ?playlist AS ?id
nie:title(?playlist) AS ?title
- tracker:added(?playlist) AS ?creation_date
- nfo:entryCounter(?playlist) AS ?childcount
+ nrl:added(?playlist) AS ?creationDate
+ nfo:entryCounter(?playlist) AS ?childCount
WHERE
{
- ?playlist a nmm:Playlist .
- FILTER ( <%(playlist_urn)s> = ?playlist )
+ BIND ( <%(playlist_urn)s> AS ?playlist )
}
- """.replace("\n", " ").strip() % {"playlist_urn": playlist_urn}
+ """.replace("\n", " ").strip() % {
+ "media_type": int(Grl.MediaType.CONTAINER),
+ "playlist_urn": playlist_urn
+ }
- options = self._fast_options.copy()
self._source.query(
- query, self.METADATA_KEYS, options, self._add_user_playlist,
- callback)
+ query, self._METADATA_PLAYLIST_KEYS, self._fast_options,
+ self._add_user_playlist, callback)
- self._window.notifications_popup.push_loading()
+ self._notificationmanager.push_loading()
query = """
INSERT {
_:playlist a nmm:Playlist ;
@@ -257,8 +231,7 @@ class GrlTrackerPlaylists(GObject.GObject):
nfo:entryCounter 0 .
}
""".replace("\n", " ").strip() % {"title": playlist_title}
- self._tracker.update_blank_async(
- query, GLib.PRIORITY_LOW, None, _create_cb, None)
+ self._tracker.update_blank_async(query, None, _create_cb, None)
def check_smart_playlist_change(self):
"""Check if smart playlists need to be updated.
@@ -267,10 +240,10 @@ class GrlTrackerPlaylists(GObject.GObject):
* it is being played (active_playlist)
* it is visible in PlaylistsView
"""
- active_playlist = self._coremodel.props.active_playlist
- if (active_playlist is not None
- and active_playlist.props.is_smart is True):
- active_playlist.update()
+ active_core_object = self._coremodel.props.active_core_object
+ if (isinstance(active_core_object, Playlist)
+ and active_core_object.props.is_smart):
+ active_core_object.update()
else:
self._coremodel.emit("smart-playlist-change")
@@ -282,20 +255,15 @@ class Playlist(GObject.GObject):
"playlist-loaded": (GObject.SignalFlags.RUN_FIRST, None, ()),
}
- METADATA_KEYS = [
+ _METADATA_PLAYLIST_KEYS = [
Grl.METADATA_KEY_ALBUM,
- Grl.METADATA_KEY_ALBUM_ARTIST,
- Grl.METADATA_KEY_ALBUM_DISC_NUMBER,
Grl.METADATA_KEY_ARTIST,
- Grl.METADATA_KEY_CREATION_DATE,
- Grl.METADATA_KEY_COMPOSER,
Grl.METADATA_KEY_DURATION,
Grl.METADATA_KEY_FAVOURITE,
Grl.METADATA_KEY_ID,
+ Grl.METADATA_KEY_LAST_PLAYED,
Grl.METADATA_KEY_PLAY_COUNT,
- Grl.METADATA_KEY_THUMBNAIL,
Grl.METADATA_KEY_TITLE,
- Grl.METADATA_KEY_TRACK_NUMBER,
Grl.METADATA_KEY_URL
]
@@ -308,9 +276,7 @@ class Playlist(GObject.GObject):
def __init__(
self, media=None, query=None, tag_text=None, source=None,
- coremodel=None, application=None, grilo=None,
- tracker_wrapper=None, songs_hash=None):
-
+ application=None, tracker_wrapper=None, songs_hash=None):
super().__init__()
"""Initialize a playlist
@@ -319,11 +285,9 @@ class Playlist(GObject.GObject):
:param string tag_text: The non translatable unique identifier
of the playlist
:param Grl.Source source: The Grilo Tracker source object
- :param CoreModel coremodel: The CoreModel instance
:param Application application: The Application instance
- :param CoreGrilo grilo: The CoreGrilo instance
- :param TrackerWrapper tracker_wrapper: The TrackerWrapper
- instance
+ :param TrackerWrapper tracker_wrapper: The TrackerWrapper instance
+ :param dict songs_hash: The songs hash table
"""
if media:
self.props.pl_id = media.get_id()
@@ -335,16 +299,16 @@ class Playlist(GObject.GObject):
self.props.query = query
self.props.tag_text = tag_text
+ self._application = application
self._model = None
self._source = source
- self._coremodel = coremodel
+ self._coremodel = application.props.coremodel
self._coreselection = application.props.coreselection
- self._grilo = grilo
self._log = application.props.log
self._songs_hash = songs_hash
- self._tracker = tracker_wrapper.props.tracker
+ self._tracker = tracker_wrapper.props.local_db
self._tracker_wrapper = tracker_wrapper
- self._window = application.props.window
+ self._notificationmanager = application.props.notificationmanager
self._fast_options = Grl.OperationOptions()
self._fast_options.set_resolution_flags(
@@ -366,30 +330,42 @@ class Playlist(GObject.GObject):
self._model = value
def _populate_model(self):
- self._window.notifications_popup.push_loading()
+ self._notificationmanager.push_loading()
query = """
SELECT
- rdf:type(?song)
- ?song AS ?tracker_urn
- tracker:id(?song) AS ?id
- nie:url(?song) AS ?url
- nie:title(?song) AS ?title
- nmm:artistName(nmm:performer(?song)) AS ?artist
- nie:title(nmm:musicAlbum(?song)) AS ?album
- nfo:duration(?song) AS ?duration
- ?tag AS ?favourite
- nie:contentAccessed(?song) AS ?last_played_time
- nie:usageCounter(?song) AS ?play_count
+ %(media_type)s AS ?type
+ ?song AS ?id
+ ?url
+ ?title
+ ?artist
+ ?album
+ ?duration
+ ?tag AS ?favorite
+ nie:contentAccessed(?song) AS ?lastPlayed
+ nie:usageCounter(?song) AS ?playCount
WHERE {
?playlist a nmm:Playlist ;
a nfo:MediaList ;
nfo:hasMediaFileListEntry ?entry .
?entry a nfo:MediaFileListEntry ;
nfo:entryUrl ?url .
- ?song a nmm:MusicPiece ;
- a nfo:FileDataObject ;
- nie:url ?url .
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT
+ ?song
+ nie:title(?song) AS ?title
+ nmm:artistName(nmm:artist(?song)) AS ?artist
+ nie:title(nmm:musicAlbum(?song)) AS ?album
+ nfo:duration(?song) AS ?duration
+ ?url
+ WHERE {
+ ?song a nmm:MusicPiece ;
+ nie:isStoredAs ?url .
+ %(location_filter)s
+ }
+ }
+ }
OPTIONAL {
?song nao:hasTag ?tag .
FILTER( ?tag = nao:predefined-tag-favorite )
@@ -397,16 +373,13 @@ class Playlist(GObject.GObject):
FILTER (
%(filter_clause)s
)
- FILTER (
- NOT EXISTS { ?song a nmm:Video }
- && NOT EXISTS { ?song a nmm:Playlist }
- )
- %(location_filter)s
}
ORDER BY nfo:listPosition(?entry)
""".replace('\n', ' ').strip() % {
+ "media_type": int(Grl.MediaType.AUDIO),
"filter_clause": 'tracker:id(?playlist) = ' + self.props.pl_id,
- "location_filter": self._tracker_wrapper.location_filter()
+ "location_filter": self._tracker_wrapper.location_filter(),
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
}
def _add_to_playlist_cb(
@@ -414,10 +387,10 @@ class Playlist(GObject.GObject):
if not media:
self.props.count = self._model.get_n_items()
self.emit("playlist-loaded")
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
- coresong = CoreSong(media, self._coreselection, self._grilo)
+ coresong = CoreSong(self._application, media)
self._bind_to_main_song(coresong)
if coresong not in self._songs_todelete:
self._model.append(coresong)
@@ -427,7 +400,8 @@ class Playlist(GObject.GObject):
Grl.ResolutionFlags.FAST_ONLY | Grl.ResolutionFlags.IDLE_RELAY)
self._source.query(
- query, self.METADATA_KEYS, options, _add_to_playlist_cb, None)
+ query, self._METADATA_PLAYLIST_KEYS, options, _add_to_playlist_cb,
+ None)
def _bind_to_main_song(self, coresong):
main_coresong = self._songs_hash[coresong.props.media.get_id()]
@@ -464,7 +438,7 @@ class Playlist(GObject.GObject):
:param str new_name: new playlist name
"""
- self._window.notifications_popup.push_loading()
+ self._notificationmanager.push_loading()
def update_cb(conn, res, data):
try:
@@ -476,7 +450,7 @@ class Playlist(GObject.GObject):
else:
self._title = new_name
finally:
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
self.thaw_notify()
query = """
@@ -499,8 +473,7 @@ class Playlist(GObject.GObject):
}
self.freeze_notify()
- self._tracker.update_async(
- query, GLib.PRIORITY_LOW, None, update_cb, None)
+ self._tracker.update_async(query, None, update_cb, None)
def stage_song_deletion(self, coresong, index):
"""Adds a song to the list of songs to delete
@@ -531,9 +504,9 @@ class Playlist(GObject.GObject):
def update_cb(conn, res, data):
# FIXME: Check for failure.
conn.update_finish(res)
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
- self._window.notifications_popup.push_loading()
+ self._notificationmanager.push_loading()
query = """
INSERT OR REPLACE {
?entry nfo:listPosition ?position .
@@ -562,7 +535,7 @@ class Playlist(GObject.GObject):
}
}
}
- }
+ };
INSERT OR REPLACE {
?playlist nfo:entryCounter ?new_counter .
}
@@ -577,7 +550,7 @@ class Playlist(GObject.GObject):
tracker:id(?playlist) = %(playlist_id)s
)
}
- }
+ };
DELETE {
?playlist nfo:hasMediaFileListEntry ?entry .
?entry a rdfs:Resource .
@@ -596,8 +569,7 @@ class Playlist(GObject.GObject):
"song_id": coresong.props.media.get_id()
}
- self._tracker.update_async(
- query, GLib.PRIORITY_LOW, None, update_cb, None)
+ self._tracker.update_async(query, None, update_cb, None)
def add_songs(self, coresongs):
"""Adds songs to the playlist
@@ -610,7 +582,7 @@ class Playlist(GObject.GObject):
self.props.count = self._model.get_n_items()
return
- coresong = CoreSong(media, self._coreselection, self._grilo)
+ coresong = CoreSong(self._application, media)
self._bind_to_main_song(coresong)
if coresong not in self._songs_todelete:
self._model.append(coresong)
@@ -620,28 +592,40 @@ class Playlist(GObject.GObject):
return
media_id = coresong.props.media.get_id()
+ miner_fs_busname = self._tracker_wrapper.props.miner_fs_busname
query = """
SELECT
- rdf:type(?song)
- ?song AS ?tracker_urn
- tracker:id(?song) AS ?id
- nie:url(?song) AS ?url
- nie:title(?song) AS ?title
- nmm:artistName(nmm:performer(?song)) AS ?artist
- nie:title(nmm:musicAlbum(?song)) AS ?album
- nfo:duration(?song) AS ?duration
- ?tag AS ?favourite
- nie:contentAccessed(?song) AS ?last_played_time
- nie:usageCounter(?song) AS ?play_count
+ %(media_type)s AS ?type
+ ?song AS ?id
+ ?url
+ ?title
+ ?artist
+ ?album
+ ?duration
+ ?tag AS ?favorite
+ nie:contentAccessed(?song) AS ?lastPlayed
+ nie:usageCounter(?song) AS ?playCount
WHERE {
?playlist a nmm:Playlist ;
a nfo:MediaList ;
nfo:hasMediaFileListEntry ?entry .
?entry a nfo:MediaFileListEntry ;
nfo:entryUrl ?url .
- ?song a nmm:MusicPiece ;
- a nfo:FileDataObject ;
- nie:url ?url .
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT
+ ?song
+ nie:title(?song) AS ?title
+ nmm:artistName(nmm:artist(?song)) AS ?artist
+ nie:title(nmm:musicAlbum(?song)) AS ?album
+ nfo:duration(?song) AS ?duration
+ WHERE {
+ ?song a nmm:MusicPiece ;
+ nie:isStoredAs ?url .
+ %(location_filter)s
+ }
+ }
+ }
OPTIONAL {
?song nao:hasTag ?tag .
FILTER( ?tag = nao:predefined-tag-favorite )
@@ -649,20 +633,17 @@ class Playlist(GObject.GObject):
FILTER (
%(filter_clause)s
)
- FILTER (
- NOT EXISTS { ?song a nmm:Video }
- && NOT EXISTS { ?song a nmm:Playlist }
- )
- %(location_filter)s
}
""".replace("\n", " ").strip() % {
+ "media_type": int(Grl.MediaType.AUDIO),
"filter_clause": "tracker:id(?song) = " + media_id,
- "location_filter": self._tracker_wrapper.location_filter()
+ "location_filter": self._tracker_wrapper.location_filter(),
+ "miner_fs_busname": miner_fs_busname,
}
- options = self._fast_options.copy()
self._source.query(
- query, self.METADATA_KEYS, options, _add_to_model)
+ query, self._METADATA_PLAYLIST_KEYS, self._fast_options,
+ _add_to_model)
for coresong in coresongs:
query = """
@@ -690,7 +671,7 @@ class Playlist(GObject.GObject):
"song_uri": coresong.props.media.get_url()}
self._tracker.update_blank_async(
- query, GLib.PRIORITY_LOW, None, _requery_media, coresong)
+ query, None, _requery_media, coresong)
def reorder(self, previous_position, new_position):
"""Changes the order of a songs in the playlist.
@@ -733,13 +714,25 @@ class Playlist(GObject.GObject):
"position": position
}
self._tracker.update_async(
- query, GLib.PRIORITY_LOW, None, _position_changed_cb,
- position)
+ query, None, _position_changed_cb, position)
class SmartPlaylist(Playlist):
"""Base class for smart playlists"""
+ _METADATA_SMART_PLAYLIST_KEYS = [
+ Grl.METADATA_KEY_ALBUM,
+ Grl.METADATA_KEY_ALBUM_DISC_NUMBER,
+ Grl.METADATA_KEY_ARTIST,
+ Grl.METADATA_KEY_DURATION,
+ Grl.METADATA_KEY_FAVOURITE,
+ Grl.METADATA_KEY_ID,
+ Grl.METADATA_KEY_PLAY_COUNT,
+ Grl.METADATA_KEY_URL,
+ Grl.METADATA_KEY_TITLE,
+ Grl.METADATA_KEY_TRACK_NUMBER,
+ ]
+
def __init__(self, **args):
super().__init__(**args)
@@ -750,29 +743,28 @@ class SmartPlaylist(Playlist):
if self._model is None:
self._model = Gio.ListStore.new(CoreSong)
- self._window.notifications_popup.push_loading()
+ self._notificationmanager.push_loading()
def _add_to_model(source, op_id, media, remaining, error):
if error:
self._log.warning("Error: {}".format(error))
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
self.emit("playlist-loaded")
return
if not media:
self.props.count = self._model.get_n_items()
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
self.emit("playlist-loaded")
return
- coresong = CoreSong(media, self._coreselection, self._grilo)
+ coresong = CoreSong(self._application, media)
self._bind_to_main_song(coresong)
self._model.append(coresong)
- options = self._fast_options.copy()
-
self._source.query(
- self.props.query, self.METADATA_KEYS, options, _add_to_model)
+ self.props.query, self._METADATA_SMART_PLAYLIST_KEYS,
+ self._fast_options, _add_to_model)
return self._model
@@ -793,9 +785,9 @@ class SmartPlaylist(Playlist):
new_model_medias.append(media)
- options = self._fast_options.copy()
self._source.query(
- self.props.query, self.METADATA_KEYS, options, _fill_new_model)
+ self.props.query, self._METADATA_SMART_PLAYLIST_KEYS,
+ self._fast_options, _fill_new_model)
def _finish_update(self, new_model_medias):
if not new_model_medias:
@@ -818,7 +810,7 @@ class SmartPlaylist(Playlist):
for idx, media in enumerate(new_model_medias):
if media.get_id() not in current_models_ids:
- coresong = CoreSong(media, self._coreselection, self._grilo)
+ coresong = CoreSong(self._application, media)
self._bind_to_main_song(coresong)
self._model.append(coresong)
self.props.count += 1
@@ -835,29 +827,45 @@ class MostPlayed(SmartPlaylist):
self._title = _("Most Played")
self.props.query = """
SELECT
- rdf:type(?song)
- tracker:id(?song) AS ?id
- ?song AS ?tracker_urn
- nie:title(?song) AS ?title
- nie:url(?song) AS ?url
- nie:title(?song) AS ?title
- nmm:artistName(nmm:performer(?song)) AS ?artist
- nie:title(nmm:musicAlbum(?song)) AS ?album
- nfo:duration(?song) AS ?duration
- nie:usageCounter(?song) AS ?play_count
- nmm:trackNumber(?song) AS ?track_number
- nmm:setNumber(nmm:musicAlbumDisc(?song)) AS ?album_disc_number
- ?tag AS ?favourite
+ %(media_type)s AS ?type
+ ?song AS ?id
+ ?title
+ ?url
+ ?artist
+ ?album
+ ?duration
+ ?trackNumber
+ ?albumDiscNumber
+ ?playCount
+ ?tag AS ?favorite
WHERE {
- ?song a nmm:MusicPiece ;
- nie:usageCounter ?count .
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT
+ ?song
+ nie:title(?song) AS ?title
+ nie:isStoredAs(?song) AS ?url
+ nmm:artistName(nmm:artist(?song)) AS ?artist
+ nie:title(nmm:musicAlbum(?song)) AS ?album
+ nfo:duration(?song) AS ?duration
+ nmm:trackNumber(?song) AS ?trackNumber
+ nmm:setNumber(nmm:musicAlbumDisc(?song))
+ AS ?albumDiscNumber
+ WHERE {
+ ?song a nmm:MusicPiece .
+ %(location_filter)s
+ }
+ }
+ }
+ ?song nie:usageCounter ?playCount
OPTIONAL { ?song nao:hasTag ?tag .
FILTER (?tag = nao:predefined-tag-favorite) }
- %(location_filter)s
}
- ORDER BY DESC(?count) LIMIT 50
+ ORDER BY DESC(?playCount) LIMIT 50
""".replace('\n', ' ').strip() % {
- "location_filter": self._tracker_wrapper.location_filter()
+ "media_type": int(Grl.MediaType.AUDIO),
+ "location_filter": self._tracker_wrapper.location_filter(),
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
}
@@ -872,28 +880,44 @@ class NeverPlayed(SmartPlaylist):
self._title = _("Never Played")
self.props.query = """
SELECT
- rdf:type(?song)
- tracker:id(?song) AS ?id
- ?song AS ?tracker_urn
- nie:title(?song) AS ?title
- nie:url(?song) AS ?url
- nie:title(?song) AS ?title
- nmm:artistName(nmm:performer(?song)) AS ?artist
- nie:title(nmm:musicAlbum(?song)) AS ?album
- nfo:duration(?song) AS ?duration
- nie:usageCounter(?song) AS ?play_count
- nmm:trackNumber(?song) AS ?track_number
- nmm:setNumber(nmm:musicAlbumDisc(?song)) AS ?album_disc_number
- ?tag AS ?favourite
+ %(media_type)s AS ?type
+ ?song AS ?id
+ ?title
+ ?url
+ ?artist
+ ?album
+ ?duration
+ ?trackNumber
+ ?albumDiscNumber
+ nie:usageCounter(?song) AS ?playCount
+ ?tag AS ?favorite
WHERE {
- ?song a nmm:MusicPiece ;
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT
+ ?song
+ nie:title(?song) AS ?title
+ nie:isStoredAs(?song) AS ?url
+ nmm:artistName(nmm:artist(?song)) AS ?artist
+ nie:title(nmm:musicAlbum(?song)) AS ?album
+ nfo:duration(?song) AS ?duration
+ nmm:trackNumber(?song) AS ?trackNumber
+ nmm:setNumber(nmm:musicAlbumDisc(?song))
+ AS ?albumDiscNumber
+ WHERE {
+ ?song a nmm:MusicPiece .
+ %(location_filter)s
+ }
+ }
+ }
FILTER ( NOT EXISTS { ?song nie:usageCounter ?count .} )
OPTIONAL { ?song nao:hasTag ?tag .
FILTER (?tag = nao:predefined-tag-favorite) }
- %(location_filter)s
} ORDER BY nfo:fileLastAccessed(?song) LIMIT 50
""".replace('\n', ' ').strip() % {
- "location_filter": self._tracker_wrapper.location_filter()
+ "media_type": int(Grl.MediaType.AUDIO),
+ "location_filter": self._tracker_wrapper.location_filter(),
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
}
@@ -915,31 +939,47 @@ class RecentlyPlayed(SmartPlaylist):
time.gmtime(time.time() - seconds_difference))
self.props.query = """
SELECT
- rdf:type(?song)
- tracker:id(?song) AS ?id
- ?song AS ?tracker_urn
- nie:title(?song) AS ?title
- nie:url(?song) AS ?url
- nie:title(?song) AS ?title
- nmm:artistName(nmm:performer(?song)) AS ?artist
- nie:title(nmm:musicAlbum(?song)) AS ?album
- nfo:duration(?song) AS ?duration
- nie:usageCounter(?song) AS ?play_count
- nmm:trackNumber(?song) AS ?track_number
- nmm:setNumber(nmm:musicAlbumDisc(?song)) AS ?album_disc_number
- ?tag AS ?favourite
+ %(media_type)s AS ?type
+ ?song AS ?id
+ ?title
+ ?url
+ ?artist
+ ?album
+ ?duration
+ ?trackNumber
+ ?albumDiscNumber
+ nie:usageCounter(?song) AS ?playCount
+ ?tag AS ?favorite
WHERE {
- ?song a nmm:MusicPiece ;
- nie:contentAccessed ?last_played .
- FILTER ( ?last_played > '%(compare_date)s'^^xsd:dateTime
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT
+ ?song
+ nie:title(?song) AS ?title
+ nie:isStoredAs(?song) AS ?url
+ nmm:artistName(nmm:artist(?song)) AS ?artist
+ nie:title(nmm:musicAlbum(?song)) AS ?album
+ nfo:duration(?song) AS ?duration
+ nmm:trackNumber(?song) AS ?trackNumber
+ nmm:setNumber(nmm:musicAlbumDisc(?song))
+ AS ?albumDiscNumber
+ WHERE {
+ ?song a nmm:MusicPiece .
+ %(location_filter)s
+ }
+ }
+ }
+ ?song nie:contentAccessed ?lastPlayed .
+ FILTER ( ?lastPlayed > '%(compare_date)s'^^xsd:dateTime
&& EXISTS { ?song nie:usageCounter ?count .} )
OPTIONAL { ?song nao:hasTag ?tag .
FILTER (?tag = nao:predefined-tag-favorite) }
- %(location_filter)s
- } ORDER BY DESC(?last_played) LIMIT 50
+ } ORDER BY DESC(?lastPlayed) LIMIT 50
""".replace('\n', ' ').strip() % {
+ "media_type": int(Grl.MediaType.AUDIO),
'compare_date': compare_date,
- "location_filter": self._tracker_wrapper.location_filter()
+ "location_filter": self._tracker_wrapper.location_filter(),
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
}
@@ -961,30 +1001,47 @@ class RecentlyAdded(SmartPlaylist):
time.gmtime(time.time() - seconds_difference))
self.props.query = """
SELECT
- rdf:type(?song)
- tracker:id(?song) AS ?id
- ?song AS ?tracker_urn
- nie:title(?song) AS ?title
- nie:url(?song) AS ?url
- nie:title(?song) AS ?title
- nmm:artistName(nmm:performer(?song)) AS ?artist
- nie:title(nmm:musicAlbum(?song)) AS ?album
- nfo:duration(?song) AS ?duration
- nie:usageCounter(?song) AS ?play_count
- nmm:trackNumber(?song) AS ?track_number
- nmm:setNumber(nmm:musicAlbumDisc(?song)) AS ?album_disc_number
- ?tag AS ?favourite
+ %(media_type)s AS ?type
+ ?song AS ?id
+ ?title
+ ?url
+ ?artist
+ ?album
+ ?duration
+ ?trackNumber
+ ?albumDiscNumber
+ nie:usageCounter(?song) AS ?playCount
+ ?tag AS ?favorite
WHERE {
- ?song a nmm:MusicPiece ;
- tracker:added ?added .
- FILTER ( tracker:added(?song) > '%(compare_date)s'^^xsd:dateTime )
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT
+ ?song
+ nie:title(?song) AS ?title
+ nie:isStoredAs(?song) AS ?url
+ nmm:artistName(nmm:artist(?song)) AS ?artist
+ nie:title(nmm:musicAlbum(?song)) AS ?album
+ nfo:duration(?song) AS ?duration
+ nmm:trackNumber(?song) AS ?trackNumber
+ nmm:setNumber(nmm:musicAlbumDisc(?song))
+ AS ?albumDiscNumber
+ ?added
+ WHERE {
+ ?song a nmm:MusicPiece ;
+ nrl:added ?added .
+ %(location_filter)s
+ FILTER ( ?added > '%(compare_date)s'^^xsd:dateTime )
+ }
+ }
+ }
OPTIONAL { ?song nao:hasTag ?tag .
FILTER (?tag = nao:predefined-tag-favorite) }
- %(location_filter)s
- } ORDER BY DESC(tracker:added(?song)) LIMIT 50
+ } ORDER BY DESC(nrl:added(?song)) LIMIT 50
""".replace('\n', ' ').strip() % {
+ "media_type": int(Grl.MediaType.AUDIO),
'compare_date': compare_date,
- "location_filter": self._tracker_wrapper.location_filter()
+ "location_filter": self._tracker_wrapper.location_filter(),
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
}
@@ -999,28 +1056,41 @@ class Favorites(SmartPlaylist):
self._title = _("Favorite Songs")
self.props.query = """
SELECT
- rdf:type(?song)
- tracker:id(?song) AS ?id
- ?song AS ?tracker_urn
- nie:title(?song) AS ?title
- nie:url(?song) AS ?url
- nie:title(?song) AS ?title
- nmm:artistName(nmm:performer(?song)) AS ?artist
- nie:title(nmm:musicAlbum(?song)) AS ?album
- nfo:duration(?song) AS ?duration
- nie:usageCounter(?song) AS ?play_count
- nmm:trackNumber(?song) AS ?track_number
- nmm:setNumber(nmm:musicAlbumDisc(?song)) AS ?album_disc_number
- nao:predefined-tag-favorite AS ?favourite
+ %(media_type)s AS ?type
+ ?song AS ?id
+ ?title
+ ?url
+ ?artist
+ ?album
+ ?duration
+ ?trackNumber
+ ?albumDiscNumber
+ nie:usageCounter(?song) AS ?playCount
+ nao:predefined-tag-favorite AS ?favorite
WHERE {
- ?song a nmm:MusicPiece ;
- nie:isStoredAs ?as ;
- nao:hasTag nao:predefined-tag-favorite .
- ?as nie:url ?url .
- OPTIONAL { ?song nao:hasTag ?tag .
- FILTER (?tag = nao:predefined-tag-favorite) }
- %(location_filter)s
- } ORDER BY DESC(tracker:added(?song))
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT
+ ?song
+ nie:title(?song) AS ?title
+ nie:isStoredAs(?song) AS ?url
+ nmm:artistName(nmm:artist(?song)) AS ?artist
+ nie:title(nmm:musicAlbum(?song)) AS ?album
+ nfo:duration(?song) AS ?duration
+ nmm:trackNumber(?song) AS ?trackNumber
+ nmm:setNumber(nmm:musicAlbumDisc(?song))
+ AS ?albumDiscNumber
+ nrl:added(?song) AS ?added
+ WHERE {
+ ?song a nmm:MusicPiece .
+ %(location_filter)s
+ }
+ }
+ }
+ ?song nao:hasTag nao:predefined-tag-favorite .
+ } ORDER BY DESC(?added)
""".replace('\n', ' ').strip() % {
- "location_filter": self._tracker_wrapper.location_filter()
+ "media_type": int(Grl.MediaType.AUDIO),
+ "location_filter": self._tracker_wrapper.location_filter(),
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
}
diff --git a/gnomemusic/grilowrappers/grltrackerwrapper.py b/gnomemusic/grilowrappers/grltrackerwrapper.py
index 31d6d681..96b19897 100644
--- a/gnomemusic/grilowrappers/grltrackerwrapper.py
+++ b/gnomemusic/grilowrappers/grltrackerwrapper.py
@@ -23,14 +23,15 @@
# delete this exception statement from your version.
import gi
-gi.require_versions({"Gfm": "0.1", "Grl": "0.3", 'Tracker': "2.0"})
-from gi.repository import Gfm, Grl, GLib, GObject, Tracker
+gi.require_versions({"Gfm": "0.1", "Grl": "0.3", "Tracker": "3.0"})
+from gi.repository import Gfm, Gio, Grl, GLib, GObject, Tracker
from gnomemusic.corealbum import CoreAlbum
from gnomemusic.coreartist import CoreArtist
from gnomemusic.coredisc import CoreDisc
from gnomemusic.coresong import CoreSong
from gnomemusic.grilowrappers.grltrackerplaylists import GrlTrackerPlaylists
+from gnomemusic.storeart import StoreArt
class GrlTrackerWrapper(GObject.GObject):
@@ -39,76 +40,95 @@ class GrlTrackerWrapper(GObject.GObject):
_SPLICE_SIZE = 100
- METADATA_KEYS = [
- Grl.METADATA_KEY_ALBUM,
+ _METADATA_ALBUM_CHANGED_KEYS = [
+ Grl.METADATA_KEY_ARTIST,
Grl.METADATA_KEY_ALBUM_ARTIST,
+ Grl.METADATA_KEY_COMPOSER,
+ Grl.METADATA_KEY_CREATION_DATE,
+ Grl.METADATA_KEY_ID,
+ Grl.METADATA_KEY_TITLE,
+ Grl.METADATA_KEY_URL
+ ]
+
+ _METADATA_SONG_FILL_KEYS = [
+ Grl.METADATA_KEY_ALBUM,
+ Grl.METADATA_KEY_ALBUM_DISC_NUMBER,
+ Grl.METADATA_KEY_ARTIST,
+ Grl.METADATA_KEY_DURATION,
+ Grl.METADATA_KEY_FAVOURITE,
+ Grl.METADATA_KEY_ID,
+ Grl.METADATA_KEY_PLAY_COUNT,
+ Grl.METADATA_KEY_TITLE,
+ Grl.METADATA_KEY_TRACK_NUMBER,
+ Grl.METADATA_KEY_URL
+ ]
+
+ _METADATA_SONG_MEDIA_QUERY_KEYS = [
+ Grl.METADATA_KEY_ALBUM,
Grl.METADATA_KEY_ALBUM_DISC_NUMBER,
Grl.METADATA_KEY_ARTIST,
- Grl.METADATA_KEY_CREATION_DATE,
- Grl.METADATA_KEY_COMPOSER,
Grl.METADATA_KEY_DURATION,
Grl.METADATA_KEY_FAVOURITE,
Grl.METADATA_KEY_ID,
Grl.METADATA_KEY_PLAY_COUNT,
- Grl.METADATA_KEY_THUMBNAIL,
Grl.METADATA_KEY_TITLE,
Grl.METADATA_KEY_TRACK_NUMBER,
Grl.METADATA_KEY_URL
]
- METADATA_THUMBNAIL_KEYS = [
+ _METADATA_THUMBNAIL_KEYS = [
Grl.METADATA_KEY_ID,
- Grl.METADATA_KEY_THUMBNAIL,
+ Grl.METADATA_KEY_THUMBNAIL
]
- def __init__(
- self, source, coremodel, application, grilo, tracker_wrapper):
+ def __init__(self, source, application, tracker_wrapper):
"""Initialize the Tracker wrapper
:param Grl.TrackerSource source: The Tracker source to wrap
- :param CoreModel coremodel: CoreModel instance to use models
- from
:param Application application: Application instance
- :param CoreGrilo grilo: The CoreGrilo instance
:param TrackerWrapper tracker_wrapper: The TrackerWrapper instance
"""
super().__init__()
self._application = application
- self._coremodel = coremodel
- self._coreselection = application.props.coreselection
- self._grilo = grilo
- self._source = None
+ coremodel = application.props.coremodel
self._log = application.props.log
- self._model = self._coremodel.props.songs
- self._albums_model = self._coremodel.props.albums
+ self._songs_model = Gio.ListStore.new(CoreSong)
+ coremodel.props.songs_proxy.append(self._songs_model)
+ self._source = None
+ self._albums_model = Gio.ListStore.new(CoreAlbum)
+ coremodel.props.albums_proxy.append(self._albums_model)
self._album_ids = {}
- self._artists_model = self._coremodel.props.artists
+ self._artists_model = Gio.ListStore.new(CoreArtist)
+ coremodel.props.artists_proxy.append(self._artists_model)
self._artist_ids = {}
self._hash = {}
- self._song_search_proxy = self._coremodel.props.songs_search_proxy
- self._album_search_model = self._coremodel.props.albums_search
- self._artist_search_model = self._coremodel.props.artists_search
+ self._song_search_proxy = coremodel.props.songs_search_proxy
+ self._album_search_model = coremodel.props.albums_search
+ self._artist_search_model = coremodel.props.artists_search
self._batch_changed_media_ids = {}
self._content_changed_timeout = None
self._tracker_playlists = None
self._tracker_wrapper = tracker_wrapper
- self._window = application.props.window
+ self._notificationmanager = application.props.notificationmanager
- self._song_search_tracker = Gfm.FilterListModel.new(self._model)
+ self._song_search_tracker = Gfm.FilterListModel.new(self._songs_model)
self._song_search_tracker.set_filter_func(lambda a: False)
self._song_search_proxy.append(self._song_search_tracker)
self._fast_options = Grl.OperationOptions()
self._fast_options.set_resolution_flags(
Grl.ResolutionFlags.FAST_ONLY | Grl.ResolutionFlags.IDLE_RELAY)
+ self._full_options = Grl.OperationOptions()
+ self._full_options.set_resolution_flags(
+ Grl.ResolutionFlags.FULL | Grl.ResolutionFlags.IDLE_RELAY)
self._content_changed_id = None
self.props.source = source
- self._initial_songs_fill(self.props.source)
- self._initial_albums_fill(self.props.source)
- self._initial_artists_fill(self.props.source)
+ self._initial_songs_fill()
+ self._initial_albums_fill()
+ self._initial_artists_fill()
@GObject.Property(type=Grl.Source, default=None)
def source(self):
@@ -176,24 +196,37 @@ class GrlTrackerWrapper(GObject.GObject):
query = """
SELECT
- rdf:type(?album)
- tracker:id(?album) AS ?id
- nie:title(?album) AS ?title
- ?composer AS ?composer
- ?album_artist AS ?album_artist
- nmm:artistName(?performer) AS ?artist
- nie:url(?song) AS ?url
- YEAR(MAX(nie:contentCreated(?song))) AS ?creation_date
+ ?type ?id ?title ?composer ?albumArtist
+ ?artist ?url ?creationDate
WHERE {
- ?album a nmm:MusicAlbum .
- ?song a nmm:MusicPiece ;
- nmm:musicAlbum ?album ;
- nmm:performer ?performer .
- OPTIONAL { ?song nmm:composer/nmm:artistName ?composer . }
- OPTIONAL { ?album nmm:albumArtist/nmm:artistName ?album_artist . }
- %(location_filter)s
- } GROUP BY ?album
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT
+ %(media_type)s AS ?type
+ ?album AS ?id
+ nie:title(?album) AS ?title
+ ?composer
+ ?albumArtist
+ nmm:artistName(?artist) AS ?artist
+ nie:isStoredAs(?song) AS ?url
+ YEAR(MAX(nie:contentCreated(?song))) AS ?creationDate
+ WHERE {
+ ?album a nmm:MusicAlbum .
+ ?song a nmm:MusicPiece ;
+ nmm:musicAlbum ?album ;
+ nmm:artist ?artist .
+ OPTIONAL { ?song nmm:composer/
+ nmm:artistName ?composer . }
+ OPTIONAL { ?album nmm:albumArtist/
+ nmm:artistName ?albumArtist . }
+ %(location_filter)s
+ } GROUP BY ?album
+ }
+ }
+ }
""".replace('\n', ' ').strip() % {
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
+ "media_type": int(Grl.MediaType.CONTAINER),
'location_filter': self._tracker_wrapper.location_filter()
}
@@ -224,40 +257,54 @@ class GrlTrackerWrapper(GObject.GObject):
if media.get_id() in self._album_ids.keys():
album = self._album_ids[media.get_id()]
else:
- album = CoreAlbum(media, self._coremodel)
+ album = CoreAlbum(self._application, media)
album_ids[media.get_id()] = album
- options = self._fast_options.copy()
-
self.props.source.query(
- query, self.METADATA_KEYS, options, check_album_cb)
+ query, self._METADATA_ALBUM_CHANGED_KEYS, self._fast_options,
+ check_album_cb)
def _check_artist_change(self):
artist_ids = {}
query = """
- SELECT
- rdf:type(?artist)
- COALESCE(tracker:id(?album_artist), tracker:id(?artist)) AS ?id
- ?artist_bind AS ?artist
+ SELECT ?type ?id ?artist
WHERE {
- ?song a nmm:MusicPiece;
- nmm:musicAlbum ?album;
- nmm:performer ?artist .
- OPTIONAL {
- ?album a nmm:MusicAlbum;
- nmm:albumArtist ?album_artist .
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT
+ %(media_type)s AS ?type
+ (COALESCE(?album_artist, ?artist) AS ?id)
+ ?artist_bind AS ?albumArtist
+ WHERE {
+ ?song a nmm:MusicPiece;
+ nmm:musicAlbum ?album;
+ nmm:artist ?artist .
+ OPTIONAL {
+ ?album a nmm:MusicAlbum;
+ nmm:albumArtist ?album_artist .
+ }
+ BIND(COALESCE(nmm:artistName(?album_artist),
+ nmm:artistName(?artist)) AS ?artist_bind)
+ %(location_filter)s
+ }
+ GROUP BY ?artist_bind
+ }
}
- BIND(COALESCE(nmm:artistName(?album_artist),
- nmm:artistName(?artist)) AS ?artist_bind)
- %(location_filter)s
}
- GROUP BY ?artist_bind
""".replace('\n', ' ').strip() % {
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
+ "media_type": int(Grl.MediaType.CONTAINER),
'location_filter': self._tracker_wrapper.location_filter()
}
+ metadata_keys = [
+ Grl.METADATA_KEY_ALBUM_ARTIST,
+ Grl.METADATA_KEY_ARTIST,
+ Grl.METADATA_KEY_ID
+ ]
+
def check_artist_cb(source, op_id, media, remaining, error):
if error:
self._log.warning("Error: {}".format(error))
@@ -284,14 +331,12 @@ class GrlTrackerWrapper(GObject.GObject):
if media.get_id() in self._artist_ids.keys():
artist = self._artist_ids[media.get_id()]
else:
- artist = CoreArtist(media, self._coremodel)
+ artist = CoreArtist(self._application, media)
artist_ids[media.get_id()] = artist
- options = self._fast_options.copy()
-
self.props.source.query(
- query, self.METADATA_KEYS, options, check_artist_cb)
+ query, metadata_keys, self._fast_options, check_artist_cb)
def _remove_media(self, media_ids):
for media_id in media_ids:
@@ -301,43 +346,55 @@ class GrlTrackerWrapper(GObject.GObject):
self._log.warning("Removal KeyError.")
return
- for idx, coresong_model in enumerate(self._model):
+ for idx, coresong_model in enumerate(self._songs_model):
if coresong_model is coresong:
self._log.debug("Removing: {}, {}".format(
coresong.props.media.get_id(), coresong.props.title))
- self._model.remove(idx)
+ self._songs_model.remove(idx)
break
def _song_media_query(self, media_ids):
media_ids = str(media_ids)[1:-1]
query = """
- SELECT DISTINCT
- rdf:type(?song)
- ?song AS ?tracker_urn
- nie:title(?song) AS ?title
- tracker:id(?song) AS ?id
- ?song
- nie:url(?song) AS ?url
- nie:title(?song) AS ?title
- nmm:artistName(nmm:performer(?song)) AS ?artist
- nie:title(nmm:musicAlbum(?song)) AS ?album
- nfo:duration(?song) AS ?duration
- nie:usageCounter(?song) AS ?play_count
- nmm:trackNumber(?song) AS ?track_number
- nmm:setNumber(nmm:musicAlbumDisc(?song)) AS ?album_disc_number
- ?tag AS ?favourite
+ SELECT
+ ?type ?urn ?title ?id ?url
+ ?artist ?album
+ ?duration ?trackNumber
+ ?albumDiscNumber
+ nie:usageCounter(?urn) AS ?playCount
+ ?tag AS ?favorite
WHERE {
- ?song a nmm:MusicPiece .
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT DISTINCT
+ %(media_type)s AS ?type
+ ?song AS ?urn
+ nie:title(?song) AS ?title
+ ?song AS ?id
+ nie:isStoredAs(?song) AS ?url
+ nmm:artistName(nmm:artist(?song)) AS ?artist
+ nie:title(nmm:musicAlbum(?song)) AS ?album
+ nfo:duration(?song) AS ?duration
+ nmm:trackNumber(?song) AS ?trackNumber
+ nmm:setNumber(nmm:musicAlbumDisc(?song))
+ AS ?albumDiscNumber
+ WHERE {
+ ?song a nmm:MusicPiece .
+ FILTER ( ?song in ( %(media_ids)s ) )
+ %(location_filter)s
+ }
+ }
+ }
OPTIONAL {
- ?song nao:hasTag ?tag .
+ ?urn nao:hasTag ?tag .
FILTER (?tag = nao:predefined-tag-favorite)
}
- FILTER ( tracker:id(?song) in ( %(media_ids)s ) )
- %(location_filter)s
}
""".replace('\n', ' ').strip() % {
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
+ "media_type": int(Grl.MediaType.AUDIO),
'location_filter': self._tracker_wrapper.location_filter(),
'media_ids': media_ids
}
@@ -355,104 +412,117 @@ class GrlTrackerWrapper(GObject.GObject):
self._remove_media(media_ids)
return
- if media.get_id() not in self._hash:
+ media_id = media.get_id()
+ if media_id not in self._hash:
+ song = CoreSong(self._application, media)
+ self._songs_model.append(song)
+ self._hash[media_id] = song
self._log.debug(
- "Media {} not in hash".format(media.get_id()))
-
- song = CoreSong(media, self._coreselection, self._grilo)
- self._model.append(song)
- self._hash[media.get_id()] = song
+ "Adding: {}, {}".format(media_id, song.props.title))
else:
- self._hash[media.get_id()].update(media)
-
- media_ids.remove(media.get_id())
+ self._hash[media_id].update(media)
- options = self._fast_options.copy()
+ media_ids.remove(media_id)
self.props.source.query(
- self._song_media_query(media_ids), self.METADATA_KEYS,
- options, _update_changed_media)
+ self._song_media_query(media_ids),
+ self._METADATA_SONG_MEDIA_QUERY_KEYS, self._fast_options,
+ _update_changed_media)
- def _initial_songs_fill(self, source):
- self._window.notifications_popup.push_loading()
+ def _initial_songs_fill(self):
+ self._notificationmanager.push_loading()
songs_added = []
def _add_to_model(source, op_id, media, remaining, error):
if error:
self._log.warning("Error: {}".format(error))
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
if not media:
- self._model.splice(self._model.get_n_items(), 0, songs_added)
- self._window.notifications_popup.pop_loading()
+ self._songs_model.splice(
+ self._songs_model.get_n_items(), 0, songs_added)
+ self._notificationmanager.pop_loading()
# Initialize the playlists subwrapper after the initial
# songs model fill, the playlists expect a filled songs
# hashtable.
self._tracker_playlists = GrlTrackerPlaylists(
- self.props.source, self._coremodel, self._application,
- self._grilo, self._tracker_wrapper, self._hash)
+ self.props.source, self._application,
+ self._tracker_wrapper, self._hash)
return
- song = CoreSong(media, self._coreselection, self._grilo)
+ song = CoreSong(self._application, media)
songs_added.append(song)
self._hash[media.get_id()] = song
if len(songs_added) == self._SPLICE_SIZE:
- self._model.splice(self._model.get_n_items(), 0, songs_added)
+ self._songs_model.splice(
+ self._songs_model.get_n_items(), 0, songs_added)
songs_added.clear()
query = """
SELECT
- rdf:type(?song)
- ?song AS ?tracker_urn
- nie:title(?song) AS ?title
- tracker:id(?song) AS ?id
- ?song
- nie:url(?song) AS ?url
- nie:title(?song) AS ?title
- nmm:artistName(nmm:performer(?song)) AS ?artist
- nie:title(nmm:musicAlbum(?song)) AS ?album
- nfo:duration(?song) AS ?duration
- nie:usageCounter(?song) AS ?play_count
- nmm:trackNumber(?song) AS ?track_number
- nmm:setNumber(nmm:musicAlbumDisc(?song)) AS ?album_disc_number
- ?tag AS ?favourite
+ ?type ?urn ?title ?id ?url
+ ?artist ?album
+ ?duration ?trackNumber
+ ?albumDiscNumber
+ nie:usageCounter(?urn) AS ?playCount
+ ?tag AS ?favorite
WHERE {
- ?song a nmm:MusicPiece .
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT
+ %(media_type)s AS ?type
+ ?song AS ?urn
+ nie:title(?song) AS ?title
+ ?song AS ?id
+ nie:isStoredAs(?song) AS ?url
+ nmm:artistName(nmm:artist(?song)) AS ?artist
+ nie:title(nmm:musicAlbum(?song)) AS ?album
+ nfo:duration(?song) AS ?duration
+ nmm:trackNumber(?song) AS ?trackNumber
+ nmm:setNumber(nmm:musicAlbumDisc(?song))
+ AS ?albumDiscNumber
+ WHERE {
+ ?song a nmm:MusicPiece .
+ %(location_filter)s
+ }
+ ORDER BY ?title
+ }
+ }
OPTIONAL {
- ?song nao:hasTag ?tag .
+ ?urn nao:hasTag ?tag .
FILTER (?tag = nao:predefined-tag-favorite)
}
- %(location_filter)s
}
- ORDER BY ?title
""".replace('\n', ' ').strip() % {
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
+ "media_type": int(Grl.MediaType.AUDIO),
'location_filter': self._tracker_wrapper.location_filter()
}
- options = self._fast_options.copy()
self.props.source.query(
- query, self.METADATA_KEYS, options, _add_to_model)
+ query, self._METADATA_SONG_FILL_KEYS, self._fast_options,
+ _add_to_model)
- def _initial_albums_fill(self, source):
- self._window.notifications_popup.push_loading()
+ def _initial_albums_fill(self):
+ self._notificationmanager.push_loading()
albums_added = []
def _add_to_albums_model(source, op_id, media, remaining, error):
if error:
self._log.warning("Error: {}".format(error))
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
if not media:
self._albums_model.splice(
self._albums_model.get_n_items(), 0, albums_added)
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
- album = CoreAlbum(media, self._coremodel)
+ album = CoreAlbum(self._application, media)
self._album_ids[media.get_id()] = album
albums_added.append(album)
if len(albums_added) == self._SPLICE_SIZE:
@@ -462,51 +532,65 @@ class GrlTrackerWrapper(GObject.GObject):
query = """
SELECT
- rdf:type(?album)
- tracker:id(?album) AS ?id
- nie:title(?album) AS ?title
- ?composer AS ?composer
- ?album_artist AS ?album_artist
- nmm:artistName(?performer) AS ?artist
- nie:url(?song) AS ?url
- YEAR(MAX(nie:contentCreated(?song))) AS ?creation_date
+ ?type ?id ?title ?composer ?albumArtist
+ ?artist ?url ?creationDate
WHERE
{
- ?album a nmm:MusicAlbum .
- ?song a nmm:MusicPiece ;
- nmm:musicAlbum ?album ;
- nmm:performer ?performer .
- OPTIONAL { ?song nmm:composer/nmm:artistName ?composer . }
- OPTIONAL { ?album nmm:albumArtist/nmm:artistName ?album_artist . }
- %(location_filter)s
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT
+ %(media_type)s AS ?type
+ ?album AS ?id
+ nie:title(?album) AS ?title
+ ?composer
+ ?albumArtist
+ nmm:artistName(?artist) AS ?artist
+ nie:isStoredAs(?song) AS ?url
+ YEAR(MAX(nie:contentCreated(?song))) AS ?creationDate
+ WHERE
+ {
+ ?album a nmm:MusicAlbum .
+ ?song a nmm:MusicPiece ;
+ nmm:musicAlbum ?album ;
+ nmm:artist ?artist .
+ OPTIONAL { ?song nmm:composer/
+ nmm:artistName ?composer . }
+ OPTIONAL { ?album nmm:albumArtist/
+ nmm:artistName ?albumArtist . }
+ %(location_filter)s
+ }
+ GROUP BY ?album
+ ORDER BY ?title ?albumArtist ?artist ?creationDate
+ }
+ }
}
- GROUP BY ?album
- ORDER BY ?title ?album_artist ?artist ?creation_date
""".replace('\n', ' ').strip() % {
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
+ "media_type": int(Grl.MediaType.CONTAINER),
'location_filter': self._tracker_wrapper.location_filter()
}
- options = self._fast_options.copy()
-
- source.query(query, self.METADATA_KEYS, options, _add_to_albums_model)
+ self.props.source.query(
+ query, self._METADATA_ALBUM_CHANGED_KEYS, self._fast_options,
+ _add_to_albums_model)
- def _initial_artists_fill(self, source):
- self._window.notifications_popup.push_loading()
+ def _initial_artists_fill(self):
+ self._notificationmanager.push_loading()
artists_added = []
def _add_to_artists_model(source, op_id, media, remaining, error):
if error:
self._log.warning("Error: {}".format(error))
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
if not media:
self._artists_model.splice(
self._artists_model.get_n_items(), 0, artists_added)
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
- artist = CoreArtist(media, self._coremodel)
+ artist = CoreArtist(self._application, media)
self._artist_ids[media.get_id()] = artist
artists_added.append(artist)
if len(artists_added) == self._SPLICE_SIZE:
@@ -515,32 +599,44 @@ class GrlTrackerWrapper(GObject.GObject):
artists_added.clear()
query = """
- SELECT
- rdf:type(?artist)
- COALESCE(tracker:id(?album_artist), tracker:id(?artist)) AS ?id
- ?artist_bind AS ?artist
+ SELECT ?type ?id ?albumArtist
WHERE {
- ?song a nmm:MusicPiece;
- nmm:musicAlbum ?album;
- nmm:performer ?artist .
- OPTIONAL {
- ?album a nmm:MusicAlbum;
- nmm:albumArtist ?album_artist .
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT
+ %(media_type)s AS ?type
+ (COALESCE(?album_artist, ?artist) AS ?id)
+ ?artist_bind AS ?albumArtist
+ WHERE {
+ ?song a nmm:MusicPiece;
+ nmm:musicAlbum ?album;
+ nmm:artist ?artist .
+ OPTIONAL {
+ ?album a nmm:MusicAlbum;
+ nmm:albumArtist ?album_artist .
+ }
+ BIND(COALESCE(nmm:artistName(?album_artist),
+ nmm:artistName(?artist)) AS ?artist_bind)
+ %(location_filter)s
+ }
+ GROUP BY ?artist_bind
+ ORDER BY ?artist_bind
+ }
}
- BIND(COALESCE(nmm:artistName(?album_artist),
- nmm:artistName(?artist)) AS ?artist_bind)
- %(location_filter)s
}
- GROUP BY ?artist_bind
- ORDER BY ?artist_bind
""".replace('\n', ' ').strip() % {
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
+ "media_type": int(Grl.MediaType.CONTAINER),
'location_filter': self._tracker_wrapper.location_filter()
}
- options = self._fast_options.copy()
+ metadata_keys = [
+ Grl.METADATA_KEY_ARTIST,
+ Grl.METADATA_KEY_ID
+ ]
- source.query(
- query, [Grl.METADATA_KEY_ARTIST], options, _add_to_artists_model)
+ self.props.source.query(
+ query, metadata_keys, self._fast_options, _add_to_artists_model)
def get_artist_albums(self, media, model):
"""Get all albums by an artist
@@ -548,29 +644,39 @@ class GrlTrackerWrapper(GObject.GObject):
:param Grl.Media media: The media with the artist id
:param Gfm.FilterListModel model: The model to fill
"""
- self._window.notifications_popup.push_loading()
+ self._notificationmanager.push_loading()
artist_id = media.get_id()
query = """
- SELECT DISTINCT
- rdf:type(?album)
- tracker:id(?album) AS ?id
- nie:title(?album) AS ?title
- nie:contentCreated(?song) AS ?date
+ SELECT
+ ?type ?id ?title ?creationDate
WHERE {
- ?album a nmm:MusicAlbum .
- OPTIONAL { ?album nmm:albumArtist ?album_artist . }
- ?song a nmm:MusicPiece;
- nmm:musicAlbum ?album;
- nmm:performer ?artist .
- FILTER ( tracker:id(?album_artist) = %(artist_id)s
- || tracker:id(?artist) = %(artist_id)s )
- %(location_filter)s
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT DISTINCT
+ %(media_type)s AS ?type
+ ?album AS ?id
+ nie:title(?album) AS ?title
+ nie:contentCreated(?song) AS ?creationDate
+ WHERE {
+ ?album a nmm:MusicAlbum .
+ OPTIONAL { ?album nmm:albumArtist ?album_artist . }
+ ?song a nmm:MusicPiece;
+ nmm:musicAlbum ?album;
+ nmm:artist ?artist .
+ FILTER ( ?album_artist = <%(artist_id)s>
+ || ?artist = <%(artist_id)s> )
+ %(location_filter)s
+ }
+ GROUP BY ?album
+ ORDER BY ?creationDate ?album
+ }
+ }
}
- GROUP BY ?album
- ORDER BY ?date ?album
""".replace('\n', ' ').strip() % {
- 'artist_id': int(artist_id),
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
+ "media_type": int(Grl.MediaType.CONTAINER),
+ "artist_id": artist_id,
'location_filter': self._tracker_wrapper.location_filter()
}
@@ -579,12 +685,12 @@ class GrlTrackerWrapper(GObject.GObject):
def query_cb(source, op_id, media, remaining, error):
if error:
self._log.warning("Error: {}".format(error))
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
if not media:
model.set_filter_func(albums_filter, albums)
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
albums.append(media)
@@ -596,9 +702,8 @@ class GrlTrackerWrapper(GObject.GObject):
return False
- options = self._fast_options.copy()
self.props.source.query(
- query, [Grl.METADATA_KEY_TITLE], options, query_cb)
+ query, [Grl.METADATA_KEY_TITLE], self._fast_options, query_cb)
def get_album_discs(self, media, disc_model):
"""Get all discs of an album
@@ -606,43 +711,54 @@ class GrlTrackerWrapper(GObject.GObject):
:param Grl.Media media: The media with the album id
:param Gfm.SortListModel disc_model: The model to fill
"""
- self._window.notifications_popup.push_loading()
+ self._notificationmanager.push_loading()
album_id = media.get_id()
query = """
- SELECT DISTINCT
- rdf:type(?song)
- tracker:id(?album) AS ?id
- nmm:setNumber(nmm:musicAlbumDisc(?song)) as ?album_disc_number
+ SELECT
+ ?type ?id ?albumDiscNumber
WHERE {
- ?song a nmm:MusicPiece;
- nmm:musicAlbum ?album .
- FILTER ( tracker:id(?album) = %(album_id)s )
- %(location_filter)s
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT DISTINCT
+ %(media_type)s AS ?type
+ ?album AS ?id
+ nmm:setNumber(nmm:musicAlbumDisc(?song))
+ AS ?albumDiscNumber
+ WHERE {
+ ?song a nmm:MusicPiece;
+ nmm:musicAlbum ?album .
+ FILTER ( ?album = <%(album_id)s> )
+ %(location_filter)s
+ }
+ ORDER BY ?albumDiscNumber
+ }
+ }
}
- ORDER BY ?album_disc_number
""".replace('\n', ' ').strip() % {
- 'album_id': int(album_id),
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
+ "media_type": int(Grl.MediaType.CONTAINER),
+ "album_id": album_id,
'location_filter': self._tracker_wrapper.location_filter()
}
def _disc_nr_cb(source, op_id, media, remaining, error):
if error:
self._log.warning("Error: {}".format(error))
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
if not media:
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
disc_nr = media.get_album_disc_number()
- coredisc = CoreDisc(media, disc_nr, self._coremodel)
+ coredisc = CoreDisc(self._application, media, disc_nr)
disc_model.append(coredisc)
- options = self._fast_options.copy()
self.props.source.query(
- query, [Grl.METADATA_KEY_ALBUM_DISC_NUMBER], options, _disc_nr_cb)
+ query, [Grl.METADATA_KEY_ALBUM_DISC_NUMBER], self._fast_options,
+ _disc_nr_cb)
def populate_album_disc_songs(self, media, disc_nr, callback):
# FIXME: Pass a model and fill it.
@@ -657,38 +773,69 @@ class GrlTrackerWrapper(GObject.GObject):
album_id = media.get_id()
query = """
- SELECT DISTINCT
- rdf:type(?song)
- ?song AS ?tracker_urn
- tracker:id(?song) AS ?id
- nie:url(?song) AS ?url
- nie:title(?song) AS ?title
- nmm:artistName(nmm:performer(?song)) AS ?artist
- nie:title(nmm:musicAlbum(?song)) AS ?album
- nfo:duration(?song) AS ?duration
- nmm:trackNumber(?song) AS ?track_number
- nmm:setNumber(nmm:musicAlbumDisc(?song)) AS ?album_disc_number
- ?tag AS ?favourite
- nie:usageCounter(?song) AS ?play_count
+ SELECT
+ ?type ?id ?url ?title
+ ?artist ?album
+ ?duration ?trackNumber ?albumDiscNumber
+ ?creationDate
+ nie:usageCounter(?id) AS ?playCount
+ ?tag AS ?favorite
WHERE {
- ?song a nmm:MusicPiece ;
- nmm:musicAlbum ?album .
- OPTIONAL { ?song nao:hasTag ?tag .
- FILTER (?tag = nao:predefined-tag-favorite) } .
- FILTER ( tracker:id(?album) = %(album_id)s
- && nmm:setNumber(nmm:musicAlbumDisc(?song)) = %(disc_nr)s
- )
- %(location_filter)s
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT DISTINCT
+ %(media_type)s AS ?type
+ ?song AS ?id
+ nie:isStoredAs(?song) AS ?url
+ nie:title(?song) AS ?title
+ nmm:artistName(nmm:artist(?song)) AS ?artist
+ nie:title(nmm:musicAlbum(?song)) AS ?album
+ nfo:duration(?song) AS ?duration
+ nmm:trackNumber(?song) AS ?trackNumber
+ nmm:setNumber(nmm:musicAlbumDisc(?song))
+ AS ?albumDiscNumber
+ YEAR(?date) AS ?creationDate
+ WHERE {
+ ?song a nmm:MusicPiece ;
+ nmm:musicAlbum ?album .
+ OPTIONAL { ?song nie:contentCreated ?date . }
+ FILTER (
+ ?album = <%(album_id)s> &&
+ nmm:setNumber(nmm:musicAlbumDisc(?song)) =
+ %(disc_nr)s
+ )
+ %(location_filter)s
+ }
+ ORDER BY ?trackNumber
+ }
+ }
+ OPTIONAL {
+ ?id nao:hasTag ?tag .
+ FILTER (?tag = nao:predefined-tag-favorite)
+ }
}
- ORDER BY ?track_number
""".replace('\n', ' ').strip() % {
+ "media_type": int(Grl.MediaType.AUDIO),
'album_id': album_id,
'disc_nr': disc_nr,
- 'location_filter': self._tracker_wrapper.location_filter()
+ 'location_filter': self._tracker_wrapper.location_filter(),
+ 'miner_fs_busname': self._tracker_wrapper.props.miner_fs_busname
}
- options = self._fast_options.copy()
- self.props.source.query(query, self.METADATA_KEYS, options, callback)
+ metadata_keys = [
+ Grl.METADATA_KEY_ALBUM,
+ Grl.METADATA_KEY_ALBUM_DISC_NUMBER,
+ Grl.METADATA_KEY_ARTIST,
+ Grl.METADATA_KEY_DURATION,
+ Grl.METADATA_KEY_FAVOURITE,
+ Grl.METADATA_KEY_ID,
+ Grl.METADATA_KEY_PLAY_COUNT,
+ Grl.METADATA_KEY_TITLE,
+ Grl.METADATA_KEY_URL
+ ]
+
+ self.props.source.query(
+ query, metadata_keys, self._fast_options, callback)
def search(self, text):
# FIXME: Searches are limited to not bog down the UI with
@@ -701,36 +848,55 @@ class GrlTrackerWrapper(GObject.GObject):
GLib.utf8_casefold(text, -1), -1, GLib.NormalizeMode.NFKD))
# Artist search
- self._window.notifications_popup.push_loading()
+ self._notificationmanager.push_loading()
query = """
- SELECT DISTINCT
- rdf:type(?artist)
- tracker:id(?artist) AS ?id
+ SELECT
+ ?type ?id
WHERE {
- ?song a nmm:MusicPiece ;
- nmm:musicAlbum ?album ;
- nmm:performer ?artist .
- BIND(tracker:normalize(
- nmm:artistName(nmm:albumArtist(?album)), 'nfkd') AS ?match1) .
- BIND(tracker:normalize(
- nmm:artistName(nmm:performer(?song)), 'nfkd') AS ?match2) .
- BIND(tracker:normalize(nmm:composer(?song), 'nfkd') AS ?match4) .
- FILTER (
- CONTAINS(tracker:case-fold(
- tracker:unaccent(?match1)), "%(name)s")
- || CONTAINS(tracker:case-fold(?match1), "%(name)s")
- || CONTAINS(tracker:case-fold(
- tracker:unaccent(?match2)), "%(name)s")
- || CONTAINS(tracker:case-fold(?match2), "%(name)s")
- || CONTAINS(tracker:case-fold(
- tracker:unaccent(?match4)), "%(name)s")
- || CONTAINS(tracker:case-fold(?match4), "%(name)s")
- )
- %(location_filter)s
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT DISTINCT
+ %(media_type)s AS ?type
+ COALESCE(?album_artist, ?artist) AS ?id
+ WHERE {
+ ?song a nmm:MusicPiece ;
+ nmm:musicAlbum ?album ;
+ nmm:artist ?artist .
+ OPTIONAL {
+ ?album a nmm:MusicAlbum ;
+ nmm:albumArtist ?album_artist .
+ }
+ BIND(COALESCE(nmm:artistName(?album_artist),
+ nmm:artistName(?artist)) AS ?artist_bind)
+ BIND(tracker:normalize(nmm:artistName(
+ nmm:albumArtist(?artist_bind)), 'nfkd')
+ AS ?match1) .
+ BIND(tracker:normalize(
+ nmm:artistName(nmm:artist(?song)), 'nfkd')
+ AS ?match2) .
+ BIND(tracker:normalize(nmm:composer(?song), 'nfkd')
+ AS ?match4) .
+ FILTER (
+ CONTAINS(tracker:case-fold(
+ tracker:unaccent(?match1)), "%(name)s")
+ || CONTAINS(tracker:case-fold(?match1), "%(name)s")
+ || CONTAINS(tracker:case-fold(
+ tracker:unaccent(?match2)), "%(name)s")
+ || CONTAINS(tracker:case-fold(?match2), "%(name)s")
+ || CONTAINS(tracker:case-fold(
+ tracker:unaccent(?match4)), "%(name)s")
+ || CONTAINS(tracker:case-fold(?match4), "%(name)s")
+ )
+ %(location_filter)s
+ }
+ LIMIT 50
+ }
+ }
}
- LIMIT 50
""".replace('\n', ' ').strip() % {
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
+ "media_type": int(Grl.MediaType.AUDIO),
'location_filter': self._tracker_wrapper.location_filter(),
'name': term
}
@@ -743,49 +909,61 @@ class GrlTrackerWrapper(GObject.GObject):
def artist_search_cb(source, op_id, media, remaining, error):
if error:
self._log.warning("Error: {}".format(error))
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
if not media:
self._artist_search_model.set_filter_func(artist_filter)
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
artist_filter_ids.append(media.get_id())
- options = self._fast_options.copy()
self.props.source.query(
- query, self.METADATA_KEYS, options, artist_search_cb)
+ query, [Grl.METADATA_KEY_ID], self._fast_options, artist_search_cb)
# Album search
- self._window.notifications_popup.push_loading()
+ self._notificationmanager.push_loading()
query = """
- SELECT DISTINCT
- rdf:type(nmm:musicAlbum(?song))
- tracker:id(nmm:musicAlbum(?song)) AS ?id
+ SELECT
+ ?type ?id
WHERE {
- ?song a nmm:MusicPiece .
- BIND(tracker:normalize(
- nie:title(nmm:musicAlbum(?song)), 'nfkd') AS ?match1) .
- BIND(tracker:normalize(
- nmm:artistName(nmm:performer(?song)), 'nfkd') AS ?match2) .
- BIND(tracker:normalize(nmm:composer(?song), 'nfkd') AS ?match4) .
- FILTER (
- CONTAINS(tracker:case-fold(
- tracker:unaccent(?match1)), "%(name)s")
- || CONTAINS(tracker:case-fold(?match1), "%(name)s")
- || CONTAINS(tracker:case-fold(
- tracker:unaccent(?match2)), "%(name)s")
- || CONTAINS(tracker:case-fold(?match2), "%(name)s")
- || CONTAINS(tracker:case-fold(
- tracker:unaccent(?match4)), "%(name)s")
- || CONTAINS(tracker:case-fold(?match4), "%(name)s")
- )
- %(location_filter)s
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT DISTINCT
+ %(media_type)s AS ?type
+ nmm:musicAlbum(?song) AS ?id
+ WHERE {
+ ?song a nmm:MusicPiece .
+ BIND(tracker:normalize(
+ nie:title(nmm:musicAlbum(?song)), 'nfkd')
+ AS ?match1) .
+ BIND(tracker:normalize(
+ nmm:artistName(nmm:artist(?song)), 'nfkd')
+ AS ?match2) .
+ BIND(tracker:normalize(nmm:composer(?song), 'nfkd')
+ AS ?match4) .
+ FILTER (
+ CONTAINS(tracker:case-fold(
+ tracker:unaccent(?match1)), "%(name)s")
+ || CONTAINS(tracker:case-fold(?match1), "%(name)s")
+ || CONTAINS(tracker:case-fold(
+ tracker:unaccent(?match2)), "%(name)s")
+ || CONTAINS(tracker:case-fold(?match2), "%(name)s")
+ || CONTAINS(tracker:case-fold(
+ tracker:unaccent(?match4)), "%(name)s")
+ || CONTAINS(tracker:case-fold(?match4), "%(name)s")
+ )
+ %(location_filter)s
+ }
+ LIMIT 50
+ }
+ }
}
- LIMIT 50
""".replace('\n', ' ').strip() % {
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
+ "media_type": int(Grl.MediaType.CONTAINER),
'location_filter': self._tracker_wrapper.location_filter(),
'name': term
}
@@ -798,55 +976,66 @@ class GrlTrackerWrapper(GObject.GObject):
def albums_search_cb(source, op_id, media, remaining, error):
if error:
self._log.warning("Error: {}".format(error))
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
if not media:
self._album_search_model.set_filter_func(album_filter)
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
album_filter_ids.append(media.get_id())
- options = self._fast_options.copy()
self.props.source.query(
- query, self.METADATA_KEYS, options, albums_search_cb)
+ query, [Grl.METADATA_KEY_ID], self._fast_options, albums_search_cb)
# Song search
- self._window.notifications_popup.push_loading()
+ self._notificationmanager.push_loading()
query = """
- SELECT DISTINCT
- rdf:type(?song)
- tracker:id(?song) AS ?id
+ SELECT
+ ?type ?id
WHERE {
- ?song a nmm:MusicPiece .
- BIND(tracker:normalize(
- nie:title(nmm:musicAlbum(?song)), 'nfkd') AS ?match1) .
- BIND(tracker:normalize(
- nmm:artistName(nmm:performer(?song)), 'nfkd') AS ?match2) .
- BIND(tracker:normalize(
- nie:title(?song), 'nfkd') AS ?match3) .
- BIND(
- tracker:normalize(nmm:composer(?song), 'nfkd') AS ?match4) .
- FILTER (
- CONTAINS(tracker:case-fold(
- tracker:unaccent(?match1)), "%(name)s")
- || CONTAINS(tracker:case-fold(?match1), "%(name)s")
- || CONTAINS(tracker:case-fold(
- tracker:unaccent(?match2)), "%(name)s")
- || CONTAINS(tracker:case-fold(?match2), "%(name)s")
- || CONTAINS(tracker:case-fold(
- tracker:unaccent(?match3)), "%(name)s")
- || CONTAINS(tracker:case-fold(?match3), "%(name)s")
- || CONTAINS(tracker:case-fold(
- tracker:unaccent(?match4)), "%(name)s")
- || CONTAINS(tracker:case-fold(?match4), "%(name)s")
- )
- %(location_filter)s
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT DISTINCT
+ %(media_type)s AS ?type
+ ?song AS ?id
+ WHERE {
+ ?song a nmm:MusicPiece .
+ BIND(tracker:normalize(
+ nie:title(nmm:musicAlbum(?song)), 'nfkd')
+ AS ?match1) .
+ BIND(tracker:normalize(
+ nmm:artistName(nmm:artist(?song)), 'nfkd')
+ AS ?match2) .
+ BIND(tracker:normalize(
+ nie:title(?song), 'nfkd') AS ?match3) .
+ BIND(tracker:normalize(nmm:composer(?song), 'nfkd')
+ AS ?match4) .
+ FILTER (
+ CONTAINS(tracker:case-fold(
+ tracker:unaccent(?match1)), "%(name)s")
+ || CONTAINS(tracker:case-fold(?match1), "%(name)s")
+ || CONTAINS(tracker:case-fold(
+ tracker:unaccent(?match2)), "%(name)s")
+ || CONTAINS(tracker:case-fold(?match2), "%(name)s")
+ || CONTAINS(tracker:case-fold(
+ tracker:unaccent(?match3)), "%(name)s")
+ || CONTAINS(tracker:case-fold(?match3), "%(name)s")
+ || CONTAINS(tracker:case-fold(
+ tracker:unaccent(?match4)), "%(name)s")
+ || CONTAINS(tracker:case-fold(?match4), "%(name)s")
+ )
+ %(location_filter)s
+ }
+ LIMIT 50
+ }
+ }
}
- LIMIT 50
""".replace('\n', ' ').strip() % {
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
+ "media_type": int(Grl.MediaType.AUDIO),
'location_filter': self._tracker_wrapper.location_filter(),
'name': term
}
@@ -859,143 +1048,178 @@ class GrlTrackerWrapper(GObject.GObject):
def songs_search_cb(source, op_id, media, remaining, error):
if error:
self._log.warning("Error: {}".format(error))
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
if not media:
self._song_search_tracker.set_filter_func(songs_filter)
- self._window.notifications_popup.pop_loading()
+ self._notificationmanager.pop_loading()
return
filter_ids.append(media.get_id())
- options = self._fast_options.copy()
-
- self.props.source.query(
- query, self.METADATA_KEYS, options, songs_search_cb)
-
- def get_album_art_for_item(self, coresong, callback):
- """Placeholder until we got a better solution
- """
- item_id = coresong.props.media.get_id()
-
- if coresong.props.media.is_audio():
- query = self._get_album_for_song_id(item_id)
- else:
- query = self._get_album_for_album_id(item_id)
-
- full_options = Grl.OperationOptions()
- full_options.set_resolution_flags(
- Grl.ResolutionFlags.FULL
- | Grl.ResolutionFlags.IDLE_RELAY)
- full_options.set_count(1)
-
self.props.source.query(
- query, self.METADATA_THUMBNAIL_KEYS, full_options, callback)
+ query, [Grl.METADATA_KEY_ID], self._fast_options, songs_search_cb)
- def _get_album_for_album_id(self, album_id):
+ def _get_album_for_media_id_query(self, media_id, song=True):
# Even though we check for the album_artist, we fill
# the artist key, since Grilo coverart plugins use
# only that key for retrieval.
- query = """
- SELECT DISTINCT
- rdf:type(?album)
- tracker:id(?album) AS ?id
- tracker:referenceIdentifier(?release_group_id)
- AS ?mb_release_group_id
- tracker:referenceIdentifier(?release_id) AS ?mb_release_id
- tracker:coalesce(nmm:artistName(?album_artist),
- nmm:artistName(?song_artist)) AS ?artist
- nie:title(?album) AS ?album
- WHERE {
- ?album a nmm:MusicAlbum .
- ?song a nmm:MusicPiece ;
- nmm:musicAlbum ?album ;
- nmm:performer ?song_artist .
- OPTIONAL {
- ?album tracker:hasExternalReference ?release_group_id .
- ?release_group_id tracker:referenceSource
- "https://musicbrainz.org/doc/Release_Group" .
- }
- OPTIONAL {
- ?album tracker:hasExternalReference ?release_id .
- ?release_id tracker:referenceSource
- "https://musicbrainz.org/doc/Release" .
- }
- OPTIONAL { ?album nmm:albumArtist ?album_artist . }
- FILTER (
- tracker:id(?album) = %(album_id)s
- )
- %(location_filter)s
- }
- """.replace("\n", " ").strip() % {
- 'album_id': album_id,
- 'location_filter': self._tracker_wrapper.location_filter()
- }
- return query
+ if song:
+ filter_clause = "?song = <{}>".format(str(media_id))
+ else:
+ filter_clause = "?album = <{}>".format(str(media_id))
- def _get_album_for_song_id(self, song_id):
- # See get_album_for_album_id comment.
query = """
- SELECT DISTINCT
- rdf:type(?album)
- tracker:id(?album) AS ?id
- tracker:referenceIdentifier(?release_group_id)
- AS ?mb_release_group_id
- tracker:referenceIdentifier(?release_id) AS ?mb_release_id
- tracker:coalesce(nmm:artistName(?album_artist),
- nmm:artistName(?song_artist)) AS ?artist
- nie:title(?album) AS ?album
+ SELECT
+ ?type ?id ?mbReleaseGroup ?mbRelease ?artist ?album
WHERE {
- ?song a nmm:MusicPiece ;
- nmm:musicAlbum ?album ;
- nmm:performer ?song_artist .
- OPTIONAL {
- ?album tracker:hasExternalReference ?release_group_id .
- ?release_group_id tracker:referenceSource
- "https://musicbrainz.org/doc/Release_Group" .
- }
- OPTIONAL {
- ?album tracker:hasExternalReference ?release_id .
- ?release_id tracker:referenceSource
- "https://musicbrainz.org/doc/Release" .
+ SERVICE <dbus:%(miner_fs_busname)s> {
+ GRAPH tracker:Audio {
+ SELECT DISTINCT
+ %(media_type)s AS ?type
+ ?album AS ?id
+ tracker:referenceIdentifier(?release_group_id)
+ AS ?mbReleaseGroup
+ tracker:referenceIdentifier(?release_id) AS ?mbRelease
+ tracker:coalesce(nmm:artistName(?album_artist),
+ nmm:artistName(?song_artist))
+ AS ?artist
+ nie:title(?album) AS ?album
+ WHERE {
+ ?album a nmm:MusicAlbum .
+ ?song a nmm:MusicPiece ;
+ nmm:musicAlbum ?album ;
+ nmm:artist ?song_artist .
+ OPTIONAL {
+ ?album tracker:hasExternalReference
+ ?release_group_id .
+ ?release_group_id tracker:referenceSource
+ "https://musicbrainz.org/doc/Release_Group" .
+ }
+ OPTIONAL {
+ ?album tracker:hasExternalReference ?release_id .
+ ?release_id tracker:referenceSource
+ "https://musicbrainz.org/doc/Release" .
+ }
+ OPTIONAL { ?album nmm:albumArtist ?album_artist . }
+ FILTER (
+ %(filter_clause)s
+ )
+ %(location_filter)s
+ }
+ }
}
- OPTIONAL { ?album nmm:albumArtist ?album_artist . }
- FILTER (
- tracker:id(?song) = %(song_id)s
- )
- FILTER (
- NOT EXISTS { ?song a nmm:Video }
- && NOT EXISTS { ?song a nmm:Playlist }
- )
- %(location_filter)s
}
""".replace("\n", " ").strip() % {
- 'location_filter': self._tracker_wrapper.location_filter(),
- 'song_id': song_id
+ "miner_fs_busname": self._tracker_wrapper.props.miner_fs_busname,
+ "media_type": int(Grl.MediaType.CONTAINER),
+ "filter_clause": filter_clause,
+ "location_filter": self._tracker_wrapper.location_filter()
}
return query
+ def get_song_art(self, coresong):
+ """Retrieve song art for the given CoreSong
+
+ Since MediaArt does not really support per-song art this
+ uses the songs album information as base to retrieve relevant
+ art and store it.
+
+ :param CoreSong coresong: CoreSong to get art for
+ """
+ media = coresong.props.media
+
+ # If there is no album and artist do not go through with the
+ # query, it will not give any results.
+ if (media.get_album() is None
+ and (media.get_album_artist() is None
+ or media.get_artist() is None)):
+ coresong.props.thumbnail = "generic"
+ return
+
+ def art_retrieved_cb(source, op_id, queried_media, remaining, error):
+ if error:
+ self._log.warning("Error: {}".format(error))
+ coresong.props.thumbnail = "generic"
+ return
+
+ if (remaining == 0
+ and queried_media is None):
+ coresong.props.thumbnail = "generic"
+ return
+
+ thumbnail_uri = queried_media.get_thumbnail()
+ if thumbnail_uri is None:
+ coresong.props.thumbnail = "generic"
+ else:
+ StoreArt(coresong, thumbnail_uri)
+
+ song_id = media.get_id()
+ query = self._get_album_for_media_id_query(song_id)
+
+ self.props.source.query(
+ query, self._METADATA_THUMBNAIL_KEYS, self._full_options,
+ art_retrieved_cb)
+
+ def get_album_art(self, corealbum):
+ """Retrieve album art for the given CoreAlbum
+
+ :param CoreAlbum corealbum: CoreAlbum to get art for
+ """
+ media = corealbum.props.media
+
+ def art_retrieved_cb(source, op_id, queried_media, remaining, error):
+ if error:
+ self._log.warning("Error: {}".format(error))
+ corealbum.props.thumbnail = "generic"
+ return
+
+ if (remaining == 0
+ and queried_media is None):
+ # art_retrieved_cb should be called two times, the
+ # empty result can be ignored.
+ return
+
+ thumbnail_uri = queried_media.get_thumbnail()
+ if thumbnail_uri is None:
+ corealbum.props.thumbnail = "generic"
+ else:
+ StoreArt(corealbum, thumbnail_uri)
+
+ album_id = media.get_id()
+ query = self._get_album_for_media_id_query(album_id, False)
+
+ self._source.query(
+ query, self._METADATA_THUMBNAIL_KEYS, self._full_options,
+ art_retrieved_cb)
+
def get_artist_art(self, coreartist):
+ """Retrieve artist art for the given CoreArtist
+
+ This retrieves art through Grilo online services only.
+
+ :param CoreArtist coreartist: CoreArtist to get art for
+ """
media = coreartist.props.media
- def _resolve_cb(source, op_id, resolved_media, data, error):
- if resolved_media.get_thumbnail() is None:
- coreartist.props.thumbnail = ""
+ def art_resolved_cb(source, op_id, resolved_media, data, error):
+ if error:
+ self._log.warning("Error: {}".format(error))
+ coreartist.props.thumbnail = "generic"
return
- media.set_thumbnail(resolved_media.get_thumbnail())
- coreartist.props.thumbnail = media.get_thumbnail()
+ if resolved_media.get_thumbnail() is None:
+ coreartist.props.thumbnail = "generic"
+ return
- full_options = Grl.OperationOptions()
- full_options.set_resolution_flags(
- Grl.ResolutionFlags.FULL | Grl.ResolutionFlags.IDLE_RELAY)
+ StoreArt(coreartist, resolved_media.get_thumbnail())
self.props.source.resolve(
- media, [Grl.METADATA_KEY_THUMBNAIL], full_options, _resolve_cb,
- None)
+ media, [Grl.METADATA_KEY_THUMBNAIL], self._full_options,
+ art_resolved_cb, None)
def stage_playlist_deletion(self, playlist):
"""Prepares playlist deletion.
diff --git a/gnomemusic/gstplayer.py b/gnomemusic/gstplayer.py
index 5cff75ab..978a0e8d 100644
--- a/gnomemusic/gstplayer.py
+++ b/gnomemusic/gstplayer.py
@@ -86,11 +86,12 @@ class GstPlayer(GObject.GObject):
self._bus.connect('message::element', self._on_bus_element)
self._bus.connect('message::eos', self._on_bus_eos)
self._bus.connect('message::new-clock', self._on_new_clock)
+ self._bus.connect("message::state-changed", self._on_state_changed)
self._bus.connect("message::stream-start", self._on_bus_stream_start)
self._player.connect("about-to-finish", self._on_about_to_finish)
- self.props.state = Playback.STOPPED
+ self._state = Playback.STOPPED
def _setup_replaygain(self):
"""Set up replaygain"""
@@ -126,6 +127,11 @@ class GstPlayer(GObject.GObject):
self.emit("about-to-finish")
def _on_async_done(self, bus, message):
+ if self._seek:
+ self._seek = False
+ self.emit("seek-finished")
+
+ def _query_duration(self):
success, duration = self._player.query_duration(
Gst.Format.TIME)
@@ -134,12 +140,6 @@ class GstPlayer(GObject.GObject):
else:
self.props.duration = duration
- if self._seek is True:
- self._seek = False
- self.emit("seek-finished")
-
- self.notify("state")
-
def _on_new_clock(self, bus, message):
clock = message.parse_new_clock()
id_ = clock.new_periodic_id(0, 1 * Gst.SECOND)
@@ -155,7 +155,7 @@ class GstPlayer(GObject.GObject):
def _on_bus_stream_start(self, bus, message):
def delayed_query():
- self._on_async_done(None, None)
+ self._query_duration()
self._tick = 0
self.emit("stream-start")
@@ -163,6 +163,25 @@ class GstPlayer(GObject.GObject):
# have been set yet.
GLib.timeout_add(1, delayed_query)
+ def _on_state_changed(self, bus, message):
+ if message.src != self._player:
+ return
+
+ old_state, new_state, _ = message.parse_state_changed()
+ self._log.debug(
+ "Player state changed: {} -> {}".format(old_state, new_state))
+
+ if new_state == Gst.State.PAUSED:
+ self._state = Playback.PAUSED
+ elif new_state == Gst.State.PLAYING:
+ self._state = Playback.PLAYING
+ elif new_state == Gst.State.READY:
+ self._state = Playback.LOADING
+ else:
+ self._state = Playback.STOPPED
+
+ self.notify("state")
+
def _on_bus_error(self, bus, message):
if self._is_missing_plugin_message(message):
self.props.state = Playback.PAUSED
@@ -185,31 +204,16 @@ class GstPlayer(GObject.GObject):
def _on_bus_eos(self, bus, message):
self.emit('eos')
- def _get_playback_status(self):
- ok, state, pending = self._player.get_state(0)
-
- if ok == Gst.StateChangeReturn.ASYNC:
- state = pending
- elif (ok != Gst.StateChangeReturn.SUCCESS):
- return Playback.STOPPED
-
- if state == Gst.State.PLAYING:
- return Playback.PLAYING
- elif state == Gst.State.PAUSED:
- return Playback.PAUSED
- elif state == Gst.State.READY:
- return Playback.LOADING
-
- return Playback.STOPPED
-
- @GObject.Property(type=int)
+ @GObject.Property(
+ type=int, flags=GObject.ParamFlags.READWRITE
+ | GObject.ParamFlags.EXPLICIT_NOTIFY)
def state(self):
"""Current state of the player
:return: state
:rtype: Playback (enum)
"""
- return self._get_playback_status()
+ return self._state
@state.setter
def state(self, state):
diff --git a/gnomemusic/mpris.py b/gnomemusic/mpris.py
index 2bb2b30e..8a8b90c9 100644
--- a/gnomemusic/mpris.py
+++ b/gnomemusic/mpris.py
@@ -22,14 +22,13 @@
# code, but you are not obligated to do so. If you do not wish to do so,
# delete this exception statement from your version.
-from itertools import chain
import re
from gi.repository import Gio, GLib
-from gnomemusic.albumartcache import lookup_art_file_from_cache
+from gnomemusic.grilowrappers.grltrackerplaylists import Playlist
from gnomemusic.gstplayer import Playback
-from gnomemusic.player import PlayerPlaylist, RepeatMode
+from gnomemusic.player import RepeatMode
from gnomemusic.widgets.songwidget import SongWidget
@@ -277,7 +276,7 @@ class MPRIS(DBusInterface):
_playlist_nb_songs = 10
def __init__(self, app):
- name = 'org.mpris.MediaPlayer2.GnomeMusic'
+ name = "org.mpris.MediaPlayer2.{}".format(app.props.application_id)
path = '/org/mpris/MediaPlayer2'
super().__init__(name, path, app)
@@ -305,6 +304,10 @@ class MPRIS(DBusInterface):
self._playlists_model.connect(
"items-changed", self._on_playlists_items_changed)
+ self._recent_playlist = self._coremodel.props.recent_playlist
+ self._recent_playlist.connect(
+ "items-changed", self._on_recent_playlist_changed)
+
self._player_playlist_type = None
self._path_list = []
self._metadata_list = []
@@ -372,21 +375,8 @@ class MPRIS(DBusInterface):
if track_nr > 0:
metadata['xesam:trackNumber'] = GLib.Variant('i', track_nr)
- # If the media has already been part of an MPRIS playlist, its
- # thumbnail is already set. Otherwise, try to look for it in the
- # cache directory and set the media thumbnail for a future use.
- # The search is only through the cache to prevent any delayed
- # loading.
- # FIXME: The thumbnail retrieval should take place in the
- # player.
- art_url = coresong.props.media.get_thumbnail()
- if not art_url:
- thumb_file = lookup_art_file_from_cache(coresong)
- if thumb_file:
- art_url = GLib.filename_to_uri(thumb_file.get_path())
- coresong.props.media.set_thumbnail(art_url)
-
- if art_url:
+ art_url = coresong.props.thumbnail
+ if art_url not in ["generic", "loading"]:
metadata['mpris:artUrl'] = GLib.Variant('s', art_url)
return metadata
@@ -417,51 +407,20 @@ class MPRIS(DBusInterface):
id_hex, index)
return path
- def _update_tracklist(self):
- previous_path_list = self._path_list
+ def _on_recent_playlist_changed(self, model, position, removed, added):
self._path_list = []
self._metadata_list = []
- current_position = self._player.props.position
- nb_songs = self._player_model.get_n_items()
-
- index_min = current_position - self._playlist_nb_songs
- index_max = current_position + self._playlist_nb_songs + 1
- if self._player_playlist_type == PlayerPlaylist.Type.ALBUM:
- index_min = 0
- index_max = self._player_model.get_n_items()
-
- first_index = max(index_min, 0)
- last_index = min(index_max, nb_songs)
- positions = range(first_index, last_index)
-
- nb_songs_max = 2 * self._playlist_nb_songs + 1
- if (self._player.props.repeat_mode == RepeatMode.ALL
- and (last_index - first_index) < nb_songs_max):
- offset_sup = min(
- self._playlist_nb_songs - last_index + current_position + 1,
- first_index)
- offset_inf = min(
- self._playlist_nb_songs - current_position + first_index,
- nb_songs - last_index)
-
- positions = chain(
- range(nb_songs - offset_inf, nb_songs), positions,
- range(offset_sup))
-
- for position in positions:
- coresong = self._player_model.get_item(position)
- path = self._get_song_dbus_path(coresong, position)
- metadata = self._get_metadata(coresong, position)
- self._path_list.append(path)
- self._metadata_list.append(metadata)
-
- # current song has changed
- if (not previous_path_list
- or previous_path_list[0] != self._path_list[0]
- or previous_path_list[-1] != self._path_list[-1]
- or len(previous_path_list) != len(self._path_list)):
- current_song_path = self._get_song_dbus_path()
- self._track_list_replaced(self._path_list, current_song_path)
+
+ offset = self._recent_playlist.get_offset()
+ for position, coresong in enumerate(self._recent_playlist):
+ offset_position = position + offset
+ self._path_list.append(
+ self._get_song_dbus_path(coresong, offset_position))
+ self._metadata_list.append(
+ self._get_metadata(coresong, offset_position))
+
+ current_song_path = self._get_song_dbus_path()
+ self._track_list_replaced(self._path_list, current_song_path)
def _get_playlist_dbus_path(self, playlist):
"""Convert a playlist to a D-Bus path
@@ -475,6 +434,7 @@ class MPRIS(DBusInterface):
# Smart Playlists do not have an id
pl_id = playlist.props.pl_id or playlist.props.tag_text
+ pl_id = pl_id.rsplit(":")[-1].replace("-", "")
return "/org/gnome/GnomeMusic/Playlist/{}".format(pl_id)
def _get_mpris_playlist_from_playlist(self, playlist):
@@ -494,12 +454,12 @@ class MPRIS(DBusInterface):
:returns: playlist existence and its structure
:rtype: tuple
"""
- current_playlist = self._coremodel.props.active_playlist
- if current_playlist is None:
+ current_core_object = self._coremodel.props.active_core_object
+ if not isinstance(current_core_object, Playlist):
return (False, ("/", "", ""))
mpris_playlist = self._get_mpris_playlist_from_playlist(
- current_playlist)
+ current_core_object)
return (True, mpris_playlist)
def _on_current_song_changed(self, player):
@@ -522,8 +482,6 @@ class MPRIS(DBusInterface):
if added == model.get_n_items():
return
- self._update_tracklist()
-
properties = {}
properties["Metadata"] = GLib.Variant("a{sv}", self._get_metadata())
@@ -556,8 +514,6 @@ class MPRIS(DBusInterface):
{'PlaybackStatus': GLib.Variant('s', playback_status), }, [])
def _on_repeat_mode_changed(self, player, param):
- self._update_tracklist()
-
properties = {}
is_shuffled = self._player.props.repeat_mode == RepeatMode.SHUFFLE
@@ -728,19 +684,27 @@ class MPRIS(DBusInterface):
:param str path: Identifier of the track to skip to
"""
current_index = self._path_list.index(self._get_song_dbus_path())
- current_coresong = self._player_model[current_index]
+ current_coresong = self._player.props.current_song
goto_index = self._path_list.index(path)
- new_coresong = self._player_model[goto_index]
+ new_position = self._player.props.position + goto_index - current_index
+ new_coresong = self._player_model[new_position]
self._player.play(new_coresong)
current_coresong.props.state = SongWidget.State.PLAYED
new_coresong.props.state = SongWidget.State.PLAYING
- def _track_list_replaced(self, tracks, current_song):
+ def _track_list_replaced(self, track_paths, current_song_path):
+ """Indicate that the entire tracklist has been replaced.
+
+ (MPRIS Method)
+
+ :param list track_paths: the new list of tracks
+ :param current_song_path: the id of the current song
+ """
parameters = {
- "Tracks": self._path_list,
- "CurrentTrack": self._get_song_dbus_path()}
+ "Tracks": track_paths,
+ "CurrentTrack": current_song_path}
self._dbus_emit_signal("TrackListReplaced", parameters)
def _load_player_playlist(self, playlist):
@@ -750,9 +714,7 @@ class MPRIS(DBusInterface):
loaded_id = self._coremodel.connect(
"playlist-loaded", _on_playlist_loaded)
- self._coremodel.props.active_playlist = playlist
- self._coremodel.set_player_model(
- PlayerPlaylist.Type.PLAYLIST, playlist.props.model)
+ self._coremodel.props.active_core_object = playlist
def _activate_playlist(self, playlist_path):
"""Starts playing the given playlist (MPRIS Method).
diff --git a/gnomemusic/notificationmanager.py b/gnomemusic/notificationmanager.py
new file mode 100644
index 00000000..6ffee620
--- /dev/null
+++ b/gnomemusic/notificationmanager.py
@@ -0,0 +1,61 @@
+# Copyright 2020 The GNOME Music Developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music. This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered. If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so. If you do not wish to do so,
+# delete this exception statement from your version.
+
+from gi.repository import GObject
+
+
+class NotificationManager(GObject.Object):
+ """Managing wrapper around the notification widgets
+ """
+
+ def __init__(self, application):
+ """Initialize the notification manager
+
+ :param Application application: The Application instance
+ """
+ super().__init__()
+
+ self._application = application
+ self._pushed = False
+ self._window = application.props.window
+
+ if self._window is None:
+ application.connect(
+ "notify::window", self._on_window_changed)
+
+ def _on_window_changed(self, klass, value):
+ self._window = self._application.props.window
+
+ def push_loading(self):
+ """Push a loading notifcation."""
+ if self._window:
+ # This makes sure push/pop are in sync when starting.
+ self._pushed = True
+ self._window.notifications_popup.push_loading()
+
+ def pop_loading(self):
+ """Pop a loading notification."""
+ if (self._window
+ and self._pushed):
+ self._window.notifications_popup.pop_loading()
diff --git a/gnomemusic/player.py b/gnomemusic/player.py
index 7104fcac..c0497a6e 100644
--- a/gnomemusic/player.py
+++ b/gnomemusic/player.py
@@ -75,7 +75,9 @@ class PlayerPlaylist(GObject.GObject):
self._discoverer.connect("discovered", self._on_discovered)
self._discoverer.start()
- self._model = self._app.props.coremodel.props.playlist_sort
+ self._coremodel = self._app.props.coremodel
+ self._model = self._coremodel.props.playlist_sort
+ self._model_recent = self._coremodel.props.recent_playlist
self.connect("notify::repeat-mode", self._on_repeat_mode_changed)
@@ -149,6 +151,7 @@ class PlayerPlaylist(GObject.GObject):
if next_song.props.validation == CoreSong.Validation.FAILED:
return self.next()
+ self._update_model_recent()
next_song.props.state = SongWidget.State.PLAYING
self._validate_next_song()
return True
@@ -177,6 +180,7 @@ class PlayerPlaylist(GObject.GObject):
if previous_song.props.validation == CoreSong.Validation.FAILED:
return self.previous()
+ self._update_model_recent()
self._model[previous_position].props.state = SongWidget.State.PLAYING
self._validate_previous_song()
return True
@@ -208,6 +212,7 @@ class PlayerPlaylist(GObject.GObject):
for idx, coresong in enumerate(self._model):
if coresong.props.state == SongWidget.State.PLAYING:
self._position = idx
+ self._update_model_recent()
return coresong
return None
@@ -234,6 +239,7 @@ class PlayerPlaylist(GObject.GObject):
self._position = position
self._validate_song(song)
self._validate_next_song()
+ self._update_model_recent()
return song
for idx, coresong in enumerate(self._model):
@@ -242,10 +248,16 @@ class PlayerPlaylist(GObject.GObject):
self._position = idx
self._validate_song(song)
self._validate_next_song()
+ self._update_model_recent()
return song
return None
+ def _update_model_recent(self):
+ recent_size = self._coremodel.props.recent_playlist_size
+ offset = max(0, self._position - recent_size)
+ self._model_recent.set_offset(offset)
+
def _on_repeat_mode_changed(self, klass, param):
# FIXME: This shuffle is too simple.
def _shuffle_sort(song_a, song_b):
@@ -412,6 +424,7 @@ class Player(GObject.GObject):
def _on_about_to_finish(self, klass):
if self.props.has_next:
+ self._log.debug("Song is about to finish, loading the next one.")
next_coresong = self._playlist.get_next()
new_url = next_coresong.props.url
self._gst_player.props.url = new_url
@@ -423,9 +436,11 @@ class Player(GObject.GObject):
if self._gapless_set:
# After 'eos' in the gapless case, the pipeline needs to be
# hard reset.
+ self._log.debug("Song finished, loading the next one.")
self.stop()
self.play(self.props.current_song)
else:
+ self._log.debug("End of the playlist, stopping the player.")
self.stop()
self._gapless_set = False
@@ -450,6 +465,7 @@ class Player(GObject.GObject):
self.emit("song-changed")
def _load(self, coresong):
+ self._log.debug("Loading song {}".format(coresong.props.title))
self._gst_player.props.state = Playback.LOADING
self._time_stamp = int(time.time())
self._gst_player.props.url = coresong.props.url
@@ -493,7 +509,9 @@ class Player(GObject.GObject):
Play the next song of the playlist, if any.
"""
- if self._playlist.next():
+ if self._gapless_set:
+ self.set_position(0.0)
+ elif self._playlist.next():
self.play(self._playlist.props.current_song)
def previous(self):
@@ -502,12 +520,24 @@ class Player(GObject.GObject):
Play the previous song of the playlist, if any.
"""
position = self._gst_player.props.position
- if position >= 5:
- self.set_position(0.0)
- return
+ if self._gapless_set:
+ self.stop()
- if self._playlist.previous():
+ if (position < 5
+ and self._playlist.has_previous()):
+ self._playlist.previous()
+ self._gapless_set = False
+ self.play(self._playlist.props.current_song)
+ # This is a special case for a song that is very short and the
+ # first song in the playlist. It can trigger gapless, but
+ # has_previous will return False.
+ elif (position < 5
+ and self._playlist.props.position == 0):
+ self.set_position(0.0)
+ self._gapless_set = False
self.play(self._playlist.props.current_song)
+ else:
+ self.set_position(0.0)
def play_pause(self):
"""Toggle play/pause state"""
diff --git a/gnomemusic/scrobbler.py b/gnomemusic/scrobbler.py
index 98bf0ba1..d133f2fa 100644
--- a/gnomemusic/scrobbler.py
+++ b/gnomemusic/scrobbler.py
@@ -31,7 +31,6 @@ gi.require_version('Soup', '2.4')
from gi.repository import Gio, GLib, Goa, GObject, Soup
from gnomemusic.musiclogger import MusicLogger
-import gnomemusic.utils as utils
class GoaLastFM(GObject.GObject):
@@ -77,6 +76,11 @@ class GoaLastFM(GObject.GObject):
return
manager = self._client.get_manager()
+
+ if manager is None:
+ self._log.info("GNOME Online Accounts is unavailable")
+ return
+
try:
manager.call_is_supported_provider(
"lastfm", None, self._lastfm_is_supported_cb)
@@ -324,7 +328,7 @@ class LastFmScrobbler(GObject.GObject):
def scrobbled(self, scrobbled):
self._scrobbled = scrobbled
- def _lastfm_api_call(self, media, time_stamp, request_type_key):
+ def _lastfm_api_call(self, coresong, time_stamp, request_type_key):
"""Internal method called by self.scrobble"""
api_key = self._goa_lastfm.client_id
sk = self._goa_lastfm.session_key
@@ -335,8 +339,8 @@ class LastFmScrobbler(GObject.GObject):
return
secret = self._goa_lastfm.secret
- artist = utils.get_artist_name(media)
- title = utils.get_media_title(media)
+ artist = coresong.props.artist
+ title = coresong.props.title
request_type = {
"update now playing": "track.updateNowPlaying",
@@ -345,7 +349,7 @@ class LastFmScrobbler(GObject.GObject):
# The album is optional. So only provide it when it is
# available.
- album = media.get_album()
+ album = coresong.props.album
request_dict = {}
if (request_type_key == "scrobble"
@@ -429,8 +433,7 @@ class LastFmScrobbler(GObject.GObject):
if not self.props.can_scrobble:
return
- media = coresong.props.media
- self._lastfm_api_call(media, time_stamp, "scrobble")
+ self._lastfm_api_call(coresong, time_stamp, "scrobble")
def now_playing(self, coresong):
"""Set now playing song to Last.fm
@@ -444,5 +447,4 @@ class LastFmScrobbler(GObject.GObject):
if not self.props.can_scrobble:
return
- media = coresong.props.media
- self._lastfm_api_call(media, None, "update now playing")
+ self._lastfm_api_call(coresong, None, "update now playing")
diff --git a/gnomemusic/songart.py b/gnomemusic/songart.py
new file mode 100644
index 00000000..450d59ad
--- /dev/null
+++ b/gnomemusic/songart.py
@@ -0,0 +1,72 @@
+# Copyright 2020 The GNOME Music developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music. This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered. If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so. If you do not wish to do so,
+# delete this exception statement from your version.
+
+import gi
+gi.require_version("MediaArt", "2.0")
+from gi.repository import GObject, MediaArt
+
+from gnomemusic.embeddedart import EmbeddedArt
+
+
+class SongArt(GObject.GObject):
+ """SongArt retrieval object
+ """
+
+ def __init__(self, application, coresong):
+ """Initialize SongArt
+
+ :param Application application: The application object
+ :param CoreSong coresong: The coresong to use
+ """
+ super().__init__()
+
+ self._application = application
+ self._coresong = coresong
+ self._album = self._coresong.props.album
+ self._artist = self._coresong.props.artist
+
+ if self._in_cache():
+ return
+
+ embedded = EmbeddedArt()
+ embedded.connect("art-found", self._on_embedded_art_found)
+ embedded.query(coresong, self._album)
+
+ def _on_embedded_art_found(self, embeddedart, found):
+ if found:
+ self._in_cache()
+ else:
+ self._application.props.coregrilo.get_song_art(self._coresong)
+
+ def _in_cache(self):
+ success, thumb_file = MediaArt.get_file(
+ self._artist, self._album, "album")
+ if (not success
+ or not thumb_file.query_exists()):
+ self._coresong.props.thumbnail = "loading"
+ return False
+
+ self._coresong.props.thumbnail = thumb_file.get_uri()
+
+ return True
diff --git a/gnomemusic/storeart.py b/gnomemusic/storeart.py
new file mode 100644
index 00000000..368d61b2
--- /dev/null
+++ b/gnomemusic/storeart.py
@@ -0,0 +1,162 @@
+# Copyright 2020 The GNOME Music developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music. This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered. If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so. If you do not wish to do so,
+# delete this exception statement from your version.
+
+import gi
+gi.require_versions({"MediaArt": "2.0", "Soup": "2.4"})
+from gi.repository import Gio, GLib, GObject, MediaArt, Soup
+
+from gnomemusic.musiclogger import MusicLogger
+from gnomemusic.coreartist import CoreArtist
+from gnomemusic.corealbum import CoreAlbum
+from gnomemusic.coresong import CoreSong
+
+
+class StoreArt(GObject.Object):
+ """Stores Art in the MediaArt cache.
+ """
+
+ def __init__(self, coreobject, uri):
+ """Initialize StoreArtistArt
+
+ :param coreobject: The CoreArtist or CoreAlbum to store art for
+ :param string uri: The art uri
+ """
+ self._coreobject = coreobject
+
+ self._log = MusicLogger()
+ self._soup_session = Soup.Session.new()
+
+ if (uri is None
+ or uri == ""):
+ self._coreobject.props.thumbnail = "generic"
+ return
+
+ cache_dir = GLib.build_filenamev(
+ [GLib.get_user_cache_dir(), "media-art"])
+ cache_dir_file = Gio.File.new_for_path(cache_dir)
+ cache_dir_file.query_info_async(
+ Gio.FILE_ATTRIBUTE_ACCESS_CAN_READ, Gio.FileQueryInfoFlags.NONE,
+ GLib.PRIORITY_LOW, None, self._cache_dir_info_read, uri)
+
+ def _cache_dir_info_read(self, cache_dir_file, res, uri):
+ try:
+ cache_dir_file.query_info_finish(res)
+ except GLib.Error:
+ # directory does not exist yet
+ try:
+ cache_dir_file.make_directory(None)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ self._coreobject.props.thumbnail = "generic"
+ return
+
+ msg = Soup.Message.new("GET", uri)
+ self._soup_session.queue_message(msg, self._read_callback, None)
+
+ def _read_callback(self, src, result, data):
+ if result.props.status_code != 200:
+ self._log.debug(
+ "Failed to get remote art: {}".format(
+ result.props.reason_phrase))
+ return
+
+ try:
+ [tmp_file, iostream] = Gio.File.new_tmp()
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ self._coreobject.props.thumbnail = "generic"
+ return
+
+ istream = Gio.MemoryInputStream.new_from_bytes(
+ result.props.response_body_data)
+ ostream = iostream.get_output_stream()
+ # FIXME: Passing the iostream here, otherwise it gets
+ # closed. PyGI specific issue?
+ ostream.splice_async(
+ istream, Gio.OutputStreamSpliceFlags.CLOSE_SOURCE
+ | Gio.OutputStreamSpliceFlags.CLOSE_TARGET, GLib.PRIORITY_LOW,
+ None, self._splice_callback, [tmp_file, iostream])
+
+ def _delete_callback(self, src, result, data):
+ try:
+ src.delete_finish(result)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+
+ def _splice_callback(self, src, result, data):
+ tmp_file, iostream = data
+
+ iostream.close_async(
+ GLib.PRIORITY_LOW, None, self._close_iostream_callback, None)
+
+ try:
+ src.splice_finish(result)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ self._coreobject.props.thumbnail = "generic"
+ return
+
+ if isinstance(self._coreobject, CoreArtist):
+ success, cache_file = MediaArt.get_file(
+ self._coreobject.props.artist, None, "artist")
+ elif isinstance(self._coreobject, CoreAlbum):
+ success, cache_file = MediaArt.get_file(
+ self._coreobject.props.artist, self._coreobject.props.title,
+ "album")
+ elif isinstance(self._coreobject, CoreSong):
+ success, cache_file = MediaArt.get_file(
+ self._coreobject.props.artist, self._coreobject.props.album,
+ "album")
+ else:
+ success = False
+
+ if not success:
+ self._coreobject.props.thumbnail = "generic"
+ return
+
+ try:
+ # FIXME: I/O blocking
+ MediaArt.file_to_jpeg(tmp_file.get_path(), cache_file.get_path())
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ self._coreobject.props.thumbnail = "generic"
+ return
+
+ self._coreobject.props.media.set_thumbnail(cache_file.get_uri())
+ self._coreobject.props.thumbnail = cache_file.get_uri()
+
+ tmp_file.delete_async(
+ GLib.PRIORITY_LOW, None, self._delete_callback, None)
+
+ def _close_iostream_callback(self, src, result, data):
+ try:
+ src.close_finish(result)
+ except GLib.Error as error:
+ self._log.warning(
+ "Error: {}, {}".format(error.domain, error.message))
diff --git a/gnomemusic/trackerwrapper.py b/gnomemusic/trackerwrapper.py
index 0990eedb..7a4faf86 100644
--- a/gnomemusic/trackerwrapper.py
+++ b/gnomemusic/trackerwrapper.py
@@ -21,11 +21,11 @@
# code, but you are not obligated to do so. If you do not wish to do so,
# delete this exception statement from your version.
-from enum import IntEnum
+import os
-from gi.repository import GLib, GObject, Tracker
+from enum import IntEnum
-from gnomemusic.musiclogger import MusicLogger
+from gi.repository import Gio, GLib, GObject, Tracker
class TrackerState(IntEnum):
@@ -37,46 +37,135 @@ class TrackerState(IntEnum):
class TrackerWrapper(GObject.GObject):
- """Create a connection to an instance of Tracker"""
- def __init__(self):
+ def __init__(self, application):
+ """Create a connection to an instance of Tracker
+
+ :param Application application: The application object
+ """
super().__init__()
- self._log = MusicLogger()
+ self._log = application.props.log
+ self._application_id = application.props.application_id
+
+ self._local_db = None
+ self._local_db_available = TrackerState.UNAVAILABLE
+
+ self._miner_fs = None
+ self._miner_fs_busname = None
+ self._miner_fs_available = TrackerState.UNAVAILABLE
- self._tracker = None
- self._tracker_available = TrackerState.UNAVAILABLE
+ self._setup_local_db()
+ self._setup_host_miner_fs()
- Tracker.SparqlConnection.get_async(None, self._connection_async_cb)
+ @staticmethod
+ def _in_flatpak():
+ """Indicates if Music is running as flatpak
+
+ :returns: True if running as flatpak.
+ :rtype: bool
+ """
+ return os.path.exists("/.flatpak-info")
+
+ def _setup_host_miner_fs(self):
+ self._miner_fs_busname = "org.freedesktop.Tracker3.Miner.Files"
+
+ self._log.debug(
+ "Connecting to session-wide Tracker indexer at {}".format(
+ self._miner_fs_busname))
- def _connection_async_cb(self, klass, result):
try:
- self._tracker = Tracker.SparqlConnection.get_finish(result)
+ self._miner_fs = Tracker.SparqlConnection.bus_new(
+ self._miner_fs_busname, None, None)
+ self._log.info("Using session-wide tracker-miner-fs-3")
+ self._miner_fs_available = TrackerState.AVAILABLE
+ self.notify("tracker-available")
except GLib.Error as error:
self._log.warning(
- "Error: {}, {}".format(error.domain, error.message))
- self.notify("tracker-available")
- return
+ "Could not connect to host Tracker miner-fs at {}: {}".format(
+ self._miner_fs_busname, error))
+ if self._in_flatpak():
+ self._setup_local_miner_fs()
+ else:
+ self._miner_fs_busname = None
+ self.notify("tracker-available")
+
+ def _setup_local_miner_fs(self):
+ self._miner_fs_busname = self._application_id + ".Tracker3.Miner.Files"
+ self._log.debug(
+ "Connecting to bundled Tracker indexer at {}".format(
+ self._miner_fs_busname))
+
+ # Calling self._application.get_dbus_connection() seems to return None
+ # here, so get the bus directly from Gio.
+ Gio.bus_get(Gio.BusType.SESSION, None,
+ self._setup_local_bus_connection_cb)
+
+ def _setup_local_bus_connection_cb(self, klass, result):
+ # Query callback for _setup_local_miner_fs() to connect to session bus
+ bus = Gio.bus_get_finish(result)
- query = "SELECT ?e WHERE { ?e a tracker:ExternalReference . }"
+ miner_fs_startup_timeout_msec = 30 * 1000
+ miner_fs_object_path = "/org/freedesktop/Tracker3/Miner/Files"
- self._tracker.query_async(
- query, None, self._query_version_check)
+ bus.call(
+ self._miner_fs_busname, miner_fs_object_path,
+ "org.freedesktop.DBus.Peer", "Ping", None, None,
+ Gio.DBusCallFlags.NONE, miner_fs_startup_timeout_msec, None,
+ self._setup_local_miner_fs_ping_cb)
+
+ def _setup_local_miner_fs_ping_cb(self, klass, result):
+ try:
+ klass.call_finish(result)
+ self._log.info("Using bundled tracker-miner-fs-3")
+ self._miner_fs = Tracker.SparqlConnection.bus_new(
+ self._miner_fs_busname, None, None)
+ self._miner_fs_available = TrackerState.AVAILABLE
+ self.notify("tracker-available")
+ except GLib.Error as error:
+ self._log.warning(
+ "Could not start local Tracker miner-fs at {}: {}".format(
+ self._miner_fs_busname, error))
+ self._miner_fs_busname = None
+ self.notify("tracker-available")
- def _query_version_check(self, klass, result):
+ def _setup_local_db(self):
+ # Open a local Tracker database.
try:
- klass.query_finish(result)
- self._tracker_available = TrackerState.AVAILABLE
+ self._local_db = Tracker.SparqlConnection.new(
+ Tracker.SparqlConnectionFlags.NONE,
+ Gio.File.new_for_path(self.cache_directory()),
+ Tracker.sparql_get_ontology_nepomuk(),
+ None)
except GLib.Error as error:
self._log.warning(
"Error: {}, {}".format(error.domain, error.message))
- self._tracker_available = TrackerState.OUTDATED
+ self.notify("tracker-available")
+ return
+ # Version checks against the local version of Tracker can be done
+ # here, set `self._tracker_available = TrackerState.OUTDATED` if the
+ # checks fail.
+ self._local_db_available = TrackerState.AVAILABLE
self.notify("tracker-available")
+ def cache_directory(self):
+ """Get directory which contains Music private data.
+
+ :returns: private store path
+ :rtype: str
+ """
+ return GLib.build_pathv(
+ GLib.DIR_SEPARATOR_S,
+ [GLib.get_user_cache_dir(), "gnome-music", "db"])
+
+ @GObject.Property(type=str, flags=GObject.ParamFlags.READABLE)
+ def miner_fs_busname(self):
+ return self._miner_fs_busname
+
@GObject.Property(type=object, flags=GObject.ParamFlags.READABLE)
- def tracker(self):
- return self._tracker
+ def local_db(self):
+ return self._local_db
@GObject.Property(
type=int, default=TrackerState.UNAVAILABLE,
@@ -84,13 +173,17 @@ class TrackerWrapper(GObject.GObject):
def tracker_available(self):
"""Get Tracker availability.
- Tracker is available if a SparqlConnection has been opened and
- if a query can be performed.
-
:returns: tracker availability
:rtype: TrackerState
"""
- return self._tracker_available
+ if (self._local_db_available == TrackerState.AVAILABLE
+ and self._miner_fs_available == TrackerState.AVAILABLE):
+ return TrackerState.AVAILABLE
+ elif (self._local_db_available == TrackerState.OUTDATED
+ or self._miner_fs_available == TrackerState.OUTDATED):
+ return TrackerState.OUTDATED
+ else:
+ return TrackerState.UNAVAILABLE
def location_filter(self):
try:
@@ -104,6 +197,101 @@ class TrackerWrapper(GObject.GObject):
music_dir = Tracker.sparql_escape_string(
GLib.filename_to_uri(music_dir))
- query = "FILTER (STRSTARTS(nie:url(?song), '{}/'))".format(music_dir)
+ query = "FILTER (STRSTARTS(nie:isStoredAs(?song), '{}/'))".format(
+ music_dir)
return query
+
+ def _update_favorite(self, media):
+ """Update favorite state of a song
+
+ :param Grl.Media media: media which contains updated favorite state
+ """
+ if (media.get_favourite()):
+ update = """
+ INSERT DATA {
+ <%(urn)s> a nmm:MusicPiece ;
+ nao:hasTag nao:predefined-tag-favorite .
+ }
+ """.replace("\n", "").strip() % {
+ "urn": media.get_id(),
+ }
+ else:
+ update = """
+ DELETE DATA {
+ <%(urn)s> nao:hasTag nao:predefined-tag-favorite .
+ }
+ """.replace("\n", "").strip() % {
+ "urn": media.get_id(),
+ }
+
+ def _update_favorite_cb(conn, res):
+ try:
+ conn.update_finish(res)
+ except GLib.Error as e:
+ self._log.warning("Unable to update favorite: {}".format(
+ e.message))
+
+ self._local_db.update_async(update, None, _update_favorite_cb)
+
+ def _update_play_count(self, media):
+ update = """
+ DELETE WHERE {
+ <%(urn)s> nie:usageCounter ?count .
+ };
+ INSERT DATA {
+ <%(urn)s> a nmm:MusicPiece ;
+ nie:usageCounter %(count)d .
+ }
+ """.replace("\n", "").strip() % {
+ "urn": media.get_id(),
+ "count": media.get_play_count(),
+ }
+
+ def _update_play_count_cb(conn, res):
+ try:
+ conn.update_finish(res)
+ except GLib.Error as e:
+ self._log.warning("Unable to update play count: {}".format(
+ e.message))
+
+ self._local_db.update_async(update, None, _update_play_count_cb)
+
+ def _update_last_played(self, media):
+ last_played = media.get_last_played().format_iso8601()
+ update = """
+ DELETE WHERE {
+ <%(urn)s> nie:contentAccessed ?accessed
+ };
+ INSERT DATA {
+ <%(urn)s> a nmm:MusicPiece ;
+ nie:contentAccessed "%(last_played)s"
+ }
+ """.replace("\n", "").strip() % {
+ "urn": media.get_id(),
+ "last_played": last_played,
+ }
+
+ def _update_last_played_cb(conn, res):
+ try:
+ conn.update_finish(res)
+ except GLib.Error as e:
+ self._log.warning("Unable to update play count: {}".format(
+ e.message))
+
+ self._local_db.update_async(update, None, _update_last_played_cb)
+
+ def update_tag(self, media, tag):
+ """Update property of a resource.
+
+ :param Grl.Media media: media which contains updated tag
+ :param str tag: tag to update
+ """
+ if tag == "favorite":
+ self._update_favorite(media)
+ elif tag == "last-played":
+ self._update_last_played(media)
+ elif tag == "play-count":
+ self._update_play_count(media)
+ else:
+ self._log.warning("Unknown tag: '{}'".format(tag))
diff --git a/gnomemusic/utils.py b/gnomemusic/utils.py
index b00f5ec1..5be7e8ca 100644
--- a/gnomemusic/utils.py
+++ b/gnomemusic/utils.py
@@ -27,9 +27,25 @@ import re
import unicodedata
from gettext import gettext as _
-from gi.repository import Gio
+from gi.repository import Gio, GLib
from gi._gi import pygobject_new_full
+from gnomemusic.musiclogger import MusicLogger
+
+
+class ArtSize(Enum):
+ """Enum for icon sizes"""
+ XSMALL = (34, 34)
+ SMALL = (48, 48)
+ MEDIUM = (128, 128)
+ LARGE = (256, 256)
+ XLARGE = (512, 512)
+
+ def __init__(self, width, height):
+ """Intialize width and height"""
+ self.width = width
+ self.height = height
+
class SongStateIcon(Enum):
"""Enum for icons used in song playing and validation"""
@@ -54,9 +70,9 @@ def get_album_title(item):
album title and in case of a container we are looking for
the title.
- :param item: A Grilo Media object
+ :param Grl.Media item: A Grilo Media object
:return: The album title
- :rtype: string
+ :rtype: str
"""
if item.is_container():
album = get_media_title(item)
@@ -76,9 +92,9 @@ def get_artist_name(item):
all. The first is preferred in most cases, because it is
the most accurate in an album setting.
- :param item: A Grilo Media object
+ :param Grl.Media item: A Grilo Media object
:return: The artist name
- :rtype: string
+ :rtype: str
"""
return (item.get_album_artist()
@@ -89,21 +105,30 @@ def get_artist_name(item):
def get_media_title(item):
"""Returns the title of the media item.
- :param item: A Grilo Media object
+ :param Grl.Media item: A Grilo Media object
:return: The title
- :rtype:
+ :rtype: str
"""
title = item.get_title()
if not title:
url = item.get_url()
- # FIXME
+ # FIXME: This and the later occurance are user facing strings,
+ # but they ideally should never be seen. A media should always
+ # contain a URL or we can not play it, in that case it should
+ # be removed.
if url is None:
return "NO URL"
file_ = Gio.File.new_for_uri(url)
- fileinfo = file_.query_info(
- "standard::display-name", Gio.FileQueryInfoFlags.NONE, None)
+ try:
+ # FIXME: query_info is not async.
+ fileinfo = file_.query_info(
+ "standard::display-name", Gio.FileQueryInfoFlags.NONE, None)
+ except GLib.Error as error:
+ MusicLogger().warning(
+ "Error: {}, {}".format(error.domain, error.message))
+ return "NO URL"
title = fileinfo.get_display_name()
title = title.replace("_", " ")
@@ -113,9 +138,9 @@ def get_media_title(item):
def get_media_year(item):
"""Returns the year when the media was created.
- :param item: A Grilo Media object
+ :param Grl.Media item: A Grilo Media object
:return: The creation year or '----' if not defined
- :rtype: string
+ :rtype: str
"""
date = item.get_creation_date()
@@ -130,7 +155,7 @@ def seconds_to_string(duration):
:param int duration: Time in seconds
:return: Time in mm:ss format
- :rtype: string
+ :rtype: str
"""
seconds = duration
minutes = seconds // 60
diff --git a/gnomemusic/views/albumsview.py b/gnomemusic/views/albumsview.py
index 81eb14f3..c2063a18 100644
--- a/gnomemusic/views/albumsview.py
+++ b/gnomemusic/views/albumsview.py
@@ -43,6 +43,8 @@ class AlbumsView(Gtk.Stack):
search_mode_active = GObject.Property(type=bool, default=False)
selection_mode = GObject.Property(type=bool, default=False)
+ title = GObject.Property(
+ type=str, default=_("Albums"), flags=GObject.ParamFlags.READABLE)
_scrolled_window = Gtk.Template.Child()
_flowbox = Gtk.Template.Child()
@@ -55,9 +57,7 @@ class AlbumsView(Gtk.Stack):
"""
super().__init__(transition_type=Gtk.StackTransitionType.CROSSFADE)
- # FIXME: Make these properties.
- self.name = "albums"
- self.title = _("Albums")
+ self.props.name = "albums"
self._application = application
self._window = application.props.window
@@ -227,11 +227,14 @@ class AlbumsView(Gtk.Stack):
if self.props.selection_mode is False:
self.props.selection_mode = True
+ rubberband_selection = len(self._flowbox.get_selected_children()) > 1
with self._application.props.coreselection.freeze_notify():
- if self._ctrl_hold is False:
+ if (rubberband_selection
+ and not self._ctrl_hold):
self.deselect_all()
for child in self._flowbox.get_selected_children():
- if self._ctrl_hold is True:
+ if (self._ctrl_hold is True
+ or not rubberband_selection):
child.props.selected = not child.props.selected
else:
child.props.selected = True
diff --git a/gnomemusic/views/artistsview.py b/gnomemusic/views/artistsview.py
index 3a8fec28..e7a7c1c2 100644
--- a/gnomemusic/views/artistsview.py
+++ b/gnomemusic/views/artistsview.py
@@ -23,31 +23,37 @@
# delete this exception statement from your version.
from gettext import gettext as _
-from gi.repository import Gdk, Gtk
+from gi.repository import GObject, Gtk
-from gnomemusic.views.baseview import BaseView
from gnomemusic.widgets.artistalbumswidget import ArtistAlbumsWidget
from gnomemusic.widgets.artisttile import ArtistTile
-class ArtistsView(BaseView):
+@Gtk.Template(resource_path="/org/gnome/Music/ui/ArtistsView.ui")
+class ArtistsView(Gtk.Box):
"""Main view of all available artists
Consists of a list of artists on the left side and an overview of
all albums by this artist on the right side.
"""
+ __gtype_name__ = "ArtistsView"
+
+ title = GObject.Property(
+ type=str, default=_("Artists"), flags=GObject.ParamFlags.READABLE)
+
+ _artist_container = Gtk.Template.Child()
+ _artist_view = Gtk.Template.Child()
+ _sidebar = Gtk.Template.Child()
+
def __init__(self, application):
"""Initialize
:param GtkApplication application: The application object
"""
- self._sidebar = Gtk.ListBox()
- sidebar_container = Gtk.ScrolledWindow()
- sidebar_container.add(self._sidebar)
+ super().__init__()
- super().__init__(
- 'artists', _("Artists"), application, sidebar_container)
+ self.props.name = "artists"
self._application = application
self._artists = {}
@@ -69,24 +75,16 @@ class ArtistsView(BaseView):
"items-changed", self._on_model_items_changed)
self._on_model_items_changed(self._model, 0, 0, 0)
- sidebar_container.props.width_request = 220
- sidebar_container.get_style_context().add_class('sidebar')
- self._sidebar.props.selection_mode = Gtk.SelectionMode.SINGLE
- self._sidebar.connect('row-activated', self._on_artist_activated)
-
- self._ctrl = Gtk.GestureMultiPress().new(self._sidebar)
- self._ctrl.props.propagation_phase = Gtk.PropagationPhase.CAPTURE
- self._ctrl.props.button = Gdk.BUTTON_PRIMARY
- self._ctrl.connect("released", self._on_sidebar_clicked)
+ self._selection_mode = False
- self.show_all()
+ self._window.bind_property(
+ "selection-mode", self, "selection-mode",
+ GObject.BindingFlags.BIDIRECTIONAL)
def _create_widget(self, coreartist):
row = ArtistTile(coreartist)
row.props.text = coreartist.props.artist
- self.bind_property("selection-mode", row, "selection-mode")
-
return row
def _on_model_items_changed(self, model, position, removed, added):
@@ -116,25 +114,18 @@ class ArtistsView(BaseView):
return
self._loaded_artists.remove(removed_artist)
- if self._view.get_visible_child_name() == removed_artist:
+ if self._artist_view.get_visible_child_name() == removed_artist:
row_next = (self._sidebar.get_row_at_index(position)
or self._sidebar.get_row_at_index(position - 1))
if row_next:
self._sidebar.select_row(row_next)
self._on_artist_activated(self._sidebar, row_next, True)
- removed_frame = self._view.get_child_by_name(removed_artist)
- self._view.remove(removed_frame)
-
- def _setup_view(self):
- self._view_container = Gtk.ScrolledWindow(hexpand=True, vexpand=True)
- self._box.pack_start(self._view_container, True, True, 0)
-
- self._view = Gtk.Stack(
- transition_type=Gtk.StackTransitionType.CROSSFADE,
- vhomogeneous=False)
- self._view_container.add(self._view)
+ removed_artist_page = self._artist_view.get_child_by_name(
+ removed_artist)
+ self._artist_view.remove(removed_artist_page)
+ @Gtk.Template.Callback()
def _on_artist_activated(self, sidebar, row, data=None, untouched=False):
"""Initializes new artist album widgets"""
# On application start the first row of ArtistView is activated
@@ -145,7 +136,6 @@ class ArtistsView(BaseView):
# ArtistsView, to circumvent this issue.
if (self.props.selection_mode
and self._window.props.active_view is self):
- row.props.selected = not row.props.selected
return
if untouched is False:
@@ -157,42 +147,50 @@ class ArtistsView(BaseView):
# Prepare a new artist_albums_widget here
coreartist = row.props.coreartist
if coreartist.props.artist in self._loaded_artists:
- scroll_vadjustment = self._view_container.props.vadjustment
+ scroll_vadjustment = self._artist_container.props.vadjustment
scroll_vadjustment.props.value = 0.
- self._view.set_visible_child_name(coreartist.props.artist)
+ self._artist_view.set_visible_child_name(coreartist.props.artist)
return
- self._artist_albums = ArtistAlbumsWidget(
- coreartist, self._application, False)
- artist_albums_frame = Gtk.Frame(
- shadow_type=Gtk.ShadowType.NONE, hexpand=True)
- artist_albums_frame.add(self._artist_albums)
- artist_albums_frame.show()
+ artist_albums = ArtistAlbumsWidget(coreartist, self._application)
+
+ self.bind_property(
+ "selection-mode", artist_albums, "selection-mode",
+ GObject.BindingFlags.SYNC_CREATE
+ | GObject.BindingFlags.BIDIRECTIONAL)
- self._view.add_named(artist_albums_frame, coreartist.props.artist)
- scroll_vadjustment = self._view_container.props.vadjustment
+ self._artist_view.add_named(artist_albums, coreartist.props.artist)
+ scroll_vadjustment = self._artist_container.props.vadjustment
scroll_vadjustment.props.value = 0.
- self._view.set_visible_child(artist_albums_frame)
+ self._artist_view.set_visible_child(artist_albums)
self._loaded_artists.append(coreartist.props.artist)
- def _on_sidebar_clicked(self, gesture, n_press, x, y):
- success, state = Gtk.get_current_event_state()
- modifiers = Gtk.accelerator_get_default_mod_mask()
- if ((state & modifiers) == Gdk.ModifierType.CONTROL_MASK
- and not self.props.selection_mode):
- self.props.selection_mode = True
+ @GObject.Property(type=bool, default=False)
+ def selection_mode(self):
+ """selection mode getter
- def _on_selection_mode_changed(self, widget, data=None):
- if self.get_parent().get_visible_child() != self:
- return
+ :returns: If selection mode is active
+ :rtype: bool
+ """
+ return self._selection_mode
- super()._on_selection_mode_changed(widget, data)
+ @selection_mode.setter
+ def selection_mode(self, value):
+ """selection-mode setter
+
+ :param bool value: Activate selection mode
+ """
+ if (value == self._selection_mode
+ or self.get_parent().get_visible_child() != self):
+ return
- self._view.props.sensitive = not self.props.selection_mode
- if self.props.selection_mode:
+ self._selection_mode = value
+ self._sidebar.props.sensitive = not self._selection_mode
+ if self._selection_mode:
self._sidebar.props.selection_mode = Gtk.SelectionMode.NONE
else:
+ self.deselect_all()
self._sidebar.props.selection_mode = Gtk.SelectionMode.SINGLE
selected_row = self._sidebar.get_row_at_index(0)
if selected_row is None:
@@ -207,15 +205,12 @@ class ArtistsView(BaseView):
self._sidebar.select_row(selected_row)
self._selected_artist = None
- def _toggle_all_selection(self, selected):
-
- def toggle_selection(child):
- child.props.selected = selected
-
- self._sidebar.foreach(toggle_selection)
-
def select_all(self):
- self._toggle_all_selection(True)
+ artist_albums = self._artist_view.get_visible_child()
+ for row in artist_albums:
+ row.get_child().select_all()
def deselect_all(self):
- self._toggle_all_selection(False)
+ artist_albums = self._artist_view.get_visible_child()
+ for row in artist_albums:
+ row.get_child().deselect_all()
diff --git a/gnomemusic/views/baseview.py b/gnomemusic/views/baseview.py
deleted file mode 100644
index 4b0ad0cc..00000000
--- a/gnomemusic/views/baseview.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright 2018 The GNOME Music Developers
-#
-# GNOME Music is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# GNOME Music is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# The GNOME Music authors hereby grant permission for non-GPL compatible
-# GStreamer plugins to be used and distributed together with GStreamer
-# and GNOME Music. This permission is above and beyond the permissions
-# granted by the GPL license by which GNOME Music is covered. If you
-# modify this code, you may extend this exception to your version of the
-# code, but you are not obligated to do so. If you do not wish to do so,
-# delete this exception statement from your version.
-
-from gi.repository import GObject, Gtk
-
-
-class BaseView(Gtk.Stack):
- """Base Class for all view classes"""
-
- selection_mode = GObject.Property(type=bool, default=False)
-
- def __init__(self, name, title, application, sidebar=None):
- """Initialize
- :param name: The view name
- :param title: The view title
- :param GtkApplication application: The application object
- :param sidebar: The sidebar object (Default: Gtk.Box)
- """
- super().__init__(transition_type=Gtk.StackTransitionType.CROSSFADE)
-
- self._grid = Gtk.Grid(orientation=Gtk.Orientation.HORIZONTAL)
- self._box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
-
- # Setup the main view
- self._setup_view()
-
- if sidebar:
- self._grid.add(sidebar)
-
- self._grid.add(self._box)
-
- self._window = application.props.window
- self._headerbar = self._window._headerbar
-
- self.name = name
- self.title = title
-
- self.add(self._grid)
- self.show_all()
-
- self.bind_property(
- "selection-mode", self._window, "selection-mode",
- GObject.BindingFlags.BIDIRECTIONAL)
-
- self.connect("notify::selection-mode", self._on_selection_mode_changed)
-
- def _setup_view(self):
- """Instantiate and set up the view object"""
- pass
-
- def _on_selection_mode_changed(self, widget, data=None):
- if self.get_parent().get_visible_child() != self:
- return
-
- if self.props.selection_mode is False:
- self.deselect_all()
diff --git a/gnomemusic/views/emptyview.py b/gnomemusic/views/emptyview.py
index 2736f085..e82a1d21 100644
--- a/gnomemusic/views/emptyview.py
+++ b/gnomemusic/views/emptyview.py
@@ -27,7 +27,7 @@ from enum import IntEnum
from gettext import gettext as _
from gi.repository import GLib, GObject, Gtk, Tracker
-from gnomemusic.albumartcache import Art
+from gnomemusic.utils import ArtSize
@Gtk.Template(resource_path="/org/gnome/Music/ui/EmptyView.ui")
@@ -106,7 +106,6 @@ class EmptyView(Gtk.Stack):
self._set_no_tracker_state()
elif self._state == EmptyView.State.TRACKER_OUTDATED:
self._set_tracker_outdated_state()
- self.show_all()
def _set_initial_state(self):
self._information_label.props.label = self._content_text
@@ -115,8 +114,8 @@ class EmptyView(Gtk.Stack):
self._icon.props.resource = "/org/gnome/Music/icons/initial-state.png"
self._icon.props.margin_bottom = 32
- self._icon.props.height_request = Art.Size.LARGE.height
- self._icon.props.width_request = Art.Size.LARGE.width
+ self._icon.props.height_request = ArtSize.LARGE.height
+ self._icon.props.width_request = ArtSize.LARGE.width
def _set_empty_state(self):
self._main_label.props.label = _("No music found")
@@ -144,7 +143,7 @@ class EmptyView(Gtk.Stack):
"Your system Tracker version seems outdated")
self._icon.props.margin_bottom = 18
self._information_label.props.label = _(
- "Music needs Tracker version 2.3.0 or higher")
+ "Music needs Tracker version 3.0.0 or higher")
self._icon.props.icon_name = "dialog-error-symbolic"
diff --git a/gnomemusic/views/playlistsview.py b/gnomemusic/views/playlistsview.py
index cdaa6ac6..9f4bde82 100644
--- a/gnomemusic/views/playlistsview.py
+++ b/gnomemusic/views/playlistsview.py
@@ -32,12 +32,14 @@ from gnomemusic.widgets.playlisttile import PlaylistTile
@Gtk.Template(resource_path="/org/gnome/Music/ui/PlaylistsView.ui")
-class PlaylistsView(Gtk.Stack):
+class PlaylistsView(Gtk.Box):
"""Main view for playlists"""
__gtype_name__ = "PlaylistsView"
- _main_container = Gtk.Template.Child()
+ title = GObject.Property(
+ type=str, default=_("Playlists"), flags=GObject.ParamFlags.READABLE)
+
_sidebar = Gtk.Template.Child()
def __init__(self, application):
@@ -45,11 +47,9 @@ class PlaylistsView(Gtk.Stack):
:param GtkApplication application: The application object
"""
- super().__init__(transition_type=Gtk.StackTransitionType.CROSSFADE)
+ super().__init__()
- # FIXME: Make these properties.
- self.name = "playlists"
- self.title = _("Playlists")
+ self.props.name = "playlists"
self._coremodel = application.props.coremodel
self._model = self._coremodel.props.playlists_sort
@@ -59,12 +59,12 @@ class PlaylistsView(Gtk.Stack):
self._untouched_list = True
self._playlist_widget = PlaylistsWidget(application, self)
- self._main_container.add(self._playlist_widget)
+ self.add(self._playlist_widget)
self._sidebar.bind_model(self._model, self._add_playlist_to_sidebar)
self._coremodel.connect(
- "notify::active-playlist", self._on_active_playlist_changed)
+ "notify::active-core-object", self._on_active_core_object_changed)
self._model.connect("items-changed", self._on_playlists_model_changed)
self._on_playlists_model_changed(self._model, 0, 0, 0)
@@ -114,19 +114,19 @@ class PlaylistsView(Gtk.Stack):
self.notify("current-playlist")
- def _on_active_playlist_changed(self, klass, val):
+ def _on_active_core_object_changed(self, klass, val):
"""Selects the active playlist when an MPRIS client
has changed it.
"""
- playlist = self._coremodel.props.active_playlist
+ active_core_object = self._coremodel.props.active_core_object
selection = self._sidebar.get_selected_row()
- if (playlist is None
- or playlist == selection.props.playlist):
+ if (not isinstance(active_core_object, Playlist)
+ or active_core_object == selection.props.playlist):
return
playlist_row = None
for row in self._sidebar:
- if row.props.playlist == playlist:
+ if row.props.playlist == active_core_object:
playlist_row = row
break
diff --git a/gnomemusic/views/searchview.py b/gnomemusic/views/searchview.py
index 1eb83657..5760e06e 100644
--- a/gnomemusic/views/searchview.py
+++ b/gnomemusic/views/searchview.py
@@ -27,7 +27,6 @@ from gettext import gettext as _
from gi.repository import Gdk, GObject, Gtk
-from gnomemusic.player import PlayerPlaylist
from gnomemusic.search import Search
from gnomemusic.widgets.albumcover import AlbumCover
from gnomemusic.widgets.albumwidget import AlbumWidget
@@ -58,6 +57,8 @@ class SearchView(Gtk.Stack):
search_state = GObject.Property(type=int, default=Search.State.NONE)
selection_mode = GObject.Property(type=bool, default=False)
state = GObject.Property(type=int, default=State.MAIN)
+ title = GObject.Property(
+ type=str, default="", flags=GObject.ParamFlags.READABLE)
_album_header = Gtk.Template.Child()
_album_flowbox = Gtk.Template.Child()
@@ -79,9 +80,7 @@ class SearchView(Gtk.Stack):
"""
super().__init__(transition_type=Gtk.StackTransitionType.CROSSFADE)
- # FIXME: Make these properties.
- self.name = "search"
- self.title = None
+ self.props.name = "search"
self._application = application
self._coremodel = application.props.coremodel
@@ -238,25 +237,28 @@ class SearchView(Gtk.Stack):
self.props.search_state = Search.State.NO_RESULT
def _song_activated(self, widget, event):
+ if widget.props.select_click:
+ widget.props.select_click = False
+ return
+
mod_mask = Gtk.accelerator_get_default_mod_mask()
if ((event.get_state() & mod_mask) == Gdk.ModifierType.CONTROL_MASK
and not self.props.selection_mode):
self.props.selection_mode = True
return
+ if self.props.selection_mode:
+ widget.props.select_click = True
+ widget.props.selected = not widget.props.selected
+ widget.props.coresong.props.selected = widget.props.selected
+ return
+
(_, button) = event.get_button()
if (button == Gdk.BUTTON_PRIMARY
and not self.props.selection_mode):
- # self.emit('song-activated', widget)
-
- self._coremodel.set_player_model(
- PlayerPlaylist.Type.SEARCH_RESULT, self._model)
+ self._coremodel.props.active_core_object = widget.props.coresong
self._player.play(widget.props.coresong)
- # FIXME: Need to ignore the event from the checkbox.
- # if self.props.selection_mode:
- # widget.props.selected = not widget.props.selected
-
return True
def _on_album_flowbox_size_allocate(self, widget, allocation, data=None):
@@ -334,6 +336,7 @@ class SearchView(Gtk.Stack):
def _on_album_activated(self, widget, child, user_data=None):
corealbum = child.props.corealbum
if self.props.selection_mode:
+ corealbum.props.selected = not corealbum.props.selected
return
# Update and display the album widget if not in selection mode
@@ -354,7 +357,7 @@ class SearchView(Gtk.Stack):
return
artist_albums_widget = ArtistAlbumsWidget(
- coreartist, self._application, True)
+ coreartist, self._application)
# FIXME: Recreating a view here. Alternate solution is used
# in AlbumsView: one view created and an update function.
# Settle on one design.
diff --git a/gnomemusic/views/songsview.py b/gnomemusic/views/songsview.py
index 20b18ba6..9eea53c0 100644
--- a/gnomemusic/views/songsview.py
+++ b/gnomemusic/views/songsview.py
@@ -23,121 +23,71 @@
# delete this exception statement from your version.
from gettext import gettext as _
-from gi.repository import Gdk, Gtk, Pango
+from gi.repository import Gdk, GObject, Gtk, Pango
from gnomemusic.coresong import CoreSong
-from gnomemusic.musiclogger import MusicLogger
-from gnomemusic.player import PlayerPlaylist
from gnomemusic.utils import SongStateIcon
-from gnomemusic.views.baseview import BaseView
from gnomemusic.widgets.starhandlerwidget import StarHandlerWidget
-class SongsView(BaseView):
+@Gtk.Template(resource_path="/org/gnome/Music/ui/SongsView.ui")
+class SongsView(Gtk.ScrolledWindow):
"""Main view of all songs sorted artistwise
Consists all songs along with songname, star, length, artist
and the album name.
"""
- _log = MusicLogger()
+ __gtype_name__ = "SongsView"
+
+ title = GObject.Property(
+ type=str, default=_("Songs"), flags=GObject.ParamFlags.READABLE)
+
+ _duration_renderer = Gtk.Template.Child()
+ _now_playing_column = Gtk.Template.Child()
+ _now_playing_cell = Gtk.Template.Child()
+ _songs_ctrlr = Gtk.Template.Child()
+ _songs_view = Gtk.Template.Child()
+ _star_column = Gtk.Template.Child()
def __init__(self, application):
"""Initialize
:param GtkApplication window: The application object
"""
- self._coremodel = application.props.coremodel
- super().__init__('songs', _("Songs"), application)
+ super().__init__()
- self._iter_to_clean = None
+ self.props.name = "songs"
- self._view.get_style_context().add_class('songs-list-old')
+ self._window = application.props.window
+ self._coremodel = application.props.coremodel
- self._add_list_renderers()
+ self._iter_to_clean = None
+ self._set_list_renderers()
self._playlist_model = self._coremodel.props.playlist_sort
+ self._songs_view.props.model = self._coremodel.props.songs_gtkliststore
+ self._model = self._songs_view.props.model
self._player = application.props.player
self._player.connect('song-changed', self._update_model)
- self._model = self._view.props.model
- self._view.show()
-
- def _setup_view(self):
- view_container = Gtk.ScrolledWindow(hexpand=True, vexpand=True)
- self._box.pack_start(view_container, True, True, 0)
-
- self._view = Gtk.TreeView()
- self._view.props.headers_visible = False
- self._view.props.valign = Gtk.Align.START
- self._view.props.model = self._coremodel.props.songs_gtkliststore
- self._view.props.activate_on_single_click = True
-
- self._ctrl = Gtk.GestureMultiPress().new(self._view)
- self._ctrl.props.propagation_phase = Gtk.PropagationPhase.CAPTURE
- self._ctrl.connect("released", self._on_view_clicked)
-
- self._view.get_selection().props.mode = Gtk.SelectionMode.SINGLE
- self._view.connect('row-activated', self._on_item_activated)
-
- view_container.add(self._view)
-
- def _add_list_renderers(self):
- now_playing_symbol_renderer = Gtk.CellRendererPixbuf(
- xpad=0, xalign=0.5, yalign=0.5)
- column_now_playing = Gtk.TreeViewColumn()
- column_now_playing.props.fixed_width = 48
- column_now_playing.pack_start(now_playing_symbol_renderer, False)
- column_now_playing.set_cell_data_func(
- now_playing_symbol_renderer, self._on_list_widget_icon_render,
- None)
- self._view.append_column(column_now_playing)
-
- selection_renderer = Gtk.CellRendererToggle()
- column_selection = Gtk.TreeViewColumn(
- "Selected", selection_renderer, active=1)
- column_selection.props.visible = False
- column_selection.props.fixed_width = 48
- self._view.append_column(column_selection)
-
- title_renderer = Gtk.CellRendererText(
- xpad=0, xalign=0.0, yalign=0.5, height=48,
- ellipsize=Pango.EllipsizeMode.END)
- column_title = Gtk.TreeViewColumn("Title", title_renderer, text=2)
- column_title.props.expand = True
- self._view.append_column(column_title)
-
- artist_renderer = Gtk.CellRendererText(
- xpad=32, ellipsize=Pango.EllipsizeMode.END)
- column_artist = Gtk.TreeViewColumn("Artist", artist_renderer, text=3)
- column_artist.props.expand = True
- self._view.append_column(column_artist)
-
- album_renderer = Gtk.CellRendererText(
- xpad=32, ellipsize=Pango.EllipsizeMode.END)
- column_album = Gtk.TreeViewColumn("Album", album_renderer, text=4)
- column_album.props.expand = True
- self._view.append_column(column_album)
-
- attrs = None
- # The attributes syntax is only possible with Pango 1.44 and above
- # https://gitlab.gnome.org/GNOME/pygobject/issues/312
- try:
- attrs = Pango.AttrList()
- attrs.insert(Pango.AttrFontFeatures.new("tnum=1"))
- except AttributeError as error:
- self._log.warning("Error: {}".format(error))
-
- duration_renderer = Gtk.CellRendererText(xalign=1.0, attributes=attrs)
- column_duration = Gtk.TreeViewColumn(
- "Duration", duration_renderer, text=5)
- self._view.append_column(column_duration)
+ self._selection_mode = False
+
+ self._window.bind_property(
+ "selection-mode", self, "selection-mode",
+ GObject.BindingFlags.BIDIRECTIONAL)
+
+ def _set_list_renderers(self):
+ self._now_playing_column.set_cell_data_func(
+ self._now_playing_cell, self._on_list_widget_icon_render, None)
self._star_handler = StarHandlerWidget(self, 6)
- column_star = Gtk.TreeViewColumn()
- self._view.append_column(column_star)
- self._star_handler.add_star_renderers(column_star)
+ self._star_handler.add_star_renderers(self._star_column)
+
+ attrs = Pango.AttrList()
+ attrs.insert(Pango.AttrFontFeatures.new("tnum=1"))
+ self._duration_renderer.props.attributes = attrs
def _on_list_widget_icon_render(self, col, cell, model, itr, data):
current_song = self._player.props.current_song
@@ -154,22 +104,40 @@ class SongsView(BaseView):
else:
cell.props.visible = False
- def _on_selection_mode_changed(self, widget, data=None):
- if self.get_parent().get_visible_child() != self:
+ @GObject.Property(type=bool, default=False)
+ def selection_mode(self):
+ """selection mode getter
+
+ :returns: If selection mode is active
+ :rtype: bool
+ """
+ return self._selection_mode
+
+ @selection_mode.setter
+ def selection_mode(self, value):
+ """selection-mode setter
+
+ :param bool value: Activate selection mode
+ """
+ if (value == self._selection_mode
+ or self.get_parent().get_visible_child() != self):
return
- super()._on_selection_mode_changed(widget, data)
+ self._selection_mode = value
+ if self._selection_mode is False:
+ self.deselect_all()
- cols = self._view.get_columns()
- cols[1].props.visible = self.props.selection_mode
+ cols = self._songs_view.get_columns()
+ cols[1].props.visible = self._selection_mode
+ @Gtk.Template.Callback()
def _on_item_activated(self, treeview, path, column):
"""Action performed when clicking on a song
clicking on star column toggles favorite
clicking on an other columns launches player
- :param Gtk.TreeView treeview: self._view
+ :param Gtk.TreeView treeview: self._songs_view
:param Gtk.TreePath path: activated row index
:param Gtk.TreeViewColumn column: activated column
"""
@@ -180,15 +148,15 @@ class SongsView(BaseView):
if self.props.selection_mode:
return
- itr = self._view.props.model.get_iter(path)
- coresong = self._view.props.model[itr][7]
- self._coremodel.set_player_model(
- PlayerPlaylist.Type.SONGS, self._view.props.model)
+ itr = self._model.get_iter(path)
+ coresong = self._model[itr][7]
+ self._coremodel.props.active_core_object = coresong
self._player.play(coresong)
+ @Gtk.Template.Callback()
def _on_view_clicked(self, gesture, n_press, x, y):
- """Ctrl+click on self._view triggers selection mode."""
+ """Ctrl+click on self._songs_view triggers selection mode."""
_, state = Gtk.get_current_event_state()
modifiers = Gtk.accelerator_get_default_mod_mask()
if (state & modifiers == Gdk.ModifierType.CONTROL_MASK
@@ -198,11 +166,11 @@ class SongsView(BaseView):
# FIXME: In selection mode, star clicks might still trigger
# activation.
if self.props.selection_mode:
- path = self._view.get_path_at_pos(x, y)
+ path = self._songs_view.get_path_at_pos(x, y)
if path is None:
return
- iter_ = self._view.props.model.get_iter(path[0])
+ iter_ = self._model.get_iter(path[0])
new_fav_status = not self._model[iter_][1]
self._model[iter_][1] = new_fav_status
self._model[iter_][7].props.selected = new_fav_status
@@ -215,20 +183,20 @@ class SongsView(BaseView):
# iter_to_clean is necessary because of a bug in GtkTreeView
# See https://gitlab.gnome.org/GNOME/gtk/issues/503
if self._iter_to_clean:
- self._view.props.model[self._iter_to_clean][9] = False
+ self._model[self._iter_to_clean][9] = False
index = self._player.props.position
current_coresong = self._playlist_model[index]
- for idx, liststore in enumerate(self._view.props.model):
+ for idx, liststore in enumerate(self._model):
if liststore[7] == current_coresong:
break
- iter_ = self._view.props.model.get_iter_from_string(str(idx))
- path = self._view.props.model.get_path(iter_)
- self._view.props.model[iter_][9] = True
- self._view.scroll_to_cell(path, None, True, 0.5, 0.5)
+ iter_ = self._model.get_iter_from_string(str(idx))
+ path = self._model.get_path(iter_)
+ self._model[iter_][9] = True
+ self._songs_view.scroll_to_cell(path, None, True, 0.5, 0.5)
- if self._view.props.model[iter_][0] != SongStateIcon.ERROR.value:
+ if self._model[iter_][0] != SongStateIcon.ERROR.value:
self._iter_to_clean = iter_.copy()
return False
diff --git a/gnomemusic/widgets/albumcover.py b/gnomemusic/widgets/albumcover.py
index efbc5b18..59878ca2 100644
--- a/gnomemusic/widgets/albumcover.py
+++ b/gnomemusic/widgets/albumcover.py
@@ -26,8 +26,8 @@ import gi
gi.require_version('Grl', '0.3')
from gi.repository import GObject, Gtk
-from gnomemusic.albumartcache import Art
from gnomemusic.corealbum import CoreAlbum
+from gnomemusic.utils import ArtSize
from gnomemusic.widgets.twolinetip import TwoLineTip
@@ -38,11 +38,9 @@ class AlbumCover(Gtk.FlowBoxChild):
Includes cover, album title, artist & selection mode checkmark.
"""
- _nr_albums = 0
-
__gtype_name__ = 'AlbumCover'
- _cover_stack = Gtk.Template.Child()
+ _art_stack = Gtk.Template.Child()
_check = Gtk.Template.Child()
_title_label = Gtk.Template.Child()
_artist_label = Gtk.Template.Child()
@@ -59,8 +57,6 @@ class AlbumCover(Gtk.FlowBoxChild):
"""
super().__init__()
- AlbumCover._nr_albums += 1
-
self._corealbum = corealbum
self._retrieved = False
@@ -85,13 +81,10 @@ class AlbumCover(Gtk.FlowBoxChild):
self.connect('query-tooltip', self._on_tooltip_query)
- self._cover_stack.props.size = Art.Size.MEDIUM
+ self._art_stack.props.size = ArtSize.MEDIUM
self.show()
- self._update_cover_id = self._cover_stack.connect(
- "updated", self._on_cover_stack_updated)
-
def retrieve(self):
"""Start retrieving the actual album cover
@@ -102,7 +95,7 @@ class AlbumCover(Gtk.FlowBoxChild):
return
self._retrieved = True
- self._cover_stack.update(self._corealbum)
+ self._art_stack.props.coreobject = self._corealbum
@GObject.Property(type=CoreAlbum, flags=GObject.ParamFlags.READABLE)
def corealbum(self):
@@ -118,7 +111,3 @@ class AlbumCover(Gtk.FlowBoxChild):
tooltip.set_custom(self._tooltip)
return True
-
- def _on_cover_stack_updated(self, cover_stack):
- AlbumCover._nr_albums -= 1
- self._cover_stack.disconnect(self._update_cover_id)
diff --git a/gnomemusic/widgets/albumwidget.py b/gnomemusic/widgets/albumwidget.py
index d75b1fe2..b7553d5f 100644
--- a/gnomemusic/widgets/albumwidget.py
+++ b/gnomemusic/widgets/albumwidget.py
@@ -26,8 +26,7 @@ from gettext import ngettext
from gi.repository import GObject, Grl, Gtk
-from gnomemusic.albumartcache import Art
-from gnomemusic.player import PlayerPlaylist
+from gnomemusic.utils import ArtSize
from gnomemusic.widgets.disclistboxwidget import DiscBox
from gnomemusic.widgets.disclistboxwidget import DiscListBox # noqa: F401
@@ -45,7 +44,7 @@ class AlbumWidget(Gtk.EventBox):
_artist_label = Gtk.Template.Child()
_composer_label = Gtk.Template.Child()
_composer_info_label = Gtk.Template.Child()
- _cover_stack = Gtk.Template.Child()
+ _art_stack = Gtk.Template.Child()
_disc_list_box = Gtk.Template.Child()
_released_info_label = Gtk.Template.Child()
_running_info_label = Gtk.Template.Child()
@@ -68,7 +67,7 @@ class AlbumWidget(Gtk.EventBox):
self._duration_signal_id = None
self._model_signal_id = None
- self._cover_stack.props.size = Art.Size.LARGE
+ self._art_stack.props.size = ArtSize.LARGE
self._player = self._application.props.player
self.bind_property(
@@ -89,7 +88,7 @@ class AlbumWidget(Gtk.EventBox):
self._corealbum = corealbum
- self._cover_stack.update(self._corealbum)
+ self._art_stack.props.coreobject = self._corealbum
album_name = self._corealbum.props.title
artist = self._corealbum.props.artist
@@ -116,8 +115,8 @@ class AlbumWidget(Gtk.EventBox):
self._album_model.items_changed(0, 0, 0)
def _create_widget(self, disc):
- disc_box = self._create_disc_box(
- disc.props.disc_nr, disc.model)
+ disc_box = DiscBox(disc)
+ disc_box.connect('song-activated', self._song_activated)
self._disc_list_box.bind_property(
"selection-mode", disc_box, "selection-mode",
@@ -126,16 +125,6 @@ class AlbumWidget(Gtk.EventBox):
return disc_box
- def _create_disc_box(self, disc_nr, album_model):
- disc_box = DiscBox(album_model)
- disc_box.set_disc_number(disc_nr)
- disc_box.props.show_durations = True
- disc_box.props.show_favorites = True
- disc_box.props.show_song_numbers = True
- disc_box.connect('song-activated', self._song_activated)
-
- return disc_box
-
def _on_model_items_changed(self, model, position, removed, added):
n_items = model.get_n_items()
if n_items == 1:
@@ -177,8 +166,7 @@ class AlbumWidget(Gtk.EventBox):
signal_id = self._coremodel.connect(
"playlist-loaded", _on_playlist_loaded)
- self._coremodel.set_player_model(
- PlayerPlaylist.Type.ALBUM, self._album_model)
+ self._coremodel.props.active_core_object = self._corealbum
return True
diff --git a/gnomemusic/widgets/artistalbumswidget.py b/gnomemusic/widgets/artistalbumswidget.py
index 42bb42ed..701ff999 100644
--- a/gnomemusic/widgets/artistalbumswidget.py
+++ b/gnomemusic/widgets/artistalbumswidget.py
@@ -24,7 +24,6 @@
from gi.repository import GObject, Gtk
-from gnomemusic.player import PlayerPlaylist
from gnomemusic.widgets.artistalbumwidget import ArtistAlbumWidget
@@ -40,15 +39,18 @@ class ArtistAlbumsWidget(Gtk.ListBox):
selection_mode = GObject.Property(type=bool, default=False)
- def __init__(
- self, coreartist, application, selection_mode_allowed=False):
+ def __init__(self, coreartist, application):
+ """Initialize the ArtistAlbumsWidget
+
+ :param CoreArtist coreartist: The CoreArtist object
+ :param Aplication application: The Application object
+ """
super().__init__()
self._application = application
- self._artist = coreartist.props.artist
+ self._artist = coreartist
self._model = coreartist.props.model
self._player = self._application.props.player
- self._selection_mode_allowed = selection_mode_allowed
self._cover_size_group = Gtk.SizeGroup.new(
Gtk.SizeGroupMode.HORIZONTAL)
@@ -58,11 +60,9 @@ class ArtistAlbumsWidget(Gtk.ListBox):
self.bind_model(self._model, self._add_album)
self.get_style_context().add_class("artist-albums-widget")
- self.show_all()
+ self.props.visible = True
def _song_activated(self, widget, song_widget):
- self._album = None
-
if self.props.selection_mode:
return
@@ -73,7 +73,7 @@ class ArtistAlbumsWidget(Gtk.ListBox):
coremodel.disconnect(signal_id)
signal_id = coremodel.connect("playlist-loaded", _on_playlist_loaded)
- coremodel.set_player_model(PlayerPlaylist.Type.ARTIST, self._model)
+ coremodel.props.active_core_object = self._artist
def _add_album(self, corealbum):
row = Gtk.ListBoxRow()
@@ -81,8 +81,7 @@ class ArtistAlbumsWidget(Gtk.ListBox):
row.props.activatable = False
widget = ArtistAlbumWidget(
- corealbum, self._selection_mode_allowed,
- self._songs_grid_size_group, self._cover_size_group)
+ corealbum, self._songs_grid_size_group, self._cover_size_group)
self.bind_property(
'selection-mode', widget, 'selection-mode',
@@ -111,4 +110,4 @@ class ArtistAlbumsWidget(Gtk.ListBox):
@GObject.Property(type=str, flags=GObject.ParamFlags.READABLE)
def artist(self):
"""Artist name"""
- return self._artist
+ return self._artist.props.artist
diff --git a/gnomemusic/widgets/artistalbumwidget.py b/gnomemusic/widgets/artistalbumwidget.py
index 2c7e5d73..5993e7cb 100644
--- a/gnomemusic/widgets/artistalbumwidget.py
+++ b/gnomemusic/widgets/artistalbumwidget.py
@@ -24,18 +24,23 @@
from gi.repository import GObject, Gtk
-from gnomemusic.albumartcache import Art
+from gnomemusic.utils import ArtSize
from gnomemusic.widgets.disclistboxwidget import DiscBox
from gnomemusic.widgets.songwidget import SongWidget
@Gtk.Template(resource_path='/org/gnome/Music/ui/ArtistAlbumWidget.ui')
class ArtistAlbumWidget(Gtk.Box):
+ """"Widget containing one album by an artist
+
+ The album cover and some information on one side and a
+ DiscListBox (list of all discs of the album) on the other side.
+ """
__gtype_name__ = 'ArtistAlbumWidget'
_album_box = Gtk.Template.Child()
- _cover_stack = Gtk.Template.Child()
+ _art_stack = Gtk.Template.Child()
_disc_list_box = Gtk.Template.Child()
_title_year = Gtk.Template.Child()
@@ -47,22 +52,22 @@ class ArtistAlbumWidget(Gtk.Box):
),
}
- def __init__(
- self, corealbum, selection_mode_allowed, size_group=None,
- cover_size_group=None):
+ def __init__(self, corealbum, size_group=None, cover_size_group=None):
+ """Initialize the ArtistAlbumWidget
+
+ :param CoreAlbum corealbum: The CoreAlbum object
+ :param GtkSizeGroup size_group: SizeGroup for the discs
+ :param GtkSizeGroup cover_size_group: SizeGroup for the cover
+ """
super().__init__(orientation=Gtk.Orientation.HORIZONTAL)
self._size_group = size_group
self._cover_size_group = cover_size_group
self._selection_mode = False
- self._selection_mode_allowed = selection_mode_allowed
-
- self._cover_stack.props.size = Art.Size.MEDIUM
- self._cover_stack.update(corealbum)
- allowed = self._selection_mode_allowed
- self._disc_list_box.props.selection_mode_allowed = allowed
+ self._art_stack.props.size = ArtSize.MEDIUM
+ self._art_stack.props.coreobject = corealbum
self.bind_property(
'selection-mode', self._disc_list_box, 'selection-mode',
@@ -78,7 +83,7 @@ class ArtistAlbumWidget(Gtk.Box):
self._size_group.add_widget(self._album_box)
if self._cover_size_group:
- self._cover_size_group.add_widget(self._cover_stack)
+ self._cover_size_group.add_widget(self._art_stack)
corealbum.props.model.connect_after(
"items-changed", self._on_model_items_changed)
@@ -88,12 +93,8 @@ class ArtistAlbumWidget(Gtk.Box):
corealbum.props.model.items_changed(0, 0, 0)
def _create_widget(self, disc):
- disc_box = self._create_disc_box(disc.props.disc_nr, disc.model)
-
- self._disc_list_box.bind_property(
- "selection-mode-allowed", disc_box, "selection-mode-allowed",
- GObject.BindingFlags.BIDIRECTIONAL
- | GObject.BindingFlags.SYNC_CREATE)
+ disc_box = DiscBox(disc)
+ disc_box.connect('song-activated', self._song_activated)
self._disc_list_box.bind_property(
"selection-mode", disc_box, "selection-mode",
@@ -102,16 +103,6 @@ class ArtistAlbumWidget(Gtk.Box):
return disc_box
- def _create_disc_box(self, disc_nr, album_model):
- disc_box = DiscBox(album_model)
- disc_box.set_disc_number(disc_nr)
- disc_box.props.show_durations = True
- disc_box.props.show_favorites = True
- disc_box.props.show_song_numbers = True
- disc_box.connect('song-activated', self._song_activated)
-
- return disc_box
-
def _on_model_items_changed(self, model, position, removed, added):
n_items = model.get_n_items()
for i in range(n_items):
diff --git a/gnomemusic/widgets/artistartstack.py b/gnomemusic/widgets/artistartstack.py
deleted file mode 100644
index 103a3596..00000000
--- a/gnomemusic/widgets/artistartstack.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# Copyright 2019 The GNOME Music developers
-#
-# GNOME Music is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# GNOME Music is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# The GNOME Music authors hereby grant permission for non-GPL compatible
-# GStreamer plugins to be used and distributed together with GStreamer
-# and GNOME Music. This permission is above and beyond the permissions
-# granted by the GPL license by which GNOME Music is covered. If you
-# modify this code, you may extend this exception to your version of the
-# code, but you are not obligated to do so. If you do not wish to do so,
-# delete this exception statement from your version.
-
-from gi.repository import GLib, GObject, Gtk
-
-from gnomemusic.albumartcache import Art
-from gnomemusic.artistart import ArtistCache, DefaultIcon
-from gnomemusic.coreartist import CoreArtist
-
-
-class ArtistArtStack(Gtk.Stack):
- """Provides a smooth transition between image states
-
- Uses a Gtk.Stack to provide an in-situ transition between an image
- state. Either between the "loading" state versus the "loaded" state
- or in between songs.
- """
-
- __gtype_name__ = "ArtistArtStack"
-
- _default_icon = DefaultIcon()
-
- def __init__(self, size=Art.Size.MEDIUM):
- """Initialize the CoverStack
-
- :param Art.Size size: The size of the art used for the cover
- """
- super().__init__()
-
- self._art = None
- self._handler_id = None
- self._size = None
- self._timeout = None
-
- self._loading_cover = Gtk.Image()
- self._cover_a = Gtk.Image()
- self._cover_b = Gtk.Image()
-
- self.add_named(self._loading_cover, "loading")
- self.add_named(self._cover_a, "A")
- self.add_named(self._cover_b, "B")
-
- self._active_child = "loading"
-
- self.props.size = size
- self.props.transition_type = Gtk.StackTransitionType.CROSSFADE
- self.props.visible_child_name = "loading"
-
- self.show_all()
-
- @GObject.Property(type=object, flags=GObject.ParamFlags.READWRITE)
- def size(self):
- """Size of the cover
-
- :returns: The size used
- :rtype: Art.Size
- """
- return self._size
-
- @size.setter
- def size(self, value):
- """Set the cover size
-
- :param Art.Size value: The size to use for the cover
- """
- self._size = value
-
- icon = self._default_icon.get(
- DefaultIcon.Type.LOADING, self.props.size, self.props.scale_factor)
- self._loading_cover.props.surface = icon
-
- @GObject.Property(type=CoreArtist, default=None)
- def coreartist(self):
- return self._coreartist
-
- @coreartist.setter
- def coreartist(self, coreartist):
- self._coreartist = coreartist
-
- self._coreartist.connect(
- "notify::cached-thumbnail-uri", self._on_thumbnail_changed)
-
- if self._coreartist.props.thumbnail is not None:
- self._on_thumbnail_changed(self._coreartist, None)
-
- def _on_thumbnail_changed(self, coreartist, uri):
- cache = ArtistCache(self.props.size, self.props.scale_factor)
- cache.connect("result", self._on_cache_result)
-
- cache.query(coreartist)
-
- def _on_cache_result(self, cache, surface):
- if self._active_child == "B":
- self._cover_a.props.surface = surface
- self.props.visible_child_name = "A"
- else:
- self._cover_b.props.surface = surface
- self.props.visible_child_name = "B"
-
- def update(self, coresong):
- """Update the stack with the given CoreSong
-
- Update the stack with the art retrieved from the given Coresong.
- :param CoreSong coresong: The CoreSong object
- """
- if self._handler_id and self._art:
- # Remove a possible dangling "finished" callback if update
- # is called again, but it is still looking for the previous
- # art.
- self._art.disconnect(self._handler_id)
- # Set the loading state only after a delay to make between
- # song transitions smooth if loading time is negligible.
- self._timeout = GLib.timeout_add(100, self._set_loading_child)
-
- self._active_child = self.props.visible_child_name
-
- self._art = Art(self.props.size, coresong, self.props.scale_factor)
- self._handler_id = self._art.connect("finished", self._art_retrieved)
- self._art.lookup()
-
- def _set_loading_child(self):
- self.props.visible_child_name = "loading"
- self._active_child = self.props.visible_child_name
- self._timeout = None
-
- return GLib.SOURCE_REMOVE
-
- def _art_retrieved(self, klass):
- if self._timeout:
- GLib.source_remove(self._timeout)
- self._timeout = None
-
- if self._active_child == "B":
- self._cover_a.props.surface = klass.surface
- self.props.visible_child_name = "A"
- else:
- self._cover_b.props.surface = klass.surface
- self.props.visible_child_name = "B"
-
- self._active_child = self.props.visible_child_name
- self._art = None
diff --git a/gnomemusic/widgets/artistsearchtile.py b/gnomemusic/widgets/artistsearchtile.py
index cd2e74ac..177ab948 100644
--- a/gnomemusic/widgets/artistsearchtile.py
+++ b/gnomemusic/widgets/artistsearchtile.py
@@ -24,9 +24,9 @@
from gi.repository import Gdk, GObject, Gtk
-from gnomemusic.albumartcache import Art
from gnomemusic.coreartist import CoreArtist
-from gnomemusic.widgets.artistartstack import ArtistArtStack # noqa: F401
+from gnomemusic.utils import ArtSize
+from gnomemusic.widgets.artstack import ArtStack # noqa: F401
from gnomemusic.widgets.twolinetip import TwoLineTip
@@ -40,7 +40,7 @@ class ArtistSearchTile(Gtk.FlowBoxChild):
__gtype_name__ = "ArtistSearchTile"
_artist_label = Gtk.Template.Child()
- _artistart_stack = Gtk.Template.Child()
+ _art_stack = Gtk.Template.Child()
_check = Gtk.Template.Child()
_events = Gtk.Template.Child()
@@ -60,8 +60,8 @@ class ArtistSearchTile(Gtk.FlowBoxChild):
self.props.coreartist = coreartist
- self._artistart_stack.props.size = Art.Size.MEDIUM
- self._artistart_stack.props.coreartist = self.props.coreartist
+ self._art_stack.props.size = ArtSize.MEDIUM
+ self._art_stack.props.coreobject = self.props.coreartist
self._tooltip = TwoLineTip()
self._tooltip.props.subtitle_visible = False
diff --git a/gnomemusic/widgets/artisttile.py b/gnomemusic/widgets/artisttile.py
index 0c092060..9be6f0fb 100644
--- a/gnomemusic/widgets/artisttile.py
+++ b/gnomemusic/widgets/artisttile.py
@@ -36,13 +36,9 @@ class ArtistTile(Gtk.ListBoxRow):
__gtype_name__ = 'ArtistTile'
- _check = Gtk.Template.Child()
_label = Gtk.Template.Child()
- _revealer = Gtk.Template.Child()
coreartist = GObject.Property(type=CoreArtist, default=None)
- selected = GObject.Property(type=bool, default=False)
- selection_mode = GObject.Property(type=bool, default=False)
text = GObject.Property(type=str, default='')
def __init__(self, coreartist=None):
@@ -50,14 +46,6 @@ class ArtistTile(Gtk.ListBoxRow):
self.props.coreartist = coreartist
- self.bind_property(
- 'selected', self._check, 'active',
- GObject.BindingFlags.BIDIRECTIONAL)
- if coreartist:
- self.bind_property(
- "selected", coreartist, "selected",
- GObject.BindingFlags.BIDIRECTIONAL)
- self.bind_property('selection-mode', self._revealer, 'reveal-child')
self.bind_property('text', self._label, 'label')
self.bind_property('text', self._label, 'tooltip-text')
diff --git a/gnomemusic/widgets/artstack.py b/gnomemusic/widgets/artstack.py
new file mode 100644
index 00000000..eb75be93
--- /dev/null
+++ b/gnomemusic/widgets/artstack.py
@@ -0,0 +1,129 @@
+# Copyright 2020 The GNOME Music developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music. This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered. If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so. If you do not wish to do so,
+# delete this exception statement from your version.
+
+from gi.repository import GObject, Gtk
+
+from gnomemusic.artcache import ArtCache
+from gnomemusic.utils import ArtSize
+
+
+class ArtStack(Gtk.Stack):
+ """Provides a smooth transition between image states
+
+ Uses a Gtk.Stack to provide an in-situ transition between an image
+ state. Between the 'loading' and 'default' art state and in between
+ songs.
+ """
+
+ __gtype_name__ = "ArtStack"
+
+ def __init__(self, size=ArtSize.MEDIUM):
+ """Initialize the ArtStack
+
+ :param ArtSize size: The size of the art used for the cover
+ """
+ super().__init__()
+
+ self._cache = None
+ self._handler_id = None
+ self._size = None
+ self._thumbnail_id = 0
+
+ self._cover_a = Gtk.Image()
+ self._cover_a.props.visible = True
+ self._cover_b = Gtk.Image()
+ self._cover_b.props.visible = True
+
+ self.add_named(self._cover_a, "A")
+ self.add_named(self._cover_b, "B")
+
+ self.props.size = size
+ self.props.transition_type = Gtk.StackTransitionType.CROSSFADE
+ self.props.visible_child_name = "A"
+
+ self.connect("destroy", self._on_destroy)
+
+ @GObject.Property(type=object, flags=GObject.ParamFlags.READWRITE)
+ def size(self):
+ """Size of the cover
+
+ :returns: The size used
+ :rtype: ArtSize
+ """
+ return self._size
+
+ @size.setter
+ def size(self, value):
+ """Set the cover size
+
+ :param ArtSize value: The size to use for the cover
+ """
+ self._cover_a.set_size_request(value.width, value.height)
+ self._size = value
+
+ @GObject.Property(type=object, default=None)
+ def coreobject(self):
+ return self._coreobject
+
+ @coreobject.setter
+ def coreobject(self, coreobject):
+ if self._thumbnail_id != 0:
+ self._coreobject.disconnect(self._thumbnail_id)
+ self._thumbnail_id = 0
+
+ self._coreobject = coreobject
+
+ self._thumbnail_id = self._coreobject.connect(
+ "notify::thumbnail", self._on_thumbnail_changed)
+
+ if self._coreobject.props.thumbnail is not None:
+ self._on_thumbnail_changed(self._coreobject, None)
+
+ def _on_thumbnail_changed(self, coreobject, uri):
+ self._disconnect_cache()
+
+ self._cache = ArtCache(self.props.size, self.props.scale_factor)
+ self._handler_id = self._cache.connect("result", self._on_cache_result)
+
+ self._cache.query(coreobject)
+
+ def _on_cache_result(self, cache, surface):
+ if self.props.visible_child_name == "B":
+ self._cover_a.props.surface = surface
+ self.props.visible_child_name = "A"
+ else:
+ self._cover_b.props.surface = surface
+ self.props.visible_child_name = "B"
+
+ def _on_destroy(self, widget):
+ # If the stack is destroyed while the art is updated, an error
+ # can occur once the art is retrieved because the ArtStack does
+ # not have children anymore.
+ self._disconnect_cache()
+
+ def _disconnect_cache(self):
+ if (self._cache is not None
+ and self._handler_id is not None):
+ self._cache.disconnect(self._handler_id)
+ self._handler_id = None
diff --git a/gnomemusic/widgets/coverstack.py b/gnomemusic/widgets/coverstack.py
deleted file mode 100644
index 88da698b..00000000
--- a/gnomemusic/widgets/coverstack.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# Copyright 2018 The GNOME Music developers
-#
-# GNOME Music is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# GNOME Music is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# The GNOME Music authors hereby grant permission for non-GPL compatible
-# GStreamer plugins to be used and distributed together with GStreamer
-# and GNOME Music. This permission is above and beyond the permissions
-# granted by the GPL license by which GNOME Music is covered. If you
-# modify this code, you may extend this exception to your version of the
-# code, but you are not obligated to do so. If you do not wish to do so,
-# delete this exception statement from your version.
-
-from gi.repository import GLib, GObject, Gtk
-
-from gnomemusic.albumartcache import Art, DefaultIcon
-
-
-class CoverStack(Gtk.Stack):
- """Provides a smooth transition between image states
-
- Uses a Gtk.Stack to provide an in-situ transition between an image
- state. Either between the 'loading' state versus the 'loaded' state
- or in between songs.
- """
-
- __gtype_name__ = 'CoverStack'
-
- __gsignals__ = {
- 'updated': (GObject.SignalFlags.RUN_FIRST, None, ())
- }
-
- _default_icon = DefaultIcon()
-
- def __init__(self, size=Art.Size.MEDIUM):
- """Initialize the CoverStack
-
- :param Art.Size size: The size of the art used for the cover
- """
- super().__init__()
-
- self._art = None
- self._handler_id = None
- self._size = None
- self._timeout = None
-
- self._loading_cover = Gtk.Image()
- self._cover_a = Gtk.Image()
- self._cover_b = Gtk.Image()
-
- self.add_named(self._loading_cover, "loading")
- self.add_named(self._cover_a, "A")
- self.add_named(self._cover_b, "B")
-
- self.props.size = size
- self.props.transition_type = Gtk.StackTransitionType.CROSSFADE
- self.props.visible_child_name = "loading"
-
- self.connect("destroy", self._on_destroy)
-
- self.show_all()
-
- @GObject.Property(type=object, flags=GObject.ParamFlags.READWRITE)
- def size(self):
- """Size of the cover
-
- :returns: The size used
- :rtype: Art.Size
- """
- return self._size
-
- @size.setter
- def size(self, value):
- """Set the cover size
-
- :param Art.Size value: The size to use for the cover
- """
- self._size = value
-
- icon = self._default_icon.get(
- DefaultIcon.Type.LOADING, self.props.size, self.props.scale_factor)
- self._loading_cover.props.surface = icon
-
- def update(self, coresong):
- """Update the stack with the given CoreSong
-
- Update the stack with the art retrieved from the given Coresong.
- :param CoreSong coresong: The CoreSong object
- """
- if self._handler_id and self._art:
- # Remove a possible dangling 'finished' callback if update
- # is called again, but it is still looking for the previous
- # art.
- self._art.disconnect(self._handler_id)
- # Set the loading state only after a delay to make between
- # song transitions smooth if loading time is negligible.
- self._timeout = GLib.timeout_add(100, self._set_loading_child)
-
- self._active_child = self.props.visible_child_name
-
- self._art = Art(self.props.size, coresong, self.props.scale_factor)
- self._handler_id = self._art.connect('finished', self._art_retrieved)
- self._art.lookup()
-
- def _set_loading_child(self):
- self.props.visible_child_name = "loading"
- self._active_child = self.props.visible_child_name
- self._timeout = None
-
- return GLib.SOURCE_REMOVE
-
- def _art_retrieved(self, klass):
- if self._timeout:
- GLib.source_remove(self._timeout)
- self._timeout = None
-
- if self._active_child == "B":
- self._cover_a.props.surface = klass.surface
- self.props.visible_child_name = "A"
- else:
- self._cover_b.props.surface = klass.surface
- self.props.visible_child_name = "B"
-
- self._active_child = self.props.visible_child_name
- self._art = None
-
- self.emit('updated')
-
- def _on_destroy(self, widget):
- # If the CoverStack is destroyed while the art is updated,
- # an error can be coccur once the art is retrieved because
- # the CoverStack does not have children anymore.
- if (self._art is not None
- and self._handler_id is not None):
- self._art.disconnect(self._handler_id)
- self._handler_id = None
diff --git a/gnomemusic/widgets/disclistboxwidget.py b/gnomemusic/widgets/disclistboxwidget.py
index 8c6fea4a..f7ef88f2 100644
--- a/gnomemusic/widgets/disclistboxwidget.py
+++ b/gnomemusic/widgets/disclistboxwidget.py
@@ -45,20 +45,19 @@ class DiscBox(Gtk.ListBoxRow):
}
selection_mode = GObject.Property(type=bool, default=False)
- selection_mode_allowed = GObject.Property(type=bool, default=True)
show_disc_label = GObject.Property(type=bool, default=False)
- show_durations = GObject.Property(type=bool, default=False)
- show_favorites = GObject.Property(type=bool, default=False)
- show_song_numbers = GObject.Property(type=bool, default=False)
- def __init__(self, model):
+ def __init__(self, coredisc):
"""Initialize
- :param model: The Gio.ListStore to use
+ :param CoreDisc coredisc: The CoreDisc object to use
"""
super().__init__()
- self._model = model
+ self._model = coredisc.props.model
+
+ disc_nr = coredisc.props.disc_nr
+ self._disc_label.props.label = _("Disc {}").format(disc_nr)
self.bind_property(
'show-disc-label', self._disc_label, 'visible',
@@ -66,13 +65,6 @@ class DiscBox(Gtk.ListBoxRow):
self._list_box.bind_model(self._model, self._create_widget)
- def set_disc_number(self, disc_number):
- """Set the dics number to display
-
- :param int disc_number: Disc number to display
- """
- self._disc_label.props.label = _("Disc {}").format(disc_number)
-
def select_all(self):
"""Select all songs"""
def child_select_all(child):
@@ -97,18 +89,6 @@ class DiscBox(Gtk.ListBoxRow):
GObject.BindingFlags.BIDIRECTIONAL
| GObject.BindingFlags.SYNC_CREATE)
- self.bind_property(
- "show-durations", song_widget, "show-duration",
- GObject.BindingFlags.SYNC_CREATE)
-
- self.bind_property(
- "show-favorites", song_widget, "show-favorite",
- GObject.BindingFlags.SYNC_CREATE)
-
- self.bind_property(
- "show-song-numbers", song_widget, "show-song-number",
- GObject.BindingFlags.SYNC_CREATE)
-
song_widget.connect('button-release-event', self._song_activated)
row = Gtk.ListBoxRow()
@@ -125,8 +105,7 @@ class DiscBox(Gtk.ListBoxRow):
mod_mask = Gtk.accelerator_get_default_mod_mask()
if ((event.get_state() & mod_mask) == Gdk.ModifierType.CONTROL_MASK
- and not self.props.selection_mode
- and self.props.selection_mode_allowed):
+ and not self.props.selection_mode):
self.props.selection_mode = True
widget.props.select_click = True
widget.props.coresong.props.selected = True
@@ -151,15 +130,13 @@ class DiscListBox(Gtk.ListBox):
"""
__gtype_name__ = 'DiscListBox'
- selection_mode_allowed = GObject.Property(type=bool, default=False)
+ selection_mode = GObject.Property(type=bool, default=False)
def __init__(self):
"""Initialize"""
super().__init__()
self.props.valign = Gtk.Align.START
- self._selection_mode = False
-
self.get_style_context().add_class("disc-list-box")
def select_all(self):
@@ -175,23 +152,3 @@ class DiscListBox(Gtk.ListBox):
child.deselect_all()
self.foreach(child_deselect_all)
-
- @GObject.Property(type=bool, default=False)
- def selection_mode(self):
- """selection mode getter
-
- :returns: If selection mode is active
- :rtype: bool
- """
- return self._selection_mode
-
- @selection_mode.setter
- def selection_mode(self, value):
- """selection-mode setter
-
- :param bool value: Activate selection mode
- """
- if not self.props.selection_mode_allowed:
- return
-
- self._selection_mode = value
diff --git a/gnomemusic/widgets/headerbar.py b/gnomemusic/widgets/headerbar.py
index 909974a2..d6b70d59 100644
--- a/gnomemusic/widgets/headerbar.py
+++ b/gnomemusic/widgets/headerbar.py
@@ -44,28 +44,28 @@ class SelectionBarMenuButton(Gtk.MenuButton):
def __init__(self):
super().__init__()
- self._selected_items_count = 0
+ self._selected_songs_count = 0
@GObject.Property(type=int, default=0, minimum=0)
- def selected_items_count(self):
- """The number of items selected
+ def selected_songs_count(self):
+ """The number of songs selected
- :returns: Number of items selected
+ :returns: Number of songs selected
:rtype: int
"""
- return self._selected_items_count
+ return self._selected_songs_count
- @selected_items_count.setter
- def selected_items_count(self, value):
- """Set the number of items selected
+ @selected_songs_count.setter
+ def selected_songs_count(self, value):
+ """Set the number of songs selected
- :param int value: The number of items selected
+ :param int value: The number of songs selected
"""
- self._selected_items_count = value
+ self._selected_songs_count = value
if value > 0:
text = ngettext(
- "Selected {} item", "Selected {} items", value).format(value)
+ "Selected {} song", "Selected {} songs", value).format(value)
self._menu_label.props.label = text
else:
self._menu_label.props.label = _("Click on items to select them")
@@ -95,7 +95,7 @@ class HeaderBar(Gtk.HeaderBar):
_menu_button = Gtk.Template.Child()
search_mode_active = GObject.Property(type=bool, default=False)
- selected_items_count = GObject.Property(type=int, default=0, minimum=0)
+ selected_songs_count = GObject.Property(type=int, default=0, minimum=0)
selection_mode_allowed = GObject.Property(type=bool, default=True)
stack = GObject.Property(type=Gtk.Stack)
@@ -133,12 +133,16 @@ class HeaderBar(Gtk.HeaderBar):
GObject.BindingFlags.BIDIRECTIONAL
| GObject.BindingFlags.SYNC_CREATE)
self.bind_property(
- "selected-items-count", self._selection_menu,
- "selected-items-count")
+ "selected-songs-count", self._selection_menu,
+ "selected-songs-count")
self.bind_property(
"search-mode-active", self._search_button, "active",
GObject.BindingFlags.BIDIRECTIONAL
| GObject.BindingFlags.SYNC_CREATE)
+ self.bind_property(
+ "selection-mode", self._search_button, "visible",
+ GObject.BindingFlags.INVERT_BOOLEAN
+ | GObject.BindingFlags.SYNC_CREATE)
self.connect(
"notify::selection-mode-allowed",
diff --git a/gnomemusic/widgets/notificationspopup.py b/gnomemusic/widgets/notificationspopup.py
index 25025149..a7774d97 100644
--- a/gnomemusic/widgets/notificationspopup.py
+++ b/gnomemusic/widgets/notificationspopup.py
@@ -27,6 +27,7 @@ from gettext import gettext as _
from gi.repository import GLib, GObject, Gtk
+@Gtk.Template(resource_path="/org/gnome/Music/ui/NotificationsPopup.ui")
class NotificationsPopup(Gtk.Revealer):
"""Display notification messages as popups
@@ -38,28 +39,16 @@ class NotificationsPopup(Gtk.Revealer):
__gtype_name__ = "NotificationsPopup"
+ _grid = Gtk.Template.Child()
+
def __init__(self):
super().__init__()
- self._setup_view()
-
- def _setup_view(self):
- frame = Gtk.Frame()
- frame.get_style_context().add_class('app-notification')
- self.add(frame)
-
- self._grid = Gtk.Grid(
- row_spacing=6, orientation=Gtk.Orientation.VERTICAL)
- frame.add(self._grid)
-
self._loading_notification = LoadingNotification()
self._loading_notification.connect('visible', self._set_visibility)
self._loading_notification.connect('invisible', self._set_visibility)
self._grid.add(self._loading_notification)
- self.show_all()
- self._loading_notification.hide()
-
def _hide_notifications(self, notification, remove):
if remove:
self._grid.remove(notification)
@@ -128,6 +117,7 @@ class NotificationsPopup(Gtk.Revealer):
notification._finish_deletion()
+@Gtk.Template(resource_path="/org/gnome/Music/ui/LoadingNotification.ui")
class LoadingNotification(Gtk.Grid):
"""LoadingNotification displays a loading notification message
@@ -140,20 +130,13 @@ class LoadingNotification(Gtk.Grid):
'invisible': (GObject.SignalFlags.RUN_FIRST, None, ())
}
+ __gtype_name__ = "LoadingNotification"
+
def __init__(self):
- super().__init__(column_spacing=18)
+ super().__init__()
self._counter = 0
self._timeout_id = 0
- spinner = Gtk.Spinner()
- spinner.start()
- self.add(spinner)
-
- label = Gtk.Label(
- label=_("Loading"), halign=Gtk.Align.START, hexpand=True)
- self.add(label)
- self.show_all()
-
def pop(self):
"""Decrease the counter. Hide notification if it reaches 0."""
self._counter = self._counter - 1
@@ -169,7 +152,7 @@ class LoadingNotification(Gtk.Grid):
def push(self):
"""Increase the counter. Start notification if necessary."""
def callback():
- self.show_all()
+ self.props.visible = True
self.emit('visible')
if self._counter == 0:
@@ -180,6 +163,7 @@ class LoadingNotification(Gtk.Grid):
self._counter = self._counter + 1
+@Gtk.Template(resource_path="/org/gnome/Music/ui/PlaylistNotification.ui")
class PlaylistNotification(Gtk.Grid):
"""Show a notification on playlist or song deletion.
@@ -187,43 +171,40 @@ class PlaylistNotification(Gtk.Grid):
to the NotificationsPopup.
"""
+ __gtype_name__ = "PlaylistNotification"
+
+ _label = Gtk.Template.Child()
+
class Type(IntEnum):
"""Enum for Playlists Notifications"""
PLAYLIST = 0
SONG = 1
def __init__(
- self, notifications_popup, coremodel, type_, playlist,
+ self, notifications_popup, application, type_, playlist,
position=None, coresong=None):
"""Creates a playlist deletion notification popup (song or playlist)
:param GtkRevealer: notifications_popup: the popup object
- :param CoreModel: core model
+ :param Apllication: application object
:param type_: NotificationType (song or playlist)
:param Playlist playlist: playlist
:param int position: position of the object to delete
:param object coresong: CoreSong for song deletion
"""
- super().__init__(column_spacing=18)
+ super().__init__()
self._notifications_popup = notifications_popup
- self._coremodel = coremodel
+ self._coregrilo = application.props.coregrilo
self.type_ = type_
self._playlist = playlist
self._position = position
self._coresong = coresong
message = self._create_notification_message()
- self._label = Gtk.Label(
- label=message, halign=Gtk.Align.START, hexpand=True)
- self.add(self._label)
-
- undo_button = Gtk.Button.new_with_mnemonic(_("_Undo"))
- undo_button.connect("clicked", self._undo_deletion)
- self.add(undo_button)
- self.show_all()
+ self._label.props.label = message
if self.type_ == PlaylistNotification.Type.PLAYLIST:
- self._coremodel.stage_playlist_deletion(self._playlist)
+ self._coregrilo.stage_playlist_deletion(self._playlist)
else:
playlist.stage_song_deletion(self._coresong, position)
@@ -241,6 +222,7 @@ class PlaylistNotification(Gtk.Grid):
return msg
+ @Gtk.Template.Callback()
def _undo_deletion(self, widget_):
"""Undo deletion and remove notification"""
if self._timeout_id > 0:
@@ -249,14 +231,22 @@ class PlaylistNotification(Gtk.Grid):
self._notifications_popup.remove_notification(self)
if self.type_ == PlaylistNotification.Type.PLAYLIST:
- self._coremodel.finish_playlist_deletion(self._playlist, False)
+ self._coregrilo.finish_playlist_deletion(self._playlist, False)
else:
self._playlist.undo_pending_song_deletion(
self._coresong, self._position)
+ @Gtk.Template.Callback()
+ def _close_notification(self, widget_):
+ if self._timeout_id > 0:
+ GLib.source_remove(self._timeout_id)
+ self._timeout_id = 0
+
+ self._finish_deletion()
+
def _finish_deletion(self):
self._notifications_popup.remove_notification(self)
if self.type_ == PlaylistNotification.Type.PLAYLIST:
- self._coremodel.finish_playlist_deletion(self._playlist, True)
+ self._coregrilo.finish_playlist_deletion(self._playlist, True)
else:
self._playlist.finish_song_deletion(self._coresong)
diff --git a/gnomemusic/widgets/playertoolbar.py b/gnomemusic/widgets/playertoolbar.py
index e060f02d..78eb0f46 100644
--- a/gnomemusic/widgets/playertoolbar.py
+++ b/gnomemusic/widgets/playertoolbar.py
@@ -25,10 +25,9 @@
from gettext import gettext as _
from gi.repository import GObject, Gtk
-from gnomemusic.albumartcache import Art
from gnomemusic.gstplayer import Playback
+from gnomemusic.utils import ArtSize
from gnomemusic.player import Player, RepeatMode
-from gnomemusic.widgets.coverstack import CoverStack # noqa: F401
from gnomemusic.widgets.smoothscale import SmoothScale # noqa: F401
from gnomemusic.widgets.twolinetip import TwoLineTip
import gnomemusic.utils as utils
@@ -44,7 +43,7 @@ class PlayerToolbar(Gtk.ActionBar):
__gtype_name__ = 'PlayerToolbar'
_artist_label = Gtk.Template.Child()
- _cover_stack = Gtk.Template.Child()
+ _art_stack = Gtk.Template.Child()
_duration_label = Gtk.Template.Child()
_next_button = Gtk.Template.Child()
_pause_image = Gtk.Template.Child()
@@ -69,7 +68,7 @@ class PlayerToolbar(Gtk.ActionBar):
self._player = None
- self._cover_stack.props.size = Art.Size.XSMALL
+ self._art_stack.props.size = ArtSize.XSMALL
self._tooltip = TwoLineTip()
@@ -177,7 +176,7 @@ class PlayerToolbar(Gtk.ActionBar):
self._tooltip.props.title = title
self._tooltip.props.subtitle = artist
- self._cover_stack.update(coresong)
+ self._art_stack.props.coreobject = coresong
@Gtk.Template.Callback()
def _on_tooltip_query(self, widget, x, y, kb, tooltip, data=None):
diff --git a/gnomemusic/widgets/playlistcontrols.py b/gnomemusic/widgets/playlistcontrols.py
index 4a517814..c406c18f 100644
--- a/gnomemusic/widgets/playlistcontrols.py
+++ b/gnomemusic/widgets/playlistcontrols.py
@@ -81,6 +81,7 @@ class PlaylistControls(Gtk.Grid):
and self._application != application)):
return
+ self._application = application
self._coremodel = application.props.coremodel
self._player = application.props.player
self._window = application.props.window
@@ -97,7 +98,7 @@ class PlaylistControls(Gtk.Grid):
self._window.set_player_visible(False)
PlaylistNotification(
- self._window.notifications_popup, self._coremodel,
+ self._window.notifications_popup, self._application,
PlaylistNotification.Type.PLAYLIST, self.props.playlist)
@Gtk.Template.Callback()
diff --git a/gnomemusic/widgets/playlistdialog.py b/gnomemusic/widgets/playlistdialog.py
index c94f3448..2c67defb 100644
--- a/gnomemusic/widgets/playlistdialog.py
+++ b/gnomemusic/widgets/playlistdialog.py
@@ -48,20 +48,25 @@ class PlaylistDialog(Gtk.Dialog):
_first_playlist_button = Gtk.Template.Child()
_first_playlist_entry = Gtk.Template.Child()
- def __init__(self, parent):
+ def __init__(self, application):
+ """Initialize PlaylistDialog
+
+ :param Application application: The application object
+ """
super().__init__()
+ self._coregrilo = application.props.coregrilo
+
self._add_playlist_button = None
self._add_playlist_entry = None
- self.props.transient_for = parent
self.set_titlebar(self._title_bar)
self._user_playlists_available = False
- self._coremodel = parent._app.props.coremodel
+
+ coremodel = application.props.coremodel
self._listbox.bind_model(
- self._coremodel.props.user_playlists_sort,
- self._create_playlist_row)
+ coremodel.props.user_playlists_sort, self._create_playlist_row)
self._set_view()
@@ -117,7 +122,7 @@ class PlaylistDialog(Gtk.Dialog):
text = self._add_playlist_entry.props.text
if text:
- self._coremodel.create_playlist(text, select_and_close_dialog)
+ self._coregrilo.create_playlist(text, select_and_close_dialog)
@Gtk.Template.Callback()
def _on_add_playlist_entry_changed(self, editable, data=None):
diff --git a/gnomemusic/widgets/playlistswidget.py b/gnomemusic/widgets/playlistswidget.py
index 164e9a73..00f9fbcd 100644
--- a/gnomemusic/widgets/playlistswidget.py
+++ b/gnomemusic/widgets/playlistswidget.py
@@ -24,7 +24,6 @@
from gi.repository import Gdk, GObject, Gtk
-from gnomemusic.player import PlayerPlaylist
from gnomemusic.widgets.notificationspopup import PlaylistNotification
from gnomemusic.widgets.playlistcontextmenu import PlaylistContextMenu
from gnomemusic.widgets.playlistcontrols import PlaylistControls # noqa: F401
@@ -50,6 +49,7 @@ class PlaylistsWidget(Gtk.Box):
"""
super().__init__()
+ self._application = application
self._window = application.props.window
self._coremodel = application.props.coremodel
self._player = application.props.player
@@ -117,9 +117,7 @@ class PlaylistsWidget(Gtk.Box):
current_playlist = self._playlists_view.props.current_playlist
signal_id = self._coremodel.connect(
"playlist-loaded", _on_playlist_loaded)
- self._coremodel.props.active_playlist = current_playlist
- self._coremodel.set_player_model(
- PlayerPlaylist.Type.PLAYLIST, current_playlist.props.model)
+ self._coremodel.props.active_core_object = current_playlist
def _on_song_widget_moved(self, target, source_position):
target_position = target.get_parent().get_index()
@@ -159,7 +157,8 @@ class PlaylistsWidget(Gtk.Box):
song_widget = selected_row.get_child()
coresong = song_widget.props.coresong
- playlist_dialog = PlaylistDialog(self._window)
+ playlist_dialog = PlaylistDialog(self._application)
+ playlist_dialog.props.transient_for = self._window
if playlist_dialog.run() == Gtk.ResponseType.ACCEPT:
playlist = playlist_dialog.props.selected_playlist
playlist.add_songs([coresong])
@@ -176,7 +175,7 @@ class PlaylistsWidget(Gtk.Box):
current_playlist = self._playlists_view.props.current_playlist
notification = PlaylistNotification( # noqa: F841
- self._window.notifications_popup, self._coremodel,
+ self._window.notifications_popup, self._application,
PlaylistNotification.Type.SONG, current_playlist, position,
coresong)
diff --git a/gnomemusic/widgets/searchheaderbar.py b/gnomemusic/widgets/searchheaderbar.py
index 2b6de962..3335726b 100644
--- a/gnomemusic/widgets/searchheaderbar.py
+++ b/gnomemusic/widgets/searchheaderbar.py
@@ -51,14 +51,14 @@ class SearchHeaderBar(Gtk.HeaderBar):
search_mode_active = GObject.Property(type=bool, default=False)
search_state = GObject.Property(type=int, default=Search.State.NONE)
- selected_items_count = GObject.Property(type=int, default=0, minimum=0)
+ selected_songs_count = GObject.Property(type=int, default=0, minimum=0)
selection_mode_allowed = GObject.Property(type=bool, default=True)
stack = GObject.Property(type=Gtk.Stack)
def __init__(self, application):
super().__init__()
- self._application = application
+ self._coregrilo = application.props.coregrilo
self._selection_mode = False
self._timeout = None
@@ -82,12 +82,16 @@ class SearchHeaderBar(Gtk.HeaderBar):
"selection-mode", self._select_button, "active",
GObject.BindingFlags.BIDIRECTIONAL)
self.bind_property(
- "selected-items-count", self._selection_menu,
- "selected-items-count")
+ "selected-songs-count", self._selection_menu,
+ "selected-songs-count")
self.bind_property(
"search-mode-active", self._search_button, "active",
GObject.BindingFlags.BIDIRECTIONAL
| GObject.BindingFlags.SYNC_CREATE)
+ self.bind_property(
+ "selection-mode", self._search_button, "visible",
+ GObject.BindingFlags.INVERT_BOOLEAN
+ | GObject.BindingFlags.SYNC_CREATE)
self.connect(
"notify::selection-mode-allowed",
@@ -185,7 +189,7 @@ class SearchHeaderBar(Gtk.HeaderBar):
search_term = self._entry.get_text()
if search_term != "":
self.props.stack.set_visible_child_name("search")
- self._application.props.coremodel.search(search_term)
+ self._coregrilo.search(search_term)
else:
self._set_error_style(False)
diff --git a/gnomemusic/widgets/selectiontoolbar.py b/gnomemusic/widgets/selectiontoolbar.py
index b97c2d39..f3a34bc4 100644
--- a/gnomemusic/widgets/selectiontoolbar.py
+++ b/gnomemusic/widgets/selectiontoolbar.py
@@ -36,22 +36,22 @@ class SelectionToolbar(Gtk.ActionBar):
'add-to-playlist': (GObject.SignalFlags.RUN_FIRST, None, ())
}
- selected_items_count = GObject.Property(type=int, default=0, minimum=0)
+ selected_songs_count = GObject.Property(type=int, default=0, minimum=0)
def __init__(self):
super().__init__()
self.connect(
- 'notify::selected-items-count', self._on_item_selection_changed)
+ 'notify::selected-songs-count', self._on_songs_selection_changed)
- self.notify("selected-items-count")
+ self.notify("selected-songs-count")
@Gtk.Template.Callback()
def _on_add_to_playlist_button_clicked(self, widget):
self.emit('add-to-playlist')
- def _on_item_selection_changed(self, widget, data):
- if self.props.selected_items_count > 0:
+ def _on_songs_selection_changed(self, widget, data):
+ if self.props.selected_songs_count > 0:
self._add_to_playlist_button.props.sensitive = True
else:
self._add_to_playlist_button.props.sensitive = False
diff --git a/gnomemusic/widgets/songwidget.py b/gnomemusic/widgets/songwidget.py
index cd0fbe97..8846e876 100644
--- a/gnomemusic/widgets/songwidget.py
+++ b/gnomemusic/widgets/songwidget.py
@@ -58,8 +58,6 @@ class SongWidget(Gtk.EventBox):
coresong = GObject.Property(type=CoreSong, default=None)
select_click = GObject.Property(type=bool, default=False)
selected = GObject.Property(type=bool, default=False)
- show_duration = GObject.Property(type=bool, default=True)
- show_favorite = GObject.Property(type=bool, default=True)
show_song_number = GObject.Property(type=bool, default=True)
_album_label = Gtk.Template.Child()
@@ -97,25 +95,29 @@ class SongWidget(Gtk.EventBox):
self._selection_mode = False
self._state = SongWidget.State.UNPLAYED
- song_number = self.props.coresong.props.track_number
- if song_number == 0:
- song_number = ""
- self._number_label.set_text(str(song_number))
+ self.props.coresong.bind_property(
+ "track-number", self, "song-number",
+ GObject.BindingFlags.SYNC_CREATE)
- title = self.props.coresong.props.title
self._title_label.set_max_width_chars(50)
- self._title_label.set_text(title)
- self._title_label.props.tooltip_text = title
+ self.props.coresong.bind_property(
+ "title", self._title_label, "label",
+ GObject.BindingFlags.SYNC_CREATE)
+ self.props.coresong.bind_property(
+ "title", self._title_label, "tooltip-text",
+ GObject.BindingFlags.SYNC_CREATE)
time = utils.seconds_to_string(self.props.coresong.props.duration)
self._duration_label.props.label = time
if show_artist_and_album is True:
- album = self.props.coresong.props.album
- self._album_label.props.label = album
+ self.props.coresong.bind_property(
+ "album", self._album_label, "label",
+ GObject.BindingFlags.SYNC_CREATE)
self._album_label.props.visible = True
- artist = self.props.coresong.props.artist
- self._artist_label.props.label = artist
+ self.props.coresong.bind_property(
+ "artist", self._artist_label, "label",
+ GObject.BindingFlags.SYNC_CREATE)
self._artist_box.props.visible = True
else:
self._size_group.remove_widget(self._album_duration_box)
@@ -124,20 +126,12 @@ class SongWidget(Gtk.EventBox):
self._play_icon.set_from_icon_name(
'media-playback-start-symbolic', Gtk.IconSize.SMALL_TOOLBAR)
- self._play_icon.set_no_show_all(True)
self.props.coresong.bind_property(
'selected', self._select_button, 'active',
GObject.BindingFlags.BIDIRECTIONAL
| GObject.BindingFlags.SYNC_CREATE)
self.bind_property(
- 'show-duration', self._duration_label, 'visible',
- GObject.BindingFlags.SYNC_CREATE)
- self._duration_label.set_no_show_all(True)
- self.bind_property(
- 'show-favorite', self._star_eventbox, 'visible',
- GObject.BindingFlags.SYNC_CREATE)
- self.bind_property(
'show-song-number', self._number_label, 'visible',
GObject.BindingFlags.SYNC_CREATE)
self.props.coresong.bind_property(
@@ -153,8 +147,6 @@ class SongWidget(Gtk.EventBox):
if not self.props.coresong.props.is_tracker:
self._star_stack.props.visible_child_name = "empty"
- self._number_label.props.no_show_all = True
-
if can_dnd is True:
self._dnd_eventbox.props.visible = True
self._drag_widget = None
@@ -184,7 +176,7 @@ class SongWidget(Gtk.EventBox):
drag_row = SongWidget(self.props.coresong)
self._drag_widget.add(drag_row)
self._drag_widget.drag_highlight_row(drag_row.get_parent())
- self._drag_widget.show_all()
+ self._drag_widget.props.visible = True
Gtk.drag_set_icon_widget(context, self._drag_widget, x, y)
@Gtk.Template.Callback()
@@ -306,3 +298,23 @@ class SongWidget(Gtk.EventBox):
self._play_icon.set_visible(True)
else:
self._play_icon.props.icon_name = SongStateIcon.PLAYING.value
+
+ @GObject.Property(type=str, default="")
+ def song_number(self):
+ """Get song number label
+
+ :returns: the song number
+ :rtype: str
+ """
+ return self._number_label.props.label
+
+ @song_number.setter
+ def song_number(self, new_nr):
+ """Set song number label from an integer
+
+ :param int new_nr: new song number
+ """
+ if new_nr == 0:
+ new_nr = ""
+
+ self._number_label.props.label = str(new_nr)
diff --git a/gnomemusic/widgets/starimage.py b/gnomemusic/widgets/starimage.py
index 0bfd7f5f..032bf6e3 100644
--- a/gnomemusic/widgets/starimage.py
+++ b/gnomemusic/widgets/starimage.py
@@ -36,7 +36,7 @@ class StarImage(Gtk.Image):
self._hover = False
self.get_style_context().add_class("star")
- self.show_all()
+ self.props.visible = True
@GObject.Property(type=bool, default=False)
def favorite(self):
diff --git a/gnomemusic/window.py b/gnomemusic/window.py
index 939855cb..c5563a22 100644
--- a/gnomemusic/window.py
+++ b/gnomemusic/window.py
@@ -39,7 +39,7 @@ from gnomemusic.views.songsview import SongsView
from gnomemusic.views.playlistsview import PlaylistsView
from gnomemusic.widgets.headerbar import HeaderBar
from gnomemusic.widgets.notificationspopup import NotificationsPopup # noqa
-from gnomemusic.widgets.playertoolbar import PlayerToolbar
+from gnomemusic.widgets.playertoolbar import PlayerToolbar # noqa: F401
from gnomemusic.widgets.playlistdialog import PlaylistDialog
from gnomemusic.widgets.searchheaderbar import SearchHeaderBar
from gnomemusic.widgets.selectiontoolbar import SelectionToolbar # noqa: F401
@@ -52,12 +52,13 @@ class Window(Gtk.ApplicationWindow):
__gtype_name__ = "Window"
active_view = GObject.Property(type=GObject.GObject, default=None)
- selected_items_count = GObject.Property(type=int, default=0, minimum=0)
+ selected_songs_count = GObject.Property(type=int, default=0, minimum=0)
selection_mode = GObject.Property(type=bool, default=False)
notifications_popup = Gtk.Template.Child()
- _box = Gtk.Template.Child()
+ _headerbar_stack = Gtk.Template.Child()
_overlay = Gtk.Template.Child()
+ _player_toolbar = Gtk.Template.Child()
_selection_toolbar = Gtk.Template.Child()
_stack = Gtk.Template.Child()
@@ -68,11 +69,11 @@ class Window(Gtk.ApplicationWindow):
"""
super().__init__(application=app, title=_("Music"))
- # Hack
self._app = app
+ self._coreselection = app.props.coreselection
- self._app._coreselection.bind_property(
- "selected-items-count", self, "selected-items-count")
+ self._coreselection.bind_property(
+ "selected-songs-count", self, "selected-songs-count")
self._settings = app.props.settings
self.add_action(self._settings.create_action('repeat'))
@@ -90,22 +91,19 @@ class Window(Gtk.ApplicationWindow):
self._view_before_search = None
self._player = app.props.player
+ self._search = app.props.search
self._setup_view()
MediaKeys(self._player, self)
def _setup_view(self):
- self._search = Search()
- self._headerbar_stack = Gtk.Stack()
- transition_type = Gtk.StackTransitionType.CROSSFADE
- self._headerbar_stack.props.transition_type = transition_type
self._headerbar = HeaderBar(self._app)
+ self._headerbar.props.stack = self._stack
self._search_headerbar = SearchHeaderBar(self._app)
self._search_headerbar.props.stack = self._stack
self._headerbar_stack.add_named(self._headerbar, "main")
self._headerbar_stack.add_named(self._search_headerbar, "search")
- self._headerbar_stack.props.name = "search"
self._search.bind_property(
"search-mode-active", self._headerbar, "search-mode-active",
@@ -122,24 +120,23 @@ class Window(Gtk.ApplicationWindow):
self._search.connect(
"notify::search-mode-active", self._on_search_mode_changed)
- self._player_toolbar = PlayerToolbar()
self._player_toolbar.props.player = self._player
self._headerbar.connect(
'back-button-clicked', self._switch_back_from_childview)
self.bind_property(
- 'selected-items-count', self._headerbar, 'selected-items-count')
+ 'selected-songs-count', self._headerbar, 'selected-songs-count')
self.bind_property(
- "selected-items-count", self._selection_toolbar,
- "selected-items-count")
+ "selected-songs-count", self._selection_toolbar,
+ "selected-songs-count")
self.bind_property(
'selection-mode', self._headerbar, 'selection-mode',
GObject.BindingFlags.BIDIRECTIONAL
| GObject.BindingFlags.SYNC_CREATE)
self.bind_property(
- "selected-items-count", self._search_headerbar,
- "selected-items-count")
+ "selected-songs-count", self._search_headerbar,
+ "selected-songs-count")
self.bind_property(
"selection-mode", self._search_headerbar, "selection-mode",
GObject.BindingFlags.BIDIRECTIONAL
@@ -151,7 +148,7 @@ class Window(Gtk.ApplicationWindow):
"selection-mode", self._selection_toolbar, "visible")
self.connect("notify::selection-mode", self._on_selection_mode_changed)
- self.views = [Gtk.Box()] * len(View)
+ self.views = [None] * len(View)
# Create only the empty view at startup
# if no music, switch to empty view and hide stack
# if some music is available, populate stack with mainviews,
@@ -165,21 +162,16 @@ class Window(Gtk.ApplicationWindow):
# bottom line of the searchbar
self._stack.get_style_context().add_class('background')
- self._box.pack_end(self._player_toolbar, False, False, 0)
-
- self.set_titlebar(self._headerbar_stack)
-
self._selection_toolbar.connect(
'add-to-playlist', self._on_add_to_playlist)
self._search.connect("notify::state", self._on_search_state_changed)
self._headerbar.props.state = HeaderBar.State.MAIN
- self._headerbar_stack.show_all()
self._app.props.coremodel.connect(
"notify::songs-available", self._on_songs_available)
- self._app.props.coremodel.props.grilo.connect(
+ self._app.props.coregrilo.connect(
"notify::tracker-available", self._on_tracker_available)
if self._app.props.coremodel.props.songs_available:
@@ -190,7 +182,7 @@ class Window(Gtk.ApplicationWindow):
def _switch_to_empty_view(self):
did_initial_state = self._settings.get_boolean('did-initial-state')
- state = self._app.props.coremodel.props.grilo.props.tracker_available
+ state = self._app.props.coregrilo.props.tracker_available
empty_view = self.views[View.EMPTY]
if state == TrackerState.UNAVAILABLE:
empty_view.props.state = EmptyView.State.NO_TRACKER
@@ -206,9 +198,9 @@ class Window(Gtk.ApplicationWindow):
def _on_search_mode_changed(self, search, value):
if self._search.props.search_mode_active:
- self._headerbar_stack.set_visible_child_name("search")
+ self._headerbar_stack.props.visible_child_name = "search"
else:
- self._headerbar_stack.set_visible_child_name("main")
+ self._headerbar_stack.props.visible_child_name = "main"
def _on_songs_available(self, klass, value):
if self._app.props.coremodel.props.songs_available:
@@ -220,8 +212,7 @@ class Window(Gtk.ApplicationWindow):
self.props.active_view = self._stack.props.visible_child
def _on_tracker_available(self, klass, value):
- grilo = self._app.props.coremodel.props.grilo
- new_state = grilo.props.tracker_available
+ new_state = self._app.props.coregrilo.props.tracker_available
if new_state != TrackerState.AVAILABLE:
self._switch_to_empty_view()
@@ -244,21 +235,11 @@ class Window(Gtk.ApplicationWindow):
self.views[View.EMPTY].props.state = EmptyView.State.SEARCH
- # FIXME: In case Grilo is already initialized before the views
- # get created, they never receive a 'ready' signal to trigger
- # population. To fix this another check was added to baseview
- # to populate if grilo is ready at the end of init. For this to
- # work however, the headerbar stack needs to be created and
- # populated. This is done below, by binding headerbar.stack to
- # to window._stack. For this to succeed, the stack needs to be
- # filled with something: Gtk.Box.
- # This is a bit of circular logic that needs to be fixed.
self._headerbar.props.state = HeaderBar.State.MAIN
- self._headerbar.props.stack = self._stack
# All views are created together, so if the album view is
# already initialized, assume the rest are as well.
- if not isinstance(self.views[View.ALBUM], Gtk.Box):
+ if self.views[View.ALBUM] is not None:
return
self.views[View.ALBUM] = AlbumsView(self._app)
@@ -272,12 +253,12 @@ class Window(Gtk.ApplicationWindow):
# empty view state is changed once album view is visible to prevent it
# from being displayed during startup
for i in self.views[View.ALBUM:]:
- if i.title:
- self._stack.add_titled(i, i.name, i.title)
+ if i.props.title:
+ self._stack.add_titled(i, i.props.name, i.props.title)
else:
- self._stack.add_named(i, i.name)
+ self._stack.add_named(i, i.props.name)
- self._stack.set_visible_child(self.views[View.ALBUM])
+ self._stack.props.visible_child = self.views[View.ALBUM]
self.views[View.SEARCH].bind_property(
"search-state", self._search, "state",
@@ -317,6 +298,7 @@ class Window(Gtk.ApplicationWindow):
# Open search bar on Ctrl + F
if (keyval == Gdk.KEY_f
and not self.views[View.PLAYLIST].rename_active
+ and not self.props.selection_mode
and self._headerbar.props.state != HeaderBar.State.SEARCH):
search_mode = self._search.props.search_mode_active
self._search.props.search_mode_active = not search_mode
@@ -399,6 +381,7 @@ class Window(Gtk.ApplicationWindow):
and (modifiers == shift_mask
or modifiers == 0)
and not self.views[View.PLAYLIST].rename_active
+ and not self.props.selection_mode
and self._headerbar.props.state != HeaderBar.State.SEARCH):
self._search.props.search_mode_active = True
@@ -449,7 +432,7 @@ class Window(Gtk.ApplicationWindow):
return
# Get back to the view before the search
- self._stack.set_visible_child(self._view_before_search)
+ self._stack.props.visible_child = self._view_before_search
def _switch_back_from_childview(self, klass=None):
if self.props.selection_mode:
@@ -471,12 +454,13 @@ class Window(Gtk.ApplicationWindow):
if self.props.active_view == self.views[View.PLAYLIST]:
return
- selected_songs = self._app._coreselection.props.selected_items
+ selected_songs = self._coreselection.props.selected_songs
if len(selected_songs) < 1:
return
- playlist_dialog = PlaylistDialog(self)
+ playlist_dialog = PlaylistDialog(self._app)
+ playlist_dialog.props.transient_for = self
if playlist_dialog.run() == Gtk.ResponseType.ACCEPT:
playlist = playlist_dialog.props.selected_playlist
playlist.add_songs(selected_songs)
diff --git a/meson.build b/meson.build
index a64fdd74..e1d3dfd3 100644
--- a/meson.build
+++ b/meson.build
@@ -1,6 +1,6 @@
project('gnome-music',
- version: '3.36.4.1',
- meson_version: '>= 0.46.0'
+ version: '3.38.0',
+ meson_version: '>= 0.49.0'
)
# Importing modules
@@ -42,11 +42,12 @@ dependency('gtk+-3.0', version: '>= 3.24.7')
dependency('libdazzle-1.0', version: '>= 3.28.0')
dependency('libmediaart-2.0', version: '>= 1.9.1')
dependency('libsoup-2.4')
-dependency('tracker-sparql-2.0', version: '>= 2.3.0')
-dependency('pygobject-3.0', version: '>= 3.29.1')
+dependency('tracker-sparql-3.0', version: '>= 2.99.3')
+dependency('pango', version: '>= 1.44.0')
+dependency('pygobject-3.0', version: '>= 3.36.1')
dependency('py3cairo', version: '>= 1.14.0')
-dependency('grilo-0.3', version: '>= 0.3.12', fallback: ['grilo', 'libgrl_dep'])
-dependency('grilo-plugins-0.3', version: '>= 0.3.10', fallback: ['grilo-plugins', 'grilo_plugins_dep'])
+dependency('grilo-0.3', version: '>= 0.3.13', fallback: ['grilo', 'libgrl_dep'])
+dependency('grilo-plugins-0.3', version: '>= 0.3.12', fallback: ['grilo-plugins', 'grilo_plugins_dep'])
subproject('libgd',
default_options: [
diff --git a/org.gnome.Music.json b/org.gnome.Music.json
index bde05d39..f1220f24 100644
--- a/org.gnome.Music.json
+++ b/org.gnome.Music.json
@@ -7,22 +7,22 @@
"tags": ["devel", "development", "nightly"],
"desktop-file-name-suffix": " ☢ï¸",
"finish-args": [
- "--share=ipc", "--socket=x11",
+ "--share=ipc",
"--share=network",
"--socket=wayland",
- "--talk-name=org.freedesktop.Tracker1",
- "--env=TRACKER_SPARQL_BACKEND=bus",
- "--talk-name=org.gnome.OnlineAccounts",
+ "--socket=fallback-x11",
+ "--socket=pulseaudio",
+ "--filesystem=xdg-music",
"--filesystem=xdg-run/dconf", "--filesystem=~/.config/dconf:ro",
"--talk-name=ca.desrt.dconf", "--env=DCONF_USER_CONFIG_DIR=.config/dconf",
- "--own-name=org.mpris.MediaPlayer2.GnomeMusic",
+ "--talk-name=org.freedesktop.Tracker3.Writeback",
+ "--talk-name=org.gnome.OnlineAccounts",
"--talk-name=org.gnome.ControlCenter",
"--talk-name=org.gnome.SettingsDaemon.MediaKeys",
"--talk-name=org.gtk.vfs",
"--talk-name=org.gtk.vfs.*",
- "--socket=pulseaudio",
- "--filesystem=xdg-music",
- "--system-talk-name=org.freedesktop.login1"
+ "--system-talk-name=org.freedesktop.login1",
+ "--add-policy=Tracker3.dbus:org.freedesktop.Tracker3.Miner.Files=tracker:Audio"
],
"cleanup": [
"/include",
@@ -58,20 +58,20 @@
]
},
{
- "name": "tracker",
+ "name": "tracker-miners",
"buildsystem": "meson",
- "cleanup": [ "/bin", "/etc", "/libexec" ],
- "config-opts": [ "-Ddocs=false",
- "-Dfunctional_tests=false",
- "-Dnetwork_manager=disabled",
- "-Dstemmer=disabled",
- "-Dunicode_support=icu",
- "-Dbash_completion=no" ],
+ "config-opts": [ "-Ddefault_index_single_directories=",
+ "-Ddefault_index_recursive_directories=&MUSIC",
+ "-Ddomain_prefix=org.gnome.Music.Devel",
+ "-Dman=false",
+ "-Dminer_fs=true",
+ "-Dminer_fs_cache_location=$XDG_CACHE_HOME/gnome-music/miner/files",
+ "-Dminer_rss=false",
+ "-Dsystemd_user_services=false"],
"sources": [
{
"type": "git",
- "url": "https://gitlab.gnome.org/GNOME/tracker.git",
- "branch": "tracker-2.3"
+ "url": "https://gitlab.gnome.org/GNOME/tracker-miners.git"
}
]
},
@@ -113,8 +113,7 @@
{
"name": "grilo-plugins",
"buildsystem": "meson",
- "config-opts": [ "-Denable-tracker=yes",
- "-Denable-bookmarks=no",
+ "config-opts": [ "-Denable-bookmarks=no",
"-Denable-dleyna=no",
"-Denable-filesystem=no",
"-Denable-freebox=no",
@@ -126,6 +125,8 @@
"-Denable-podcasts=no",
"-Denable-thetvdb=no",
"-Denable-tmdb=no",
+ "-Denable-tracker=no",
+ "-Denable-tracker3=yes",
"-Denable-vimeo=no",
"-Denable-youtube=no" ],
"sources": [
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 337ac20b..c88c5b2c 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -9,16 +9,17 @@ data/ui/AppMenu.ui
data/ui/HeaderBar.ui
data/ui/help-overlay.ui
data/ui/LastfmDialog.ui
+data/ui/LoadingNotification.ui
data/ui/PlayerToolbar.ui
data/ui/PlaylistContextMenu.ui
data/ui/PlaylistControls.ui
data/ui/PlaylistDialog.ui
+data/ui/PlaylistNotification.ui
data/ui/SearchHeaderBar.ui
data/ui/SearchView.ui
data/ui/SelectionBarMenuButton.ui
data/ui/SelectionToolbar.ui
gnomemusic/__init__.py
-gnomemusic/albumartcache.py
gnomemusic/application.py
gnomemusic/grilowrappers/grltrackerplaylists.py
gnomemusic/gstplayer.py
diff --git a/po/ca.po b/po/ca.po
index 9295eb4d..f02d854a 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 11:24+0000\n"
+"POT-Creation-Date: 2020-09-01 19:48+0000\n"
"PO-Revision-Date: 2020-02-19 06:43+0100\n"
"Last-Translator: Adolfo Jayme Barrientos <fitojb@ubuntu.com>\n"
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
@@ -47,12 +47,12 @@ msgstr ""
"Trobeu cançons en la vostra col·lecció, obteniu música des de servidors DLNA "
"o proveu quelcom nou amb els serveis Jamendo i Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:67
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "L'equip de desenvolupament del Música del GNOME"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Música"
@@ -136,18 +136,19 @@ msgstr ""
#: data/org.gnome.Music.gschema.xml:48
msgid "Report music history to Last.fm"
-msgstr "Informa de l'històric reproduccions a Last.fm"
+msgstr "Informa de l'històric de reproduccions a Last.fm"
#: data/org.gnome.Music.gschema.xml:49
msgid ""
"Enables or disables sending scrobbles and the “currently playing†info to "
"Last.fm."
msgstr ""
-""
+"Activa o desactiva l'enviament de «scrobbles» i la informació de la "
+"«reproducció actual» a Last.fm."
#: data/ui/AboutDialog.ui.in:9
msgid "Copyright © 2018 GNOME Music Developers"
-msgstr "Copyright © 2018 els desenvolupadors del Música del GNOME"
+msgstr "Copyright © 2018 l'equip de desenvolupament del Música del GNOME"
#: data/ui/AboutDialog.ui.in:10
msgid "A music player and management application for GNOME."
@@ -209,15 +210,15 @@ msgstr ""
"La imatge «Magic of the vinyl» d'en Sami Pyylampi està llicenciada sota CC-"
"BY-SA 2.0 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Publicat"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Durada"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Compositor"
@@ -231,7 +232,7 @@ msgstr "Informa de la música que escolteu"
#: data/ui/AppMenu.ui:69
msgid "_Keyboard Shortcuts"
-msgstr "_Tecles de drecera"
+msgstr "_Dreceres de teclat"
#: data/ui/AppMenu.ui:83
msgid "_Help"
@@ -249,16 +250,16 @@ msgstr "Menú"
msgid "Select"
msgstr "Selecciona"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Cancel·la"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Cerca"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Enrere"
@@ -352,6 +353,8 @@ msgid ""
"Last.fm is a music discovery service that gives you personalised "
"recommendations based on the music you listen to."
msgstr ""
+"Last.fm és un servei de descobriment de música que us dóna recomanacions "
+"personalitzades basades en la música que escolteu."
#: data/ui/LastfmDialog.ui:32 gnomemusic/widgets/lastfmdialog.py:58
msgid "Music Reporting Not Setup"
@@ -359,12 +362,18 @@ msgstr "La informe de la música no configurat"
#: data/ui/LastfmDialog.ui:46 gnomemusic/widgets/lastfmdialog.py:61
msgid "Login to your Last.fm account to report your music listening."
-msgstr "Inicieu la sessió amb el compte de Last.fm per a informar de la música que escolteu."
+msgstr ""
+"Inicieu la sessió amb el compte de Last.fm per a informar de la música que "
+"escolteu."
#: data/ui/LastfmDialog.ui:57 gnomemusic/widgets/lastfmdialog.py:59
msgid "Login"
msgstr "Inicia la sessió"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "S'està carregant"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Mescla"
@@ -382,15 +391,15 @@ msgstr "Repeteix la cançó"
msgid "Shuffle/Repeat Off"
msgstr "Aleatori/Repetició desactivada"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Anterior"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Reprodueix"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Següent"
@@ -423,7 +432,7 @@ msgstr "_Canvia el nom…"
msgid "Playlist Name"
msgstr "Nom de la llista de reproducció"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Fet"
@@ -451,19 +460,23 @@ msgstr "Afegeix a la llista de reproducció"
msgid "_Add"
msgstr "_Afegeix"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:51
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Desfés"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Artistes"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Mostra-ho tot"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Àlbums"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:49
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Cançons"
@@ -477,70 +490,70 @@ msgstr "No en seleccionis cap"
#: data/ui/SelectionBarMenuButton.ui:31 gnomemusic/widgets/headerbar.py:71
msgid "Click on items to select them"
-msgstr "Feu clic als elements per seleccionar-los"
+msgstr "Feu clic als elements per a seleccionar-los"
#: data/ui/SelectionToolbar.ui:9
msgid "_Add to Playlist"
msgstr "_Afegeix a la llista de reproducció"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:827
msgid "Most Played"
msgstr "Més reproduïdes"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:880
msgid "Never Played"
msgstr "Mai s'han reproduït"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:932
msgid "Recently Played"
msgstr "Reproduccions recents"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:994
msgid "Recently Added"
msgstr "Afegits recentment"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1056
msgid "Favorite Songs"
msgstr "Cançons preferides"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "No s'ha pogut reproduir el fitxer"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Cerca a {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " i "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
-msgstr[0] "Cal {} per reproduir el fitxer però no està instal·lat."
-msgstr[1] "Calen {} per reproduir el fitxer però no estan instal·lats."
+msgstr[0] "uCal {} per a reproduir el fitxer però no està instal·lat."
+msgstr[1] "Calen {} per a reproduir el fitxer però no estan instal·lats."
#: gnomemusic/inhibitsuspend.py:63
msgid "Playing music"
msgstr "Reproducció de música"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Àlbum desconegut"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Artista desconegut"
@@ -558,62 +571,62 @@ msgstr "Carpeta de la música"
msgid "The contents of your {} will appear here."
msgstr "Els continguts de la {} apareixeran aquí."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Ep, DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "No s'ha trobat música"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Proveu una cerca diferent"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "El Música del GNOME no s'ha pogut connectar al Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr ""
"Els fitxers de música no es poden indexar si el Tracker no s'està executant"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "El vostre Tracker del sistema sembla obsolet"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "El Música necessita Tracker versió 2.3.0 o superior"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "El Música necessita Tracker versió 3.0.0 o superior"
-#: gnomemusic/views/playlistsview.py:53
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Llistes de reproducció"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Resultats d'artistes"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Resultats d'àlbums"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minut"
msgstr[1] "{} minuts"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disc {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "{} element seleccionat"
-msgstr[1] "{} elements seleccionats"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} cançó seleccionada"
+msgstr[1] "{} cançons seleccionades"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -632,27 +645,19 @@ msgstr "Sessió iniciada com a {}"
msgid "Configure"
msgstr "Configura"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "S'està carregant"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Desfés"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "S'ha suprimit la llista de reproducció {}"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} suprimit de {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Fes una pausa"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} cançó"
diff --git a/po/cs.po b/po/cs.po
index 1757b204..668639bf 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -10,8 +10,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-22 01:05+0000\n"
-"PO-Revision-Date: 2020-02-23 11:06+0100\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-08-28 22:16+0200\n"
"Last-Translator: Marek Černocký <marek@manet.cz>\n"
"Language-Team: ÄeÅ¡tina <gnome-cs-list@gnome.org>\n"
"Language: cs\n"
@@ -46,12 +46,12 @@ msgstr ""
"Hledejte si skladby ve své hudební sbírce, přistupujte k hudbě na serverech "
"DLNA nebo zkuste něco nového díky službám Jamendo a Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Vývojáři Hudby GNOME"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Hudba"
@@ -207,15 +207,15 @@ msgstr ""
"Obrázek „Magic of the vinyl“ od autora Sami Pyylampi je licencován pod CC-BY-"
"SA 2.0 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Vydáno"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Délka"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Skladatel"
@@ -247,16 +247,16 @@ msgstr "Nabídka"
msgid "Select"
msgstr "Vybrat"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Zrušit"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Hledat"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Zpět"
@@ -360,12 +360,17 @@ msgstr "Sdělování informací není nastavené"
#: data/ui/LastfmDialog.ui:46 gnomemusic/widgets/lastfmdialog.py:61
msgid "Login to your Last.fm account to report your music listening."
msgstr ""
-"Aby se mohly sdělovat informace, co posloucháte, musíte s k Last.fm přihlásit."
+"Aby se mohly sdělovat informace, co posloucháte, musíte s k Last.fm "
+"přihlásit."
#: data/ui/LastfmDialog.ui:57 gnomemusic/widgets/lastfmdialog.py:59
msgid "Login"
msgstr "Přihlásit"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "NaÄítá se"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Náhodně zamíchat"
@@ -383,15 +388,15 @@ msgstr "Opakovat skladbu"
msgid "Shuffle/Repeat Off"
msgstr "Náhodně/opakování vypnuto"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Předchozí"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Přehrát"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Následující"
@@ -424,7 +429,7 @@ msgstr "_Přejmenovat…"
msgid "Playlist Name"
msgstr "Název seznamu k přehrání"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Hotovo"
@@ -452,19 +457,23 @@ msgstr "Přidání do seznamu k přehrání"
msgid "_Add"
msgstr "Přid_at"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Zpět"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Umělci"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Zobrazit vše"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Alba"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Skladby"
@@ -485,49 +494,49 @@ msgid "_Add to Playlist"
msgstr "Přid_at do seznamu k přehrání"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "NejÄastÄ›ji pÅ™ehráváno"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Nikdy nepřehráno"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Nedávno přehráno"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Nedávno přidáno"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Oblíbené skladby"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Soubor nelze přehrát"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Hledat v instalátoru {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " a "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "K přehrání souboru je zapotřebí kodek {}, ale není nainstalován."
@@ -540,11 +549,11 @@ msgstr[2] ""
msgid "Playing music"
msgstr "Přehrává se hudba"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Neznámé album"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Neznámý umělec"
@@ -562,63 +571,63 @@ msgstr "Složka s hudbou"
msgid "The contents of your {} will appear here."
msgstr "Zde se objeví, co obsahuje vaše {}."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hej, DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Nenalezena žádná hudba"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Zkuste hledat nějak jinak"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "Hudbě GNOME se nezdařilo spojit s programem Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Pokud ten neběží, není možné indexovat hudební soubory"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Verze programu Tracker je pravděpodoně zastaralá"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Hudba potřebuje program Tracker ve verzi 2.3.0 nebo vyšší"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Hudba potřebuje program Tracker ve verzi 3.0.0 nebo vyšší"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Seznamy k přehrání"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Nalezení umělci"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Nalezená alba"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minuta"
msgstr[1] "{} minuty"
msgstr[2] "{} minut"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disk {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Vybrána {} položka"
-msgstr[1] "Vybrány {} položky"
-msgstr[2] "Vybráno {} položek"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Vybrána {} skladba"
+msgstr[1] "Vybrány {} skladby"
+msgstr[2] "Vybráno {} skladeb"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -637,27 +646,19 @@ msgstr "Přihlášeno pod jménem {}"
msgid "Configure"
msgstr "Nastavit"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "NaÄítá se"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Zpět"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Seznam k přehrání {} byl odstraněn"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "Skladba {} byla odebrána ze seznamu {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pozastavit"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} skladba"
diff --git a/po/da.po b/po/da.po
index d6cb0800..fe45ed07 100644
--- a/po/da.po
+++ b/po/da.po
@@ -12,8 +12,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 11:24+0000\n"
-"PO-Revision-Date: 2020-02-16 13:58+0100\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-09-08 19:24+0200\n"
"Last-Translator: Alan Mortensen <alanmortensen.am@gmail.com>\n"
"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
"Language: da\n"
@@ -23,7 +23,7 @@ msgstr ""
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Language: da_DK\n"
"X-Source-Language: C\n"
-"X-Generator: Poedit 2.0.6\n"
+"X-Generator: Poedit 2.3\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -50,12 +50,12 @@ msgstr ""
"Find spor i din lokale samling, hent musik fra DLNA-servere eller prøv noget "
"nyt med tjenesterne Jamendo og Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:67
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "GNOME Musik-udviklerne"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Musik"
@@ -212,15 +212,15 @@ msgstr ""
"“Magic of the vinyl†af Sami Pyylampi, billede er licenseret af CC-BY-SA 2.0 "
"https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Udgivet"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Spilletid"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Komponist"
@@ -252,16 +252,16 @@ msgstr "Menu"
msgid "Select"
msgstr "Vælg"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Annullér"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Søg"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Tilbage"
@@ -372,6 +372,10 @@ msgstr ""
msgid "Login"
msgstr "Log ind"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Indlæser"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Bland"
@@ -389,15 +393,15 @@ msgstr "Gentag sang"
msgid "Shuffle/Repeat Off"
msgstr "Bland/gentag fra"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Forrige"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Afspil"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Næste"
@@ -430,7 +434,7 @@ msgstr "_Omdøb …"
msgid "Playlist Name"
msgstr "Navn på afspilningsliste"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Færdig"
@@ -458,19 +462,23 @@ msgstr "Tilføj til afspilningsliste"
msgid "_Add"
msgstr "_Tilføj"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:51
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Fortryd"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Kunstnere"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Vis alle"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Album"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:49
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Sange"
@@ -491,49 +499,49 @@ msgid "_Add to Playlist"
msgstr "_Tilføj til afspilningsliste"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Mest afspillet"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Aldrig afspillet"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Afspillet for nylig"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Tilføjet for nylig"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Yndlingssange"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Kan ikke afspille filen"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Find i {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " og "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} kræves for at afspille filen, men er ikke installeret."
@@ -543,11 +551,11 @@ msgstr[1] "{} kræves for at afspille filen, men er ikke installeret."
msgid "Playing music"
msgstr "Afspiller musik"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Ukendt album"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Ukendt kunstner"
@@ -565,61 +573,61 @@ msgstr "Musikmappe"
msgid "The contents of your {} will appear here."
msgstr "Indholdet af din {} vil blive vist her."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hey DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Ingen musik fundet"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Prøv en anden søgning"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME Musik kunne ikke forbinde til Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Dine musikfiler kan ikke indekseres, hvis ikke Tracker kører"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Dit system synes at have en gammel version af Tracker"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Musik kræver Tracker version 2.3.0 eller nyere"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Musik kræver Tracker version 3.0.0 eller nyere"
-#: gnomemusic/views/playlistsview.py:53
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Afspilningslister"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Resultater — kunstnere"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Resultater — albummer"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minut"
msgstr[1] "{} minutter"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disk {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "{} element valgt"
-msgstr[1] "{} elementer valgt"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} sang valgt"
+msgstr[1] "{} sange valgt"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -638,27 +646,19 @@ msgstr "Logget ind som {}"
msgid "Configure"
msgstr "Konfigurér"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Indlæser"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Fortryd"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Afspilningslisten {} fjernet"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} fjernet fra {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pause"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} sang"
diff --git a/po/de.po b/po/de.po
index 67704090..364a6d42 100644
--- a/po/de.po
+++ b/po/de.po
@@ -4,7 +4,8 @@
#
# music listening = Musikverlauf
#
-# Mario Blättermann <mario.blaettermann@gmail.com>, 2013, 2016-2018.
+#
+# Mario Blättermann <mario.blaettermann@gmail.com>, 2013, 2016-2018, 2020.
# Tobias Endrigkeit <tobiasendrigkeit@outlook.com>, 2013.
# Christian Kirbach <christian.kirbach@gmail.com>, 2013.
# Benjamin Steinwender <b@stbe.at>, 2013.
@@ -12,21 +13,20 @@
# Bernd Homuth <dev@hmt.im>, 2014, 2015.
# Vinzenz Vietzke <vinz@vinzv.de>, 2018.
# Tim Sabsch <tim@sabsch.com>, 2019-2020.
-#
msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-03-02 23:22+0000\n"
-"PO-Revision-Date: 2020-02-19 20:40+0100\n"
-"Last-Translator: Tim Sabsch <tim@sabsch.com>\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-09-04 16:54+0200\n"
+"Last-Translator: Mario Blättermann <mario.blaettermann@gmail.com>\n"
"Language-Team: Deutsch <gnome-de@gnome.org>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.2.4\n"
+"X-Generator: Lokalize 20.08.0\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -54,12 +54,12 @@ msgstr ""
"Finden Sie Titel in Ihrer lokalen Sammlung, beziehen Sie Musik von DLNA-"
"Servern oder entdecken Sie Neues mit den Diensten Jamendo und Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:97
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Die GNOME-Musik-Entwickler"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Musik"
@@ -221,15 +221,15 @@ msgstr ""
"Das Bild “Magic of the vinyl†von Sami Pyylampi ist unter CC-BY-SA 2.0 "
"lizenziert, https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Erschienen"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Spielzeit"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Komponist"
@@ -261,16 +261,16 @@ msgstr "Menü"
msgid "Select"
msgstr "Auswählen"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "A_bbrechen"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Suchen"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Zurück"
@@ -380,6 +380,10 @@ msgstr ""
msgid "Login"
msgstr "Anmelden"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Laden"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Zufällig"
@@ -397,15 +401,15 @@ msgstr "Titel wiederholen"
msgid "Shuffle/Repeat Off"
msgstr "Zufall/Wiederholung aus"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Vorheriges"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Wiedergeben"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Nächstes"
@@ -438,7 +442,7 @@ msgstr "_Umbenennen …"
msgid "Playlist Name"
msgstr "Name der Wiedergabeliste"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Fertig"
@@ -466,19 +470,23 @@ msgstr "Zur Wiedergabeliste hinzufügen"
msgid "_Add"
msgstr "_Hinzufügen"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Rückgängig"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Künstler"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Alle ansehen"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Alben"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Titel"
@@ -499,49 +507,49 @@ msgid "_Add to Playlist"
msgstr "Zur Wiedergabeliste _hinzufügen"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:822
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Am häufigsten wiedergegeben"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:859
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Noch nie wiedergegeben"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:895
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Zuletzt wiedergegeben"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:941
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Zuletzt hinzugefügt"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:986
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Lieblingstitel"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Datei kann nicht abgespielt werden"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "In {} _suchen"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " und "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] ""
@@ -553,11 +561,11 @@ msgstr[1] ""
msgid "Playing music"
msgstr "Musik wird wiedergegeben"
-#: gnomemusic/utils.py:65
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Unbekanntes Album"
-#: gnomemusic/utils.py:86
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Unbekannter Künstler"
@@ -576,61 +584,64 @@ msgstr "Musikordner"
msgid "The contents of your {} will appear here."
msgstr "Der Inhalt von Ihrem {} wird hier angezeigt werden."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hey DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Keine Musik gefunden"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Andere Suche ausprobieren"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME Musik konnte nicht mit Tracker verbunden werden"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Ihre Musikdateien können nicht ohne Tracker indiziert werden"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Ihre Systemversion von Tracker scheint veraltet zu sein"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Musik benötigt Tracker-Version 2.3.0 oder neuer"
+#: gnomemusic/views/emptyview.py:146
+#| msgid "Music needs Tracker version 2.3.0 or higher"
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Musik benötigt Tracker-Version 3.0.0 oder neuer"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Wiedergabelisten"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Künstler-Ergebnisse"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Alben-Ergebnisse"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} Minute"
msgstr[1] "{} Minuten"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disc {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "{} Objekt gewählt"
-msgstr[1] "{} Objekte gewählt"
+#| msgid "Selected {} item"
+#| msgid_plural "Selected {} items"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} Titel gewählt"
+msgstr[1] "{} Titel gewählt"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -649,27 +660,19 @@ msgstr "Angemeldet als {}"
msgid "Configure"
msgstr "Einrichten"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Laden"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Rückgängig"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Wiedergabeliste {} entfernt"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} von {} entfernt"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pause"
-#: gnomemusic/widgets/playlistcontrols.py:126
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} Titel"
diff --git a/po/el.po b/po/el.po
index 26286a5d..eb900546 100644
--- a/po/el.po
+++ b/po/el.po
@@ -10,16 +10,16 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2019-11-09 21:05+0000\n"
-"PO-Revision-Date: 2020-01-07 01:04+0200\n"
-"Last-Translator: Efstathios Iosifidis <iosifidis@opensuse.org>\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-09-09 00:32+0300\n"
+"Last-Translator: Efstathios Iosifidis <eiosifidis@gnome.org>\n"
"Language-Team: Greek, Modern (1453-) <gnome-el-list@gnome.org>\n"
"Language: el\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.2.4\n"
+"X-Generator: Poedit 2.3\n"
"X-Project-Style: gnome\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
@@ -49,12 +49,12 @@ msgstr ""
"διακομιστές DLNA ή δοκιμάστε κάτι καινοÏÏιο με το Jamendo και τις υπηÏεσίες "
"Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:52
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Οι Ï€ÏογÏαμματιστές του GNOME Music"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:59
-#: gnomemusic/window.py:77
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Μουσική"
@@ -135,6 +135,18 @@ msgstr ""
"ΕνεÏγοποίηση ή απενεÏγοποίηση την αναστολή συστήματος αναστολής κατά την "
"αναπαÏαγωγή μουσικής"
+#: data/org.gnome.Music.gschema.xml:48
+msgid "Report music history to Last.fm"
+msgstr "ΑναφοÏά ιστοÏÎ¹ÎºÎ¿Ï Î¼Î¿Ï…ÏƒÎ¹ÎºÎ®Ï‚ στην Last.fm"
+
+#: data/org.gnome.Music.gschema.xml:49
+msgid ""
+"Enables or disables sending scrobbles and the “currently playing†info to "
+"Last.fm."
+msgstr ""
+"ΕνεÏγοποιεί ή απενεÏγοποιεί την αποστολή πληÏοφοÏιών αÏχείων \"που "
+"αναπαÏάγονται αυτήν τη στιγμή\" στο Last.fm."
+
#: data/ui/AboutDialog.ui.in:9
msgid "Copyright © 2018 GNOME Music Developers"
msgstr "Πνευματικά δικαιώματα © 2018 GNOME Music Developers"
@@ -201,27 +213,35 @@ msgstr ""
"\"Magic of the vinyl\" από Sami Pyylampi εικόνα υπό την άδεια CC-BY-SA 2.0 "
"https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "ΚυκλοφόÏησε"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "ΕκτελοÏμενη διάÏκεια"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Συνθέτης"
-#: data/ui/AppMenu.ui:21
+#: data/ui/AppMenu.ui:20 data/ui/LastfmDialog.ui:8
+msgid "Last.fm Account"
+msgstr "ΛογαÏιασμός Last.fm"
+
+#: data/ui/AppMenu.ui:38
+msgid "Report Music Listening"
+msgstr "ΑναφοÏά ακÏόασης μουσικής"
+
+#: data/ui/AppMenu.ui:69
msgid "_Keyboard Shortcuts"
msgstr "1821"
-#: data/ui/AppMenu.ui:35
+#: data/ui/AppMenu.ui:83
msgid "_Help"
msgstr "_Βοήθεια"
-#: data/ui/AppMenu.ui:49
+#: data/ui/AppMenu.ui:97
msgid "_About Music"
msgstr "_ΠεÏί του Μουσική"
@@ -233,16 +253,16 @@ msgstr "ΜενοÏ"
msgid "Select"
msgstr "Επιλογή"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "ΑκÏ_Ïωση"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Αναζήτηση"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Πίσω"
@@ -331,6 +351,31 @@ msgctxt "shortcut window"
msgid "Go back"
msgstr "Μετάβαση πίσω"
+#: data/ui/LastfmDialog.ui:21
+msgid ""
+"Last.fm is a music discovery service that gives you personalised "
+"recommendations based on the music you listen to."
+msgstr ""
+"Το Last.fm είναι μια υπηÏεσία που ανακαλÏπτετε μουσική και σας παÏέχει "
+"εξατομικευμένες Ï€Ïοτάσεις βάσει της μουσικής που ακοÏτε."
+
+#: data/ui/LastfmDialog.ui:32 gnomemusic/widgets/lastfmdialog.py:58
+msgid "Music Reporting Not Setup"
+msgstr "Δεν είναι Ïυθμισμένη η αναφοÏά μουσικής"
+
+#: data/ui/LastfmDialog.ui:46 gnomemusic/widgets/lastfmdialog.py:61
+msgid "Login to your Last.fm account to report your music listening."
+msgstr ""
+"Συνδεθείτε στον λογαÏιασμό σας Last.fm για να αναφέÏετε τη μουσική σας."
+
+#: data/ui/LastfmDialog.ui:57 gnomemusic/widgets/lastfmdialog.py:59
+msgid "Login"
+msgstr "ΣÏνδεση"
+
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Γίνεται φόÏτωση"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Τυχαία σειÏά"
@@ -348,15 +393,15 @@ msgstr "Επανάληψη Ï„ÏαγουδιοÏ"
msgid "Shuffle/Repeat Off"
msgstr "Τυχαία σειÏά/ΑνενεÏγή επανάληψη"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "ΠÏοηγοÏμενο"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:159
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "ΑναπαÏαγωγή"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Επόμενο"
@@ -385,7 +430,7 @@ msgstr "_ΔιαγÏαφή"
msgid "_Rename…"
msgstr "_Μετονομασία…"
-#: data/ui/PlaylistControls.ui:40
+#: data/ui/PlaylistControls.ui:41
msgid "Playlist Name"
msgstr "Όνομα λίστας αναπαÏαγωγής"
@@ -417,19 +462,23 @@ msgstr "ΠÏοσθήκη στη λίστα αναπαÏαγωγής"
msgid "_Add"
msgstr "_ΠÏοσθήκη"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:59
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "Α_ναίÏεση"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Καλλιτέχνες"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "ΠÏοβολή όλων"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:63
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Δίσκοι"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:57
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "ΤÏαγοÏδια"
@@ -441,7 +490,7 @@ msgstr "Επιλογή όλων"
msgid "Select None"
msgstr "Καμία επιλογή"
-#: data/ui/SelectionBarMenuButton.ui:31 gnomemusic/widgets/headerbar.py:75
+#: data/ui/SelectionBarMenuButton.ui:31 gnomemusic/widgets/headerbar.py:71
msgid "Click on items to select them"
msgstr "Πατήστε σε αντικείμενα για να τα επιλέξετε"
@@ -450,49 +499,49 @@ msgid "_Add to Playlist"
msgstr "ΠÏο_σθήκη στη λίστα αναπαÏαγωγής"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:727
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Το πεÏισσότεÏο παιγμένο"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:764
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Δεν παίχτηκε ποτέ"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:800
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Παίχτηκε Ï€Ïόσφατα"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:846
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "ΠÏοστέθηκε Ï€Ïόσφατα"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:891
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Αγαπημένα Ï„ÏαγοÏδια"
-#: gnomemusic/gstplayer.py:403
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "ΑδÏνατη η αναπαÏαγωγή του αÏχείου"
-#: gnomemusic/gstplayer.py:409
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "ΕÏ_Ïεση στο {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:420
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " και "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:423
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:425
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] ""
@@ -500,112 +549,120 @@ msgstr[0] ""
msgstr[1] ""
"ΑπαιτοÏνται τα {} για αναπαÏαγωγή του αÏχείου, αλλά δεν είναι εγκατεστημένα."
-#: gnomemusic/inhibitsuspend.py:72
+#: gnomemusic/inhibitsuspend.py:63
msgid "Playing music"
msgstr "ΑναπαÏαγωγή μουσικής"
-#: gnomemusic/utils.py:62
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Άγνωστο άλμπουμ"
-#: gnomemusic/utils.py:83
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Άγνωστος καλλιτέχνης"
-#: gnomemusic/views/emptyview.py:73
+#: gnomemusic/views/emptyview.py:67
msgid "Your XDG Music directory is not set."
msgstr "Ο κατάλογός Μουσική XDG δεν έχει Ïυθμιστεί."
-#: gnomemusic/views/emptyview.py:80
+#: gnomemusic/views/emptyview.py:74
msgid "Music folder"
msgstr "Φάκελος μουσικής"
#. TRANSLATORS: This is a label to display a link to open user's music
#. folder. {} will be replaced with the translated text 'Music folder'
-#: gnomemusic/views/emptyview.py:84
+#: gnomemusic/views/emptyview.py:78
msgid "The contents of your {} will appear here."
msgstr "Τα πεÏιεχόμενα του {} θα εμφανιστοÏν εδώ."
-#: gnomemusic/views/emptyview.py:120
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Γεια σου DJ"
-#: gnomemusic/views/emptyview.py:130 gnomemusic/views/emptyview.py:136
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Δεν βÏέθηκε μουσική"
-#: gnomemusic/views/emptyview.py:138
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Δοκιμάστε μια διαφοÏετική αναζήτηση"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "Το GNOME Music δεν μπόÏεσε να συνδεθεί με το Tracker"
-#: gnomemusic/views/emptyview.py:147
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr ""
"Δεν είναι δυνατή η ευÏετηÏίαση των αÏχείων μουσικής σας χωÏίς την εκτέλεση "
"του Tracker"
-#: gnomemusic/views/emptyview.py:155
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Η έκδοση Tracker του συστήματος είναι παÏωχημένη"
-#: gnomemusic/views/emptyview.py:158
-#| msgid "Music needs Tracker version 2.2.0 or higher"
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Η Μουσική χÏειάζεται έκδοση Tracker 2.3.0 ή μεγαλÏτεÏη"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Η Μουσική χÏειάζεται έκδοση Tracker 3.0.0 ή μεγαλÏτεÏη"
-#: gnomemusic/views/playlistsview.py:58
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Λίστες αναπαÏαγωγής"
-#: gnomemusic/views/searchview.py:366
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Αποτελέσματα Καλλιτεχνών"
-#: gnomemusic/views/searchview.py:380
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Αποτελέσματα Δίσκων"
-#: gnomemusic/widgets/albumwidget.py:145
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} λεπτό"
msgstr[1] "{} λεπτά"
-#: gnomemusic/widgets/disclistboxwidget.py:82
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Δίσκος {}"
-#: gnomemusic/widgets/headerbar.py:72
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Επιλέχθηκε %d στοιχείο"
-msgstr[1] "Επιλέχθηκαν %d στοιχεία"
+#: gnomemusic/widgets/headerbar.py:68
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Επιλέχθηκε {} Ï„ÏαγοÏδι"
+msgstr[1] "Επιλέχθηκαν {} Ï„ÏαγοÏδια"
-#: gnomemusic/widgets/notificationspopup.py:168
-msgid "Loading"
-msgstr "Γίνεται φόÏτωση"
+#: gnomemusic/widgets/lastfmdialog.py:65
+msgid "Your music listening is reported to Last.fm."
+msgstr "Η μουσική που ακοÏτε αναφέÏεται στο Last.fm."
-#: gnomemusic/widgets/notificationspopup.py:241
-msgid "_Undo"
-msgstr "Α_ναίÏεση"
+#: gnomemusic/widgets/lastfmdialog.py:67
+msgid "Your music listening is not reported to Last.fm."
+msgstr "Η μουσική που ακοÏτε δεν αναφέÏεται στο Last.fm."
+
+#. TRANSLATORS: displays the username of the Last.fm account
+#: gnomemusic/widgets/lastfmdialog.py:71
+msgid "Logged in as {}"
+msgstr "Συνδεδεμένος ως {}"
+
+#: gnomemusic/widgets/lastfmdialog.py:72
+msgid "Configure"
+msgstr "ΡÏθμιση"
-#: gnomemusic/widgets/notificationspopup.py:256
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "ΑφαιÏέθηκε η λίστα αναπαÏαγωγής {}"
-#: gnomemusic/widgets/notificationspopup.py:260
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} αφαιÏέθηκε από {}"
-#: gnomemusic/widgets/playertoolbar.py:156
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "ΠαÏση"
-#: gnomemusic/widgets/playlistcontrols.py:83
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} Ï„ÏαγοÏδι"
diff --git a/po/es.po b/po/es.po
index 7d85205c..b4b09717 100644
--- a/po/es.po
+++ b/po/es.po
@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 14:09+0000\n"
-"PO-Revision-Date: 2020-02-17 11:50+0100\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-09-01 10:58+0200\n"
"Last-Translator: Daniel Mustieles <daniel.mustieles@gmail.com>\n"
"Language-Team: Spanish - Spain <gnome-es-list@gnome.org>\n"
"Language: es_ES\n"
@@ -18,7 +18,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Gtranslator 3.34.0\n"
+"X-Generator: Gtranslator 3.36.0\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -45,12 +45,12 @@ msgstr ""
"Buscar pistas en su colección local, obtener música de servidores DNA o "
"probar algo nuevo con los servicios de Jamendo y Magnatunes."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Los desarrolladores de GNOME Música"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "MuÌsica"
@@ -206,15 +206,15 @@ msgstr ""
"La imagen «Magic of the vinyl» de Sami Pyylampi está licenciada bajo la CC-"
"BY-SA 2.0 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Publicado"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Duración"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Compositor"
@@ -246,16 +246,16 @@ msgstr "MenuÌ"
msgid "Select"
msgstr "Seleccionar"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Cancelar"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Buscar"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "AtraÌs"
@@ -365,6 +365,10 @@ msgstr ""
msgid "Login"
msgstr "Iniciar sesión"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Cargando"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Mezclar"
@@ -382,15 +386,15 @@ msgstr "Repetir canción"
msgid "Shuffle/Repeat Off"
msgstr "No mezclar ni repetir"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Anterior"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Reproducir"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Siguiente"
@@ -423,7 +427,7 @@ msgstr "_Renombrar…"
msgid "Playlist Name"
msgstr "Nombre de la lista de reproducción"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Hecho"
@@ -451,19 +455,23 @@ msgstr "Añadir a la lista de reproducción"
msgid "_Add"
msgstr "_Añadir"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Deshacer"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Artistas"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Ver todo"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Ãlbumes"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Canciones"
@@ -484,49 +492,49 @@ msgid "_Add to Playlist"
msgstr "Añadir a la _lista de reproducción"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Más reproducidas"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "No reproducidas nunca"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Reproducidas recientemente"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Añadidas recientemente"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Canciones favoritas"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "No se puede reproducir el archivo"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Buscar en {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " y "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "Se necesita {} para reproducir el archivo, pero no está instalado."
@@ -537,11 +545,11 @@ msgstr[1] ""
msgid "Playing music"
msgstr "Reproducir música"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Ãlbum desconocido"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Artista desconocido"
@@ -559,70 +567,69 @@ msgstr "Carpeta de música"
msgid "The contents of your {} will appear here."
msgstr "El contenido de su {} aparecerá aquí."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hola Dj"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "No se ha encontrado música"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Pruebe a hacer una búsqueda diferente"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME Música no se ha podido conectar a Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr ""
"Sus archivos de música no se pueden indexar si Tracker no está en ejecución"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Su versión de Tracker no está actualizada"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Música necesita Tracker 2.3.0 o superior"
+#: gnomemusic/views/emptyview.py:146
+#| msgid "Music needs Tracker version 2.3.0 or higher"
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Música necesita Tracker 3.3.0 o superior"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Listas de reproducción"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Resultados de artistas"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Resultados de álbumes"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minuto"
msgstr[1] "{} minutos"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disco {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "{} elemento seleccionado"
-msgstr[1] "{} elementos seleccionados"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} canción seleccionada"
+msgstr[1] "{} canciones seleccionadas"
#: gnomemusic/widgets/lastfmdialog.py:65
-#| msgid "Report music history to Last.fm"
msgid "Your music listening is reported to Last.fm."
msgstr "La música que escucha se envía a Last.fm."
#: gnomemusic/widgets/lastfmdialog.py:67
-#| msgid "Report music history to Last.fm"
msgid "Your music listening is not reported to Last.fm."
msgstr "La música que escucha no se envía a Last.fm."
@@ -635,27 +642,19 @@ msgstr "Sesión iniciada como {}"
msgid "Configure"
msgstr "Configurar"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Cargando"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Deshacer"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Lista de reproducción {} eliminada"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} eliminado de {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pausar"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} canción"
diff --git a/po/eu.po b/po/eu.po
index ad341c98..f6ad5314 100644
--- a/po/eu.po
+++ b/po/eu.po
@@ -3,13 +3,13 @@
# This file is distributed under the same license as the gnome-music package.
#
# Iñaki Larrañaga Murgoitio <dooteo@zundan.com>, 2013, 2014, 2015, 2016, 2017.
-# Asier Sarasua Garmendia <asier.saraua@gmail.com>, 2013, 2019, 2020.
+# Asier Sarasua Garmendia <asiersarasua@ni.eus>, 2013, 2019, 2020.
msgid ""
msgstr "Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 11:24+0000\n"
-"PO-Revision-Date: 2020-02-15 10:00+0100\n"
-"Last-Translator: Asier Sarasua Garmendia <asier.sarasua@gmail.com>\n"
+"POT-Creation-Date: 2020-09-01 11:41+0000\n"
+"PO-Revision-Date: 2020-09-01 10:00+0100\n"
+"Last-Translator: Asier Sarasua Garmendia <asiersarasua@ni.eus>\n"
"Language-Team: Basque <librezale@librezale.eus>\n"
"Language: eu\n"
"MIME-Version: 1.0\n"
@@ -38,12 +38,12 @@ msgid ""
"something new with the Jamendo and Magnatune services."
msgstr "Aurkitu pistak zure bilduma lokalean, eskuratu musika DLNA zerbitzarietatik edo bilatuzerbait berria Jamendu eta Magnatune zerbitzuetan."
-#: data/org.gnome.Music.appdata.xml.in.in:67
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "GNOME Musika aplikazioaren garatzaileak"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Musika"
@@ -180,15 +180,15 @@ msgstr "GNOME Music software librea da; birbana eta/edo alda dezakezu Free Softw
"Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301,\n"
"USA."
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Argitaratua"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Iraupena"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Konpositorea"
@@ -220,16 +220,16 @@ msgstr "Menua"
msgid "Select"
msgstr "Hautatu"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Utzi"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Bilatu"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Atzera"
@@ -336,6 +336,10 @@ msgstr "Hasi saioa zure Last.fm kontuan entzuten duzun musikaren berri emateko."
msgid "Login"
msgstr "Saio-hasiera"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Kargatzen"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Ausaz"
@@ -353,15 +357,15 @@ msgstr "Errepikatu abestia"
msgid "Shuffle/Repeat Off"
msgstr "Ausaz/Ez errepikatu"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Aurrekoa"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Erreproduzitu"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Hurrengoa"
@@ -394,7 +398,7 @@ msgstr "Be_rrizendatu…"
msgid "Playlist Name"
msgstr "Zerrendaren izena"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Eginda"
@@ -422,19 +426,23 @@ msgstr "Gehitu erreprodukzio-zerrendari…"
msgid "_Add"
msgstr "_Gehitu"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:51
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Desegin"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Artistak"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Ikusi dena"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Albumak"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:49
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Abestiak"
@@ -455,49 +463,49 @@ msgid "_Add to Playlist"
msgstr "_Gehitu zerrendari"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:827
msgid "Most Played"
msgstr "Gehien erreproduzitua"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:880
msgid "Never Played"
msgstr "Inoiz erreproduzitu gabea"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:932
msgid "Recently Played"
msgstr "Azken aldian erreproduzitua"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:994
msgid "Recently Added"
msgstr "Azken aldian gehitua"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1056
msgid "Favorite Songs"
msgstr "Gogoko abestiak"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Ezin da fitxategia erreproduzitu"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Bilatu hemen: {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " eta "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} behar da fitxategia erreproduzitzeko, baina ez dago instalatuta."
@@ -507,11 +515,11 @@ msgstr[1] "{} behar dira fitxategia erreproduzitzeko, baina ez daude instalatuta
msgid "Playing music"
msgstr "Musika erreproduzitzen"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Album ezezaguna"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Artista ezezaguna"
@@ -529,61 +537,61 @@ msgstr "Musikaren karpeta"
msgid "The contents of your {} will appear here."
msgstr "Zure {} edukiak hemen agertuko dira."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hi DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Ez da musikarik aurkitu"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Saiatu bestelako bilaketa"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME Musika ezin izan da Tracker-ekin konektatu"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Zure musika-fitxategiak ezin dira indexatu Tracker exekutatzen ez bada"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Zure sistemako Tracker bertsioa zaharkituta dagoela dirudi"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Musika aplikazioak Tracker 2.3.0 bertsioa edo berriagoa behar du"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Musika aplikazioak Tracker 3.0.0 bertsioa edo berriagoa behar du"
-#: gnomemusic/views/playlistsview.py:53
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Erreprodukzio-zerrendak"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Artisten emaitzak"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Albumen emaitzak"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "Minutu {}"
msgstr[1] "{} minutu"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "{} diskoa"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Elementu {} hautatuta"
-msgstr[1] "{} elementu hautatuta"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Abesti {} hautatuta"
+msgstr[1] "{} abesti hautatuta"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -602,27 +610,19 @@ msgstr "Saioa hasita {} erabiltzailearekin"
msgid "Configure"
msgstr "Konfiguratu"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Kargatzen"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Desegin"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "{} zerrenda kenduta"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} kenduta hemendik: {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pausatu"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "Abesti {}"
diff --git a/po/fa.po b/po/fa.po
index 2e143885..3b410298 100644
--- a/po/fa.po
+++ b/po/fa.po
@@ -9,15 +9,15 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 14:09+0000\n"
-"PO-Revision-Date: 2020-02-16 05:57+0000\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-08-31 06:25+0000\n"
"Last-Translator: Danial Behzadi <dani.behzi@ubuntu.com>\n"
"Language-Team: Persian <>\n"
"Language: fa\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.3\n"
+"X-Generator: Poedit 2.4.1\n"
"Plural-Forms: nplurals=1; plural=0;\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
@@ -44,12 +44,12 @@ msgstr ""
"یاÙتن قطعه‌ها روی گنجینهٔ محلّیتان، گرÙتن آهنگ‌ها از کارسازهای DLNA یا آزمودن چیزی "
"جدید با خدمت‌های جمندو و ماگناتون."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "توسعه‌دهندگان آهنگ‌های گنوم"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "آهنگ‌ها"
@@ -195,15 +195,15 @@ msgstr ""
"تصویر «Magic of the vinyl» توسط Sami Pyylampi تحت لیسانس CC-BY-SA 2.0 از https://"
"www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "منتشر شده در"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "طول اجرا"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "آهنگ‌ساز"
@@ -235,16 +235,16 @@ msgstr "Ùهرست"
msgid "Select"
msgstr "گزینش"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_لغو"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "جست‌وجو"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "برگشت"
@@ -353,6 +353,10 @@ msgstr "برای گزارش گوش کردنتان به آهنگ‌ها، وارØ
msgid "Login"
msgstr "ورود"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "در حال بار کردن"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "بر زدن"
@@ -370,15 +374,15 @@ msgstr "تکرار آواز"
msgid "Shuffle/Repeat Off"
msgstr "خاموشی بر زدن/تکرار"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "پیشین"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "پخش"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "بعدی"
@@ -411,7 +415,7 @@ msgstr "_تغییر نام…"
msgid "Playlist Name"
msgstr "نام Ùهرست پخش"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_انجام شد"
@@ -439,19 +443,23 @@ msgstr "اÙزودن به Ùهرست پخش"
msgid "_Add"
msgstr "ا_Ùزودن"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_برگردان"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "هنرمندان"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "نمایش همه"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "آلبوم‌ها"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "آوازها"
@@ -472,49 +480,49 @@ msgid "_Add to Playlist"
msgstr "ا_Ùزودن به Ùهرست پخش"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "بیش‌ترین پخش شده"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "هرگز پخش نشده"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "اخیراً پخش شده"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "اخیراً اضاÙÙ‡ شده"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "آوازهای محبوب"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "نمی‌توان پرونده را پخش کرد"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_یاÙتن در {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " Ùˆ "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr "، "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "برای پخش پرونده نیاز به {} است، ولی نصب نشده."
@@ -523,11 +531,11 @@ msgstr[0] "برای پخش پرونده نیاز به {} است، ولی نصب
msgid "Playing music"
msgstr "در حال پخش آهنگ"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "آلبوم ناشناس"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "هنرمند ناشناس"
@@ -545,59 +553,59 @@ msgstr "شاخهٔ موسیقی"
msgid "The contents of your {} will appear here."
msgstr "محتویات {} شما در اینجا نمایان می‌شوند."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "هی دی‌جی"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "هیچ آهنگی پیدا نشد"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "جست‌وجویی دیگر را بیازمایید"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "آهنگ‌های گنوم نتوانست به ردیاب وصل شود"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "بدون وجود ردیاب، پرونده‌های آهنگتان قادر به Ùهرست‌شدن نیستند"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "به نظر نگارش ردیاب سامانه‌تان قدیمی است"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "آهنگ‌ها به نگارش ۲.۳.۰ یا بالاتر ردیاب نیاز دارد"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "آهنگ‌ها به نگارش ۳٫۰٫۰ یا بالاتر ردیاب نیاز دارد"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Ùهرست‌های پخش"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "نتیجه‌های هنرمندان"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "نتیجه‌های آلبوم‌ها"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} دقیقه"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "دیسک {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "{} مورد گزیده"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} آواز گزیده"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -616,27 +624,19 @@ msgstr "وارد شده به عنوان {}"
msgid "Configure"
msgstr "پیکربندی"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "در حال بار کردن"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_برگردان"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Ùهرست پخش {} برداشته شد"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} از {} برداشته شد"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Ù…Ú©Ø«"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} آهنگ"
diff --git a/po/fi.po b/po/fi.po
index f15854d7..d5e2aeb0 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-22 01:05+0000\n"
-"PO-Revision-Date: 2020-02-22 16:51+0200\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-08-28 18:20+0300\n"
"Last-Translator: Jiri Grönroos <jiri.gronroos+l10n@iki.fi>\n"
"Language-Team: suomi <lokalisointi-lista@googlegroups.com>\n"
"Language: fi\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.3\n"
+"X-Generator: Poedit 2.4.1\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -43,12 +43,12 @@ msgstr ""
"Etsi kappaleita paikallisesta kokoelmastasi, toista musiikkia DLNA-"
"palvelimilta tai löydä jotain uutta Jamendo- ja Magnatune-palveluista."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Gnomen musiikkisoittimen kehittäjät"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Musiikki"
@@ -180,15 +180,15 @@ msgid ""
"https://www.flickr.com/photos/_spy_/12270839403"
msgstr ""
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Julkaistu"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Kesto"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Säveltäjä"
@@ -220,16 +220,16 @@ msgstr "Valikko"
msgid "Select"
msgstr "Valitse"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Peru"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Hae"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Takaisin"
@@ -338,6 +338,10 @@ msgstr "Kirjaudu Last.fm-tilillesi lähettääksesi musiikin kuunteluhistoriasi.
msgid "Login"
msgstr "Kirjaudu"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Ladataan"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Sekoita"
@@ -355,15 +359,15 @@ msgstr "Kertaa kappale"
msgid "Shuffle/Repeat Off"
msgstr "Sekoitus/kertaus pois"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Edellinen"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Toista"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Seuraava"
@@ -396,7 +400,7 @@ msgstr "_Nimeä uudelleen…"
msgid "Playlist Name"
msgstr "Soittolistan nimi"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Valmis"
@@ -424,19 +428,23 @@ msgstr "Lisää soittolistaan"
msgid "_Add"
msgstr "_Lisää"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Kumoa"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Esittäjät"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Näytä kaikki"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Albumit"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Kappaleet"
@@ -457,49 +465,49 @@ msgid "_Add to Playlist"
msgstr "Lisää _soittolistalle"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Eniten toistettu"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Ei koskaan toistettu"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Äskettäin toistettu"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Äskettäin lisätty"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Suosikkikappaleet"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Tiedoston toistaminen epäonnistui"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Etsi sovelluksella {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " ja "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} vaaditaan tiedoston toistamiseksi, mutta sitä ei ole asennettu."
@@ -509,11 +517,11 @@ msgstr[1] "{} vaaditaan tiedoston toistamiseksi, mutta niitä ei ole asennettu."
msgid "Playing music"
msgstr "Toistetaan musiikkia"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Tuntematon albumi"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Tuntematon esittäjä"
@@ -531,61 +539,61 @@ msgstr "Musiikkikansio"
msgid "The contents of your {} will appear here."
msgstr "{}n sisältö ilmestyy tähän."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hei DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Musiikkia ei löytynyt"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Kokeile haku eri ehdoilla"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "Musiikki ei voinut yhdistää Trackeriin"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Musiikkitiedostojasi ei voi indeksoida, jos Tracker ei ole käynnissä"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Järjestelmään asennettu Tracker vaikuttaa olevan vanhentunut"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Musiikki tarvitsee Trackerin version 2.3.0 tai uudemman"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Musiikki tarvitsee Trackerin version 3.0.0 tai uudemman"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Soittolistat"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Esittäjätulokset"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Albumitulokset"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minuutti"
msgstr[1] "{} minuuttia"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Levy {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Valittu {} kohde"
-msgstr[1] "Valittu {} kohdetta"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} kappale valittu"
+msgstr[1] "{} kappaletta valittu"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -604,27 +612,19 @@ msgstr "Kirjautuneena tilillä {}"
msgid "Configure"
msgstr "Määritä"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Ladataan"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Kumoa"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Soittolista {} poistettu"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} poistettu soittolistalta {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Keskeytä"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} kappale"
diff --git a/po/fr.po b/po/fr.po
index b4c6a2a1..822f853c 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -8,21 +8,22 @@
# William Oprandi <william.oprandi@gmail.com>, 2019.
# Charles Monzat <charles.monzat@free.fr>, 2018-2019.
# Julien Humbert <julroy67@gmail.com>, 2020.
+# vanadiae <vanadiae35@gmail.com>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 14:09+0000\n"
-"PO-Revision-Date: 2020-02-17 11:28+0900\n"
-"Last-Translator: Julien Humbert <julroy67@gmail.com>\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-08-28 21:00+0200\n"
+"Last-Translator: vanadiae <vanadiae35@gmail.com>\n"
"Language-Team: GNOME French Team <gnomefr@traduc.org>\n"
-"Language: fr\n"
+"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Poedit 2.3\n"
+"X-Generator: Gtranslator 3.36.0\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -50,12 +51,12 @@ msgstr ""
"serveurs DLNA ou essayez quelque chose de nouveau avec les services Jamendo "
"et Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Les développeurs de l’application Musique de GNOME"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Musique"
@@ -215,15 +216,15 @@ msgstr ""
"L’image « Magic of the vinyl » par Sami Pyylampi est sous licence CC BY-SA "
"2.0 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Publié"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Durée"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Compositeur"
@@ -255,16 +256,16 @@ msgstr "Menu"
msgid "Select"
msgstr "Sélectionner"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "A_nnuler"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Rechercher"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Retour"
@@ -375,6 +376,10 @@ msgstr ""
msgid "Login"
msgstr "Se connecter"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Chargement en cours"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Mélanger"
@@ -392,15 +397,15 @@ msgstr "Répéter le morceau"
msgid "Shuffle/Repeat Off"
msgstr "Désactiver mélanger/répéter"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Précédent"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Lecture"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Suivant"
@@ -433,7 +438,7 @@ msgstr "_Renommer…"
msgid "Playlist Name"
msgstr "Nom de la liste de lecture"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Terminé"
@@ -461,19 +466,23 @@ msgstr "Ajouter à la liste de lecture"
msgid "_Add"
msgstr "_Ajouter"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "Ann_uler"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Artistes"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Tout afficher"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Albums"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Morceaux"
@@ -494,49 +503,49 @@ msgid "_Add to Playlist"
msgstr "_Ajouter à la liste de lecture"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Les plus joués"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Jamais joués"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Joués récemment"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Ajoutés récemment"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Morceaux favoris"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Impossible de lire le fichier"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Trouver dans {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " et "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} est nécessaire pour lire le fichier, mais il n’est pas installé."
@@ -547,11 +556,11 @@ msgstr[1] ""
msgid "Playing music"
msgstr "Lecture de musique en cours"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Album inconnu"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Artiste inconnu"
@@ -569,61 +578,62 @@ msgstr "Dossier de musique"
msgid "The contents of your {} will appear here."
msgstr "Le contenu de votre {} s’affichera ici."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hé DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Aucune musique trouvée"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Essayez une recherche différente"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "Musique ne peut pas se connecter à Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Vos musiques ne peuvent pas être indexées si Tracker ne fonctionne pas"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Votre version de Tracker semble obsolète"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Musique nécessite Tracker version 2.3.0 ou ultérieure"
+#: gnomemusic/views/emptyview.py:146
+#| msgid "Music needs Tracker version 2.3.0 or higher"
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Musique nécessite Tracker version 3.0.0 ou ultérieure"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Listes de lecture"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Résultats pour Artistes"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Résultats pour Albums"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minute"
msgstr[1] "{} minutes"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disque {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "{} élément est sélectionné"
-msgstr[1] "{} éléments sont sélectionnés"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} morceau sélectionné"
+msgstr[1] "{} morceaux sélectionnés"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -642,27 +652,19 @@ msgstr "Connecté en tant que {}"
msgid "Configure"
msgstr "Configurer"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Chargement en cours"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "Ann_uler"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Liste de lecture {} supprimée"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} supprimé de {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pause"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} morceau"
diff --git a/po/fur.po b/po/fur.po
index e9cab3e8..d5dabdca 100644
--- a/po/fur.po
+++ b/po/fur.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-01-26 14:51+0000\n"
-"PO-Revision-Date: 2020-01-27 09:25+0100\n"
+"POT-Creation-Date: 2020-05-30 22:52+0000\n"
+"PO-Revision-Date: 2020-07-14 17:17+0200\n"
"Last-Translator: Fabio Tomat <f.t.public@gmail.com>\n"
"Language-Team: Friulian <fur@li.org>\n"
"Language: fur\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.2.4\n"
+"X-Generator: Poedit 2.3.1\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -43,12 +43,12 @@ msgstr ""
"Cjate i tocs te colezion locâl, oten musiche dai servidôrs DLNA o cîr alc di "
"gnûf cui servizis Jamendo e Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:67
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "I svilupadôrs di GNOME Musiche"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
-#: gnomemusic/window.py:77
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:58
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Musiche"
@@ -206,35 +206,35 @@ msgstr ""
"La imagjin “Magic of the vinyl†by Sami Pyylampi e je in licence di CC-BY-SA "
"2.0 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Publicât"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Durade"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Compositôr"
-#: data/ui/AppMenu.ui:20
+#: data/ui/AppMenu.ui:20 data/ui/LastfmDialog.ui:8
msgid "Last.fm Account"
msgstr "Account Last.fm"
-#: data/ui/AppMenu.ui:39
+#: data/ui/AppMenu.ui:38
msgid "Report Music Listening"
msgstr "Invie la musiche che tu scoltis"
-#: data/ui/AppMenu.ui:70
+#: data/ui/AppMenu.ui:69
msgid "_Keyboard Shortcuts"
msgstr "_Scurtis di tastiere"
-#: data/ui/AppMenu.ui:84
+#: data/ui/AppMenu.ui:83
msgid "_Help"
msgstr "_Jutori"
-#: data/ui/AppMenu.ui:98
+#: data/ui/AppMenu.ui:97
msgid "_About Music"
msgstr "_Informazions su Musiche"
@@ -246,16 +246,16 @@ msgstr "Menù"
msgid "Select"
msgstr "Selezione"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Anule"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Cîr"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Torne indaûr"
@@ -344,6 +344,30 @@ msgctxt "shortcut window"
msgid "Go back"
msgstr "Torne indaûr"
+#: data/ui/LastfmDialog.ui:21
+msgid ""
+"Last.fm is a music discovery service that gives you personalised "
+"recommendations based on the music you listen to."
+msgstr ""
+"Last.fm al è un servizi di scuvierte de musiche che ti da conseis "
+"personalizâts in base ae musiche che tu scoltis."
+
+#: data/ui/LastfmDialog.ui:32 gnomemusic/widgets/lastfmdialog.py:58
+msgid "Music Reporting Not Setup"
+msgstr "Segnalazion de musiche, no configurade"
+
+#: data/ui/LastfmDialog.ui:46 gnomemusic/widgets/lastfmdialog.py:61
+msgid "Login to your Last.fm account to report your music listening."
+msgstr "Jentre tal to account Last.fm par inviâ la musiche che tu scoltis."
+
+#: data/ui/LastfmDialog.ui:57 gnomemusic/widgets/lastfmdialog.py:59
+msgid "Login"
+msgstr "Jentre"
+
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Daûr a cjariâ"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Messede"
@@ -361,15 +385,15 @@ msgstr "Ripet cjançon"
msgid "Shuffle/Repeat Off"
msgstr "Messede/ripet studâts"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Precedent"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:159
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:147
msgid "Play"
msgstr "Sune"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Prossim"
@@ -398,7 +422,7 @@ msgstr "_Scancele"
msgid "_Rename…"
msgstr "_Cambie non…"
-#: data/ui/PlaylistControls.ui:40
+#: data/ui/PlaylistControls.ui:41
msgid "Playlist Name"
msgstr "Non de liste des musichis"
@@ -430,19 +454,23 @@ msgstr "Zonte ae liste des musichis"
msgid "_Add"
msgstr "_Zonte"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:59
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "A_nule"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Artiscj"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Visualize dut"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:62
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Album"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:57
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:45
msgid "Songs"
msgstr "Cjancçons"
@@ -454,7 +482,7 @@ msgstr "Selezione dut"
msgid "Select None"
msgstr "Selezione nuie"
-#: data/ui/SelectionBarMenuButton.ui:31 gnomemusic/widgets/headerbar.py:75
+#: data/ui/SelectionBarMenuButton.ui:31 gnomemusic/widgets/headerbar.py:71
msgid "Click on items to select them"
msgstr "Cliche sui elements par selezionaju"
@@ -463,162 +491,171 @@ msgid "_Add to Playlist"
msgstr "_Zonte ae liste des musichis"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:749
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:822
msgid "Most Played"
msgstr "Plui scoltats"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:786
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:858
msgid "Never Played"
msgstr "Mai scoltât"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:822
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:893
msgid "Recently Played"
msgstr "Scoltât di recent"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:868
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:938
msgid "Recently Added"
msgstr "Zontât di recent"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:913
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:982
msgid "Favorite Songs"
msgstr "Tocs preferîts"
-#: gnomemusic/gstplayer.py:403
+#: gnomemusic/gstplayer.py:374
msgid "Unable to play the file"
msgstr "Impussibil riprodusi il file"
-#: gnomemusic/gstplayer.py:409
+#: gnomemusic/gstplayer.py:380
msgid "_Find in {}"
msgstr "_Cjate in {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:420
+#: gnomemusic/gstplayer.py:390
msgid " and "
msgstr " e "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:423
+#: gnomemusic/gstplayer.py:393
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:425
+#: gnomemusic/gstplayer.py:395
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "Al covente {} par riprodusi il file, ma nol è instalât."
msgstr[1] "A coventin {} par riprodusi il file, ma no son instalâts."
-#: gnomemusic/inhibitsuspend.py:72
+#: gnomemusic/inhibitsuspend.py:63
msgid "Playing music"
msgstr "Riproduzion musiche"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:65
msgid "Unknown album"
msgstr "Album no cognossût"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:86
msgid "Unknown Artist"
msgstr "Artist no cognossût"
-#: gnomemusic/views/emptyview.py:73
+#: gnomemusic/views/emptyview.py:67
msgid "Your XDG Music directory is not set."
-msgstr "La tô cartele XDG di Musiche no je stabilide"
+msgstr "La tô cartele XDG di Musiche no je stabilide."
# minuscul parce che al ven fûr la prime volte che si invie il program e il test al è tal mieç di une frase:
# Il contignût de tô cartele di musiche...
-#: gnomemusic/views/emptyview.py:80
+#: gnomemusic/views/emptyview.py:74
msgid "Music folder"
msgstr "cartele de musiche"
# %s o ai viodût che al ven fûr "cartele di musiche"
#. TRANSLATORS: This is a label to display a link to open user's music
#. folder. {} will be replaced with the translated text 'Music folder'
-#: gnomemusic/views/emptyview.py:84
+#: gnomemusic/views/emptyview.py:78
msgid "The contents of your {} will appear here."
msgstr "Il contignût de tô {} al vignarà mostrât achì."
-#: gnomemusic/views/emptyview.py:120
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hey DJ"
-#: gnomemusic/views/emptyview.py:130 gnomemusic/views/emptyview.py:136
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Nissune musiche cjatade"
-#: gnomemusic/views/emptyview.py:138
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Prove une ricercje diferente"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME Musiche nol rive a conetisi al Tracker"
-#: gnomemusic/views/emptyview.py:147
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr ""
"I tiei file di musiche no puedin jessi metûts in indiç cence vê in esecuzion "
"Tracker"
-#: gnomemusic/views/emptyview.py:155
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Il Tracker dal to sisteme al semee sorpassât"
-#: gnomemusic/views/emptyview.py:158
+#: gnomemusic/views/emptyview.py:146
msgid "Music needs Tracker version 2.3.0 or higher"
msgstr "Musiche al à bisugne de version 2.3.0 (o plui resinte) di Tracker"
-#: gnomemusic/views/playlistsview.py:58
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Listis di musichis"
-#: gnomemusic/views/searchview.py:363
+#: gnomemusic/views/searchview.py:383
msgid "Artists Results"
msgstr "Risultâts artiscj"
-#: gnomemusic/views/searchview.py:377
+#: gnomemusic/views/searchview.py:398
msgid "Albums Results"
msgstr "Risultâts album"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:155
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minût"
msgstr[1] "{} minûts"
-#: gnomemusic/widgets/disclistboxwidget.py:76
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disc {}"
-#: gnomemusic/widgets/headerbar.py:72
+#: gnomemusic/widgets/headerbar.py:68
msgid "Selected {} item"
msgid_plural "Selected {} items"
msgstr[0] "Selezionât {} element"
msgstr[1] "Selezionâts {} elements"
-#: gnomemusic/widgets/notificationspopup.py:171
-msgid "Loading"
-msgstr "Daûr a cjariâ"
+#: gnomemusic/widgets/lastfmdialog.py:65
+msgid "Your music listening is reported to Last.fm."
+msgstr "La musiche che tu scoltis e ven segnalade a Last.fm."
-#: gnomemusic/widgets/notificationspopup.py:244
-msgid "_Undo"
-msgstr "A_nule"
+#: gnomemusic/widgets/lastfmdialog.py:67
+msgid "Your music listening is not reported to Last.fm."
+msgstr "La musiche che tu scoltis no ven inviade a Last.fm."
+
+#. TRANSLATORS: displays the username of the Last.fm account
+#: gnomemusic/widgets/lastfmdialog.py:71
+msgid "Logged in as {}"
+msgstr "Jentrât come {}"
+
+#: gnomemusic/widgets/lastfmdialog.py:72
+msgid "Configure"
+msgstr "Configure"
-#: gnomemusic/widgets/notificationspopup.py:259
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Liste di musichis {} gjavade"
-#: gnomemusic/widgets/notificationspopup.py:263
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} gjavât di {}"
-#: gnomemusic/widgets/playertoolbar.py:156
+#: gnomemusic/widgets/playertoolbar.py:144
msgid "Pause"
msgstr "Pause"
-#: gnomemusic/widgets/playlistcontrols.py:112
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} Cjançon"
diff --git a/po/gl.po b/po/gl.po
index 97bbcf31..aec26fa6 100644
--- a/po/gl.po
+++ b/po/gl.po
@@ -2,21 +2,22 @@
# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# Fran Diéguez <frandieguez@gnome.org>, 2012.
-# Fran Dieguez <frandieguez@gnome.org>, 2012-2019.
+# Fran Dieguez <frandieguez@gnome.gl>, 2012-2020.
+#
msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 14:09+0000\n"
-"PO-Revision-Date: 2020-02-15 21:47+0100\n"
-"Last-Translator: Fran Diéguez <frandieguez@gnome.org>\n"
-"Language-Team: Galician\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-09-01 21:46+0200\n"
+"Last-Translator: Fran Dieguez <frandieguez@gnome.gl>\n"
+"Language-Team: Galician <Proxecto Trasno <proxecto@trasno.gal>>\n"
"Language: gl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.3\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"X-Generator: Gtranslator 3.36.0\n"
"X-Project-Style: gnome\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
@@ -44,12 +45,12 @@ msgstr ""
"Atope pistas na súa colección local, obteña música desde servidores DLNA ou "
"tente algo novo cos servizos Jamendo e Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Os desenvolvedores de GNOME Music"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Música"
@@ -206,15 +207,15 @@ msgstr ""
"A imaxe de “Magic of the vinyl†por Sami Pyylampi ten licenza CC-BY-SA 2.0 "
"https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Publicada"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Lonxitude da execución"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Compositor"
@@ -246,16 +247,16 @@ msgstr "Menú"
msgid "Select"
msgstr "Seleccionar"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Cancelar"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Buscar"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Atrás"
@@ -365,6 +366,10 @@ msgstr ""
msgid "Login"
msgstr "Iniciar sesión"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Cargando"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Aleatorio"
@@ -382,15 +387,15 @@ msgstr "Repetir canción"
msgid "Shuffle/Repeat Off"
msgstr "Desactivar Aleatorio/Repetir"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Anterior"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Reproducir"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Seguinte"
@@ -423,7 +428,7 @@ msgstr "_Renomear…"
msgid "Playlist Name"
msgstr "Nome da lista de reprodución"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Feito"
@@ -451,19 +456,23 @@ msgstr "Engadir á lista de reprodución"
msgid "_Add"
msgstr "_Engadir"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Desfacer"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Artistas"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Ver todo"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Ãlbumes"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Cancións"
@@ -484,49 +493,49 @@ msgid "_Add to Playlist"
msgstr "_Engadir á lista de reprodución"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Máis reproducidos"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Nunca reproducidos"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Reproducidos recentemente"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Engadidos recentemente"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Cancións favoritas"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Non foi posíbel reproducir o ficheiro"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Buscar en {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " e "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} requírese para reproducir o ficheiro, pero non está instalado."
@@ -537,11 +546,11 @@ msgstr[1] ""
msgid "Playing music"
msgstr "Reproducindo música"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Ãlbum descoñecido"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Artista descoñecido"
@@ -559,62 +568,65 @@ msgstr "Cartafol de música"
msgid "The contents of your {} will appear here."
msgstr "Os contidos de {} aparecerán aquí."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hola DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Non se atopou música"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Probe unha busca diferente"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "Música de GNOME non puido conectarse a Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr ""
"Os seus ficheiros de música non poden indexarse sen ter Tracker executándose"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "A versión de Tracker do seu sistema semella desfasada"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Música precisa Tracker versión 2.3.0 ou superior"
+#: gnomemusic/views/emptyview.py:146
+#| msgid "Music needs Tracker version 2.3.0 or higher"
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Música precisa Tracker versión 3.0.0 ou superior"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Listas de reprodución"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Resultados de artistas"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Resultados de álbumes"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minuto"
msgstr[1] "{} minutos"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disco {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Elemento {} seleccionado"
-msgstr[1] "Elementos {} seleccionados"
+#| msgid "Selected {} item"
+#| msgid_plural "Selected {} items"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Canción {} seleccionadas"
+msgstr[1] "Cancións {} seleccionadas"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -633,27 +645,19 @@ msgstr "Sesión iniciada como {}"
msgid "Configure"
msgstr "Configurar"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Cargando"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Desfacer"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Elminouse a lista de reprodución {}"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} eliminado de {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pausar"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} canción"
diff --git a/po/hr.po b/po/hr.po
index daa86d79..e111c7a7 100644
--- a/po/hr.po
+++ b/po/hr.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-28 16:00+0000\n"
-"PO-Revision-Date: 2020-03-01 12:09+0100\n"
-"Last-Translator: gogo <linux.hr@protonmail.com>\n"
+"POT-Creation-Date: 2020-09-01 19:48+0000\n"
+"PO-Revision-Date: 2020-09-01 22:44+0200\n"
+"Last-Translator: gogo <trebelnik2@gmail.com>\n"
"Language-Team: Croatian <hr@li.org>\n"
"Language: hr\n"
"MIME-Version: 1.0\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
-"X-Generator: Poedit 2.0.6\n"
+"X-Generator: Poedit 2.3\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -44,12 +44,12 @@ msgstr ""
"Potražite pjesme u svojoj lokalnoj kolekciji, nabavite glazbu na DLNA "
"poslužiteljima ili isprobajte nešto novo s Jamenado i Magnatune uslugama."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "GNOME Glazbeni razvijatelji"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Glazba"
@@ -205,15 +205,15 @@ msgstr ""
"“Magic of the vinyl†by Sami Pyylampi image je licenciran na CC-BY-SA 2.0 "
"https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Objavljeno"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Trajanje"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Skladatelj"
@@ -245,16 +245,16 @@ msgstr "Izbornik"
msgid "Select"
msgstr "Odaberi"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Odustani"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Pretraga"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Natrag"
@@ -365,6 +365,10 @@ msgstr ""
msgid "Login"
msgstr "Prijava"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "UÄitavanje"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "NaizmjeniÄno"
@@ -382,15 +386,15 @@ msgstr "Ponovi pjesmu"
msgid "Shuffle/Repeat Off"
msgstr "NaizmjeniÄno/Ponovi iskljuÄi"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Prijašnja"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Reproduciraj"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Sljedeća"
@@ -423,7 +427,7 @@ msgstr "_Preimenuj…"
msgid "Playlist Name"
msgstr "Naziv popis izvođenja"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Završeno"
@@ -451,19 +455,23 @@ msgstr "Dodaj na popis izvođenja"
msgid "_Add"
msgstr "_Dodaj"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Vrati"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "IzvoÄ‘aÄi"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Prikaži sve"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Albumi"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Pjesme"
@@ -484,49 +492,49 @@ msgid "_Add to Playlist"
msgstr "_Dodaj na popis izvođenja"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:800
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:827
msgid "Most Played"
msgstr "Najslušanije"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:837
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:880
msgid "Never Played"
msgstr "Nepreslušano"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:873
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:932
msgid "Recently Played"
msgstr "Nedavno slušano"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:919
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:994
msgid "Recently Added"
msgstr "Nedavno dodano"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:964
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1056
msgid "Favorite Songs"
msgstr "Omiljene pjesme"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Nemoguća reprodukcija datoteke"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Pretraži u {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " i "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} je potreban za reprodukciju datoteke, ali nije instaliran."
@@ -537,11 +545,11 @@ msgstr[2] "{} su potrebni za reprodukciju datoteke, ali nisu instalirani."
msgid "Playing music"
msgstr "Reprodukcija glazbe"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Nepoznat album"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Nepoznati izvoÄ‘aÄ"
@@ -559,65 +567,65 @@ msgstr "Glazbene mape"
msgid "The contents of your {} will appear here."
msgstr "Sadržaj vaše {} će se pojaviti ovdje."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hej DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Glazba nije pronađena"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "PokuÅ¡aj drugaÄiju pretragu"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME Glazba se ne može povezati s Pratiteljem"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr ""
"Ne može se stvoriti sadržaj vaših glazbenih datoteka bez pokrenutog "
"Pratitelja"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Izgleda da je inaÄica vaÅ¡eg Pratitelja sustava zastarjela"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Glazba treba Pratitelja inaÄice 2.3.0 ili novijeg"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Glazba treba Pratitelja inaÄice 3.0.0 ili novijeg"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Popis izvođenja"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Rezultati izvoÄ‘aÄa"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Rezultati albuma"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minuta"
msgstr[1] "{} minute"
msgstr[2] "{} minuta"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disk {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Odabrana {} stavka"
-msgstr[1] "Odabrane {} stavke"
-msgstr[2] "Odabrane {} stavke"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Odabrana {} pjesma"
+msgstr[1] "Odabrane {} pjesme"
+msgstr[2] "Odabrane {} pjesama"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -636,27 +644,19 @@ msgstr "Prijavljeni kao {}"
msgid "Configure"
msgstr "Podesi"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "UÄitavanje"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Vrati"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Popis izvođenja {} uklonjen"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} uklonjeno iz {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pauziraj"
-#: gnomemusic/widgets/playlistcontrols.py:126
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} pjesma"
diff --git a/po/hu.po b/po/hu.po
index 47e99853..a43e762d 100644
--- a/po/hu.po
+++ b/po/hu.po
@@ -9,16 +9,16 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 11:24+0000\n"
-"PO-Revision-Date: 2020-02-17 21:45+0100\n"
-"Last-Translator: Balázs Úr <ur.balazs at fsf dot hu>\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-09-06 19:42+0200\n"
+"Last-Translator: Meskó Balázs <mesko.balazs@fsf.hu>\n"
"Language-Team: Hungarian <gnome-hu-list at gnome dot org>\n"
"Language: hu\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Lokalize 19.04.3\n"
+"X-Generator: Poedit 2.4.1\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -46,12 +46,12 @@ msgstr ""
"kiszolgálókról vagy próbáljon ki valami újat a Jamendo és Magnatune "
"szolgáltatásokkal."
-#: data/org.gnome.Music.appdata.xml.in.in:67
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "A GNOME Zene fejlesztői"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Zene"
@@ -206,15 +206,15 @@ msgstr ""
"„Magic of the vinyl†– Sami Pyylampi képe CC-BY-SA 2.0 licenc szerint: "
"https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Kiadva"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Futási hossz"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Zeneszerző"
@@ -246,16 +246,16 @@ msgstr "Menü"
msgid "Select"
msgstr "Kiválasztás"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Mégse"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Keresés"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Vissza"
@@ -364,6 +364,10 @@ msgstr "Jelentkezzen be a Last.fm-fiókjába, hogy jelentse, mit hallgat."
msgid "Login"
msgstr "Bejelentkezés"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Betöltés"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Véletlen sorrend"
@@ -381,15 +385,15 @@ msgstr "Szám ismétlése"
msgid "Shuffle/Repeat Off"
msgstr "Véletlen/Ismétlés kikapcsolva"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Előző"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Lejátszás"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Következő"
@@ -422,7 +426,7 @@ msgstr "Ãt_nevezés…"
msgid "Playlist Name"
msgstr "Lejátszólista neve"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Kész"
@@ -450,19 +454,23 @@ msgstr "Hozzáadás a lejátszólistához"
msgid "_Add"
msgstr "_Hozzáadás"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:51
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Visszavonás"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Előadók"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Összes megtekintése"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Albumok"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:49
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Számok"
@@ -483,49 +491,49 @@ msgid "_Add to Playlist"
msgstr "Hozzá_adás a lejátszólistához"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Legtöbbet lejátszott"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Sosem lejátszott"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Legutóbb lejátszott"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Legutóbb hozzáadott"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Kedvenc számok"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Nem lehet lejátszani a fájlt"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Keresés ebben: {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " és "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} szükséges a fájl lejátszásához, de nincs telepítve."
@@ -535,11 +543,11 @@ msgstr[1] "{} szükségesek a fájl lejátszásához, de nincsenek telepítve."
msgid "Playing music"
msgstr "Zene lejátszása"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Ismeretlen album"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Ismeretlen előadó"
@@ -559,63 +567,62 @@ msgstr "Zenék mappa"
msgid "The contents of your {} will appear here."
msgstr "A {} tartalma itt fog megjelenni."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hé DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Nem található zene"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Próbáljon egy másik keresést"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "A GNOME Zene nem tudott kapcsolódni a Trackerhez"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "A zenefájlokat nem lehet indexelni a Tracker futtatása nélkül"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "A rendszer Tracker verziója elavultnak tűnik"
-#: gnomemusic/views/emptyview.py:147
-#| msgid "Music needs Tracker version 2.2.0 or higher"
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "A Zene a Tracker 2.3.0 vagy újabb verzióját igényli"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "A Zene a Tracker 3.0.0 vagy újabb verzióját igényli"
-#: gnomemusic/views/playlistsview.py:53
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Lejátszólisták"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Előadók találatai"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Albumok találatai"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} perc"
msgstr[1] "{} perc"
# FIXME ez lehet, hogy egy lemezcím, vagy sorszám, akkor nem lesz szép.
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Lemez {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "{} elem kijelölve"
-msgstr[1] "{} elem kijelölve"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} szám kijelölve"
+msgstr[1] "{} szám kijelölve"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -634,27 +641,19 @@ msgstr "Bejelentkezve mint {}"
msgid "Configure"
msgstr "Beállítás"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Betöltés"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Visszavonás"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "A(z) {} lejátszólista eltávolítva"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} eltávolítva innen: {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Szünet"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} szám"
diff --git a/po/id.po b/po/id.po
index 9092dfbc..32a59b16 100644
--- a/po/id.po
+++ b/po/id.po
@@ -9,15 +9,15 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 14:09+0000\n"
-"PO-Revision-Date: 2020-02-19 20:40+0700\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-08-28 22:19+0700\n"
"Last-Translator: Kukuh Syafaat <kukuhsyafaat@gnome.org>\n"
"Language-Team: Indonesian <gnome@i15n.org>\n"
"Language: id\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.3\n"
+"X-Generator: Poedit 2.4.1\n"
"Plural-Forms: nplurals=2; plural= n!=1;\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
@@ -45,12 +45,12 @@ msgstr ""
"Temukan trek di koleksi lokal Anda, dapatkan musik dari server DLNA atau "
"coba sesuatu yang baru dengan layanan Jamendo dan Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Para Pengembang GNOME Musik"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Musik"
@@ -205,15 +205,15 @@ msgstr ""
"Citra \"Magic of the vinyl\" oleh Sami Pyylampi dilisensikan memakai CC-BY-"
"SA 2.0 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Dirilis"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Lama Putar"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Pencipta"
@@ -245,16 +245,16 @@ msgstr "Menu"
msgid "Select"
msgstr "Pilih"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Batal"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Cari"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Mundur"
@@ -363,6 +363,10 @@ msgstr "Masuk ke akun Last.fm Anda untuk melaporkan musik yang Anda dengar."
msgid "Login"
msgstr "Masuk"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Memuat"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Acak"
@@ -380,15 +384,15 @@ msgstr "Ulangi Lagu"
msgid "Shuffle/Repeat Off"
msgstr "Acak/Ulang Mati"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Sebelumnya"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Putar"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Selanjutnya"
@@ -421,7 +425,7 @@ msgstr "_Ubah Nama…"
msgid "Playlist Name"
msgstr "Nama Daftar Putar"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Selesai"
@@ -449,19 +453,23 @@ msgstr "Tambah ke Daftar Putar"
msgid "_Add"
msgstr "T_ambah"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "Tak _Jadi"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Artis"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Tampilkan Semua"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Album"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Lagu"
@@ -482,49 +490,49 @@ msgid "_Add to Playlist"
msgstr "T_ambah ke Daftar Putar"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Paling Sering Diputar"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Tak Pernah Diputar"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Baru-baru Ini Diputar"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Baru-baru Ini Ditambahkan"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Lagu Favorit"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Tak dapat memutar berkas"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Cari di {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " dan "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} diperlukan untuk memutar berkas, tapi tak terpasang."
@@ -534,11 +542,11 @@ msgstr[1] "{} diperlukan untuk memutar berkas, tapi tak terpasang."
msgid "Playing music"
msgstr "Memutar musik"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Album tak dikenal"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Artis Tak Dikenal"
@@ -556,61 +564,61 @@ msgstr "Folder musik"
msgid "The contents of your {} will appear here."
msgstr "Konten {} Anda akan muncul di sini."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hey DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Tak ada musik"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Cobalah pencarian lain"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME Musik tidak dapat terhubung ke Pelacak"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Berkas musik Anda tidak dapat diindeks tanpa Pelacak berjalan"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Versi Pelacak sistem Anda tampaknya sudah usang"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Musik membutuhkan Pelacak versi 2.3.0 atau lebih tinggi"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Musik membutuhkan Pelacak versi 3.0.0 atau lebih tinggi"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Daftar Putar"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Hasil Artis"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Hasil Album"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} menit"
msgstr[1] "{} menit"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Cakram {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Dipilih {} butir"
-msgstr[1] "Dipilih {} butir"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Dipilih {} lagu"
+msgstr[1] "Dipilih {} lagu"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -629,27 +637,19 @@ msgstr "Masuk sebagai {}"
msgid "Configure"
msgstr "Konfigurasikan"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Memuat"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "Tak _Jadi"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Daftar putar {} dihapus"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} dihapus dari {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Tahan"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} Lagu"
diff --git a/po/it.po b/po/it.po
index 99e6a8fc..ed492671 100644
--- a/po/it.po
+++ b/po/it.po
@@ -19,8 +19,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 14:09+0000\n"
-"PO-Revision-Date: 2020-02-21 13:42+0100\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-09-03 09:27+0200\n"
"Last-Translator: Milo Casagrande <milo@milo.name>\n"
"Language-Team: Italian <tp@lists.linux.it>\n"
"Language: it\n"
@@ -29,7 +29,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n!=1);\n"
"X-Launchpad-Export-Date: 2012-03-06 09:28+0000\n"
-"X-Generator: Poedit 2.2.4\n"
+"X-Generator: Poedit 2.4.1\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -57,12 +57,12 @@ msgstr ""
"Trova brani nella propria collezione musicale, attraverso servizi DLNA o per "
"qualche cosa di nuovo è possibile usare servizi come Jamendo e Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Gli sviluppatori di GNOME Musica"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Musica"
@@ -219,15 +219,15 @@ msgstr ""
"“Magic of the vinyl†by Sami Pyylampi image is licensed by CC-BY-SA 2.0 "
"https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Pubblicato"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Durata"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Compositore"
@@ -259,16 +259,16 @@ msgstr "Menù"
msgid "Select"
msgstr "Seleziona"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "A_nnulla"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Cerca"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Indietro"
@@ -378,6 +378,10 @@ msgstr ""
msgid "Login"
msgstr "Accedi"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Caricamento"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Mischia"
@@ -395,15 +399,15 @@ msgstr "Ripeti brano"
msgid "Shuffle/Repeat Off"
msgstr "Mischia/Ripeti disattivati"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Precedente"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Riproduci"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Successiva"
@@ -436,7 +440,7 @@ msgstr "_Rinomina…"
msgid "Playlist Name"
msgstr "Nome playlist"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Fatto"
@@ -464,19 +468,23 @@ msgstr "Aggiungi a playlist"
msgid "_Add"
msgstr "A_ggiungi"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "A_nnulla"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Artisti"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Visualizza tutti"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Album"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Brani"
@@ -497,49 +505,49 @@ msgid "_Add to Playlist"
msgstr "Aggiungi a _playlist"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Più ascoltati"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Mai ascoltati"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Ascoltati di recente"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Aggiunti di recente"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Brani preferiti"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Impossibile riprodurre il file"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Trova in {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " e "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} è richiesto per riprodurre i file, ma non è installato."
@@ -549,11 +557,11 @@ msgstr[1] "{} sono richiesti per riprodurre il file, ma non sono installati."
msgid "Playing music"
msgstr "Musica in riproduzione"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Album sconosciuto"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Artista sconosciuto"
@@ -571,63 +579,63 @@ msgstr "Cartella Musica"
msgid "The contents of your {} will appear here."
msgstr "Il contenuto della propria «{}» apparirà qui."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hey DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Nessuna musica trovata"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Provare con un'altra ricerca"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "Impossibile collegarsi a Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr ""
"Non è possibile indicizzare i propri file musicali senza Tracker in "
"esecuzione"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "La versione di Tracker del sistema non sembra essere recente"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Musica necessita della versione 2.3.0, o successive, di Tracker"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Musica necessita della versione 3.0.0, o successive, di Tracker"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Playlist"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Risultati artisti"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Risultati album"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minuto"
msgstr[1] "{} minuti"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disco {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Selezionato {} elemento"
-msgstr[1] "Selezionati {} elementi"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Selezionato {} brano"
+msgstr[1] "Selezionati {} brani"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -646,27 +654,19 @@ msgstr "Accesso eseguito come {}"
msgid "Configure"
msgstr "Configura"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Caricamento"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "A_nnulla"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Playlist {} rimossa"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} rimosso da {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pausa"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} brano"
diff --git a/po/ja.po b/po/ja.po
index a012903c..c8e6a2d3 100644
--- a/po/ja.po
+++ b/po/ja.po
@@ -12,8 +12,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-01-15 19:29+0000\n"
-"PO-Revision-Date: 2020-02-09 23:00+0900\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-08-31 22:30+0900\n"
"Last-Translator: sicklylife <translation@sicklylife.jp>\n"
"Language-Team: Japanese <gnome-translation@gnome.gr.jp>\n"
"Language: ja\n"
@@ -43,12 +43,12 @@ msgid ""
"something new with the Jamendo and Magnatune services."
msgstr ""
-#: data/org.gnome.Music.appdata.xml.in.in:67
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "The GNOME Music developers"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
-#: gnomemusic/window.py:77
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:59
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "ミュージック"
@@ -59,15 +59,15 @@ msgstr "音楽プレーヤー"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: data/org.gnome.Music.desktop.in.in:13
msgid "Music;Player;"
-msgstr "Music;Player;音楽;ミュージック;å†ç”Ÿ;プレーヤー;"
+msgstr "Music;Player;音楽;楽曲;ミュージック;å†ç”Ÿ;プレーヤー;"
#: data/org.gnome.Music.gschema.xml:12
msgid "Window size"
-msgstr "ウィンドウサイズ"
+msgstr "ウィンドウã®ã‚µã‚¤ã‚º"
#: data/org.gnome.Music.gschema.xml:13
msgid "Window size (width and height)."
-msgstr "ウィンドウサイズ (å¹…ã¨é«˜ã•) ã§ã™ã€‚"
+msgstr "ウィンドウã®ã‚µã‚¤ã‚º (å¹…ã¨é«˜ã•) ã§ã™ã€‚"
#: data/org.gnome.Music.gschema.xml:17
msgid "Window position"
@@ -75,15 +75,15 @@ msgstr "ウィンドウã®ä½ç½®"
#: data/org.gnome.Music.gschema.xml:18
msgid "Window position (x and y)."
-msgstr "ウィンドウã®ä½ç½® (x 㨠y)ã§ã™ã€‚"
+msgstr "ウィンドウã®ä½ç½® (X 軸㨠Y 軸) ã§ã™ã€‚"
#: data/org.gnome.Music.gschema.xml:22
msgid "Window maximized"
-msgstr "ウィンドウ最大化"
+msgstr "ウィンドウã®æœ€å¤§åŒ–"
#: data/org.gnome.Music.gschema.xml:23
msgid "Window maximized state."
-msgstr "ウィンドウ最大化ã®çŠ¶æ…‹ã§ã™ã€‚"
+msgstr "ウィンドウã®æœ€å¤§åŒ–状態ã§ã™ã€‚"
#: data/org.gnome.Music.gschema.xml:27
msgid "Playback repeat mode"
@@ -108,7 +108,7 @@ msgstr "ReplayGain を有効ã«ã™ã‚‹"
#: data/org.gnome.Music.gschema.xml:34
msgid "Enables or disables ReplayGain for albums"
-msgstr "アルãƒãƒ ã® ReplayGain を有効ã«ã™ã‚‹ã‹ã©ã†ã‹ã®è¨­å®šã§ã™ã€‚"
+msgstr "アルãƒãƒ ã® ReplayGain を有効ã«ã™ã‚‹ã‹ã©ã†ã‹"
#: data/org.gnome.Music.gschema.xml:38
msgid "Inital state has been displayed"
@@ -142,11 +142,11 @@ msgstr "Copyright © 2018 GNOME Music Developers"
#: data/ui/AboutDialog.ui.in:10
msgid "A music player and management application for GNOME."
-msgstr "GNOME å‘ã‘音楽プレーヤーã¨ç®¡ç†ã‚¢ãƒ—リケーション"
+msgstr "音楽ã®å†ç”Ÿã¨ç®¡ç†ã‚’ã™ã‚‹ãŸã‚ã® GNOME アプリケーションã§ã™ã€‚"
#: data/ui/AboutDialog.ui.in:12
msgid "Visit GNOME Music website"
-msgstr "GNOME ミュージック㮠Web サイトã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹"
+msgstr "GNOME ミュージックã®ã‚¦ã‚§ãƒ–サイトã«ã‚¢ã‚¯ã‚»ã‚¹ã™ã‚‹"
#: data/ui/AboutDialog.ui.in:13
msgid ""
@@ -176,35 +176,35 @@ msgid ""
"https://www.flickr.com/photos/_spy_/12270839403"
msgstr ""
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "リリース日"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "å†ç”Ÿæ™‚é–“"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "作曲者"
-#: data/ui/AppMenu.ui:20
+#: data/ui/AppMenu.ui:20 data/ui/LastfmDialog.ui:8
msgid "Last.fm Account"
msgstr "Last.fm アカウント"
-#: data/ui/AppMenu.ui:39
+#: data/ui/AppMenu.ui:38
msgid "Report Music Listening"
-msgstr ""
+msgstr "鑑賞ã—ãŸéŸ³æ¥½ã‚’報告"
-#: data/ui/AppMenu.ui:70
+#: data/ui/AppMenu.ui:69
msgid "_Keyboard Shortcuts"
msgstr "キーボードショートカット(_K)"
-#: data/ui/AppMenu.ui:84
+#: data/ui/AppMenu.ui:83
msgid "_Help"
msgstr "ヘルプ(_H)"
-#: data/ui/AppMenu.ui:98
+#: data/ui/AppMenu.ui:97
msgid "_About Music"
msgstr "“ミュージックâ€ã«ã¤ã„ã¦(_A)"
@@ -216,16 +216,16 @@ msgstr "メニュー"
msgid "Select"
msgstr "é¸æŠž"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "キャンセル(_C)"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "検索"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "戻る"
@@ -314,6 +314,31 @@ msgctxt "shortcut window"
msgid "Go back"
msgstr "戻る"
+#: data/ui/LastfmDialog.ui:21
+msgid ""
+"Last.fm is a music discovery service that gives you personalised "
+"recommendations based on the music you listen to."
+msgstr ""
+"Last.fm ã¯ã€ã‚ãªãŸã®é‘‘賞ã—ãŸéŸ³æ¥½ã®å‚¾å‘ã‹ã‚‰ãŠå‹§ã‚ã®éŸ³æ¥½ã‚’探ã—出ã—"
+"ã¦æ示ã—ã¦ãれるã€éŸ³æ¥½ãƒ‡ã‚£ã‚¹ã‚«ãƒãƒªãƒ¼ã‚µãƒ¼ãƒ“スã§ã™ã€‚"
+
+#: data/ui/LastfmDialog.ui:32 gnomemusic/widgets/lastfmdialog.py:58
+msgid "Music Reporting Not Setup"
+msgstr "音楽ã®å ±å‘Šã‚’セットアップã—ã¦ã„ã¾ã›ã‚“"
+
+#: data/ui/LastfmDialog.ui:46 gnomemusic/widgets/lastfmdialog.py:61
+msgid "Login to your Last.fm account to report your music listening."
+msgstr ""
+"鑑賞ã—ãŸéŸ³æ¥½ã‚’報告ã™ã‚‹ãŸã‚ã« Last.fm ã®ã‚¢ã‚«ã‚¦ãƒ³ãƒˆã¸ãƒ­ã‚°ã‚¤ãƒ³ã—ã¦ãã ã•ã„。"
+
+#: data/ui/LastfmDialog.ui:57 gnomemusic/widgets/lastfmdialog.py:59
+msgid "Login"
+msgstr "ログイン"
+
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "読ã¿è¾¼ã¿ä¸­"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "シャッフル"
@@ -331,15 +356,15 @@ msgstr "1曲リピート"
msgid "Shuffle/Repeat Off"
msgstr "シャッフル/リピートオフ"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "å‰"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:159
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "å†ç”Ÿ"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "次"
@@ -368,7 +393,7 @@ msgstr "削除(_D)"
msgid "_Rename…"
msgstr "åå‰ã‚’変更(_R)…"
-#: data/ui/PlaylistControls.ui:40
+#: data/ui/PlaylistControls.ui:41
msgid "Playlist Name"
msgstr "プレイリストå"
@@ -400,19 +425,23 @@ msgstr "プレイリストã«è¿½åŠ "
msgid "_Add"
msgstr "追加(_A)"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:59
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "å…ƒã«æˆ»ã™(_U)"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "アーティスト"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "ã™ã¹ã¦è¡¨ç¤º"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:62
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "アルãƒãƒ "
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:57
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "曲"
@@ -424,7 +453,7 @@ msgstr "ã™ã¹ã¦é¸æŠž"
msgid "Select None"
msgstr "é¸æŠžãªã—"
-#: data/ui/SelectionBarMenuButton.ui:31 gnomemusic/widgets/headerbar.py:75
+#: data/ui/SelectionBarMenuButton.ui:31 gnomemusic/widgets/headerbar.py:71
msgid "Click on items to select them"
msgstr "アイテムをクリックã—ã¦é¸æŠž"
@@ -433,159 +462,169 @@ msgid "_Add to Playlist"
msgstr "プレイリストã«è¿½åŠ (_A)"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:748
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:822
msgid "Most Played"
msgstr "最もå†ç”Ÿã—ãŸæ›²"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:785
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:858
msgid "Never Played"
msgstr "未å†ç”Ÿã®æ›²"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:821
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:893
msgid "Recently Played"
msgstr "最近å†ç”Ÿã—ãŸæ›²"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:867
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:938
msgid "Recently Added"
msgstr "最近追加ã—ãŸæ›²"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:912
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:982
msgid "Favorite Songs"
msgstr "ãŠæ°—ã«å…¥ã‚Šã®æ›²"
-#: gnomemusic/gstplayer.py:403
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "ファイルをå†ç”Ÿã§ãã¾ã›ã‚“"
-#: gnomemusic/gstplayer.py:409
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "{} ã§æ¤œç´¢(_F)"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:420
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " 㨠"
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:423
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:425
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "ファイルã®å†ç”Ÿã«ã¯ {} ãŒå¿…è¦ã§ã™ãŒã€ã‚¤ãƒ³ã‚¹ãƒˆãƒ¼ãƒ«ã•ã‚Œã¦ã„ã¾ã›ã‚“。"
-#: gnomemusic/inhibitsuspend.py:72
+#: gnomemusic/inhibitsuspend.py:63
msgid "Playing music"
-msgstr ""
+msgstr "å†ç”Ÿä¸­"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "ä¸æ˜Žãªã‚¢ãƒ«ãƒãƒ "
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "ä¸æ˜Žãªã‚¢ãƒ¼ãƒ†ã‚£ã‚¹ãƒˆ"
-#: gnomemusic/views/emptyview.py:73
+#: gnomemusic/views/emptyview.py:67
msgid "Your XDG Music directory is not set."
-msgstr ""
+msgstr "XDG ã® Music ディレクトリを設定ã—ã¦ã„ã¾ã›ã‚“。"
-#: gnomemusic/views/emptyview.py:80
+#: gnomemusic/views/emptyview.py:74
msgid "Music folder"
msgstr "ミュージックフォルダー"
#. TRANSLATORS: This is a label to display a link to open user's music
#. folder. {} will be replaced with the translated text 'Music folder'
-#: gnomemusic/views/emptyview.py:84
+#: gnomemusic/views/emptyview.py:78
msgid "The contents of your {} will appear here."
msgstr "ã‚ãªãŸã®{}ã®å†…容ãŒã“ã“ã«è¡¨ç¤ºã•ã‚Œã¾ã™ã€‚"
-#: gnomemusic/views/emptyview.py:120
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr ""
-#: gnomemusic/views/emptyview.py:130 gnomemusic/views/emptyview.py:136
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
-msgstr "曲ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+msgstr "曲ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“ã§ã—ãŸ"
-#: gnomemusic/views/emptyview.py:138
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
-msgstr "別ã®æ¤œç´¢ã‚’試ã—ã¦ãã ã•ã„"
+msgstr "ä»–ã®ã‚­ãƒ¼ãƒ¯ãƒ¼ãƒ‰ã‚’試ã—ã¦ãã ã•ã„"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME ミュージック㌠Tracker ã«æŽ¥ç¶šã§ãã¾ã›ã‚“ã§ã—ãŸ"
-#: gnomemusic/views/emptyview.py:147
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Tracker を実行ã—ã¦ã„ãªã„ã¨éŸ³æ¥½ãƒ•ã‚¡ã‚¤ãƒ«ã¯ã‚¤ãƒ³ãƒ‡ãƒƒã‚¯ã‚¹ã•ã‚Œã¾ã›ã‚“"
-#: gnomemusic/views/emptyview.py:155
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Tracker ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒå¤ã™ãŽã¾ã™"
-#: gnomemusic/views/emptyview.py:158
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Tracker ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 2.3.0 以é™ãŒå¿…è¦ã§ã™"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Tracker ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 3.0.0 以é™ãŒå¿…è¦ã§ã™"
-#: gnomemusic/views/playlistsview.py:58
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "プレイリスト"
-#: gnomemusic/views/searchview.py:363
+#: gnomemusic/views/searchview.py:381
msgid "Artists Results"
msgstr "アーティストã®æ¤œç´¢çµæžœ"
-#: gnomemusic/views/searchview.py:377
+#: gnomemusic/views/searchview.py:396
msgid "Albums Results"
msgstr "アルãƒãƒ ã®æ¤œç´¢çµæžœ"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} 分"
-#: gnomemusic/widgets/disclistboxwidget.py:76
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "ディスク {}"
-#: gnomemusic/widgets/headerbar.py:72
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "{} 件é¸æŠž"
+#: gnomemusic/widgets/headerbar.py:68
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} 曲é¸æŠž"
-#: gnomemusic/widgets/notificationspopup.py:171
-msgid "Loading"
-msgstr "読ã¿è¾¼ã¿ä¸­"
+#: gnomemusic/widgets/lastfmdialog.py:65
+msgid "Your music listening is reported to Last.fm."
+msgstr ""
+"鑑賞ã—ãŸéŸ³æ¥½ãŒ Last.fm ã«å ±å‘Šã•ã‚Œã¾ã™ã€‚"
-#: gnomemusic/widgets/notificationspopup.py:244
-msgid "_Undo"
-msgstr "å…ƒã«æˆ»ã™(_U)"
+#: gnomemusic/widgets/lastfmdialog.py:67
+msgid "Your music listening is not reported to Last.fm."
+msgstr ""
+"鑑賞ã—ãŸéŸ³æ¥½ãŒ Last.fm ã«å ±å‘Šã•ã‚Œã¾ã›ã‚“。"
-#: gnomemusic/widgets/notificationspopup.py:259
+#. TRANSLATORS: displays the username of the Last.fm account
+#: gnomemusic/widgets/lastfmdialog.py:71
+msgid "Logged in as {}"
+msgstr "{} ã§ãƒ­ã‚°ã‚¤ãƒ³"
+
+#: gnomemusic/widgets/lastfmdialog.py:72
+msgid "Configure"
+msgstr "設定"
+
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "プレイリスト {} を削除ã—ã¾ã—ãŸ"
-#: gnomemusic/widgets/notificationspopup.py:263
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} ã‚’ {} ã‹ã‚‰å‰Šé™¤ã—ã¾ã—ãŸ"
-#: gnomemusic/widgets/playertoolbar.py:156
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "一時åœæ­¢"
-#: gnomemusic/widgets/playlistcontrols.py:112
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} 曲"
-
#~ msgid "Enables or disables playback notifications"
#~ msgstr "å†ç”Ÿä¸­ã®æ›²ã®é€šçŸ¥ã‚’有効ã«ã™ã‚‹ã‹ã©ã†ã‹ã®è¨­å®šã§ã™ã€‚"
diff --git a/po/kk.po b/po/kk.po
index c28eaf76..947e5970 100644
--- a/po/kk.po
+++ b/po/kk.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-05-30 22:03+0000\n"
-"PO-Revision-Date: 2020-06-24 12:43+0500\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-09-06 22:37+0500\n"
"Last-Translator: Baurzhan Muftakhidinov <baurthefirst@gmail.com>\n"
"Language-Team: Kazakh <kk_KZ@googlegroups.com>\n"
"Language: kk\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Poedit 2.3.1\n"
+"X-Generator: Poedit 2.4.1\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -44,12 +44,12 @@ msgstr ""
"немеÑе Jamendo мен Magnatune қызметтері арқылы бірнәрÑе жаңаны қолданып "
"көріңіз."
-#: data/org.gnome.Music.appdata.xml.in.in:132
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "GNOME музыкаÑÑ‹ әзірлеушілері"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Музыка"
@@ -206,15 +206,15 @@ msgstr ""
"Sami Pyylampi шығарған \"Magic of the vinyl\" Ñуреті CC-BY-SA 2.0 аÑÑында "
"лицензиÑланған https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Шығарылған"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Ұзақтығы"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Композитор"
@@ -246,16 +246,16 @@ msgstr "Мәзір"
msgid "Select"
msgstr "Таңдау"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "Ба_Ñ Ñ‚Ð°Ñ€Ñ‚Ñƒ"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Іздеу"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Кері"
@@ -364,6 +364,10 @@ msgstr "Музыка тыңдау туралы хабарлау үшін Last.fm
msgid "Login"
msgstr "Кіру"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Жүктелуде"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "ÐралаÑтыру"
@@ -381,15 +385,15 @@ msgstr "Тректі қайталау"
msgid "Shuffle/Repeat Off"
msgstr "ÐралаÑтыру/қайталау Ñөндірілген"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Ðлдыңғы"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Ойнату"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "КелеÑÑ–"
@@ -422,7 +426,7 @@ msgstr "Ðтын Ó©_згерту…"
msgid "Playlist Name"
msgstr "Ойнату тізімінің аты"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Дайын"
@@ -450,19 +454,23 @@ msgstr "Ойнату тізіміне қоÑу"
msgid "_Add"
msgstr "Қо_Ñу"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "Бол_дырмау"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "ӘртіÑтер"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Барлығын қарау"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Ðльбомдар"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:51
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Өлеңдер"
@@ -483,49 +491,49 @@ msgid "_Add to Playlist"
msgstr "Ойнату тізіміне Ò›_оÑу"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:835
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Ең жиі ойнатылған"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:872
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Ешқашан ойналмаған"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:908
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Жақында ойналған"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:954
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Жақында қоÑылған"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Таңдамалы өлеңдер"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Файлды ойнату мүмкін емеÑ"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "{} ішінен _табу"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " және "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "файлды ойнату үшін {} керек, бірақ, ол орнатылмаған."
@@ -534,11 +542,11 @@ msgstr[0] "файлды ойнату үшін {} керек, бірақ, ол о
msgid "Playing music"
msgstr "Музыканы ойнату"
-#: gnomemusic/utils.py:65
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "БелгіÑіз альбом"
-#: gnomemusic/utils.py:86
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "БелгіÑіз әртіÑ"
@@ -556,60 +564,60 @@ msgstr "Музыка бумаÑÑ‹"
msgid "The contents of your {} will appear here."
msgstr "{} құрамаÑÑ‹ оÑында көрÑетіледі."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Сәлем DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Музыка табылмады"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "БаÑқа Ñөздерді іздеп көріңіз"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME музыка қолданбаÑÑ‹ Трекерге байланыÑа алмады"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr ""
"Сіздің музыка файлдарыңызды Трекер орындалып тұрмаÑа индекÑтеу мүмкін емеÑ"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Жүйелік Tracker нұÑқаÑÑ‹ еÑкірген ÑиÑқты"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Музыка қолданбаÑÑ‹ Tracker 2.3.0 немеÑе жоғарылау нұÑқаÑын талап етеді"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Музыка қолданбаÑÑ‹ Tracker 3.0.0 немеÑе жоғарылау нұÑқаÑын талап етеді"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Ойнату тізімдері"
-#: gnomemusic/views/searchview.py:383
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "ӘртіÑтер нәтижелері"
-#: gnomemusic/views/searchview.py:398
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Ðльбомдар нәтижелері"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} минут"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "ДиÑк {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "{} нәрÑе таңдалды"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} өлең таңдалды"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -628,27 +636,19 @@ msgstr "{} ретінде кірген"
msgid "Configure"
msgstr "Баптау"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Жүктелуде"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "Бол_дырмау"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "{} ойнату тізімі өшірілген"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} {} ішінен өшірілді"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "ÐÑлдату"
-#: gnomemusic/widgets/playlistcontrols.py:126
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} өлең"
diff --git a/po/ko.po b/po/ko.po
index 486a9503..52035d5c 100644
--- a/po/ko.po
+++ b/po/ko.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 11:24+0000\n"
-"PO-Revision-Date: 2020-02-28 18:02+0900\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-08-30 23:52+0900\n"
"Last-Translator: Seong-ho Cho <shcho@gnome.org>\n"
"Language-Team: Korean <gnome-kr@googlegroups.com>\n"
"Language: ko\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Poedit 2.2.4\n"
+"X-Generator: Poedit 2.3.1\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -43,12 +43,12 @@ msgstr ""
"로컬 ìŒì•… 모ìŒì—ì„œ íŠ¸ëž™ì„ ì°¾ê±°ë‚˜, DLNA 서버ì—ì„œ ìŒì•…ì„ ê°€ì ¸ì˜¤ê±°ë‚˜, 쟈멘ë„와 "
"매그너튠 서비스ì—ì„œ 새 ìŒì•…ì„ ê°–ì•„ë³´ì‹­ì‹œì˜¤."
-#: data/org.gnome.Music.appdata.xml.in.in:67
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "The GNOME Music developers"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "ìŒì•…"
@@ -97,7 +97,7 @@ msgid ""
"“song†(repeat current song), “all†(repeat playlist, no shuffle), "
"“shuffle†(shuffle playlist, presumes repeat all)."
msgstr ""
-"ëª¨ì•„ë†“ì€ ìŒì•…ì„ ë°˜ë³µ 재ìƒí•  지 무작위로 재ìƒí•  지 나타내는 값입니다. 사용할 "
+"ëª¨ì•„ë†“ì€ ìŒì•…ì„ ë°˜ë³µ 재ìƒí• ì§€ 무작위로 재ìƒí• ì§€ 나타내는 값입니다. 사용할 "
"수 있는 ê°’ì€ â€œnoneâ€(반복 ë° ìž„ì˜ ìž¬ìƒ ë”), “songâ€(현재 노래 반복), “allâ€(재"
"ìƒ ëª©ë¡ ë°˜ë³µ, ìž„ì˜ ìž¬ìƒ ì•ˆí•¨), “shuffleâ€(ìž¬ìƒ ëª©ë¡ ìž„ì˜ ìž¬ìƒ, 모든 곡 반복으"
"로 간주)입니다."
@@ -198,15 +198,15 @@ msgstr ""
"Sami Pyylampiì˜ â€œMagic of the vinyl†ì´ë¯¸ì§€ëŠ” CC-BY-SA 2.0 ë¼ì´ì„ ìŠ¤ì— ë”°ë¼ ì‚¬"
"용합니다 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "발매ì¼"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "ìž¬ìƒ ì‹œê°„"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "작곡가"
@@ -238,16 +238,16 @@ msgstr "메뉴"
msgid "Select"
msgstr "ì„ íƒ"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "취소(_C)"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "검색"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "뒤로"
@@ -355,6 +355,10 @@ msgstr "ê°ìƒ ìŒì•…ì„ ë³´ê³ í•˜ë ¤ë©´ last.fm 계정으로 로그ì¸í•˜ì‹­ì‹œ
msgid "Login"
msgstr "로그ì¸"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "불러오는 중"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "뒤섞기"
@@ -372,15 +376,15 @@ msgstr "한 곡만 반복"
msgid "Shuffle/Repeat Off"
msgstr "뒤섞기/반복 ë”"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "ì´ì „"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "재ìƒ"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "다ìŒ"
@@ -413,7 +417,7 @@ msgstr "ì´ë¦„ 바꾸기(_R)…"
msgid "Playlist Name"
msgstr "ìž¬ìƒ ëª©ë¡ ì´ë¦„"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "완료(_D)"
@@ -441,19 +445,23 @@ msgstr "ìž¬ìƒ ëª©ë¡ì— 추가"
msgid "_Add"
msgstr "추가(_A)"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:51
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "ë˜ëŒë¦¬ê¸°(_U)"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "ìŒì•…ê°€"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "ëª¨ë‘ ë³´ê¸°"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "앨범"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:49
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "노래"
@@ -474,49 +482,49 @@ msgid "_Add to Playlist"
msgstr "ìž¬ìƒ ëª©ë¡ì— 추가(_A)"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "가장 ë§Žì´ ìž¬ìƒí•¨"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "ìž¬ìƒ ì•ˆí•¨"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "최근 재ìƒí•¨"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "최근 추가함"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "ì¦ê²¨ì°¾ëŠ” 곡"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "파ì¼ì„ 재ìƒí•  수 없습니다"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "{}ì—ì„œ 찾기(_F)"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " ë° "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "파ì¼ì„ 재ìƒí•˜ë ¤ë©´ {}ì´(ê°€) 필요하지만 설치하지 않았습니다."
@@ -525,11 +533,11 @@ msgstr[0] "파ì¼ì„ 재ìƒí•˜ë ¤ë©´ {}ì´(ê°€) 필요하지만 설치하지 ì•Š
msgid "Playing music"
msgstr "ìŒì•… ìž¬ìƒ ì¤‘"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "알 수 없는 앨범"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "ì•Œ 수 없는 ìŒì•…ê°€"
@@ -547,59 +555,59 @@ msgstr "ìŒì•… í´ë”"
msgid "The contents of your {} will appear here."
msgstr "{} ë‚´ìš©ì€ ì—¬ê¸°ì— ë‚˜íƒ€ë‚©ë‹ˆë‹¤."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "안녕 DJ~"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "ìŒì•…ì´ ì—†ìŠµë‹ˆë‹¤"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "다른 방법으로 검색 ì‹œë„"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "그놈 ìŒì•…ì„ íŠ¸ëž˜ì»¤ì— ì—°ê²°í•  수 없습니다"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "트래커를 실행하지 않고는 ìŒì•… 파ì¼ì„ ìƒ‰ì¸ ì²˜ë¦¬í•  수 없습니다"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "ì‹œìŠ¤í…œì— ì„¤ì¹˜í•œ 트래커 ë²„ì „ì´ ì˜¤ëž˜ë습니다"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "그놈 ìŒì•…ì—서는 버전 2.3.0 ì´ìƒì˜ 트래커가 필요합니다"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "그놈 ìŒì•…ì—서는 버전 3.0.0 ì´ìƒì˜ 트래커가 필요합니다"
-#: gnomemusic/views/playlistsview.py:53
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "ìž¬ìƒ ëª©ë¡"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "ìŒì•…ê°€ ê²°ê³¼"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "앨범 결과"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{}분"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "ë””ìŠ¤í¬ {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "항목 {}ê°œ ì„ íƒí•¨"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "ìŒì•… {}곡 ì„ íƒí•¨"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -618,27 +626,19 @@ msgstr "{} 사용ìžë¡œ 로그ì¸í•©ë‹ˆë‹¤"
msgid "Configure"
msgstr "설정"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "불러오는 중"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "ë˜ëŒë¦¬ê¸°(_U)"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "{} ìž¬ìƒ ëª©ë¡ì„ 제거했습니다"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} í•­ëª©ì„ {}ì—ì„œ 제거했습니다"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "ì¼ì‹œ 정지"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "노래 {}곡"
diff --git a/po/lt.po b/po/lt.po
index 82698e41..5c9240d1 100644
--- a/po/lt.po
+++ b/po/lt.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 14:09+0000\n"
-"PO-Revision-Date: 2020-02-17 22:51+0200\n"
+"POT-Creation-Date: 2020-09-01 19:48+0000\n"
+"PO-Revision-Date: 2020-09-01 22:49+0300\n"
"Last-Translator: Aurimas ÄŒernius <aurisc4@gmail.com>\n"
"Language-Team: Lietuvių <gnome-lt@lists.akl.lt>\n"
"Language: lt\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n"
"%100<10 || n%100>=20) ? 1 : 2)\n"
-"X-Generator: Gtranslator 3.34.0\n"
+"X-Generator: Gtranslator 3.36.0\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -44,12 +44,12 @@ msgstr ""
"Raskite takelius savo vietinėje kolekcijoje, gaukite muziką iš DLNA serverių "
"arba pabandykite kÄ… nors naujo su Jamendo ir Magnatune paslaugomis."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "GNOME Muzikos kūrėjai"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Muzika"
@@ -201,15 +201,15 @@ msgstr ""
"Sami Pyylampi „Magic of the vinyl“ paveikslėlis platintas pagal CC-BY-SA 2.0 "
"licencijÄ… https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "IÅ¡leista"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Grojimo trukmÄ—"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Kompozitorius"
@@ -241,16 +241,16 @@ msgstr "Meniu"
msgid "Select"
msgstr "Žymėti"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Atsisakyti"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Paieška"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Grįžti"
@@ -361,6 +361,10 @@ msgstr ""
msgid "Login"
msgstr "Prisijungti"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Įkeliama"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Maišyti"
@@ -378,15 +382,15 @@ msgstr "Kartoti dainÄ…"
msgid "Shuffle/Repeat Off"
msgstr "Maišyti/nekartoti"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "AnkstesnÄ—"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Groti"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Kita"
@@ -419,7 +423,7 @@ msgstr "Pe_rvadinti…"
msgid "Playlist Name"
msgstr "GrojaraÅ¡Äio pavadinimas"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "A_tlikta"
@@ -447,19 +451,23 @@ msgstr "Pridėti į grojaraštį"
msgid "_Add"
msgstr "_PridÄ—ti"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Atšaukti"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "AtlikÄ—jai"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Rodyti viskÄ…"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Albumai"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Dainos"
@@ -480,49 +488,49 @@ msgid "_Add to Playlist"
msgstr "_Pridėti į grojaraštį"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:827
msgid "Most Played"
msgstr "Dažniausiai grojama"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:880
msgid "Never Played"
msgstr "Niekada negrota"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:932
msgid "Recently Played"
msgstr "Neseniai grota"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:994
msgid "Recently Added"
msgstr "Neseniai pridÄ—ta"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1056
msgid "Favorite Songs"
msgstr "MÄ—giama daina"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Nepavyksta groti failo"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Rasti {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " ir "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "Failui pagroti reikalingas {}, bet jis neįdiegtas."
@@ -533,11 +541,11 @@ msgstr[2] "Failui pagroti reikalingi {}, bet jie neįdiegti."
msgid "Playing music"
msgstr "Grojama muzika"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Nežinomas albumas"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Nežinomas atlikėjas"
@@ -555,71 +563,70 @@ msgstr "Muzikos aplankas"
msgid "The contents of your {} will appear here."
msgstr "Čia matysite savo {} aplanko turinį"
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Sveikas, DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Nerasta muzikos"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Bandykite kitą paiešką"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME muzikai nepavyko prisijungti prie Tracker sistemos"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "JÅ«sų muzikos failų negalima indeksuoti be veikianÄios Tracker sistemos"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Jūsų sistemos Tracker versija atrodo pasenusi"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Muzikai reikia Tracker versijos 2.3.0 arba naujesnÄ—s"
+#: gnomemusic/views/emptyview.py:146
+#| msgid "Music needs Tracker version 2.3.0 or higher"
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Muzikai reikia Tracker versijos 3.0.0 arba naujesnÄ—s"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "GrojaraÅ¡Äiai"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Atlikėjų rezultatai"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Albumų rezultatai"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minutÄ—"
msgstr[1] "{} minutÄ—s"
msgstr[2] "{} minuÄių"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Diskas {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Pažymėtas {} elementas"
-msgstr[1] "Pažymėti {} elementai"
-msgstr[2] "Pažymėta {} elementų"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Pažymėta {} daina"
+msgstr[1] "Pažymėtos {} dainos"
+msgstr[2] "Pažymėta {} dainų"
#: gnomemusic/widgets/lastfmdialog.py:65
-#| msgid "Report music history to Last.fm"
msgid "Your music listening is reported to Last.fm."
msgstr "Apie jūsų klausomą muziką bus pranešama Last.fm"
#: gnomemusic/widgets/lastfmdialog.py:67
-#| msgid "Report music history to Last.fm"
msgid "Your music listening is not reported to Last.fm."
msgstr "Apie jūsų klausomą muziką nėra pranešama Last.fm"
@@ -632,27 +639,19 @@ msgstr "Prisijungta kaip {}"
msgid "Configure"
msgstr "Nustatyti"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Įkeliama"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Atšaukti"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Grojaraštis {} pašalintas"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} pašalinta iš {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pristabdyti"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} daina"
diff --git a/po/lv.po b/po/lv.po
index 982db858..6870e47e 100644
--- a/po/lv.po
+++ b/po/lv.po
@@ -1,13 +1,13 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
#
-# RÅ«dolfs Mazurs <rudolfs.mazurs@gmail.com>, 2013, 2014, 2016, 2017, 2018, 2019.
+# RÅ«dolfs Mazurs <rudolfs.mazurs@gmail.com>, 2013, 2014, 2016, 2017, 2018, 2019, 2020.
msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2019-08-06 17:01+0000\n"
-"PO-Revision-Date: 2019-08-24 17:18+0200\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-09-12 21:23+0300\n"
"Last-Translator: RÅ«dolfs Mazurs <rudolfs.mazurs@gmail.com>\n"
"Language-Team: Latvian <lata-l10n@googlegroups.com>\n"
"Language: lv\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 :"
" 2);\n"
-"X-Generator: Lokalize 2.0\n"
+"X-Generator: Lokalize 19.12.3\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -43,13 +43,12 @@ msgstr ""
"Atrodiet celiņus jÅ«su lokÄlajÄ kolekcijÄ, saņemiet mÅ«ziku no DLNA serveriem "
"vai no Jamendo un Magnatune pakalpojumiem."
-#: data/org.gnome.Music.appdata.xml.in.in:52
-#| msgid "Copyright © 2018 GNOME Music Developers"
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "GNOME MÅ«zikas izstrÄdÄtÄji"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:59
-#: gnomemusic/window.py:77
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "MÅ«zika"
@@ -127,6 +126,18 @@ msgstr "NomÄkt sistÄ“mas iesnauÅ¡anu"
msgid "Enables or disables inhibiting system suspend while playing music"
msgstr "IeslÄ“dz vai izslÄ“dz sistÄ“mas iesnauÅ¡anas nomÄkÅ¡anu, kad atskaņo mÅ«ziku"
+#: data/org.gnome.Music.gschema.xml:48
+msgid "Report music history to Last.fm"
+msgstr "Ziņot Last.fm par mūzikas vēsturi"
+
+#: data/org.gnome.Music.gschema.xml:49
+msgid ""
+"Enables or disables sending scrobbles and the “currently playing†info to "
+"Last.fm."
+msgstr ""
+"IeslÄ“dz vai izslÄ“dz scrobbles un “palÅ¡aik atskaņo†informÄcijas sÅ«tÄ«Å¡anu uz"
+" Last.fm."
+
#: data/ui/AboutDialog.ui.in:9
msgid "Copyright © 2018 GNOME Music Developers"
msgstr "AutortiesÄ«bas © 2018 GNOME MÅ«zikas izstrÄdÄtÄji"
@@ -189,48 +200,56 @@ msgstr ""
"Sami Pyylampi attēls “Magic of the vinyl†ir zem licences CC-BY-SA 2.0 "
"https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Izlaists"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Atskaņošanas ilgums"
-#: data/ui/AlbumWidget.ui:166 gnomemusic/widgets/searchbar.py:70
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Komponists"
-#: data/ui/AppMenu.ui:21
+#: data/ui/AppMenu.ui:20 data/ui/LastfmDialog.ui:8
+msgid "Last.fm Account"
+msgstr "Last.fm konts"
+
+#: data/ui/AppMenu.ui:38
+msgid "Report Music Listening"
+msgstr "Ziņot par mūzikas klausīšanos"
+
+#: data/ui/AppMenu.ui:69
msgid "_Keyboard Shortcuts"
msgstr "_TastatÅ«ras Ä«sinÄjumtaustiņi"
-#: data/ui/AppMenu.ui:35
+#: data/ui/AppMenu.ui:83
msgid "_Help"
msgstr "_Palīdzība"
-#: data/ui/AppMenu.ui:49
+#: data/ui/AppMenu.ui:97
msgid "_About Music"
msgstr "P_ar mūziku"
-#: data/ui/HeaderBar.ui:13
+#: data/ui/HeaderBar.ui:16
msgid "Menu"
msgstr "Izvēlne"
-#: data/ui/HeaderBar.ui:36 data/ui/SearchHeaderBar.ui:13
+#: data/ui/HeaderBar.ui:39 data/ui/SearchHeaderBar.ui:16
msgid "Select"
msgstr "Izvēlēties"
-#: data/ui/HeaderBar.ui:58 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:35
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "At_celt"
-#: data/ui/HeaderBar.ui:77 data/ui/SearchHeaderBar.ui:54
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Meklēt"
-#: data/ui/HeaderBar.ui:100
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Atpakaļ"
@@ -319,6 +338,31 @@ msgctxt "shortcut window"
msgid "Go back"
msgstr "Iet atpakaļ"
+#: data/ui/LastfmDialog.ui:21
+msgid ""
+"Last.fm is a music discovery service that gives you personalised "
+"recommendations based on the music you listen to."
+msgstr ""
+"Last.fm ir mÅ«zikas atklÄÅ¡anas pakalpojums, kas jums dod personalizÄ“tus"
+" ieteikumus balstoties uz tÄ, kÄdu mÅ«ziku jÅ«s klausÄties."
+
+#: data/ui/LastfmDialog.ui:32 gnomemusic/widgets/lastfmdialog.py:58
+msgid "Music Reporting Not Setup"
+msgstr "Mūzikas ziņošana nav iestatīta"
+
+#: data/ui/LastfmDialog.ui:46 gnomemusic/widgets/lastfmdialog.py:61
+msgid "Login to your Last.fm account to report your music listening."
+msgstr ""
+"Ierakstieties savÄ Last.fm kontÄ, lai ziņotu par savu mÅ«zikas klausÄ«Å¡anos."
+
+#: data/ui/LastfmDialog.ui:57 gnomemusic/widgets/lastfmdialog.py:59
+msgid "Login"
+msgstr "Ierakstīties"
+
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "IelÄdÄ“"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Sajaukt"
@@ -336,15 +380,15 @@ msgstr "AtkÄrtot dziesmu"
msgid "Shuffle/Repeat Off"
msgstr "IzslÄ“gt jaukÅ¡anu/atkÄrtoÅ¡anu"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Iepriekšējais"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:153
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Atskaņot"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "NÄkamais"
@@ -373,7 +417,7 @@ msgstr "_Dzēst"
msgid "_Rename…"
msgstr "PÄ_rdÄ“vÄ“t…"
-#: data/ui/PlaylistControls.ui:40
+#: data/ui/PlaylistControls.ui:41
msgid "Playlist Name"
msgstr "RepertuÄra nosaukums"
@@ -405,19 +449,23 @@ msgstr "Pievienot repertuÄram"
msgid "_Add"
msgstr "_Pievienot"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:59
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Atsaukt"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "IzpildÄ«tÄji"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:104
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "RÄdÄ«t visu"
-#: data/ui/SearchView.ui:94 gnomemusic/views/albumsview.py:61
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Albumi"
-#: data/ui/SearchView.ui:144 gnomemusic/views/songsview.py:57
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Dziesmas"
@@ -429,7 +477,7 @@ msgstr "Izvēlēties visu"
msgid "Select None"
msgstr "Iezīmēt neko"
-#: data/ui/SelectionBarMenuButton.ui:31 gnomemusic/widgets/headerbar.py:75
+#: data/ui/SelectionBarMenuButton.ui:31 gnomemusic/widgets/headerbar.py:71
msgid "Click on items to select them"
msgstr "Spiediet uz vienumiem, lai tos izvēlētos"
@@ -438,191 +486,198 @@ msgid "_Add to Playlist"
msgstr "_Pievienot repertuÄram"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:673
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "VisbiežÄk atskaņotÄs"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:707
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Nekad neatskaņotÄs"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:740
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Nesen atskaņotÄs"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:784
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Nesen pievienotÄs"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:827
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "IecienÄ«tÄs dziesmas"
-#: gnomemusic/gstplayer.py:403
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "NeizdevÄs atskaņot datni"
-#: gnomemusic/gstplayer.py:409
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Meklēt mapē {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:420
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " un "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:423
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:425
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "Lai atskaņotu datni, nepieciešams {}, bet tas nav uzinstalēts."
msgstr[1] "Lai atskaņotu datni, nepieciešami {}, bet tie nav uzinstalēti."
msgstr[2] "Lai atskaņotu datni, nepieciešami {}, bet tie nav uzinstalēti."
-#: gnomemusic/inhibitsuspend.py:72
+#: gnomemusic/inhibitsuspend.py:63
msgid "Playing music"
msgstr "Atskaņo mūziku"
-#: gnomemusic/utils.py:62
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "NezinÄms albums"
-#: gnomemusic/utils.py:83
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "NezinÄms izpildÄ«tÄjs"
-#: gnomemusic/views/emptyview.py:79
+#: gnomemusic/views/emptyview.py:67
+msgid "Your XDG Music directory is not set."
+msgstr "Jūsu XDG mūzikas direktorija nav iestatīta."
+
+#: gnomemusic/views/emptyview.py:74
msgid "Music folder"
msgstr "MÅ«zikas mape"
#. TRANSLATORS: This is a label to display a link to open user's music
#. folder. {} will be replaced with the translated text 'Music folder'
-#: gnomemusic/views/emptyview.py:83
+#: gnomemusic/views/emptyview.py:78
msgid "The contents of your {} will appear here."
msgstr "JÅ«su {} saturs parÄdÄ«sies Å¡eit"
-#: gnomemusic/views/emptyview.py:119
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Eu DJ"
-#: gnomemusic/views/emptyview.py:129 gnomemusic/views/emptyview.py:135
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Nav atrasta mūzika"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "MÄ“Ä£iniet ar citu meklÄ“jamo vÄrdu"
-#: gnomemusic/views/emptyview.py:143
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME Mūzika nevarēja savienoties ar Tracker"
-#: gnomemusic/views/emptyview.py:146
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Nevar indeksēt jūsu mūzikas datnes, ja nedarbojas Tracker"
-#: gnomemusic/views/emptyview.py:154
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Jūsu sistēmas Tracker versija ir novecojusi"
-#: gnomemusic/views/emptyview.py:157
-msgid "Music needs Tracker version 2.2.0 or higher"
-msgstr "MÅ«zikai vajag Tracker vismaz versiju 2.2.0"
+#: gnomemusic/views/emptyview.py:146
+#| msgid "Music needs Tracker version 2.2.0 or higher"
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "MÅ«zikai vajag Tracker vismaz versiju 3.0.0"
-#: gnomemusic/views/playlistsview.py:58
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "RepertuÄri"
-#: gnomemusic/views/searchview.py:363
-#| msgid "Artists"
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "IzpildÄ«tÄju rezultÄti"
-#: gnomemusic/views/searchview.py:377
-#| msgid "Albums"
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Albumu rezultÄti"
-#: gnomemusic/widgets/albumwidget.py:147
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minūte"
msgstr[1] "{} minūtes"
msgstr[2] "{} minūšu"
-#: gnomemusic/widgets/disclistboxwidget.py:82
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disks (}"
-#: gnomemusic/widgets/headerbar.py:72
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Izvēlēts {} vienums"
-msgstr[1] "Izvēlēti {} vienumi"
-msgstr[2] "Izvēlēti {} vienumi"
-
-#: gnomemusic/widgets/notificationspopup.py:168
-msgid "Loading"
-msgstr "IelÄdÄ“"
-
-#: gnomemusic/widgets/notificationspopup.py:241
-msgid "_Undo"
-msgstr "_Atsaukt"
-
-#: gnomemusic/widgets/notificationspopup.py:256
+#: gnomemusic/widgets/headerbar.py:68
+#| msgid "Selected {} item"
+#| msgid_plural "Selected {} items"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Izvēlēta {} dziesma"
+msgstr[1] "Izvēlētas {} dziesmas"
+msgstr[2] "Izvēlētas {} dziesmas"
+
+#: gnomemusic/widgets/lastfmdialog.py:65
+msgid "Your music listening is reported to Last.fm."
+msgstr "JÅ«su mÅ«zikas klausÄ«Å¡anÄs tiek ziņota uz Last.fm."
+
+#: gnomemusic/widgets/lastfmdialog.py:67
+msgid "Your music listening is not reported to Last.fm."
+msgstr "JÅ«su mÅ«zikas klausÄ«Å¡anÄs netiek tiek ziņota uz Last.fm."
+
+#. TRANSLATORS: displays the username of the Last.fm account
+#: gnomemusic/widgets/lastfmdialog.py:71
+msgid "Logged in as {}"
+msgstr "IerakstÄ«jies kÄ {}"
+
+#: gnomemusic/widgets/lastfmdialog.py:72
+msgid "Configure"
+msgstr "Konfigurēt"
+
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "RepertuÄra {} ir izņemts"
-#: gnomemusic/widgets/notificationspopup.py:260
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} izņemts no {}"
-#: gnomemusic/widgets/playertoolbar.py:150
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pauzēt"
-#: gnomemusic/widgets/playlistcontrols.py:83
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} dziesma"
msgstr[1] "{} dziesmas"
msgstr[2] "{} dziesmu"
-#: gnomemusic/widgets/searchbar.py:67 gnomemusic/widgets/searchbar.py:116
-msgid "All"
-msgstr "Visi"
+#~ msgid "All"
+#~ msgstr "Visi"
-#: gnomemusic/widgets/searchbar.py:68
-msgid "Artist"
-msgstr "IzpildÄ«tÄjs"
+#~ msgid "Artist"
+#~ msgstr "IzpildÄ«tÄjs"
-#: gnomemusic/widgets/searchbar.py:69
-msgid "Album"
-msgstr "Albums"
+#~ msgid "Album"
+#~ msgstr "Albums"
-#: gnomemusic/widgets/searchbar.py:71
-msgid "Track Title"
-msgstr "Celiņa nosaukums"
+#~ msgid "Track Title"
+#~ msgstr "Celiņa nosaukums"
-#: gnomemusic/widgets/searchbar.py:117
-msgid "Local"
-msgstr "LokÄls"
+#~ msgid "Local"
+#~ msgstr "LokÄls"
-#: gnomemusic/widgets/searchbar.py:286
-msgid "Sources"
-msgstr "Avoti"
+#~ msgid "Sources"
+#~ msgstr "Avoti"
-#: gnomemusic/widgets/searchbar.py:297
-msgid "Match"
-msgstr "Atbilst"
+#~ msgid "Match"
+#~ msgstr "Atbilst"
#~ msgid "@icon@"
#~ msgstr "@icon@"
diff --git a/po/nl.po b/po/nl.po
index 042dacf9..69db94f3 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -12,8 +12,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 11:24+0000\n"
-"PO-Revision-Date: 2020-02-24 18:52+0100\n"
+"POT-Creation-Date: 2020-08-21 14:47+0000\n"
+"PO-Revision-Date: 2020-08-25 18:12+0200\n"
"Last-Translator: Nathan Follens <nthn@unseen.is>\n"
"Language-Team: Dutch <gnome-nl-list@gnome.org>\n"
"Language: nl\n"
@@ -21,7 +21,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.3\n"
+"X-Generator: Poedit 2.4.1\n"
"X-Project-Style: gnome\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
@@ -49,12 +49,12 @@ msgstr ""
"Zoek nummers in uw lokale verzameling, haal muziek op van DLNA-servers of "
"probeer eens iets nieuws met de Jamendo- en Magnatune-diensten."
-#: data/org.gnome.Music.appdata.xml.in.in:67
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "De Gnome Muziek-ontwikkelaars"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:59
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Muziek"
@@ -211,15 +211,15 @@ msgstr ""
"‘Magic of the vinyl’ door Sami Pyylampi afbeelding is uitgebracht onder CC-"
"BY-SA 2.0 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Uitgegeven"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Speelduur"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Componist"
@@ -251,16 +251,16 @@ msgstr "Menu"
msgid "Select"
msgstr "Selecteren"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Annuleren"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Zoeken"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Terug"
@@ -370,6 +370,10 @@ msgstr ""
msgid "Login"
msgstr "Aanmelden"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Laden"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Willekeurig"
@@ -387,15 +391,15 @@ msgstr "Nummer herhalen"
msgid "Shuffle/Repeat Off"
msgstr "Willekeurig/Herhalen uit"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Vorige"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Afspelen"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Volgende"
@@ -428,7 +432,7 @@ msgstr "He_rnoemen…"
msgid "Playlist Name"
msgstr "Afspeellijstnaam"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Klaar"
@@ -456,19 +460,23 @@ msgstr "Toevoegen aan afspeellijst"
msgid "_Add"
msgstr "_Toevoegen"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:51
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Ongedaan maken"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Artiesten"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Alles tonen"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Muziekalbum"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:49
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Nummers"
@@ -489,49 +497,49 @@ msgid "_Add to Playlist"
msgstr "Toevoegen aan _afspeellijst"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:822
msgid "Most Played"
msgstr "Meest afgespeeld"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:858
msgid "Never Played"
msgstr "Nooit afgespeeld"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:893
msgid "Recently Played"
msgstr "Onlangs afgespeeld"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:938
msgid "Recently Added"
msgstr "Onlangs toegevoegd"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:982
msgid "Favorite Songs"
msgstr "Favoriete nummers"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Kan het bestand niet afspelen"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Zoeken in {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " en "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] ""
@@ -543,11 +551,11 @@ msgstr[1] ""
msgid "Playing music"
msgstr "Muziek wordt afgespeeld"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Onbekend album"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Onbekende artiest"
@@ -565,63 +573,63 @@ msgstr "Muziekmap"
msgid "The contents of your {} will appear here."
msgstr "De inhoud van uw {} zal hier verschijnen."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hoi DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Geen muziek gevonden"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Probeer een andere zoekopdracht"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "Gnome Muziek kon geen verbinding maken met Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr ""
"Uw muziekbestanden kunnen niet geïndexeerd worden zonder dat Tracker wordt "
"uitgevoerd"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Uw versie van Tracker is verouderd"
-#: gnomemusic/views/emptyview.py:147
+#: gnomemusic/views/emptyview.py:146
msgid "Music needs Tracker version 2.3.0 or higher"
msgstr "Muziek vereist versie 2.3.0 of hoger van Tracker"
-#: gnomemusic/views/playlistsview.py:53
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Afspeellijsten"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:381
msgid "Artists Results"
msgstr "Artiestresultaten"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:396
msgid "Albums Results"
msgstr "Albumresultaten"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minuut"
msgstr[1] "{} minuten"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Schijf {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "{} item geselecteerd"
-msgstr[1] "{} items geselecteerd"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} nummer geselecteerd"
+msgstr[1] "{} nummers geselecteerd"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -640,27 +648,19 @@ msgstr "Aangemeld als {}"
msgid "Configure"
msgstr "Configureren"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Laden"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Ongedaan maken"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Afspeellijst {} verwijderd"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} verwijderd uit {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pauzeren"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} nummer"
diff --git a/po/pl.po b/po/pl.po
index 4024f2aa..8151a3c5 100644
--- a/po/pl.po
+++ b/po/pl.po
@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 11:24+0000\n"
-"PO-Revision-Date: 2020-02-16 16:39+0100\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-08-29 12:13+0200\n"
"Last-Translator: Piotr DrÄ…g <piotrdrag@gmail.com>\n"
"Language-Team: Polish <community-poland@mozilla.org>\n"
"Language: pl\n"
@@ -45,12 +45,12 @@ msgstr ""
"Umożliwia wyszukiwanie utworów w lokalnej kolekcji, pobieranie muzyki "
"z serwerów DLNA oraz wypróbowywanie nowości z serwisów Jamendo i Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:67
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Programiści odtwarzacza muzyki GNOME"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Muzyka"
@@ -210,15 +210,15 @@ msgstr ""
"Obraz „Magic of the vinyl†autorstwa Sami’ego Pyylampi na licencji CC-BY-SA "
"2.0 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Rok wydania"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Czas trwania"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Kompozytor"
@@ -250,16 +250,16 @@ msgstr "Menu"
msgid "Select"
msgstr "Zaznacza"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Anuluj"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Wyszukuje"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Wstecz"
@@ -368,6 +368,10 @@ msgstr "Zgłaszanie odsłuchanych utworów wymaga zalogowania na konto Last.fm."
msgid "Login"
msgstr "Zaloguj siÄ™"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Wczytywanie"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Odtwarzanie losowe"
@@ -385,15 +389,15 @@ msgstr "Powtarzanie utworu"
msgid "Shuffle/Repeat Off"
msgstr "Wyłączenie losowania/powtarzania"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Poprzedni"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Odtwarza"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Następny"
@@ -426,7 +430,7 @@ msgstr "_Zmień nazwę…"
msgid "Playlist Name"
msgstr "Nazwa listy odtwarzania"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Gotowe"
@@ -454,19 +458,23 @@ msgstr "Dodanie do listy odtwarzania"
msgid "_Add"
msgstr "_Dodaj"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:51
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "Cof_nij"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Wykonawcy"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Wyświetl wszystko"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Albumy"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:49
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Utwory"
@@ -487,49 +495,49 @@ msgid "_Add to Playlist"
msgstr "_Dodaj do listy odtwarzania"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Najczęściej odtwarzane"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Nigdy nieodtworzone"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Ostatnio odtwarzane"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Ostatnio dodane"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Ulubione utwory"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Nie można odtworzyć pliku"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Znajdź w „{}â€"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " i "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} jest wymagane do odtworzenia pliku, ale nie jest zainstalowane."
@@ -540,11 +548,11 @@ msgstr[2] "{} sÄ… wymagane do odtworzenia pliku, ale nie sÄ… zainstalowane."
msgid "Playing music"
msgstr "Odtwarzanie muzyki"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Nieznany album"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Nieznany wykonawca"
@@ -562,63 +570,63 @@ msgstr "katalogu z muzyką"
msgid "The contents of your {} will appear here."
msgstr "W tym miejscu będzie znajdować się zawartość {}."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Witaj w odtwarzaczu muzyki"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Nie odnaleziono plików muzycznych"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Proszę spróbować innych słów"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "Odtwarzacz muzyki GNOME nie może połączyć się z usługą Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Bez działającej usługi Tracker nie można wykryć plików z muzyką"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Wersja usługi Tracker zainstalowana na komputerze jest przestarzała"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Odtwarzacz muzyki wymaga wersji 2.3.0 lub wyższej"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Odtwarzacz muzyki wymaga wersji 3.0.0 lub wyższej"
-#: gnomemusic/views/playlistsview.py:53
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Listy odtwarzania"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Wyniki wyszukiwania wśród wykonawców"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Wyniki wyszukiwania wśród albumów"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minuta"
msgstr[1] "{} minuty"
msgstr[2] "{} minut"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "{}. płyta"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Zaznaczono {} element"
-msgstr[1] "Zaznaczono {} elementy"
-msgstr[2] "Zaznaczono {} elementów"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Zaznaczono {} utwór"
+msgstr[1] "Zaznaczono {} utwory"
+msgstr[2] "Zaznaczono {} utworów"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -637,27 +645,19 @@ msgstr "Zalogowano jako {}"
msgid "Configure"
msgstr "Skonfiguruj"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Wczytywanie"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "Cof_nij"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "UsuniÄ™to listÄ™ odtwarzania „{}â€"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "UsuniÄ™to utwór „{}†z listy „{}â€"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Wstrzymuje"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} utwór"
diff --git a/po/pt.po b/po/pt.po
index bd6689af..a8c4ceb5 100644
--- a/po/pt.po
+++ b/po/pt.po
@@ -4,53 +4,97 @@
# António Lima <amrlima@gmail.com>, 2013.
# Tiago Santos <tiagofsantos81@sapo.pt>, 2014 - 2017.
# Pedro Albuquerque <palbuquerque73@openmailbox.com>, 2015.
+# Juliano de Souza Camargo <julianosc@protonmail.com>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
-"Report-Msgid-Bugs-To: https://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
-"music&keywords=I18N+L10N&component=general\n"
-"POT-Creation-Date: 2017-03-01 09:59+0000\n"
-"PO-Revision-Date: 2017-03-23 14:44+0000\n"
-"Last-Translator: Tiago Santos <tiagofsantos81@sapo.pt>\n"
-"Language-Team: Português <palbuquerque73@openmailbox.com>\n"
+"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-09-11 21:53-0300\n"
+"Last-Translator: Juliano de Souza Camargo <julianosc@protonmail.com>\n"
+"Language-Team: Portuguese <>\n"
"Language: pt\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.8.7.1\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+"X-Generator: Gtranslator 3.36.0\n"
-#: ../data/org.gnome.Music.gschema.xml.h:1
+#: data/org.gnome.Music.appdata.xml.in.in:6
+msgid "GNOME Music"
+msgstr "Música"
+
+#: data/org.gnome.Music.appdata.xml.in.in:7
+#: data/org.gnome.Music.desktop.in.in:5
+msgid "Play and organize your music collection"
+msgstr "Reproduz e organiza a sua coleção de música"
+
+#: data/org.gnome.Music.appdata.xml.in.in:9
+msgid ""
+"An easy way to play your music. Automatically discover music on your "
+"computer, the local network and internet services."
+msgstr ""
+"Uma maneira fácil de tocar música. Descobre músicas automaticamente em seu "
+"computador, na rede local ou em serviços na Internet."
+
+#: data/org.gnome.Music.appdata.xml.in.in:12
+msgid ""
+"Find tracks in your local collection, get music from DLNA servers or try "
+"something new with the Jamendo and Magnatune services."
+msgstr ""
+"Encontre faixas em seu repertório local, transfira músicas de servidores "
+"DLNA ou tente algo novo com os serviços Jamendo e Magnatune."
+
+#: data/org.gnome.Music.appdata.xml.in.in:110
+#| msgid "Copyright © 2016 GNOME Music Developers"
+msgid "The GNOME Music developers"
+msgstr "Programadores do Música"
+
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
+msgid "Music"
+msgstr "Música"
+
+#: data/org.gnome.Music.desktop.in.in:4
+msgid "Music Player"
+msgstr "Reprodutor de música"
+
+#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
+#: data/org.gnome.Music.desktop.in.in:13
+msgid "Music;Player;"
+msgstr "Reprodutor;Música;"
+
+#: data/org.gnome.Music.gschema.xml:12
msgid "Window size"
msgstr "Tamanho da janela"
-#: ../data/org.gnome.Music.gschema.xml.h:2
+#: data/org.gnome.Music.gschema.xml:13
msgid "Window size (width and height)."
msgstr "Tamanho da janela (largura e altura)."
-#: ../data/org.gnome.Music.gschema.xml.h:3
+#: data/org.gnome.Music.gschema.xml:17
msgid "Window position"
msgstr "Posição da janela"
-#: ../data/org.gnome.Music.gschema.xml.h:4
+#: data/org.gnome.Music.gschema.xml:18
msgid "Window position (x and y)."
msgstr "Posição da janela (x e y)."
-#: ../data/org.gnome.Music.gschema.xml.h:5
+#: data/org.gnome.Music.gschema.xml:22
msgid "Window maximized"
msgstr "Janela maximizada"
-#: ../data/org.gnome.Music.gschema.xml.h:6
+#: data/org.gnome.Music.gschema.xml:23
msgid "Window maximized state."
msgstr "Estado maximizado da janela"
-#: ../data/org.gnome.Music.gschema.xml.h:7
+#: data/org.gnome.Music.gschema.xml:27
msgid "Playback repeat mode"
msgstr "Modo de repetição de reprodução"
#. Translators: Don't translate allowed values, just the description in the brackets
-#: ../data/org.gnome.Music.gschema.xml.h:9
+#: data/org.gnome.Music.gschema.xml:29
msgid ""
"Value identifies whether to repeat or randomize playback through the "
"collection. Allowed values are: “none†(repeat and shuffle are off), "
@@ -62,282 +106,80 @@ msgstr ""
"desligados), “song†(repete a música atual), “all†(repete a lista sem "
"misturar), “shuffle†(misturar a lista e assumir repetir todas)."
-#: ../data/org.gnome.Music.gschema.xml.h:10
-msgid "Search mode"
-msgstr "Modo de procura"
-
-#: ../data/org.gnome.Music.gschema.xml.h:11
-msgid "If true, the search bar is shown."
-msgstr "Se verdadeiro, a barra de procura é mostrada."
-
-#: ../data/org.gnome.Music.gschema.xml.h:12
-msgid "Notifications mode"
-msgstr "Modo de notificações"
-
-#: ../data/org.gnome.Music.gschema.xml.h:13
-msgid "Enables or disables playback notifications"
-msgstr "Ativa ou desativa notificações de reprodução"
-
-#: ../data/org.gnome.Music.gschema.xml.h:14
+#: data/org.gnome.Music.gschema.xml:33
msgid "Enable ReplayGain"
msgstr "Ativar ReplayGain"
-#: ../data/org.gnome.Music.gschema.xml.h:15
+#: data/org.gnome.Music.gschema.xml:34
msgid "Enables or disables ReplayGain for albums"
msgstr "Ativa ou desativa ReplyGain para álbuns"
-#: ../data/org.gnome.Music.gschema.xml.h:16
+#: data/org.gnome.Music.gschema.xml:38
msgid "Inital state has been displayed"
msgstr "O estado inicial foi mostrado"
-#: ../data/org.gnome.Music.gschema.xml.h:17
+#: data/org.gnome.Music.gschema.xml:39
msgid "Set to true when initial state has been displayed"
msgstr "Definido como verdadeiro quando o estado inicial foi mostrado"
-#: ../data/gnome-music.desktop.in.h:1 ../gnomemusic/application.py:53
-#: ../gnomemusic/application.py:101 ../gnomemusic/toolbar.py:90
-#: ../gnomemusic/window.py:68 ../data/AboutDialog.ui.in.h:1
-msgid "Music"
-msgstr "Música"
-
-#: ../data/gnome-music.desktop.in.h:2
-msgid "Music Player"
-msgstr "Reprodutor de música"
-
-#: ../data/gnome-music.desktop.in.h:3 ../data/gnome-music.appdata.xml.in.h:2
-msgid "Play and organize your music collection"
-msgstr "Reproduz e organiza a sua coleção de música"
-
-#: ../data/gnome-music.desktop.in.h:4
-msgid "Music;Player;"
-msgstr "Reprodutor;Música;"
-
-#: ../data/gnome-music.appdata.xml.in.h:1
-msgid "GNOME Music"
-msgstr "Música"
-
-#: ../data/gnome-music.appdata.xml.in.h:3
-msgid "Music is the new GNOME music playing application."
-msgstr "Música é a nova aplicação de reprodução de música do GNOME"
-
-#: ../gnomemusic/notification.py:55 ../data/PlayerToolbar.ui.h:6
-msgid "Previous"
-msgstr "Anterior"
-
-#: ../gnomemusic/notification.py:58 ../gnomemusic/player.py:559
-msgid "Pause"
-msgstr "Pausa"
-
-#: ../gnomemusic/notification.py:61 ../gnomemusic/player.py:562
-#: ../data/PlayerToolbar.ui.h:7
-msgid "Play"
-msgstr "Reproduzir"
-
-#: ../gnomemusic/notification.py:63 ../data/PlayerToolbar.ui.h:8
-msgid "Next"
-msgstr "Seguinte"
-
-#: ../gnomemusic/player.py:1132
-msgid "Unable to play the file"
-msgstr "Impossível reproduzir o ficheiro"
-
-#. TRANSLATORS: this is a button to launch a codec installer.
-#. %s will be replaced with the software installer's name, e.g.
-#. 'Software' in case of gnome-software.
-#: ../gnomemusic/player.py:1137
-#, python-format
-msgid "_Find in %s"
-msgstr "_Localizar em %s"
-
-#. TRANSLATORS: separator for a list of codecs
-#: ../gnomemusic/player.py:1147
-msgid " and "
-msgstr " e "
-
-#. TRANSLATORS: separator for a list of codecs
-#: ../gnomemusic/player.py:1150
-msgid ", "
-msgstr ", "
-
-#: ../gnomemusic/player.py:1151
-#, python-format
-msgid "%s is required to play the file, but is not installed."
-msgid_plural "%s are required to play the file, but are not installed."
-msgstr[0] "%s é requerido para reproduzir o ficheiro, mas não está instalado."
-msgstr[1] ""
-"%s são requeridos para reproduzir o ficheiro, mas não estão instalados."
-
-#. TRANSLATORS: this is a playlist name
-#: ../gnomemusic/playlists.py:59
-msgid "Most Played"
-msgstr "Mais ouvidos"
-
-#. TRANSLATORS: this is a playlist name
-#: ../gnomemusic/playlists.py:64
-msgid "Never Played"
-msgstr "Nunca ouvidos"
-
-#. TRANSLATORS: this is a playlist name
-#: ../gnomemusic/playlists.py:69
-msgid "Recently Played"
-msgstr "Ouvidos recentemente"
-
-#. TRANSLATORS: this is a playlist name
-#: ../gnomemusic/playlists.py:74
-msgid "Recently Added"
-msgstr "Adicionados recentemente"
-
-#. TRANSLATORS: this is a playlist name
-#: ../gnomemusic/playlists.py:79
-msgid "Favorite Songs"
-msgstr "Canções favoritas"
-
-#. TRANSLATORS: The following translatable string should be a
-#. vertical bar-separated list of all-lowercase articles that
-#. should be ignored when alphabetizing artists/albums. This
-#. list should include the basic english translatable strings
-#. regardless of language because they are so universal.
-#. If some articles occur more frequently than others, the most
-#. common one should appear first, the least common one last.
-#: ../gnomemusic/query.py:90
-msgid "the|a|an"
-msgstr "a|um|uma"
-
-#: ../gnomemusic/searchbar.py:63 ../gnomemusic/searchbar.py:111
-msgid "All"
-msgstr "Todas"
-
-#: ../gnomemusic/searchbar.py:64
-msgid "Artist"
-msgstr "Artista"
-
-#: ../gnomemusic/searchbar.py:65
-msgid "Album"
-msgstr "Ãlbum"
-
-#: ../gnomemusic/searchbar.py:66 ../data/AlbumWidget.ui.h:3
-msgid "Composer"
-msgstr "Compositor"
-
-#: ../gnomemusic/searchbar.py:67
-msgid "Track Title"
-msgstr "Título da faixa"
-
-#: ../gnomemusic/searchbar.py:112
-msgid "Local"
-msgstr "Local"
-
-#: ../gnomemusic/searchbar.py:224
-msgid "Sources"
-msgstr "Fontes"
-
-#: ../gnomemusic/searchbar.py:231
-msgid "Match"
-msgstr "Comparar"
+#: data/org.gnome.Music.gschema.xml:43
+msgid "Inhibit system suspend"
+msgstr "Inibir suspensão do sistema"
-#: ../gnomemusic/utils.py:63
-msgid "Unknown Artist"
-msgstr "Artista desconhecido"
-
-#: ../gnomemusic/utils.py:75
-msgid "Untitled"
-msgstr "Sem nome"
-
-#: ../gnomemusic/views/albumsview.py:44 ../gnomemusic/views/searchview.py:454
-msgid "Albums"
-msgstr "Ãlbuns"
+#: data/org.gnome.Music.gschema.xml:44
+msgid "Enables or disables inhibiting system suspend while playing music"
+msgstr "Ativa ou desativa a suspensão do sistema quando a tocar música"
-#: ../gnomemusic/views/artistsview.py:52 ../gnomemusic/views/searchview.py:455
-msgid "Artists"
-msgstr "Artistas"
+#: data/org.gnome.Music.gschema.xml:48
+msgid "Report music history to Last.fm"
+msgstr "Relatar histórico de músicas ao Last.fm"
-#: ../gnomemusic/views/baseview.py:196
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Item {} selecionado"
-msgstr[1] "Itens {} selecionados"
-
-#: ../gnomemusic/views/baseview.py:201 ../gnomemusic/views/baseview.py:303
-#: ../gnomemusic/widgets/albumwidget.py:198
-#: ../gnomemusic/widgets/artistalbumswidget.py:232 ../data/headerbar.ui.h:3
-msgid "Click on items to select them"
-msgstr "Clique nos itens para os selecionar"
-
-#: ../gnomemusic/views/emptyview.py:51
-msgid "Music folder"
-msgstr "Pasta de música"
-
-#: ../gnomemusic/views/emptysearchview.py:50
-msgid "Try a different search"
-msgstr "Tente uma procura diferente"
-
-#: ../gnomemusic/views/initialstateview.py:50
-msgid "Hey DJ"
-msgstr "Hey DJ"
-
-#: ../gnomemusic/views/playlistview.py:58 ../gnomemusic/views/searchview.py:457
-msgid "Playlists"
-msgstr "Listas de reprodução"
-
-#: ../gnomemusic/views/playlistview.py:421
-#, python-format
-msgid "%d Song"
-msgid_plural "%d Songs"
-msgstr[0] "%d música"
-msgstr[1] "%d músicas"
-
-#: ../gnomemusic/views/searchview.py:456 ../gnomemusic/views/songsview.py:52
-msgid "Songs"
-msgstr "Músicas"
-
-#: ../gnomemusic/widgets/albumwidget.py:194
-#: ../gnomemusic/widgets/artistalbumswidget.py:228
-#, python-format
-msgid "Selected %d item"
-msgid_plural "Selected %d items"
-msgstr[0] "%d item selecionado"
-msgstr[1] "%d itens selecionados"
-
-#: ../gnomemusic/widgets/albumwidget.py:291
-#: ../gnomemusic/widgets/albumwidget.py:345
-#, python-format
-msgid "%d min"
-msgstr "%d min"
-
-#: ../gnomemusic/widgets/disclistboxwidget.py:189
-msgid "Disc {}"
-msgstr "Disco {}"
-
-#: ../gnomemusic/window.py:128
-msgid "Loading"
-msgstr "A carregar"
-
-#. Undo button
-#: ../gnomemusic/window.py:183
-msgid "_Undo"
-msgstr "_Desfazer"
-
-#: ../gnomemusic/window.py:342
-msgid "Empty"
-msgstr "Vazia"
-
-#: ../gnomemusic/window.py:419
-msgid "Playlist {} removed"
-msgstr "Lista {} removida"
+#: data/org.gnome.Music.gschema.xml:49
+msgid ""
+"Enables or disables sending scrobbles and the “currently playing†info to "
+"Last.fm."
+msgstr ""
+"Ativa ou desativa envio de scrobbles e informações de “a tocar†ao Last.fm"
-#: ../data/AboutDialog.ui.in.h:2
-msgid "Copyright © 2016 GNOME Music Developers"
-msgstr "Copyright © 2016 Programadores do Música"
+#: data/ui/AboutDialog.ui.in:9
+#| msgid "Copyright © 2016 GNOME Music Developers"
+msgid "Copyright © 2018 GNOME Music Developers"
+msgstr "Copyright © 2018 Programadores do Música"
-#: ../data/AboutDialog.ui.in.h:3
+#: data/ui/AboutDialog.ui.in:10
msgid "A music player and management application for GNOME."
msgstr "Uma aplicação para reprodução e gestão de música para o GNOME."
-#: ../data/AboutDialog.ui.in.h:4
+#: data/ui/AboutDialog.ui.in:12
msgid "Visit GNOME Music website"
msgstr "Visite a página web do Música"
-#: ../data/AboutDialog.ui.in.h:5
+#: data/ui/AboutDialog.ui.in:13
+#| msgid ""
+#| "GNOME Music is free software; you can redistribute it and/or modify it "
+#| "under the terms of the GNU General Public License as published by the "
+#| "Free Software Foundation; either version 2 of the License, or (at your "
+#| "option) any later version.\n"
+#| "\n"
+#| "GNOME Music is distributed in the hope that it will be useful, but "
+#| "WITHOUT ANY WARRANTY; without even the implied warranty of "
+#| "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General "
+#| "Public License for more details.\n"
+#| "\n"
+#| "You should have received a copy of the GNU General Public License along "
+#| "with GNOME Music; if not, write to the Free Software Foundation, Inc., 51 "
+#| "Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n"
+#| "\n"
+#| "The GNOME Music authors hereby grant permission for non-GPL compatible "
+#| "GStreamer plugins to be used and distributed together with GStreamer and "
+#| "GNOME Music. This permission is above and beyond the permissions granted "
+#| "by the GPL license by which GNOME Music is covered. If you modify this "
+#| "code, you may extend this exception to your version of the code, but you "
+#| "are not obligated to do so. If you do not wish to do so, delete this "
+#| "exception statement from your version.\n"
+#| "\n"
+#| "“Magic of the vinyl†by Sami Pyylampi image is licensed by CC-BY-SA 2.0 "
+#| "https://www.flickr.com/photos/_spy_/12270839403\n"
msgid ""
"GNOME Music is free software; you can redistribute it and/or modify it under "
"the terms of the GNU General Public License as published by the Free "
@@ -362,7 +204,7 @@ msgid ""
"statement from your version.\n"
"\n"
"“Magic of the vinyl†by Sami Pyylampi image is licensed by CC-BY-SA 2.0 "
-"https://www.flickr.com/photos/_spy_/12270839403\n"
+"https://www.flickr.com/photos/_spy_/12270839403"
msgstr ""
"O GNOME Música é uma aplicação livre; pode redistribuí-la e/ou alterá-la sob "
"os termos da Licença Pública Genérica GNU tal como publicada pela Free "
@@ -371,10 +213,10 @@ msgstr ""
"\n"
"O GNOME Música é distribuído na esperança de ser útil, mas SEM QUALQUER "
"GARANTIA; nem mesmo a garantia implícita de COMERCIALIZAÇÃO ou ADEQUAÇÃO A "
-"QUALQUER PROPÓSITO. Veja a GNU General Public License para mais detalhes.\n"
+"QUALQUER PROPÓSITO. Veja a Licença Pública Genérica GNU para mais detalhes.\n"
"\n"
-"Deverá ter recebido uma cópia da GNU General Public License juntamente com o "
-"GNOME Música. se não, escreva (em Inglês) para a Free Software Foundation, "
+"Deverá ter recebido uma cópia da Licença Pública Genérica GNU juntamente com "
+"o GNOME Música; se não, escreva (em Inglês) para a Free Software Foundation, "
"Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n"
"\n"
"Os autores do GNOME Música concedem aqui permissão para que extensões "
@@ -386,207 +228,533 @@ msgstr ""
"da sua versão.\n"
"\n"
"A imagem “Magic of the vinyl†de Sami Pyylampi é licensiada por CC-BY-SA 2.0 "
-"https://www.flickr.com/photos/_spy_/12270839403\n"
+"https://www.flickr.com/photos/_spy_/12270839403"
-#: ../data/AlbumWidget.ui.h:1
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Lançado"
-#: ../data/AlbumWidget.ui.h:2
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Duração da execução"
-#: ../data/app-menu.ui.h:1
+#: data/ui/AlbumWidget.ui:167
+msgid "Composer"
+msgstr "Compositor"
+
+#: data/ui/AppMenu.ui:20 data/ui/LastfmDialog.ui:8
+msgid "Last.fm Account"
+msgstr "Conta Last.fm"
+
+#: data/ui/AppMenu.ui:38
+msgid "Report Music Listening"
+msgstr "Relatar músicas tocadas"
+
+#: data/ui/AppMenu.ui:69
msgid "_Keyboard Shortcuts"
msgstr "_Atalhos de teclado"
-#: ../data/app-menu.ui.h:2
+#: data/ui/AppMenu.ui:83
msgid "_Help"
msgstr "A_Juda"
-#: ../data/app-menu.ui.h:3
-msgid "_About"
-msgstr "_Sobre"
+#: data/ui/AppMenu.ui:97
+#| msgid "_About"
+msgid "_About Music"
+msgstr "_Sobre Música"
-#: ../data/app-menu.ui.h:4
-msgid "_Quit"
-msgstr "_Sair"
-
-#: ../data/headerbar.ui.h:1
-msgid "Select All"
-msgstr "Selecionar todas"
-
-#: ../data/headerbar.ui.h:2
-msgid "Select None"
-msgstr "Não selecionar nenhuma"
-
-#: ../data/headerbar.ui.h:4
-msgid "Search"
-msgstr "Procurar"
+#: data/ui/HeaderBar.ui:16
+msgid "Menu"
+msgstr "Menu"
-#: ../data/headerbar.ui.h:5
+#: data/ui/HeaderBar.ui:39 data/ui/SearchHeaderBar.ui:16
msgid "Select"
msgstr "Selecionar"
-#: ../data/headerbar.ui.h:6 ../data/PlaylistDialog.ui.h:5
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Cancelar"
-#: ../data/headerbar.ui.h:7
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
+msgid "Search"
+msgstr "Procurar"
+
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Recuar"
-#: ../data/help-overlay.ui.h:1
+#: data/ui/help-overlay.ui:13
msgctxt "shortcut window"
msgid "General"
msgstr "Geral"
-#: ../data/help-overlay.ui.h:2
+#: data/ui/help-overlay.ui:17
msgctxt "shortcut window"
msgid "Close window"
msgstr "Fechar janela"
-#: ../data/help-overlay.ui.h:3
+#: data/ui/help-overlay.ui:24
msgctxt "shortcut window"
msgid "Search"
msgstr "Procurar"
-#: ../data/help-overlay.ui.h:4
+#: data/ui/help-overlay.ui:31
msgctxt "shortcut window"
msgid "Help"
msgstr "Ajuda"
-#: ../data/help-overlay.ui.h:5
+#: data/ui/help-overlay.ui:38
msgctxt "shortcut window"
msgid "Shortcuts"
msgstr "Atalhos"
-#: ../data/help-overlay.ui.h:6
+#: data/ui/help-overlay.ui:47
msgctxt "shortcut window"
msgid "Playback"
msgstr "Reproduzir"
-#: ../data/help-overlay.ui.h:7
+#: data/ui/help-overlay.ui:51
msgctxt "shortcut window"
msgid "Play/Pause"
msgstr "Reproduzir/Pausa"
-#: ../data/help-overlay.ui.h:8
+#: data/ui/help-overlay.ui:58
msgctxt "shortcut window"
msgid "Next song"
msgstr "Música seguinte"
-#: ../data/help-overlay.ui.h:9
+#: data/ui/help-overlay.ui:65
msgctxt "shortcut window"
msgid "Previous song"
msgstr "Música anterior"
-#: ../data/help-overlay.ui.h:10
+#: data/ui/help-overlay.ui:72
msgctxt "shortcut window"
msgid "Toggle repeat"
msgstr "Alternar repetir"
-#: ../data/help-overlay.ui.h:11
+#: data/ui/help-overlay.ui:79
msgctxt "shortcut window"
msgid "Toggle shuffle"
msgstr "Alternar misturar"
-#: ../data/help-overlay.ui.h:12
+#: data/ui/help-overlay.ui:88
msgctxt "shortcut window"
msgid "Navigation"
msgstr "Navegação"
-#: ../data/help-overlay.ui.h:13
+#: data/ui/help-overlay.ui:92
msgctxt "shortcut window"
msgid "Go to Albums"
msgstr "Ir para Ãlbuns"
-#: ../data/help-overlay.ui.h:14
+#: data/ui/help-overlay.ui:99
msgctxt "shortcut window"
msgid "Go to Artists"
msgstr "Ir para Artistas"
-#: ../data/help-overlay.ui.h:15
+#: data/ui/help-overlay.ui:106
msgctxt "shortcut window"
msgid "Go to Songs"
msgstr "Ir para Canções"
-#: ../data/help-overlay.ui.h:16
+#: data/ui/help-overlay.ui:113
msgctxt "shortcut window"
msgid "Go to Playlists"
msgstr "Adicionar à lista de reprodução"
-#: ../data/help-overlay.ui.h:17
+#: data/ui/help-overlay.ui:120
msgctxt "shortcut window"
msgid "Go back"
msgstr "Voltar atrás"
-#: ../data/NoMusic.ui.h:1
-msgid "No music found"
-msgstr "Nenhuma música encontrada"
+#: data/ui/LastfmDialog.ui:21
+msgid ""
+"Last.fm is a music discovery service that gives you personalised "
+"recommendations based on the music you listen to."
+msgstr ""
+"O Last.fm é um serviço de localização de músicas que dá-lhe recomendações "
+"personalizadas baseadas nas músicas que ouve."
+
+#: data/ui/LastfmDialog.ui:32 gnomemusic/widgets/lastfmdialog.py:58
+msgid "Music Reporting Not Setup"
+msgstr "Relatar músicas não configurado"
-#. Translators: %s will be replaced with a link with text
-#: ../data/NoMusic.ui.h:4
-#, no-c-format
-msgid "The contents of your %s will appear here."
-msgstr "O conteúdo de %s aparece aqui."
+#: data/ui/LastfmDialog.ui:46 gnomemusic/widgets/lastfmdialog.py:61
+msgid "Login to your Last.fm account to report your music listening."
+msgstr "Inicie sessão na sua conta Last.fm para relatar as músicas que ouve."
-#: ../data/PlayerToolbar.ui.h:1
+#: data/ui/LastfmDialog.ui:57 gnomemusic/widgets/lastfmdialog.py:59
+msgid "Login"
+msgstr "Início de sessão"
+
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "A carregar"
+
+#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Misturar"
-#: ../data/PlayerToolbar.ui.h:2
+#: data/ui/PlayerToolbar.ui:11
msgid "Repeat All"
msgstr "Repetir todas"
-#: ../data/PlayerToolbar.ui.h:3
+#: data/ui/PlayerToolbar.ui:16
msgid "Repeat Song"
msgstr "Repetir música"
#. Causes tracks to play in random order
-#: ../data/PlayerToolbar.ui.h:5
+#: data/ui/PlayerToolbar.ui:21
msgid "Shuffle/Repeat Off"
msgstr "Desligar Misturar/Repetir"
-#: ../data/PlaylistControls.ui.h:1
+#: data/ui/PlayerToolbar.ui:69
+msgid "Previous"
+msgstr "Anterior"
+
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
+msgid "Play"
+msgstr "Reproduzir"
+
+#: data/ui/PlayerToolbar.ui:101
+msgid "Next"
+msgstr "Seguinte"
+
+#: data/ui/PlaylistContextMenu.ui:5
+#| msgid "Play"
+msgctxt "context menu item"
+msgid "Play"
+msgstr "Reproduzir"
+
+#: data/ui/PlaylistContextMenu.ui:9
+#| msgid "_Add to Playlist"
+msgid "Add to Playlist…"
+msgstr "Adicionar à lista de reprodução..."
+
+#: data/ui/PlaylistContextMenu.ui:13
+#| msgid "_Remove from Playlist"
+msgid "Remove From Playlist"
+msgstr "Remover da lista de reprodução"
+
+#: data/ui/PlaylistControls.ui:6
msgid "_Play"
msgstr "Re_Produzir"
-#: ../data/PlaylistControls.ui.h:2
+#: data/ui/PlaylistControls.ui:10
msgid "_Delete"
msgstr "_Eliminar"
-#: ../data/PlaylistControls.ui.h:3
+#: data/ui/PlaylistControls.ui:14
+msgid "_Rename…"
+msgstr "_Renomear…"
+
+#: data/ui/PlaylistControls.ui:41
msgid "Playlist Name"
msgstr "Nome da lista de reprodução"
-#: ../data/PlaylistDialog.ui.h:1
+#: data/ui/PlaylistControls.ui:74
+msgid "_Done"
+msgstr "_Terminado"
+
+#: data/ui/PlaylistDialog.ui:66
msgid "Enter a name for your first playlist"
msgstr "Introduza um nome para a sua primeira playlist"
-#: ../data/PlaylistDialog.ui.h:2
+#: data/ui/PlaylistDialog.ui:92
msgid "C_reate"
msgstr "C_riar"
-#: ../data/PlaylistDialog.ui.h:3
-msgid "New Playlist"
-msgstr "Nova lista de reprodução"
+#: data/ui/PlaylistDialog.ui:155
+#| msgid "New Playlist"
+msgid "New Playlist…"
+msgstr "Nova lista de reprodução..."
-#: ../data/PlaylistDialog.ui.h:4
+#: data/ui/PlaylistDialog.ui:169
msgid "Add"
msgstr "Adicionar"
-#: ../data/PlaylistDialog.ui.h:6
+#: data/ui/PlaylistDialog.ui:241
+#| msgid "_Add to Playlist"
+msgid "Add to Playlist"
+msgstr "Adicionar à lista de reprodução"
+
+#: data/ui/PlaylistDialog.ui:257
msgid "_Add"
msgstr "_Adicionar"
-#: ../data/SelectionToolbar.ui.h:1
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Desfazer"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
+msgid "Artists"
+msgstr "Artistas"
+
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
+msgid "View All"
+msgstr "Ver tudo"
+
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
+msgid "Albums"
+msgstr "Ãlbuns"
+
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
+msgid "Songs"
+msgstr "Músicas"
+
+#: data/ui/SelectionBarMenuButton.ui:7
+msgid "Select All"
+msgstr "Selecionar todas"
+
+#: data/ui/SelectionBarMenuButton.ui:11
+msgid "Select None"
+msgstr "Não selecionar nenhuma"
+
+#: data/ui/SelectionBarMenuButton.ui:31 gnomemusic/widgets/headerbar.py:71
+msgid "Click on items to select them"
+msgstr "Clique nos itens para os selecionar"
+
+#: data/ui/SelectionToolbar.ui:9
msgid "_Add to Playlist"
msgstr "_Adicionar à lista de reprodução"
-#: ../data/SelectionToolbar.ui.h:2
-msgid "_Remove from Playlist"
-msgstr "_Remover da lista de reprodução"
+#. TRANSLATORS: this is a playlist name
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
+msgid "Most Played"
+msgstr "Mais ouvidos"
+
+#. TRANSLATORS: this is a playlist name
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
+msgid "Never Played"
+msgstr "Nunca ouvidos"
+
+#. TRANSLATORS: this is a playlist name
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
+msgid "Recently Played"
+msgstr "Ouvidos recentemente"
+
+#. TRANSLATORS: this is a playlist name
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
+msgid "Recently Added"
+msgstr "Adicionados recentemente"
+
+#. TRANSLATORS: this is a playlist name
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
+msgid "Favorite Songs"
+msgstr "Canções favoritas"
+
+#: gnomemusic/gstplayer.py:378
+msgid "Unable to play the file"
+msgstr "Impossível reproduzir o ficheiro"
+
+#: gnomemusic/gstplayer.py:384
+#| msgid "_Find in %s"
+msgid "_Find in {}"
+msgstr "_Localizar em {}"
+
+#. TRANSLATORS: separator for two codecs
+#: gnomemusic/gstplayer.py:394
+msgid " and "
+msgstr " e "
+
+#. TRANSLATORS: separator for a list of codecs
+#: gnomemusic/gstplayer.py:397
+msgid ", "
+msgstr ", "
+
+#: gnomemusic/gstplayer.py:399
+#| msgid "%s is required to play the file, but is not installed."
+#| msgid_plural "%s are required to play the file, but are not installed."
+msgid "{} is required to play the file, but is not installed."
+msgid_plural "{} are required to play the file, but are not installed."
+msgstr[0] "{} é requerido para reproduzir o ficheiro, mas não está instalado."
+msgstr[1] ""
+"{} são requeridos para reproduzir o ficheiro, mas não estão instalados."
+
+#: gnomemusic/inhibitsuspend.py:63
+msgid "Playing music"
+msgstr "A tocar música"
+
+#: gnomemusic/utils.py:81
+#| msgid "Unknown Album"
+msgid "Unknown album"
+msgstr "Ãlbum desconhecido"
+
+#: gnomemusic/utils.py:102
+msgid "Unknown Artist"
+msgstr "Artista desconhecido"
+
+#: gnomemusic/views/emptyview.py:67
+msgid "Your XDG Music directory is not set."
+msgstr "Seu diretório XDG Music não está definido."
+
+#: gnomemusic/views/emptyview.py:74
+msgid "Music folder"
+msgstr "Pasta de música"
+
+#. TRANSLATORS: This is a label to display a link to open user's music
+#. folder. {} will be replaced with the translated text 'Music folder'
+#: gnomemusic/views/emptyview.py:78
+#| msgid "The contents of your %s will appear here."
+msgid "The contents of your {} will appear here."
+msgstr "O conteúdo de {} aparece aqui."
+
+#: gnomemusic/views/emptyview.py:112
+msgid "Hey DJ"
+msgstr "Hey DJ"
+
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
+msgid "No music found"
+msgstr "Nenhuma música encontrada"
+
+#: gnomemusic/views/emptyview.py:128
+msgid "Try a different search"
+msgstr "Tente uma procura diferente"
+
+#: gnomemusic/views/emptyview.py:133
+msgid "GNOME Music could not connect to Tracker"
+msgstr "O Música não pôde ligar ao rastreador"
+
+#: gnomemusic/views/emptyview.py:136
+msgid "Your music files cannot be indexed without Tracker running"
+msgstr ""
+"Seus ficheiros de músicas não podem ser indexados sem que o rastreador "
+"esteja em execução"
+
+#: gnomemusic/views/emptyview.py:143
+msgid "Your system Tracker version seems outdated"
+msgstr "A versão do rastreador em seu sistema parece desatualizada"
+
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "O Música precisa dum rastreador com versão 3.0.0 ou maior"
+
+#: gnomemusic/views/playlistsview.py:41
+msgid "Playlists"
+msgstr "Listas de reprodução"
+
+#: gnomemusic/views/searchview.py:386
+#| msgid "Artists"
+msgid "Artists Results"
+msgstr "Artistas encontrados"
+
+#: gnomemusic/views/searchview.py:401
+#| msgid "Albums"
+msgid "Albums Results"
+msgstr "Ãlbuns encontrados"
+
+#: gnomemusic/widgets/albumwidget.py:154
+msgid "{} minute"
+msgid_plural "{} minutes"
+msgstr[0] "{} minuto"
+msgstr[1] "{} minutos"
+
+#: gnomemusic/widgets/disclistboxwidget.py:60
+msgid "Disc {}"
+msgstr "Disco {}"
+
+#: gnomemusic/widgets/headerbar.py:68
+#| msgid "Selected {} item"
+#| msgid_plural "Selected {} items"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Música {} selecionada"
+msgstr[1] "Musicas {} selecionadas"
+
+#: gnomemusic/widgets/lastfmdialog.py:65
+msgid "Your music listening is reported to Last.fm."
+msgstr "As músicas que ouve são relatadas ao Last.fm"
+
+#: gnomemusic/widgets/lastfmdialog.py:67
+msgid "Your music listening is not reported to Last.fm."
+msgstr "As músicas que ouve não são relatadas ao Last.fm"
+
+#. TRANSLATORS: displays the username of the Last.fm account
+#: gnomemusic/widgets/lastfmdialog.py:71
+msgid "Logged in as {}"
+msgstr "Sessão iniciada como {}"
+
+#: gnomemusic/widgets/lastfmdialog.py:72
+msgid "Configure"
+msgstr "Configurar"
+
+#: gnomemusic/widgets/notificationspopup.py:216
+msgid "Playlist {} removed"
+msgstr "Lista {} removida"
+
+#: gnomemusic/widgets/notificationspopup.py:220
+msgid "{} removed from {}"
+msgstr "{} removida de {}"
+
+#: gnomemusic/widgets/playertoolbar.py:143
+msgid "Pause"
+msgstr "Pausa"
+
+#: gnomemusic/widgets/playlistcontrols.py:127
+#| msgid "%d Song"
+#| msgid_plural "%d Songs"
+msgid "{} Song"
+msgid_plural "{} Songs"
+msgstr[0] "{} música"
+msgstr[1] "{} músicas"
+
+#~ msgid "Search mode"
+#~ msgstr "Modo de procura"
+
+#~ msgid "If true, the search bar is shown."
+#~ msgstr "Se verdadeiro, a barra de procura é mostrada."
+
+#~ msgid "Notifications mode"
+#~ msgstr "Modo de notificações"
+
+#~ msgid "Enables or disables playback notifications"
+#~ msgstr "Ativa ou desativa notificações de reprodução"
+
+#~ msgid "Music is the new GNOME music playing application."
+#~ msgstr "Música é a nova aplicação de reprodução de música do GNOME"
+
+#~ msgid "the|a|an"
+#~ msgstr "a|um|uma"
+
+#~ msgid "All"
+#~ msgstr "Todas"
+
+#~ msgid "Artist"
+#~ msgstr "Artista"
+
+#~ msgid "Album"
+#~ msgstr "Ãlbum"
+
+#~ msgid "Track Title"
+#~ msgstr "Título da faixa"
+
+#~ msgid "Local"
+#~ msgstr "Local"
+
+#~ msgid "Sources"
+#~ msgstr "Fontes"
+
+#~ msgid "Match"
+#~ msgstr "Comparar"
+
+#~ msgid "Untitled"
+#~ msgstr "Sem nome"
+
+#~ msgid "Selected %d item"
+#~ msgid_plural "Selected %d items"
+#~ msgstr[0] "%d item selecionado"
+#~ msgstr[1] "%d itens selecionados"
+
+#~ msgid "%d min"
+#~ msgstr "%d min"
+
+#~ msgid "Empty"
+#~ msgstr "Vazia"
+
+#~ msgid "_Quit"
+#~ msgstr "_Sair"
#~ msgid "Max chars to display in track name on Artist view"
#~ msgstr "Nº máximo de caracteres a mostrar no nome da faixa na vista Artista"
@@ -598,9 +766,6 @@ msgstr "_Remover da lista de reprodução"
#~ "Esta definição modifica a quantidade de caracteres do título da faixa na "
#~ "vista Artista. Defina como -1 para desativar."
-#~ msgid "Unknown Album"
-#~ msgstr "Ãlbum desconhecido"
-
#~ msgid "the a an"
#~ msgstr "o a um uma"
diff --git a/po/pt_BR.po b/po/pt_BR.po
index ad2b4a67..25719907 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -9,21 +9,22 @@
# Enrico Nicoletto <liverig@gmail.com>, 2013-2016.
# Fábio Nogueira <fnogueira@gnome.org> 2018.
# Rafael Fontenelle <rafaelff@gnome.org>, 2012-2020.
+# Henrique Machado Campos <henriquecamposrj@gmail.com>, 2020.
#
msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 14:09+0000\n"
-"PO-Revision-Date: 2020-02-16 15:13-0300\n"
-"Last-Translator: Rafael Fontenelle <rafaelff@gnome.org>\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-08-31 21:34-0300\n"
+"Last-Translator: Henrique Machado Campos <henriquecamposrj@gmail.com>\n"
"Language-Team: Brazilian Portuguese <gnome-pt_br-list@gnome.org>\n"
"Language: pt_BR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1)\n"
-"X-Generator: Gtranslator 3.32.0\n"
+"X-Generator: Gtranslator 3.36.0\n"
"X-Project-Style: gnome\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
@@ -51,12 +52,12 @@ msgstr ""
"Encontre faixas em sua coleção local, obtenha músicas de servidores DLNA ou "
"tente algo novo com os serviços Jamendo e Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Os Desenvolvedores do GNOME Música"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Música"
@@ -213,15 +214,15 @@ msgstr ""
"A imagem “Magic of the vinyl†de Sami Pyylampi é licenciada sob CC-BY-SA 2.0 "
"https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Lançado"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Comprimento de reprodução"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Compositor"
@@ -253,16 +254,16 @@ msgstr "Menu"
msgid "Select"
msgstr "Selecionar"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Cancelar"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Pesquisar"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Voltar"
@@ -371,6 +372,10 @@ msgstr "Faça login sua conta do Last.fm para relatar suas músicas."
msgid "Login"
msgstr "Entrar"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Carregando"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Embaralhar"
@@ -388,15 +393,15 @@ msgstr "Repetir música"
msgid "Shuffle/Repeat Off"
msgstr "Desligar embaralhar/repetir"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Anterior"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Reproduzir"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Próxima"
@@ -429,7 +434,7 @@ msgstr "_Renomear…"
msgid "Playlist Name"
msgstr "Nome da lista de reprodução"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Finalizado"
@@ -457,19 +462,23 @@ msgstr "Adicionar para lista de reprodução"
msgid "_Add"
msgstr "_Adicionar"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Desfazer"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Artistas"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Ver tudo"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Ãlbuns"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Músicas"
@@ -490,49 +499,49 @@ msgid "_Add to Playlist"
msgstr "_Adicionar para lista de reprodução"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Mais tocadas"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Nunca tocadas"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Recentemente tocadas"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Recentemente adicionadas"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Músicas favoritas"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Não foi possível reproduzir o arquivo"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Procurar em {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " e "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} é necessário para reproduzir o arquivo, mas não está instalado."
@@ -543,11 +552,11 @@ msgstr[1] ""
msgid "Playing music"
msgstr "Reproduzindo música"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Ãlbum desconhecido"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Artista desconhecido"
@@ -565,69 +574,68 @@ msgstr "pasta Músicas"
msgid "The contents of your {} will appear here."
msgstr "O conteúdo da sua {} irá aparecer aqui."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Ei, DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Nenhuma música encontrada"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Tente uma pesquisa diferente"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "O GNOME Música não conseguiu se conectar ao Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Seus arquivos de música não podem ser indexados sem o Tracker ativo"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "A versão do Tracker do seu sistema parece estar desatualizada"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Música precisa do Tracker na versão 2.3.0 ou mais novo"
+#: gnomemusic/views/emptyview.py:146
+#| msgid "Music needs Tracker version 2.3.0 or higher"
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Música precisa do Tracker na versão 3.0.0 ou mais novo"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Listas de reprodução"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Resultados de artistas"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Resultados de álbuns"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minuto"
msgstr[1] "{} minutos"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disco {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "{} item selecionado"
-msgstr[1] "{} itens selecionados"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} música selecionada"
+msgstr[1] "{} músicas selecionadas"
#: gnomemusic/widgets/lastfmdialog.py:65
-#| msgid "Report music history to Last.fm"
msgid "Your music listening is reported to Last.fm."
msgstr "A música sendo ouvida é relatada à Last.fm."
#: gnomemusic/widgets/lastfmdialog.py:67
-#| msgid "Report music history to Last.fm"
msgid "Your music listening is not reported to Last.fm."
msgstr "A música sendo ouvida não é relatada à Last.fm."
@@ -640,27 +648,19 @@ msgstr "Autenticado como {}"
msgid "Configure"
msgstr "Configurar"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Carregando"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Desfazer"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Lista de reprodução {} removida"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} removida de {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pausar"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} música"
diff --git a/po/ro.po b/po/ro.po
index 01f8f378..77bafef9 100644
--- a/po/ro.po
+++ b/po/ro.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-03-28 21:42+0000\n"
-"PO-Revision-Date: 2020-04-22 13:07+0300\n"
+"POT-Creation-Date: 2020-03-21 19:07+0000\n"
+"PO-Revision-Date: 2020-05-03 15:21+0300\n"
"Last-Translator: Florentina Mușat <florentina.musat.28 [at] gmail [dot] "
"com>\n"
"Language-Team: Gnome Romanian Translation Team <gnomero-list@lists."
@@ -143,8 +143,8 @@ msgid ""
"Enables or disables sending scrobbles and the “currently playing†info to "
"Last.fm."
msgstr ""
-"Activează sau dezactivează trimiterea de scrobbles și informațiile de la „se "
-"redă acum†la Last.fm."
+"Activează sau dezactivează trimiterea de scrobbles și de informații de la "
+"„se redă acum†către Last.fm."
#: data/ui/AboutDialog.ui.in:9
msgid "Copyright © 2018 GNOME Music Developers"
@@ -353,12 +353,12 @@ msgid ""
"Last.fm is a music discovery service that gives you personalised "
"recommendations based on the music you listen to."
msgstr ""
-"Last.fm este un serviciu de descoperire a muzicii care vă oferă recomandări "
+"Last.fm este un serviciu de descoperire de muzică ce vă oferă recomandări "
"personalizate pe baza muzicii pe care o ascultați."
#: data/ui/LastfmDialog.ui:32 gnomemusic/widgets/lastfmdialog.py:58
msgid "Music Reporting Not Setup"
-msgstr "Raportarea muzicii nu este stabilită"
+msgstr "Raportarea de muzică nu este stabilită"
#: data/ui/LastfmDialog.ui:46 gnomemusic/widgets/lastfmdialog.py:61
msgid "Login to your Last.fm account to report your music listening."
@@ -467,7 +467,7 @@ msgstr "Vizualizează toate"
msgid "Albums"
msgstr "Albume"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:51
+#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
msgid "Songs"
msgstr "Melodii"
@@ -488,27 +488,27 @@ msgid "_Add to Playlist"
msgstr "_Adaugă în lista de redare"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:835
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:822
msgid "Most Played"
msgstr "Cele mai redate"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:872
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:859
msgid "Never Played"
msgstr "Niciodată redate"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:908
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:895
msgid "Recently Played"
msgstr "Redate recent"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:954
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:941
msgid "Recently Added"
msgstr "Adăugate recent"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:986
msgid "Favorite Songs"
msgstr "Melodii favorite"
@@ -551,7 +551,7 @@ msgstr "Artist necunoscut"
#: gnomemusic/views/emptyview.py:67
msgid "Your XDG Music directory is not set."
-msgstr "Directorul de Muzică XDG nu este stabilit."
+msgstr "Directorul de muzică XDG nu este stabilit."
#: gnomemusic/views/emptyview.py:74
msgid "Music folder"
diff --git a/po/sk.po b/po/sk.po
index 5f764366..c5b02412 100644
--- a/po/sk.po
+++ b/po/sk.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-03-28 21:42+0000\n"
-"PO-Revision-Date: 2020-04-05 22:18+0200\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-09-04 11:25+0200\n"
"Last-Translator: Dušan Kazik <prescott66@gmail.com>\n"
"Language-Team: Slovak <gnome-sk-list@gnome.org>\n"
"Language: sk\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=3; plural=(n==1) ? 1 : (n>=2 && n<=4) ? 2 : 0;\n"
-"X-Generator: Poedit 2.3\n"
+"X-Generator: Poedit 2.4.1\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -47,8 +47,8 @@ msgstr ""
msgid "The GNOME Music developers"
msgstr "Vývojári aplikácie Hudba prostredia GNOME"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Hudba"
@@ -204,15 +204,15 @@ msgstr ""
"Obrázok „Magic of the vinyl“ od Samiho Pyylampiho je vytvorený pod licenciou "
"CC-BY-SA 2.0 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Vydaný"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Dĺžka"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Skladateľ"
@@ -244,17 +244,17 @@ msgstr "Ponuka"
msgid "Select"
msgstr "Vybrať"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Zrušiť"
# DK:tooltip
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Vyhľadávanie"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Späť"
@@ -365,6 +365,10 @@ msgstr "Pre nahlásenie vami poÄúvanej hudby, sa prihláste do služby Last.fm
msgid "Login"
msgstr "Prihlásiť"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "NaÄítava sa"
+
# GtkRadioMenuItem
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
@@ -384,16 +388,16 @@ msgstr "Opakovať skladbu"
msgid "Shuffle/Repeat Off"
msgstr "Vypnúť zamiešanie/opakovanie"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Predchádzajúca"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Prehrať"
# DK: skladba
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Nasledujúca"
@@ -428,7 +432,7 @@ msgstr "_Premenovať…"
msgid "Playlist Name"
msgstr "Názov zoznamu skladieb"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_DokonÄiÅ¥"
@@ -457,19 +461,23 @@ msgstr "Pridanie do zoznamu skladieb"
msgid "_Add"
msgstr "_Pridať"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "Vrátiť _späť"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Interpreti"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Zobraziť všetko"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Albumy"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:51
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Skladby"
@@ -491,49 +499,49 @@ msgid "_Add to Playlist"
msgstr "_Pridať do zoznamu skladieb"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:835
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Najviac prehrávané"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:872
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Nikdy neprehraté"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:908
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Nedávno prehrávané"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:954
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Nedávno pridané"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Obľúbené skladby"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Nie je možné prehrať tento súbor"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Nájsť pomocou programu {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " a "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] ""
@@ -547,11 +555,11 @@ msgstr[2] ""
msgid "Playing music"
msgstr "Prehráva sa hudba"
-#: gnomemusic/utils.py:65
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Neznámy album"
-#: gnomemusic/utils.py:86
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Neznámy interpret"
@@ -569,63 +577,63 @@ msgstr "prieÄinku s hudbou"
msgid "The contents of your {} will appear here."
msgstr "Tu sa zobrazí obsah vášho {}."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hey DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Nenašla sa žiadna hudba"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Skúste vyhľadaÅ¥ nieÄo iné"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "Aplikácii Hudba prostredia GNOME sa nepodarilo pripojiÅ¥ k sledovaÄu"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "VaÅ¡e hudobné súbory nemôžu byÅ¥ indexované bez spusteného sledovaÄa"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Zdá sa, že verzia vášho systémového sledovaÄa je zastaralá"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Aplikácia Hudba vyžaduje verziu sledovaÄa 2.3.0 alebo vyÅ¡Å¡iu"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Aplikácia Hudba vyžaduje verziu sledovaÄa 3.0.0 alebo vyÅ¡Å¡iu"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Zoznamy skladieb"
-#: gnomemusic/views/searchview.py:383
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Výsledky s interpretami"
-#: gnomemusic/views/searchview.py:398
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Výsledky s albumami"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minút"
msgstr[1] "{} minúta"
msgstr[2] "{} minúty"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disk Ä. {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Vybraných {} položiek"
-msgstr[1] "Vybraná {} položka"
-msgstr[2] "Vybrané {} položky"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Vybraných {} skladieb"
+msgstr[1] "Vybraná {} skladba"
+msgstr[2] "Vybrané {} skladby"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -644,27 +652,19 @@ msgstr "Prihlásený ako {}"
msgid "Configure"
msgstr "Nastaviť"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "NaÄítava sa"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "Vrátiť _späť"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Zoznam skladieb {} bol odstránený"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "Skladba {} odstránená zo zoznamu skladieb {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Pozastaviť"
-#: gnomemusic/widgets/playlistcontrols.py:126
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} skladieb"
diff --git a/po/sl.po b/po/sl.po
index fe376e8b..fd625662 100644
--- a/po/sl.po
+++ b/po/sl.po
@@ -8,8 +8,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-03-30 14:11+0000\n"
-"PO-Revision-Date: 2020-04-05 22:12+0200\n"
+"POT-Creation-Date: 2020-08-28 15:20+0000\n"
+"PO-Revision-Date: 2020-08-28 21:39+0200\n"
"Last-Translator: Matej UrbanÄiÄ <mateju@svn.gnome.org>\n"
"Language-Team: Slovenian GNOME Translation Team <gnome-si@googlegroups.com>\n"
"Language: sl_SI\n"
@@ -19,7 +19,7 @@ msgstr ""
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n"
"%100==4 ? 3 : 0);\n"
"X-Poedit-SourceCharset: utf-8\n"
-"X-Generator: Poedit 2.2.4\n"
+"X-Generator: Poedit 2.3\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -46,12 +46,12 @@ msgstr ""
"Iskanje posnetkov v zbirki, pridobivanje glasbe prek strežnikov DLNA in "
"iskanje s storitvami Jamendo in Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:117
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Razvijalci programa GNOME Glasba"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Glasba"
@@ -207,15 +207,15 @@ msgstr ""
"Slika Samija Pyylampija »Magic of the vinyl« je objavljena z dovoljenjem CC-"
"BY-SA 2.0 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
-msgstr "izdano"
+msgstr "Izdano"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
-msgstr "Dolžina predvajanja"
+msgstr "Skupna dolžina"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Skladatelj"
@@ -247,16 +247,16 @@ msgstr "Meni"
msgid "Select"
msgstr "Izberi"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_PrekliÄi"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Iskanje"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Nazaj"
@@ -365,6 +365,10 @@ msgstr "Prijavite se v raÄun Last.fm za poroÄanje o posluÅ¡anju glasbe"
msgid "Login"
msgstr "Prijava"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Nalaganje"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Premešaj"
@@ -382,15 +386,15 @@ msgstr "Ponovi skladbo"
msgid "Shuffle/Repeat Off"
msgstr "OnemogoÄi premeÅ¡anje/ponavljanje"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Predhodna"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Predvajaj"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Naslednja"
@@ -423,7 +427,7 @@ msgstr "P_reimenuj …"
msgid "Playlist Name"
msgstr "Ime seznama predvajanja"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_KonÄano"
@@ -451,19 +455,23 @@ msgstr "Dodaj na seznam predvajanja"
msgid "_Add"
msgstr "_Dodaj"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Razveljavi"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Izvajalci"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Pokaži vse"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Albumi"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:51
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Skladbe"
@@ -484,49 +492,49 @@ msgid "_Add to Playlist"
msgstr "Dodaj na _seznam predvajanja"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:835
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Najpogosteje predvajano"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:872
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Nikoli predvajano"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:908
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Nedavno predvajano"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:954
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Nedavno dodano"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Priljubljeni posnetki"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Datoteke ni mogoÄe predvajati."
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Najdi v {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr "in "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} so zahtevani za predvajanje datoteke, vendar niso nameÅ¡Äeni."
@@ -538,11 +546,11 @@ msgstr[3] "{} so zahtevani za predvajanje datoteke, vendar niso nameÅ¡Äeni."
msgid "Playing music"
msgstr "Predvajanje glasbe"
-#: gnomemusic/utils.py:65
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Neznan album"
-#: gnomemusic/utils.py:86
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Neznan izvajalec"
@@ -560,49 +568,49 @@ msgstr "Glasbena mapa"
msgid "The contents of your {} will appear here."
msgstr "Vsebina {} bo prikazana na tem mestu."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hej, DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Ni shranjene glasbe"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Poskusite drugaÄno iskanje"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "Ni mogoÄe vzpostaviti povezave s programom Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr ""
"Glasbenih datotek brez zagnanega programa Tracker ni mogoÄe indeksirati."
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Sistemska razliÄica paketa Tracker je videti zastarela"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
msgstr ""
-"Program Music zahteva namestitev razliÄice paketa Tracker 2.3.0 ali viÅ¡je"
+"Program Music zahteva namestitev razliÄice paketa Tracker 3.0.0 ali viÅ¡je"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Seznami predvajanja"
-#: gnomemusic/views/searchview.py:383
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Izvajalci"
-#: gnomemusic/views/searchview.py:398
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Albumi"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minut"
@@ -610,17 +618,17 @@ msgstr[1] "{} minuta"
msgstr[2] "{} minuti"
msgstr[3] "{} minute"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disk {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Izbranih je {} predmetov"
-msgstr[1] "Izbran je {} predmet"
-msgstr[2] "Izbrana sta {} predmeta"
-msgstr[3] "Izbrani so {} predmeti"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Izbranih je {} skladb"
+msgstr[1] "Izbrana je {} skladba"
+msgstr[2] "Izbrani sta {} skladbi"
+msgstr[3] "Izbrane so {} skladbe"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -639,27 +647,19 @@ msgstr "Trenutno je dejavna prijava {}"
msgid "Configure"
msgstr "Nastavi"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Nalaganje"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Razveljavi"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Seznam predvajanja {} je odstranjen"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} odstranjen iz {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Premor"
-#: gnomemusic/widgets/playlistcontrols.py:126
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} skladb"
diff --git a/po/sr.po b/po/sr.po
index 0643336d..30f6bc4f 100644
--- a/po/sr.po
+++ b/po/sr.po
@@ -6,8 +6,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 14:09+0000\n"
-"PO-Revision-Date: 2020-02-17 21:08+0100\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-09-03 09:59+0200\n"
"Last-Translator: Марко Ðœ. КоÑтић <marko.m.kostic@gmail.com>\n"
"Language-Team: ÑрпÑки <gnome-sr@googlegroups.org>\n"
"Language: sr\n"
@@ -17,7 +17,7 @@ msgstr ""
"Plural-Forms: nplurals=4; plural=n==1? 3 : n%10==1 && n%100!=11 ? 0 : n"
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
"X-Project-Style: gnome\n"
-"X-Generator: Poedit 2.3\n"
+"X-Generator: Poedit 2.4.1\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -44,12 +44,12 @@ msgstr ""
"Ðађите нумере у вашој локалној збирци, добавите музику Ñа ДЛÐÐ Ñервера или "
"пробајте нешто ново Ñа Ðамендо и Магнатјун уÑлугама."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Програмери Гномове музике"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Музика"
@@ -60,7 +60,7 @@ msgstr "Програм за музику"
#. Translators: Search terms to find this application. Do NOT translate or localize the semicolons! The list MUST also end with a semicolon!
#: data/org.gnome.Music.desktop.in.in:13
msgid "Music;Player;"
-msgstr "музика;пуÑти;пуштач;плејер;muzika;pusti;puÅ¡taÄ;plejer;Music;Player;"
+msgstr "Music;Player;музика;пуÑти;пуштач;плејер;muzika;pusti;puÅ¡taÄ;plejer;"
#: data/org.gnome.Music.gschema.xml:12
msgid "Window size"
@@ -205,15 +205,15 @@ msgstr ""
"Слика \"Magic of the vinyl\" од Самија Пилампија је лиценцирана под CC-BY-SA "
"2.0 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Издат"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Дужина трајања"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Композитор"
@@ -245,16 +245,16 @@ msgstr "Изборник"
msgid "Select"
msgstr "Изабери"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Откажи"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Потражи"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Ðазад"
@@ -365,6 +365,10 @@ msgstr ""
msgid "Login"
msgstr "Пријава"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Учитавам"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "ÐаÑумично"
@@ -382,15 +386,15 @@ msgstr "Понови пеÑму"
msgid "Shuffle/Repeat Off"
msgstr "ИÑкључи мешање/понављање"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Претходно"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "ПуÑти"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Ðаредно"
@@ -423,7 +427,7 @@ msgstr "_Преименуј…"
msgid "Playlist Name"
msgstr "Ðазив ÑпиÑка нумера"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Готово"
@@ -451,19 +455,23 @@ msgstr "Додај на ÑпиÑак нумера"
msgid "_Add"
msgstr "_Додај"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Опозови"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Извођачи"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Прикажи Ñве"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Ðлбуми"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "ПеÑме"
@@ -484,49 +492,49 @@ msgid "_Add to Playlist"
msgstr "_Додај на ÑпиÑак нумера"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "Ðајвише пуштане"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Ðикад пуштане"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Ðедавно пуштане"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Ðедавно додате"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Омиљене пеÑме"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Ðе могу да пуÑтим датотеку"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Пронађи у {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " и "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} је потребан за пуштање датотеке али није инÑталиран."
@@ -538,11 +546,11 @@ msgstr[3] "{} је потребан за пуштање датотеке али
msgid "Playing music"
msgstr "Пуштам музику"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Ðепознат албум"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Ðепознат извођач"
@@ -560,48 +568,48 @@ msgstr "ФаÑцикла Ñа музиком"
msgid "The contents of your {} will appear here."
msgstr "Садржај фаÑцикле „{}“ ће Ñе појавити овде."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
-msgstr "Хеј! Диџеј!"
+msgstr "Хеј! Ди-џеј!"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "ÐиÑам пронашао музику"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Пробајте Ñа другачијом претрагом"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "Гномова Музика није могла да Ñе повеже на Трагача"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr ""
"Ваше музичке датотеке не могу бити попиÑане уколико Трагач није покренут"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Издање вашег ÑиÑтемÑког трагача делује заÑтарело"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Музици је потребан трагач издања 2.3.0 или новије"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Музици је потребан трагач (Tracker) издања 3.0.0 или новије"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "СпиÑак нумера"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Резултати извођача"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Резултати албума"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} минут"
@@ -609,17 +617,17 @@ msgstr[1] "{} минута"
msgstr[2] "{} минута"
msgstr[3] "{} минут"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "ДиÑк {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Изабрана је {} Ñтавка"
-msgstr[1] "Изабране Ñу {} Ñтавке"
-msgstr[2] "Изабрано је {} Ñтавки"
-msgstr[3] "Изабрана је {} Ñтавка"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Изабрана је {} пеÑма"
+msgstr[1] "Изабране Ñу {} пеÑме"
+msgstr[2] "Изабрано је {} пеÑми"
+msgstr[3] "Изабрана је једна пеÑма"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -638,27 +646,19 @@ msgstr "Пријављен као {}"
msgid "Configure"
msgstr "ПодеÑи"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Учитавам"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Опозови"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "СпиÑак нумера {} је уклоњен"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "Ставка {} уклоњена из {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "ЗаÑтани"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} пеÑма"
diff --git a/po/sv.po b/po/sv.po
index bb51b3b6..38c1a9fa 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 14:09+0000\n"
-"PO-Revision-Date: 2020-02-20 13:46+0100\n"
+"POT-Creation-Date: 2020-09-01 19:48+0000\n"
+"PO-Revision-Date: 2020-09-04 11:37+0200\n"
"Last-Translator: Anders Jonsson <anders.jonsson@norsjovallen.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
@@ -18,7 +18,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.3\n"
+"X-Generator: Poedit 2.4.1\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -45,12 +45,12 @@ msgstr ""
"Hitta spår i din lokala samling, erhåll musik från DLNA-servrar eller pröva "
"någonting nytt med Jamendo och Magnatune-tjänsterna."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "GNOME Musik-utvecklarna"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Musik"
@@ -207,15 +207,15 @@ msgstr ""
"Bilden â€Magic of the vinyl†av Sami Pyylampi är licensierad med CC-BY-SA 2.0 "
"https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Utgiven"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Speltid"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Kompositör"
@@ -247,16 +247,16 @@ msgstr "Meny"
msgid "Select"
msgstr "Välj"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Avbryt"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Sök"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Bakåt"
@@ -365,6 +365,10 @@ msgstr "Logga in på ditt Last.fm-konto för att rapportera ditt musiklyssnande.
msgid "Login"
msgstr "Logga in"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Läser in"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Spela i slumpmässig ordning"
@@ -382,15 +386,15 @@ msgstr "Upprepa låt"
msgid "Shuffle/Repeat Off"
msgstr "Spela i ordning utan upprepning"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Föregående"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Spela"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Nästa"
@@ -423,7 +427,7 @@ msgstr "_Byt namn…"
msgid "Playlist Name"
msgstr "Namn på spellista"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Färdig"
@@ -451,19 +455,23 @@ msgstr "Lägg till i spellista"
msgid "_Add"
msgstr "_Lägg till"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Ã…ngra"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Artister"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Visa alla"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Album"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "LÃ¥tar"
@@ -484,49 +492,49 @@ msgid "_Add to Playlist"
msgstr "_Lägg till i spellista"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:827
msgid "Most Played"
msgstr "Mest spelade"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:880
msgid "Never Played"
msgstr "Aldrig spelade"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:932
msgid "Recently Played"
msgstr "Nyligen spelade"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:994
msgid "Recently Added"
msgstr "Nyligen tillagda"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1056
msgid "Favorite Songs"
msgstr "Favoritlåtar"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Kan inte spela upp filen"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Hitta i {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " och "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "{} krävs för att spela upp filen men är inte installerad."
@@ -536,11 +544,11 @@ msgstr[1] "{} krävs för att spela upp filen men är inte installerade."
msgid "Playing music"
msgstr "Spelar upp musik"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Okänt album"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Okänd artist"
@@ -558,61 +566,61 @@ msgstr "Musikmapp"
msgid "The contents of your {} will appear here."
msgstr "Innehållet i din {} kommer att visas här."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hej DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Ingen musik hittades"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Försök med en annan sökning"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME Musik kunde inte ansluta till Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Dina musikfiler kan inte indexeras utan att Tracker körs"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Ditt systems version av Tracker verkar gammal"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Musik kräver version 2.3.0 eller högre av Tracker"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Musik kräver version 3.0.0 eller högre av Tracker"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Spellistor"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Artistresultat"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Albumresultat"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} minut"
msgstr[1] "{} minuter"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Skiva {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Markerade {} objekt"
-msgstr[1] "Markerade {} objekt"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Markerade {} låt"
+msgstr[1] "Markerade {} låtar"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -631,27 +639,19 @@ msgstr "Inloggad som {}"
msgid "Configure"
msgstr "Konfigurera"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Läser in"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Ã…ngra"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "Spellista {} borttagen"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} borttagen från {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Gör paus"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} låt"
diff --git a/po/tr.po b/po/tr.po
index 62ce883d..d27ed730 100644
--- a/po/tr.po
+++ b/po/tr.po
@@ -9,15 +9,15 @@
# Furkan Tokaç <developmentft@gmail.com>, 2017.
# Doğa Deniz Arıcı <bluegreenbrain@gmail.com>, 2018.
# Sabri Ãœnal <libreajans@gmail.com>, 2019-2020.
-# Emin Tufan Çetin <etcetin@gmail.com>, 2013-2019.
+# Emin Tufan Çetin <etcetin@gmail.com>, 2013-2020.
#
msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 14:09+0000\n"
-"PO-Revision-Date: 2020-02-18 13:36+0300\n"
-"Last-Translator: Sabri Ãœnal <libreajans@gmail.com>\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-08-30 12:11+0300\n"
+"Last-Translator: Emin Tufan Çetin <etcetin@gmail.com>\n"
"Language-Team: Turkish <gnome-turk@gnome.org>\n"
"Language: tr\n"
"MIME-Version: 1.0\n"
@@ -31,17 +31,18 @@ msgstr ""
msgid "GNOME Music"
msgstr "GNOME Müzik"
-#: data/org.gnome.Music.appdata.xml.in.in:7 data/org.gnome.Music.desktop.in.in:5
+#: data/org.gnome.Music.appdata.xml.in.in:7
+#: data/org.gnome.Music.desktop.in.in:5
msgid "Play and organize your music collection"
msgstr "Müzik derleminizi çalın ve yönetin"
#: data/org.gnome.Music.appdata.xml.in.in:9
msgid ""
-"An easy way to play your music. Automatically discover music on your computer, "
-"the local network and internet services."
+"An easy way to play your music. Automatically discover music on your "
+"computer, the local network and internet services."
msgstr ""
-"Müziğinizi çalmanın kolay yolu. Bilgisayarınızdaki, yerel ağınızdaki ve internet "
-"hizmetlerinizdeki müziği kendiliğinden keşfeder."
+"Müziğinizi çalmanın kolay yolu. Bilgisayarınızdaki, yerel ağınızdaki ve "
+"internet hizmetlerinizdeki müziği kendiliğinden keşfeder."
#: data/org.gnome.Music.appdata.xml.in.in:12
msgid ""
@@ -51,12 +52,12 @@ msgstr ""
"Yerel derleminizdeki parçaları bulun, DLNA sunucularından müzik alın veya "
"Jamendo ve Magnatune hizmetleriyle yeni ÅŸeyler deneyin."
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "GNOME Müzik Geliştiricileri"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Müzik"
@@ -100,14 +101,14 @@ msgstr "Çalma yineleme kipi"
#. Translators: Don't translate allowed values, just the description in the brackets
#: data/org.gnome.Music.gschema.xml:29
msgid ""
-"Value identifies whether to repeat or randomize playback through the collection. "
-"Allowed values are: “none†(repeat and shuffle are off), “song†(repeat current "
-"song), “all†(repeat playlist, no shuffle), “shuffle†(shuffle playlist, "
-"presumes repeat all)."
+"Value identifies whether to repeat or randomize playback through the "
+"collection. Allowed values are: “none†(repeat and shuffle are off), "
+"“song†(repeat current song), “all†(repeat playlist, no shuffle), "
+"“shuffle†(shuffle playlist, presumes repeat all)."
msgstr ""
"Bu değer, derlemdeki parçaların yinelemeli mi yoksa karışık mı çalınacağını "
"belirtir. İzin verilen değerler şunlardır: “none†(yineleme ve karıştırma "
-"kapalı), “song†(geçerli parçayı yinele), “all†(çalma listesini yinele, "
+"kapalı), “song†(geçerli şarkıyı yinele), “all†(çalma listesini yinele, "
"karıştırma), “shuffle†(çalma listesini karıştır, tümü yinelenebilir)."
#: data/org.gnome.Music.gschema.xml:33
@@ -133,8 +134,8 @@ msgstr "Sistemin askıya alınmasını önle"
#: data/org.gnome.Music.gschema.xml:44
msgid "Enables or disables inhibiting system suspend while playing music"
msgstr ""
-"Müzik çalarken sistemin askıya alınmasını önlemeyi etkinleştir veya devre dışı "
-"bırak"
+"Müzik çalarken sistemin askıya alınmasını önlemeyi etkinleştir veya devre "
+"dışı bırak"
#: data/org.gnome.Music.gschema.xml:48
msgid "Report music history to Last.fm"
@@ -142,11 +143,11 @@ msgstr "Müzik geçmişini Last.fm’e bildir"
#: data/org.gnome.Music.gschema.xml:49
msgid ""
-"Enables or disables sending scrobbles and the “currently playing†info to Last."
-"fm."
+"Enables or disables sending scrobbles and the “currently playing†info to "
+"Last.fm."
msgstr ""
-"Last.fm’e skroplamaları ve “şu anda çalan†bilgilerini göndermeyi etkinleştirir "
-"veya devre dışı bırakır."
+"Last.fm’e skroplamaları ve “şu anda çalan†bilgilerini göndermeyi "
+"etkinleştirir veya devre dışı bırakır."
#: data/ui/AboutDialog.ui.in:9
msgid "Copyright © 2018 GNOME Music Developers"
@@ -162,60 +163,64 @@ msgstr "GNOME Müzik web sitesini ziyaret et"
#: data/ui/AboutDialog.ui.in:13
msgid ""
-"GNOME Music is free software; you can redistribute it and/or modify it under the "
-"terms of the GNU General Public License as published by the Free Software "
-"Foundation; either version 2 of the License, or (at your option) any later "
-"version.\n"
+"GNOME Music is free software; you can redistribute it and/or modify it under "
+"the terms of the GNU General Public License as published by the Free "
+"Software Foundation; either version 2 of the License, or (at your option) "
+"any later version.\n"
"\n"
-"GNOME Music is distributed in the hope that it will be useful, but WITHOUT ANY "
-"WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A "
-"PARTICULAR PURPOSE. See the GNU General Public License for more details.\n"
+"GNOME Music is distributed in the hope that it will be useful, but WITHOUT "
+"ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or "
+"FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for "
+"more details.\n"
"\n"
"You should have received a copy of the GNU General Public License along with "
-"GNOME Music; if not, write to the Free Software Foundation, Inc., 51 Franklin "
-"Street, Fifth Floor, Boston, MA 02110-1301 USA.\n"
+"GNOME Music; if not, write to the Free Software Foundation, Inc., 51 "
+"Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n"
"\n"
-"The GNOME Music authors hereby grant permission for non-GPL compatible GStreamer "
-"plugins to be used and distributed together with GStreamer and GNOME Music. "
-"This permission is above and beyond the permissions granted by the GPL license "
-"by which GNOME Music is covered. If you modify this code, you may extend this "
-"exception to your version of the code, but you are not obligated to do so. If "
-"you do not wish to do so, delete this exception statement from your version.\n"
+"The GNOME Music authors hereby grant permission for non-GPL compatible "
+"GStreamer plugins to be used and distributed together with GStreamer and "
+"GNOME Music. This permission is above and beyond the permissions granted by "
+"the GPL license by which GNOME Music is covered. If you modify this code, "
+"you may extend this exception to your version of the code, but you are not "
+"obligated to do so. If you do not wish to do so, delete this exception "
+"statement from your version.\n"
"\n"
-"“Magic of the vinyl†by Sami Pyylampi image is licensed by CC-BY-SA 2.0 https://"
-"www.flickr.com/photos/_spy_/12270839403"
+"“Magic of the vinyl†by Sami Pyylampi image is licensed by CC-BY-SA 2.0 "
+"https://www.flickr.com/photos/_spy_/12270839403"
msgstr ""
"GNOME Müzik, özgür yazılımdır; Özgür Yazılım Vakfı tarafından yayımlanan GNU "
-"Genel Kamu Lisansının 2. sürümü ya da (isteğe bağlı olarak) sonraki sürümleri "
-"koşulları altında yeniden dağıtabilir ve/veya değiştirebilirsiniz.\n"
+"Genel Kamu Lisansının 2. sürümü ya da (isteğe bağlı olarak) sonraki "
+"sürümleri koşulları altında yeniden dağıtabilir ve/veya "
+"değiştirebilirsiniz.\n"
"\n"
-"GNOME Müzik kullanışlı olması maksadıyla dağıtılmaktadır, ancak HİÇBİR GARANTİSİ "
-"YOKTUR; aynı zamanda BİR AMACA UYGUNLUĞU ya da SATILABİLİRLİĞİ garanti etmez. "
-"Daha çok ayrıntı için GNU Genel Kamu Lisansına bakınız.\n"
+"GNOME Müzik kullanışlı olması maksadıyla dağıtılmaktadır, ancak HİÇBİR "
+"GARANTİSİ YOKTUR; aynı zamanda BİR AMACA UYGUNLUĞU ya da SATILABİLİRLİĞİ "
+"garanti etmez. Daha çok ayrıntı için GNU Genel Kamu Lisansına bakınız.\n"
"\n"
-"GNU Genel Kamu Lisansı’nın bir kopyasını GNOME Müzik ile almış olmalısınız; eğer "
-"almadıysanız Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, "
-"Boston, MA 02110-1301 USA adresine yazın.\n"
+"GNU Genel Kamu Lisansı’nın bir kopyasını GNOME Müzik ile almış olmalısınız; "
+"eğer almadıysanız Free Software Foundation, Inc., 51 Franklin Street, Fifth "
+"Floor, Boston, MA 02110-1301 USA adresine yazın.\n"
"\n"
-"GNOME Müzik yazarları GPL uyumlu olmayan GStreamer eklentilerinin GStreamer ve "
-"GNOME Müzik ile birlikte kullanılmasına ve dağıtılmasına izin vermektedirler. "
-"Bu izin GNOME Müzik’in lisansı olan GPL lisansının üzerinde ve onu kapsayıcı "
-"olarak verilmektedir. EÄŸer bu kodu deÄŸiÅŸtirirseniz zorunlu olmamakla birlikte "
-"bu geniÅŸletmeyi kendi kodunuza uygulayabilirsiniz. Bunu yapmak istemezseniz "
-"kendi sürümünüzden bu istisna ifadesini kaldırabilirsiniz.\n"
+"GNOME Müzik yazarları GPL uyumlu olmayan GStreamer eklentilerinin GStreamer "
+"ve GNOME Müzik ile birlikte kullanılmasına ve dağıtılmasına izin "
+"vermektedirler. Bu izin GNOME Müzik’in lisansı olan GPL lisansının üzerinde "
+"ve onu kapsayıcı olarak verilmektedir. Eğer bu kodu değiştirirseniz zorunlu "
+"olmamakla birlikte bu geniÅŸletmeyi kendi kodunuza uygulayabilirsiniz. Bunu "
+"yapmak istemezseniz kendi sürümünüzden bu istisna ifadesini "
+"kaldırabilirsiniz.\n"
"\n"
"Sami Pyylampi eseri “Magic of the vinyl†CC-BY-SA 2.0 ile lisanslanmıştır "
"https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
-msgstr "Yayımlandı"
+msgstr "Yayım"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "Uzunluk"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Besteci"
@@ -247,16 +252,16 @@ msgstr "Menü"
msgid "Select"
msgstr "Seç"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_Vazgeç"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Ara"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Geri"
@@ -288,7 +293,7 @@ msgstr "Kısayollar"
#: data/ui/help-overlay.ui:47
msgctxt "shortcut window"
msgid "Playback"
-msgstr "Kayıttan yürütme"
+msgstr "Kayıttan yürüt"
#: data/ui/help-overlay.ui:51
msgctxt "shortcut window"
@@ -347,10 +352,10 @@ msgstr "Geri git"
#: data/ui/LastfmDialog.ui:21
msgid ""
-"Last.fm is a music discovery service that gives you personalised recommendations "
-"based on the music you listen to."
+"Last.fm is a music discovery service that gives you personalised "
+"recommendations based on the music you listen to."
msgstr ""
-"Last.fm, dinlediğiniz müziğe göre kişiselleştirilmiş öneriler sunan bir müzik "
+"Last.fm, dinlediğiniz müziğe göre kişiselleştirilmiş öneriler sunan müzik "
"keÅŸif hizmetidir."
#: data/ui/LastfmDialog.ui:32 gnomemusic/widgets/lastfmdialog.py:58
@@ -365,6 +370,10 @@ msgstr "Müzik dinlemenizi bildirmek için Last.fm hesabınıza giriş yapın."
msgid "Login"
msgstr "GiriÅŸ"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "Yükleniyor"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "Karıştır"
@@ -382,15 +391,15 @@ msgstr "Şarkıyı Yinele"
msgid "Shuffle/Repeat Off"
msgstr "Karıştırma/Yineleme Kapalı"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "Önceki"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Çal"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "Sonraki"
@@ -423,7 +432,7 @@ msgstr "_Yeniden Adlandır…"
msgid "Playlist Name"
msgstr "Çalma Listesi Adı"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Bitti"
@@ -451,19 +460,23 @@ msgstr "Çalma Listesine Ekle"
msgid "_Add"
msgstr "_Ekle"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Geri Al"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Sanatçılar"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "Tümünü Görüntüle"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Albümler"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:48
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "Şarkılar"
@@ -484,49 +497,49 @@ msgid "_Add to Playlist"
msgstr "Çalma Listesine _Ekle"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "En Çok Çalınanlar"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Hiç Çalınmayanlar"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Son Çalınanlar"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Yeni Eklenenler"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "En Sevdiğiniz Şarkılar"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Dosya çalınamıyor"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "{} içinde _bul"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " ve "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "Dosyayı çalmak için {} gerekiyor ancak kurulu değil."
@@ -535,11 +548,11 @@ msgstr[0] "Dosyayı çalmak için {} gerekiyor ancak kurulu değil."
msgid "Playing music"
msgstr "Çalan müzik"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Bilinmeyen albüm"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Bilinmeyen Sanatçı"
@@ -557,59 +570,59 @@ msgstr "Müzik klasörü"
msgid "The contents of your {} will appear here."
msgstr "{} içeriğiniz burada görünecek."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Hey DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Hiç müzik bulunamadı"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
-msgstr "BaÅŸka bir arama deneyin"
+msgstr "BaÅŸka arama deneyin"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME Müzik, Trackerʼa bağlanamadı"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Müzik dosyalarınız Tracker çalışmadan dizinlenemez"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Sisteminizin Tracker sürümü eski görünüyor"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Müzik, Tracker sürüm 2.3.0 veya üstünü gerektirmektedir"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Müzik, Tracker sürüm 3.0.0 veya üstünü gerektirmektedir"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "Çalma listeleri"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Sanatçı Sonuçları"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Albüm Sonuçları"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} dakika"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "Disk {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "{} öge seçildi"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "{} şarkı seçildi"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -628,27 +641,19 @@ msgstr "{} olarak giriş yapıldı"
msgid "Configure"
msgstr "Yapılandır"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "Yükleniyor"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Geri Al"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "{} çalma listesi kaldırıldı"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{}, {}ʼden silindi"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Duraklat"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} Şarkı"
@@ -719,15 +724,16 @@ msgstr[0] "{} Şarkı"
#~ msgstr "the|a|an"
#~ msgid "Max chars to display in track name on Artist view"
-#~ msgstr "Sanatçı görünümünde gösterilen parça adı için en fazla karakter sayısı"
+#~ msgstr ""
+#~ "Sanatçı görünümünde gösterilen parça adı için en fazla karakter sayısı"
#~ msgid ""
#~ "This setting modifies the amount of chars for track title on Artist view "
#~ "before its been ellipsized. Set this to -1 to disable"
#~ msgstr ""
-#~ "Bu ayar sanatçı görünümünde gösterilen parça adının üç nokta koyulmadan önce "
-#~ "görünecek karakter sayısını değiştirir. Devre dışı bırakmak için -1 olarak "
-#~ "ayarlayın."
+#~ "Bu ayar sanatçı görünümünde gösterilen parça adının üç nokta koyulmadan "
+#~ "önce görünecek karakter sayısını değiştirir. Devre dışı bırakmak için -1 "
+#~ "olarak ayarlayın."
#~ msgid "Not playing"
#~ msgstr "Yürütülmüyor"
diff --git a/po/uk.po b/po/uk.po
index 2a226216..29ee5ae7 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -9,8 +9,8 @@ msgid ""
msgstr ""
"Project-Id-Version: 1.0\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 11:24+0000\n"
-"PO-Revision-Date: 2020-03-06 17:46+0200\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-08-28 18:18+0300\n"
"Last-Translator: Yuri Chornoivan <yurchor@ukr.net>\n"
"Language-Team: Ukrainian <kde-i18n-uk@kde.org>\n"
"Language: uk\n"
@@ -19,7 +19,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n"
"%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n"
-"X-Generator: Lokalize 20.03.70\n"
+"X-Generator: Lokalize 20.11.70\n"
"X-Project-Style: gnome\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
@@ -47,12 +47,12 @@ msgstr ""
"Знаходь композиції у локальній збірці, отримай музику з DLNA Ñерверів або "
"Ñпробуй щоÑÑŒ нове з ÑервіÑами Jamendo та Magnatune."
-#: data/org.gnome.Music.appdata.xml.in.in:67
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "Розробники Музики GNOME"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "Музика"
@@ -141,8 +141,8 @@ msgid ""
"Enables or disables sending scrobbles and the “currently playing†info to "
"Last.fm."
msgstr ""
-"Вмикає або вимикає надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ñƒ Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ‚Ð° даних щодо поточного"
-" Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¼ÑƒÐ·Ð¸ÐºÐ¸ на Last.fm."
+"Вмикає або вимикає надÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ñƒ Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ‚Ð° даних щодо поточного "
+"Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¼ÑƒÐ·Ð¸ÐºÐ¸ на Last.fm."
#: data/ui/AboutDialog.ui.in:9
msgid "Copyright © 2018 GNOME Music Developers"
@@ -207,15 +207,15 @@ msgstr ""
"Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ â€œMagic of the vinyl†автора Sami Pyylampi викориÑтано на умовах "
"ліцензії CC-BY-SA 2.0 https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "Випущено"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "ТриваліÑÑ‚ÑŒ виконаннÑ"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "Композитор"
@@ -247,16 +247,16 @@ msgstr "Меню"
msgid "Select"
msgstr "Вибрати"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "_СкаÑувати"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "Пошук"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "Ðазад"
@@ -350,8 +350,8 @@ msgid ""
"Last.fm is a music discovery service that gives you personalised "
"recommendations based on the music you listen to."
msgstr ""
-"Last.fm — Ñлужба Ð¾Ð·Ð½Ð°Ð¹Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· музикою, Ñка надає вам перÑоналізовані"
-" рекомендації на оÑнові даних щодо музики, Ñку ви Ñлухаєте."
+"Last.fm — Ñлужба Ð¾Ð·Ð½Ð°Ð¹Ð¾Ð¼Ð»ÐµÐ½Ð½Ñ Ð· музикою, Ñка надає вам перÑоналізовані "
+"рекомендації на оÑнові даних щодо музики, Ñку ви Ñлухаєте."
#: data/ui/LastfmDialog.ui:32 gnomemusic/widgets/lastfmdialog.py:58
msgid "Music Reporting Not Setup"
@@ -360,13 +360,17 @@ msgstr "ÐадÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð¶ÑƒÑ€Ð½Ð°Ð»Ñ–Ð² Ð²Ñ–Ð´Ñ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð½Ðµ нал
#: data/ui/LastfmDialog.ui:46 gnomemusic/widgets/lastfmdialog.py:61
msgid "Login to your Last.fm account to report your music listening."
msgstr ""
-"Увійдіть до вашого облікового запиÑу на Last.fm, щоб надіÑлати дані журналу"
-" відтвореннÑ."
+"Увійдіть до вашого облікового запиÑу на Last.fm, щоб надіÑлати дані журналу "
+"відтвореннÑ."
#: data/ui/LastfmDialog.ui:57 gnomemusic/widgets/lastfmdialog.py:59
msgid "Login"
msgstr "Увійти"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "ЗавантаженнÑ"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "У довільному порÑдку"
@@ -384,15 +388,15 @@ msgstr "Повторювати піÑню"
msgid "Shuffle/Repeat Off"
msgstr "Довільний порÑдок/ÐŸÐ¾Ð²Ñ‚Ð¾Ñ€ÐµÐ½Ð½Ñ Ð²Ð¸Ð¼ÐºÐ½ÐµÐ½Ð¾"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "ПопереднÑ"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "Програти"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "ÐаÑтупна"
@@ -425,7 +429,7 @@ msgstr "_Перейменувати…"
msgid "Playlist Name"
msgstr "Ðазва ÑпиÑку композицій"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "_Зроблено"
@@ -453,19 +457,23 @@ msgstr "Додати до ÑпиÑку композицій"
msgid "_Add"
msgstr "_Додати"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:51
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "_Повернути"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "Виконавці"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "ПереглÑнути вÑе"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "Ðльбоми"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:49
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "ПіÑні"
@@ -486,49 +494,49 @@ msgid "_Add to Playlist"
msgstr "_Додати до ÑпиÑку композицій"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "ЧаÑто Ñлухали"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "Ðіколи не Ñлухали"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "Ðедавно Ñлухали"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "Ðедавно додано"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "Улюблені піÑні"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "Ðеможливо відтворити файл"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "_Знайти в {}"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " Ñ– "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
msgstr ", "
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "Потрібний {}, щоб програти файл, але його не вÑтановлено."
@@ -540,11 +548,11 @@ msgstr[3] "Потрібний {}, щоб програти файл, але йоÐ
msgid "Playing music"
msgstr "ПрограєтьÑÑ Ð¼ÑƒÐ·Ð¸ÐºÐ°"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "Ðевідомий альбом"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "Ðевідомий виконавець"
@@ -562,47 +570,48 @@ msgstr "Тека з музикою"
msgid "The contents of your {} will appear here."
msgstr "Тут з'ÑвитьÑÑ Ð²Ð¼Ñ–ÑÑ‚ {}."
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "Ðгов, ді-джею!"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "Музики не знайдено"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "Спробуйте пошукати інакше"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "Музика GNOME не може з'єднатиÑÑŒ з Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "Музика не може бути індекÑована без запущеного Tracker"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "Схоже, верÑÑ–Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð¸ Tracker заÑтаріла"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "Музика вимагає програму Tracker з верÑією 2.3.0 або вище"
+#: gnomemusic/views/emptyview.py:146
+#| msgid "Music needs Tracker version 2.3.0 or higher"
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "Ð”Ð»Ñ Ñ€Ð¾Ð±Ð¾Ñ‚Ð¸ «Музики» потрібна програма Tracker верÑÑ–Ñ— 3.0.0 або вище"
-#: gnomemusic/views/playlistsview.py:53
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "СпиÑки композицій"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "Виконавці"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "Ðльбоми"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} хвилина"
@@ -610,17 +619,17 @@ msgstr[1] "{} хвилини"
msgstr[2] "{} хвилин"
msgstr[3] "{} хвилина"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "ДиÑк {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "Вибрано {} об'єкт"
-msgstr[1] "Вибрано {} об'єкти"
-msgstr[2] "Вибрано {} об'єктів"
-msgstr[3] "Вибрано {} об'єкт"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "Вибрано {} композицію"
+msgstr[1] "Вибрано {} композиції"
+msgstr[2] "Вибрано {} композицій"
+msgstr[3] "Вибрано {} композицію"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -639,27 +648,19 @@ msgstr "Вхід до ÑиÑтеми від імені {}"
msgid "Configure"
msgstr "Ðалаштувати"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "ЗавантаженнÑ"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "_Повернути"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "СпиÑок композицій {} вилучено"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} вилучено з {}"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "Призупинити"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} піÑнÑ"
diff --git a/po/zh_CN.po b/po/zh_CN.po
index cfd3f2df..f17c8835 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -12,8 +12,8 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-03-28 21:42+0000\n"
-"PO-Revision-Date: 2020-04-03 23:10+0800\n"
+"POT-Creation-Date: 2020-08-28 15:14+0000\n"
+"PO-Revision-Date: 2020-08-29 10:01-0400\n"
"Last-Translator: Cheng Lu <chenglu1990@gmail.com>\n"
"Language-Team: Chinese (China) <i18n-zh@googlegroups.com>\n"
"Language: zh_CN\n"
@@ -21,8 +21,8 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
+"X-Generator: Poedit 2.4.1\n"
"X-DamnedLies-Scope: partial\n"
-"X-Generator: Gtranslator 2.91.7\n"
#: data/org.gnome.Music.appdata.xml.in.in:6
msgid "GNOME Music"
@@ -51,8 +51,8 @@ msgstr ""
msgid "The GNOME Music developers"
msgstr "GNOME“音ä¹â€å¼€å‘者"
-#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:57
-#: gnomemusic/window.py:69
+#: data/org.gnome.Music.desktop.in.in:3 gnomemusic/application.py:60
+#: gnomemusic/window.py:70
msgid "Music"
msgstr "音ä¹"
@@ -129,6 +129,16 @@ msgstr "阻止系统挂起"
msgid "Enables or disables inhibiting system suspend while playing music"
msgstr "播放音ä¹æ—¶æ˜¯å¦é˜»æ­¢ç³»ç»Ÿä¼‘眠"
+#: data/org.gnome.Music.gschema.xml:48
+msgid "Report music history to Last.fm"
+msgstr "将您的音ä¹åŽ†å²è®°å½•æŠ¥å‘Šç»™ Last.fm"
+
+#: data/org.gnome.Music.gschema.xml:49
+msgid ""
+"Enables or disables sending scrobbles and the “currently playing†info to "
+"Last.fm."
+msgstr "å¯ç”¨æˆ–ç¦ç”¨å‘ Last.fm å‘é€å½“å‰æ’­æ”¾çš„曲目以åŠâ€œæ­£åœ¨æ’­æ”¾â€ä¿¡æ¯çš„功能。"
+
#: data/ui/AboutDialog.ui.in:9
msgid "Copyright © 2018 GNOME Music Developers"
msgstr "版æƒæ‰€æœ‰ © 2018 GNOME“音ä¹â€å¼€å‘者"
@@ -188,15 +198,15 @@ msgstr ""
"æ¥è‡ª Sami Pyylampi 的“Magic of the vinylâ€å›¾åƒä½¿ç”¨ CC-BY-SA 2.0 许å¯è¯ "
"https://www.flickr.com/photos/_spy_/12270839403"
-#: data/ui/AlbumWidget.ui:105
+#: data/ui/AlbumWidget.ui:107
msgid "Released"
msgstr "å‘布时间"
-#: data/ui/AlbumWidget.ui:121
+#: data/ui/AlbumWidget.ui:123
msgid "Running Length"
msgstr "总时长"
-#: data/ui/AlbumWidget.ui:166
+#: data/ui/AlbumWidget.ui:167
msgid "Composer"
msgstr "作曲"
@@ -228,16 +238,16 @@ msgstr "èœå•"
msgid "Select"
msgstr "选择"
-#: data/ui/HeaderBar.ui:61 data/ui/PlaylistDialog.ui:244
-#: data/ui/SearchHeaderBar.ui:38
+#: data/ui/HeaderBar.ui:60 data/ui/PlaylistDialog.ui:244
+#: data/ui/SearchHeaderBar.ui:37
msgid "_Cancel"
msgstr "å–消(_C)"
-#: data/ui/HeaderBar.ui:80 data/ui/SearchHeaderBar.ui:57
+#: data/ui/HeaderBar.ui:79 data/ui/SearchHeaderBar.ui:56
msgid "Search"
msgstr "æœç´¢"
-#: data/ui/HeaderBar.ui:103
+#: data/ui/HeaderBar.ui:102
msgid "Back"
msgstr "åŽé€€"
@@ -344,6 +354,10 @@ msgstr "登录您的 Last.fm å¸å·ä»¥ä¾¿æŠ¥å‘Šæ‚¨çš„音ä¹æ”¶å¬æƒ…况。"
msgid "Login"
msgstr "登录"
+#: data/ui/LoadingNotification.ui:16
+msgid "Loading"
+msgstr "正在加载"
+
#: data/ui/PlayerToolbar.ui:6
msgid "Shuffle"
msgstr "éšæœºæ’­æ”¾"
@@ -361,15 +375,15 @@ msgstr "é‡å¤æ’­æ”¾"
msgid "Shuffle/Repeat Off"
msgstr "关闭“éšæœº/é‡å¤æ’­æ”¾â€"
-#: data/ui/PlayerToolbar.ui:70
+#: data/ui/PlayerToolbar.ui:69
msgid "Previous"
msgstr "上一首"
-#: data/ui/PlayerToolbar.ui:86 gnomemusic/widgets/playertoolbar.py:147
+#: data/ui/PlayerToolbar.ui:85 gnomemusic/widgets/playertoolbar.py:146
msgid "Play"
msgstr "播放"
-#: data/ui/PlayerToolbar.ui:102
+#: data/ui/PlayerToolbar.ui:101
msgid "Next"
msgstr "下一首"
@@ -402,7 +416,7 @@ msgstr "é‡å‘½å(_R)…"
msgid "Playlist Name"
msgstr "播放列表å"
-#: data/ui/PlaylistControls.ui:75
+#: data/ui/PlaylistControls.ui:74
msgid "_Done"
msgstr "完æˆ(_D)"
@@ -430,19 +444,23 @@ msgstr "添加到播放列表"
msgid "_Add"
msgstr "添加(_A)"
-#: data/ui/SearchView.ui:44 gnomemusic/views/artistsview.py:50
+#: data/ui/PlaylistNotification.ui:22
+msgid "_Undo"
+msgstr "撤销(_U)"
+
+#: data/ui/SearchView.ui:43 gnomemusic/views/artistsview.py:43
msgid "Artists"
msgstr "艺术家"
-#: data/ui/SearchView.ui:54 data/ui/SearchView.ui:107
+#: data/ui/SearchView.ui:53 data/ui/SearchView.ui:106
msgid "View All"
msgstr "查看所有"
-#: data/ui/SearchView.ui:97 gnomemusic/views/albumsview.py:60
+#: data/ui/SearchView.ui:96 gnomemusic/views/albumsview.py:47
msgid "Albums"
msgstr "专辑"
-#: data/ui/SearchView.ui:150 gnomemusic/views/songsview.py:51
+#: data/ui/SearchView.ui:149 gnomemusic/views/songsview.py:44
msgid "Songs"
msgstr "歌曲"
@@ -463,49 +481,49 @@ msgid "_Add to Playlist"
msgstr "添加到播放列表(_A)"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:835
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:832
msgid "Most Played"
msgstr "最多播放"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:872
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:885
msgid "Never Played"
msgstr "从未播放"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:908
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:937
msgid "Recently Played"
msgstr "最近播放"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:954
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Recently Added"
msgstr "最近添加"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:1061
msgid "Favorite Songs"
msgstr "收è—歌曲"
-#: gnomemusic/gstplayer.py:374
+#: gnomemusic/gstplayer.py:378
msgid "Unable to play the file"
msgstr "无法播放该文件"
-#: gnomemusic/gstplayer.py:380
+#: gnomemusic/gstplayer.py:384
msgid "_Find in {}"
msgstr "在 {} 中查找(_F)"
#. TRANSLATORS: separator for two codecs
-#: gnomemusic/gstplayer.py:390
+#: gnomemusic/gstplayer.py:394
msgid " and "
msgstr " 和 "
#. TRANSLATORS: separator for a list of codecs
-#: gnomemusic/gstplayer.py:393
+#: gnomemusic/gstplayer.py:397
msgid ", "
-msgstr "ã€"
+msgstr "〠"
-#: gnomemusic/gstplayer.py:395
+#: gnomemusic/gstplayer.py:399
msgid "{} is required to play the file, but is not installed."
msgid_plural "{} are required to play the file, but are not installed."
msgstr[0] "éœ€è¦ {} æ¥æ’­æ”¾è¯¥æ–‡ä»¶ï¼Œä½†å®ƒå°šæœªå®‰è£…。"
@@ -514,11 +532,11 @@ msgstr[0] "éœ€è¦ {} æ¥æ’­æ”¾è¯¥æ–‡ä»¶ï¼Œä½†å®ƒå°šæœªå®‰è£…。"
msgid "Playing music"
msgstr "正在播放音ä¹"
-#: gnomemusic/utils.py:65
+#: gnomemusic/utils.py:81
msgid "Unknown album"
msgstr "未知专辑"
-#: gnomemusic/utils.py:86
+#: gnomemusic/utils.py:102
msgid "Unknown Artist"
msgstr "未知艺术家"
@@ -536,61 +554,59 @@ msgstr "音ä¹æ–‡ä»¶å¤¹"
msgid "The contents of your {} will appear here."
msgstr "{} 的内容将会显示在此处。"
-#: gnomemusic/views/emptyview.py:113
+#: gnomemusic/views/emptyview.py:112
msgid "Hey DJ"
msgstr "嘿 DJ"
-#: gnomemusic/views/emptyview.py:122 gnomemusic/views/emptyview.py:127
+#: gnomemusic/views/emptyview.py:121 gnomemusic/views/emptyview.py:126
msgid "No music found"
msgstr "未找到音ä¹"
-#: gnomemusic/views/emptyview.py:129
+#: gnomemusic/views/emptyview.py:128
msgid "Try a different search"
msgstr "å°è¯•ä¸åŒçš„æœç´¢"
-#: gnomemusic/views/emptyview.py:134
+#: gnomemusic/views/emptyview.py:133
msgid "GNOME Music could not connect to Tracker"
msgstr "GNOME 音ä¹æ— æ³•è¿žæŽ¥åˆ° Tracker"
-#: gnomemusic/views/emptyview.py:137
+#: gnomemusic/views/emptyview.py:136
msgid "Your music files cannot be indexed without Tracker running"
msgstr "在 Tracker 未è¿è¡Œæ—¶æ— æ³•å¯¹ä½ çš„音ä¹æ–‡ä»¶è¿›è¡Œç´¢å¼•"
-#: gnomemusic/views/emptyview.py:144
+#: gnomemusic/views/emptyview.py:143
msgid "Your system Tracker version seems outdated"
msgstr "您的系统跟踪器版本似乎已过时"
-#: gnomemusic/views/emptyview.py:147
-msgid "Music needs Tracker version 2.3.0 or higher"
-msgstr "音ä¹éœ€è¦è·Ÿè¸ªå™¨ç‰ˆæœ¬ 2.3.0 或更高"
+#: gnomemusic/views/emptyview.py:146
+msgid "Music needs Tracker version 3.0.0 or higher"
+msgstr "音ä¹éœ€è¦è·Ÿè¸ªå™¨ç‰ˆæœ¬ 3.0.0 或更高"
-#: gnomemusic/views/playlistsview.py:52
+#: gnomemusic/views/playlistsview.py:41
msgid "Playlists"
msgstr "播放列表"
-#: gnomemusic/views/searchview.py:383
-#| msgid "Artists"
+#: gnomemusic/views/searchview.py:386
msgid "Artists Results"
msgstr "艺术家结果"
-#: gnomemusic/views/searchview.py:398
-#| msgid "Albums"
+#: gnomemusic/views/searchview.py:401
msgid "Albums Results"
msgstr "专辑结果"
-#: gnomemusic/widgets/albumwidget.py:165
+#: gnomemusic/widgets/albumwidget.py:154
msgid "{} minute"
msgid_plural "{} minutes"
msgstr[0] "{} 分钟"
-#: gnomemusic/widgets/disclistboxwidget.py:74
+#: gnomemusic/widgets/disclistboxwidget.py:60
msgid "Disc {}"
msgstr "唱片 {}"
#: gnomemusic/widgets/headerbar.py:68
-msgid "Selected {} item"
-msgid_plural "Selected {} items"
-msgstr[0] "已选中 {} 个项目"
+msgid "Selected {} song"
+msgid_plural "Selected {} songs"
+msgstr[0] "已选中 {} 首歌曲"
#: gnomemusic/widgets/lastfmdialog.py:65
msgid "Your music listening is reported to Last.fm."
@@ -609,27 +625,19 @@ msgstr "以 {} 登录"
msgid "Configure"
msgstr "设置"
-#: gnomemusic/widgets/notificationspopup.py:153
-msgid "Loading"
-msgstr "正在加载"
-
-#: gnomemusic/widgets/notificationspopup.py:220
-msgid "_Undo"
-msgstr "撤销(_U)"
-
-#: gnomemusic/widgets/notificationspopup.py:235
+#: gnomemusic/widgets/notificationspopup.py:216
msgid "Playlist {} removed"
msgstr "播放列表 {} 已移除"
-#: gnomemusic/widgets/notificationspopup.py:239
+#: gnomemusic/widgets/notificationspopup.py:220
msgid "{} removed from {}"
msgstr "{} 已从 {} 移除"
-#: gnomemusic/widgets/playertoolbar.py:144
+#: gnomemusic/widgets/playertoolbar.py:143
msgid "Pause"
msgstr "æš‚åœ"
-#: gnomemusic/widgets/playlistcontrols.py:126
+#: gnomemusic/widgets/playlistcontrols.py:127
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} 首歌曲"
diff --git a/po/zh_TW.po b/po/zh_TW.po
index 31762e44..4e9e62b7 100644
--- a/po/zh_TW.po
+++ b/po/zh_TW.po
@@ -7,9 +7,9 @@ msgid ""
msgstr ""
"Project-Id-Version: gnome-music master\n"
"Report-Msgid-Bugs-To: https://gitlab.gnome.org/GNOME/gnome-music/issues\n"
-"POT-Creation-Date: 2020-02-15 14:09+0000\n"
-"PO-Revision-Date: 2020-02-22 09:03+0800\n"
-"Last-Translator: Chao-Hsiung Liao <j_h_liau@yahoo.com.tw>\n"
+"POT-Creation-Date: 2020-03-28 21:40+0000\n"
+"PO-Revision-Date: 2020-05-02 00:22+0800\n"
+"Last-Translator: Cheng-Chia Tseng <pswo10680@gmail.com>\n"
"Language-Team: Chinese <zh-l10n@linux.org.tw>\n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
@@ -41,7 +41,7 @@ msgstr ""
"在您的本地集åˆä¸­æ‰¾å°‹æ›²ç›®ï¼Œå¾ž DLNA 伺æœå™¨å–得音樂或é€éŽ Jamendo å’Œ Magnatune "
"æœå‹™æ‰¾å°‹äº›æ–°éŸ³æ¨‚。"
-#: data/org.gnome.Music.appdata.xml.in.in:82
+#: data/org.gnome.Music.appdata.xml.in.in:110
msgid "The GNOME Music developers"
msgstr "GNOME 音樂開發團隊"
@@ -222,7 +222,7 @@ msgstr "求助(_H)"
#: data/ui/AppMenu.ui:97
msgid "_About Music"
-msgstr "關於音樂(_A)"
+msgstr "關於《音樂》(_A)"
#: data/ui/HeaderBar.ui:16
msgid "Menu"
@@ -467,27 +467,27 @@ msgid "_Add to Playlist"
msgstr "加入至播放清單(_A)"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:741
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:835
msgid "Most Played"
msgstr "最常播放"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:778
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:872
msgid "Never Played"
msgstr "從未播放"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:814
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:908
msgid "Recently Played"
msgstr "最近播放"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:860
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:954
msgid "Recently Added"
msgstr "最近加入"
#. TRANSLATORS: this is a playlist name
-#: gnomemusic/grilowrappers/grltrackerplaylists.py:905
+#: gnomemusic/grilowrappers/grltrackerplaylists.py:999
msgid "Favorite Songs"
msgstr "喜愛的歌曲"
@@ -518,11 +518,11 @@ msgstr[0] "éœ€è¦ {} æ‰èƒ½æ’­æ”¾é€™å€‹æª”案,但尚未安è£ã€‚"
msgid "Playing music"
msgstr "正在播放音樂"
-#: gnomemusic/utils.py:64
+#: gnomemusic/utils.py:65
msgid "Unknown album"
msgstr "未知專輯"
-#: gnomemusic/utils.py:85
+#: gnomemusic/utils.py:86
msgid "Unknown Artist"
msgstr "ä¸æ˜Žçš„演出者"
@@ -572,11 +572,11 @@ msgstr "ã€ŠéŸ³æ¨‚ã€‹éœ€è¦ Tracker 2.3.0 版或更新版本"
msgid "Playlists"
msgstr "播放清單"
-#: gnomemusic/views/searchview.py:373
+#: gnomemusic/views/searchview.py:383
msgid "Artists Results"
msgstr "演出者çµæžœ"
-#: gnomemusic/views/searchview.py:388
+#: gnomemusic/views/searchview.py:398
msgid "Albums Results"
msgstr "專輯çµæžœ"
@@ -631,7 +631,7 @@ msgstr "{} 已從 {} 移除"
msgid "Pause"
msgstr "æš«åœ"
-#: gnomemusic/widgets/playlistcontrols.py:129
+#: gnomemusic/widgets/playlistcontrols.py:126
msgid "{} Song"
msgid_plural "{} Songs"
msgstr[0] "{} 首歌曲"
diff --git a/subprojects/shared-modules/CODEOWNERS b/subprojects/shared-modules/CODEOWNERS
index 1be232ae..d8841d17 100644
--- a/subprojects/shared-modules/CODEOWNERS
+++ b/subprojects/shared-modules/CODEOWNERS
@@ -7,8 +7,5 @@
/intltool/ @TingPing
/libappindicator/ @TingPing
/libsecret/ @Lctrs
-/libusb/ @A6GibKm
/openjpeg/ @bochecha
/python2.7/ @bilelmoussaoui
-/linux-audio/ @hfiguiere
-/lua5.1/ @Unrud
diff --git a/subprojects/shared-modules/README.md b/subprojects/shared-modules/README.md
index cde47075..5a0ec035 100644
--- a/subprojects/shared-modules/README.md
+++ b/subprojects/shared-modules/README.md
@@ -23,15 +23,6 @@ To update the submodule:
git submodule update --remote --merge
```
-To remove the submodule:
-
-```
-git submodule deinit -f -- shared-modules
-rm -rf .git/modules/shared-modules
-git rm -f shared-modules
-rm .gitmodules
-```
-
[See the description in the Flathub wiki](https://github.com/flathub/flathub/wiki/App-Requirements#shared-modules) for more information.
diff --git a/subprojects/shared-modules/glew/glew.json b/subprojects/shared-modules/glew/glew.json
index 92c62c9a..6ec15bf7 100644
--- a/subprojects/shared-modules/glew/glew.json
+++ b/subprojects/shared-modules/glew/glew.json
@@ -14,8 +14,8 @@
"sources": [
{
"type": "archive",
- "url": "https://downloads.sourceforge.net/project/glew/glew/2.2.0/glew-2.2.0.tgz",
- "sha256": "d4fc82893cfb00109578d0a1a2337fb8ca335b3ceccf97b97e5cc7f08e4353e1"
+ "url": "https://downloads.sourceforge.net/project/glew/glew/2.1.0/glew-2.1.0.tgz",
+ "sha256": "04de91e7e6763039bc11940095cd9c7f880baba82196a7765f727ac05a993c95"
}
],
"cleanup": [
diff --git a/subprojects/shared-modules/gtk2/arc-gtk2-theme-Replace-Inkscape-dependency-with-rsvg-convert.patch b/subprojects/shared-modules/gtk2/arc-gtk2-theme-Replace-Inkscape-dependency-with-rsvg-convert.patch
deleted file mode 100644
index 90e09509..00000000
--- a/subprojects/shared-modules/gtk2/arc-gtk2-theme-Replace-Inkscape-dependency-with-rsvg-convert.patch
+++ /dev/null
@@ -1,180 +0,0 @@
-From d5e0034183564df5fec8e4dde1705116c7b38021 Mon Sep 17 00:00:00 2001
-From: Patrick Griffis <tingping@tingping.se>
-Date: Sat, 16 May 2020 18:00:36 -0700
-Subject: [PATCH] Replace Inkscape dependency with rsvg-convert
-
-rsvg-convert is a *much* smaller dependency that all systems with
-a functioning GTK installation should have easy access to.
----
- common/gtk-2.0/Makefile.am | 6 +-----
- common/gtk-2.0/render-asset.sh | 16 ++++++++--------
- common/gtk-3.0/common.am | 12 ++----------
- common/xfwm4/Makefile.am | 6 +-----
- common/xfwm4/render-asset.sh | 16 ++++++++--------
- configure.ac | 8 ++------
- 6 files changed, 22 insertions(+), 42 deletions(-)
-
-diff --git a/common/gtk-2.0/Makefile.am b/common/gtk-2.0/Makefile.am
-index 010823a..873013a 100644
---- a/common/gtk-2.0/Makefile.am
-+++ b/common/gtk-2.0/Makefile.am
-@@ -35,11 +35,7 @@ $(light): $(srcdir)/light/assets.svg | light/assets
- $(dark): $(srcdir)/dark/assets.svg | dark/assets
-
- $(light) $(dark):
--if INKSCAPE_1_0_OR_NEWER
-- $(INKSCAPE) --export-id-only --export-filename="$@" --export-id="$(basename $(notdir $@))" --export-dpi=$(if $(filter $(OPTION_GTK2_HIDPI),true),192,96) "$<" >/dev/null
--else !INKSCAPE_1_0_OR_NEWER
-- $(INKSCAPE) --export-id-only --export-png="$@" --export-id="$(basename $(notdir $@))" --export-dpi=$(if $(filter $(OPTION_GTK2_HIDPI),true),192,96) "$<" >/dev/null
--endif
-+ $(RSVG_CONVERT) --format=png --output="$@" --export-id="$(basename $(notdir $@))" --dpi-x=$(if $(filter $(OPTION_GTK2_HIDPI),true),192,96) --dpi-y=$(if $(filter $(OPTION_GTK2_HIDPI),true),192,96) "$<" >/dev/null
- $(OPTIPNG) -o7 --quiet "$@"
-
- menubar-toolbar/%-dark.png: dark/assets/%.png | menubar-toolbar
-diff --git a/common/gtk-2.0/render-asset.sh b/common/gtk-2.0/render-asset.sh
-index 6685414..f6198af 100755
---- a/common/gtk-2.0/render-asset.sh
-+++ b/common/gtk-2.0/render-asset.sh
-@@ -1,7 +1,7 @@
- #!/bin/bash
- set -ueo pipefail
-
--INKSCAPE="$(which inkscape)"
-+RSVG_CONVERT="$(which rsvg-convert)"
- OPTIPNG="$(which optipng)"
-
- ASSETS_DIR="$1"
-@@ -14,9 +14,9 @@ if [[ -f "${result_file}" ]] ; then
- echo "${result_file} already exists."
- else
- echo "Rendering '${result_file}'"
-- "$INKSCAPE" --export-id="$i" \
-- --export-id-only \
-- --export-png="${result_file}" "$SRC_FILE" >/dev/null \
-+ "$RSVG_CONVERT" --export-id="$i" \
-+ --format=png
-+ --output="${result_file}" "$SRC_FILE" >/dev/null \
- && "$OPTIPNG" -o7 --quiet "${result_file}"
- fi
-
-@@ -26,10 +26,10 @@ if [[ "$OPTION_GTK2_HIDPI" == "true" ]]; then
- echo "${result_file_hidpi} already exists."
- else
- echo "Rendering '${result_file_hidpi}'"
-- "$INKSCAPE" --export-id="$i" \
-- --export-id-only \
-- --export-dpi=192 \
-- --export-png="${result_file_hidpi}" "$SRC_FILE" >/dev/null \
-+ "$RSVG_CONVERT" --export-id="$i" \
-+ --dpi-x=192 --dpi-y=192 \
-+ --format=png
-+ --output="${result_file_hidpi}" "$SRC_FILE" >/dev/null \
- && "$OPTIPNG" -o7 --quiet "${result_file_hidpi}"
- fi
- fi
-diff --git a/common/gtk-3.0/common.am b/common/gtk-3.0/common.am
-index a93d01d..9e4b102 100644
---- a/common/gtk-3.0/common.am
-+++ b/common/gtk-3.0/common.am
-@@ -14,19 +14,11 @@ clean:
- rm -rf assets/ light/ dark/ darker/ lighter/
-
- $(normal): $(srcdir)/assets.svg | assets
--if INKSCAPE_1_0_OR_NEWER
-- $(INKSCAPE) --export-id-only --export-filename="$@" --export-id="$(basename $(notdir $@))" --export-dpi=96 "$<" >/dev/null
--else !INKSCAPE_1_0_OR_NEWER
-- $(INKSCAPE) --export-id-only --export-png="$@" --export-id="$(basename $(notdir $@))" --export-dpi=96 "$<" >/dev/null
--endif
-+ $(RSVG_CONVERT) --format=png --output="$@" --export-id="$(basename $(notdir $@))" --dpi-y=96 --dpi-x=96 "$<" >/dev/null
- $(OPTIPNG) -o7 --quiet "$@"
-
- $(hidpi): $(srcdir)/assets.svg | assets
--if INKSCAPE_1_0_OR_NEWER
-- $(INKSCAPE) --export-id-only --export-filename="$@" --export-id="$(patsubst %@2,%,$(basename $(notdir $@)))" --export-dpi=192 "$<" >/dev/null
--else !INKSCAPE_1_0_OR_NEWER
-- $(INKSCAPE) --export-id-only --export-png="$@" --export-id="$(patsubst %@2,%,$(basename $(notdir $@)))" --export-dpi=192 "$<" >/dev/null
--endif
-+ $(RSVG_CONVERT) --format=png --output="$@" --export-id="$(patsubst %@2,%,$(basename $(notdir $@)))" --dpi-y=192 --dpi-x=192 "$<" >/dev/null
- $(OPTIPNG) -o7 --quiet "$@"
-
- .PHONY: normal hidpi clean
-diff --git a/common/xfwm4/Makefile.am b/common/xfwm4/Makefile.am
-index e5fbdc5..1f21183 100644
---- a/common/xfwm4/Makefile.am
-+++ b/common/xfwm4/Makefile.am
-@@ -17,11 +17,7 @@ $(light): $(srcdir)/light/assets.svg | light/assets
- $(dark): $(srcdir)/dark/assets.svg | dark/assets
-
- $(light) $(dark):
--if INKSCAPE_1_0_OR_NEWER
-- $(INKSCAPE) --export-id-only --export-filename="$@" --export-id="$(basename $(notdir $@))" --export-dpi=$(if $(filter $(OPTION_GTK2_HIDPI),true),192,96) "$<" >/dev/null
--else !INKSCAPE_1_0_OR_NEWER
-- $(INKSCAPE) --export-id-only --export-png="$@" --export-id="$(basename $(notdir $@))" --export-dpi=$(if $(filter $(OPTION_GTK2_HIDPI),true),192,96) "$<" >/dev/null
--endif
-+ $(RSVG_CONVERT) --format=png --output="$@" --export-id="$(basename $(notdir $@))" --dpi-y=$(if $(filter $(OPTION_GTK2_HIDPI),true),192,96) --dpi-x=$(if $(filter $(OPTION_GTK2_HIDPI),true),192,96) "$<" >/dev/null
- $(OPTIPNG) -o7 --quiet "$@"
-
- .PHONY: light dark clean
-diff --git a/common/xfwm4/render-asset.sh b/common/xfwm4/render-asset.sh
-index 6685414..f6198af 100755
---- a/common/xfwm4/render-asset.sh
-+++ b/common/xfwm4/render-asset.sh
-@@ -1,7 +1,7 @@
- #!/bin/bash
- set -ueo pipefail
-
--INKSCAPE="$(which inkscape)"
-+RSVG_CONVERT="$(which rsvg-convert)"
- OPTIPNG="$(which optipng)"
-
- ASSETS_DIR="$1"
-@@ -14,9 +14,9 @@ if [[ -f "${result_file}" ]] ; then
- echo "${result_file} already exists."
- else
- echo "Rendering '${result_file}'"
-- "$INKSCAPE" --export-id="$i" \
-- --export-id-only \
-- --export-png="${result_file}" "$SRC_FILE" >/dev/null \
-+ "$RSVG_CONVERT" --export-id="$i" \
-+ --format=png
-+ --output="${result_file}" "$SRC_FILE" >/dev/null \
- && "$OPTIPNG" -o7 --quiet "${result_file}"
- fi
-
-@@ -26,10 +26,10 @@ if [[ "$OPTION_GTK2_HIDPI" == "true" ]]; then
- echo "${result_file_hidpi} already exists."
- else
- echo "Rendering '${result_file_hidpi}'"
-- "$INKSCAPE" --export-id="$i" \
-- --export-id-only \
-- --export-dpi=192 \
-- --export-png="${result_file_hidpi}" "$SRC_FILE" >/dev/null \
-+ "$RSVG_CONVERT" --export-id="$i" \
-+ --dpi-x=192 --dpi-y=192 \
-+ --format=png
-+ --output="${result_file_hidpi}" "$SRC_FILE" >/dev/null \
- && "$OPTIPNG" -o7 --quiet "${result_file_hidpi}"
- fi
- fi
-diff --git a/configure.ac b/configure.ac
-index f0725f1..1a52cc7 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -48,12 +48,8 @@ AM_CONDITIONAL([GNOME_SHELL_3_32_OR_NEWER], [test "0$GNOME_SHELL_VERSMNR" -ge 31
- AS_IF([test "x$ENABLE_CINNAMON" != xno], [ARC_CINNAMON])
-
- AS_IF([test "x$ENABLE_GTK2" != xno -o "x$ENABLE_GTK3" != xno -o "x$ENABLE_XFWM" != xno], [
-- AC_PATH_PROG([INKSCAPE], [inkscape])
-- AS_IF([test "x$ac_cv_path_INKSCAPE" = x], [AC_MSG_ERROR([inkscape not found])])
-- AS_IF([test "x$ac_cv_path_INKSCAPE" != x],
-- [INKSCAPE_VERSMJR=`inkscape --version 2> /dev/null | cut -d' ' -f2 | cut -d'.' -f1`]
-- AM_CONDITIONAL([INKSCAPE_1_0_OR_NEWER], [test "x$INKSCAPE_VERSMJR" = x1])
-- )
-+ AC_PATH_PROG([RSVG_CONVERT], [rsvg-convert])
-+ AS_IF([test "x$ac_cv_path_RSVG_CONVERT" = x], [AC_MSG_ERROR([rsvg-convert not found])])
- AC_PATH_PROG([OPTIPNG], [optipng])
- AS_IF([test "x$ac_cv_path_OPTIPNG" = x], [AC_MSG_ERROR([optipng not found])])
- ])
---
-2.26.0
-
diff --git a/subprojects/shared-modules/gtk2/gtk2-common-themes.json b/subprojects/shared-modules/gtk2/gtk2-common-themes.json
deleted file mode 100644
index ecbf080d..00000000
--- a/subprojects/shared-modules/gtk2/gtk2-common-themes.json
+++ /dev/null
@@ -1,226 +0,0 @@
-{
- "name": "gtk2-common-themes",
- "buildsystem": "simple",
- "build-commands": [],
- "modules": [
- {
- "name": "sassc",
- "// NOTE": "This is used by Yaru, Greybird, and Materia",
- "cleanup": ["*"],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/sass/sassc/archive/3.5.0.tar.gz",
- "sha256": "26f54e31924b83dd706bc77df5f8f5553a84d51365f0e3c566df8de027918042"
- },
- {
- "type": "script",
- "commands": ["autoreconf -si"]
- }
- ],
- "modules": [
- {
- "name": "libsass",
- "cleanup": ["*"],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/sass/libsass/archive/3.5.4.tar.gz",
- "sha256": "5f61cbcddaf8e6ef7a725fcfa5d05297becd7843960f245197ebb655ff868770"
- },
- {
- "type": "script",
- "commands": ["autoreconf -si"]
- }
- ]
- }
- ]
- },
- {
- "name": "gtk2-murrine-engine",
- "// NOTE": "Used by Arc",
- "cleanup": [
- "*.la"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://download.gnome.org/sources/murrine/0.98/murrine-0.98.2.tar.xz",
- "sha256": "e9c68ae001b9130d0f9d1b311e8121a94e5c134b82553ba03971088e57d12c89"
- },
- {
- "type": "patch",
- "path": "murrine-engine-fix-crash.patch"
- }
- ]
- },
- {
- "name": "arc-gtk2-theme",
- "// NOTE": "This is used by Solus and is popular",
- "// FIXME": "This has a dependency on inkscape and my patch isn't quite good enough sadly",
- "disabled": true,
- "config-opts": [
- "--disable-gnome-shell",
- "--disable-cinnamon",
- "--disable-gtk3",
- "--disable-metacity",
- "--disable-xfwm",
- "--disable-plank",
- "--disable-openbox",
- "--disable-unity"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/jnsh/arc-theme/releases/download/20200513/arc-theme-20200513.tar.xz",
- "sha256": "cd268b878d6ad7c81b7acc0f89b66e26ee9a9a92eafb03b792318d51707f1962"
- },
- {
- "type": "patch",
- "path": "arc-gtk2-theme-Replace-Inkscape-dependency-with-rsvg-convert.patch"
- },
- {
- "type": "shell",
- "commands": ["sed -i 's|\"$srcdir/configure\" $@||' autogen.sh"]
- }
- ],
- "modules": [
- {
- "name": "optipng",
- "cleanup": ["*"],
- "sources": [
- {
- "type": "archive",
- "url": "https://prdownloads.sourceforge.net/optipng/optipng-0.7.7.tar.gz",
- "sha256": "4f32f233cef870b3f95d3ad6428bfe4224ef34908f1b42b0badf858216654452"
- }
- ]
- }
- ]
- },
- {
- "name": "breeze-gtk2-theme",
- "// NOTE": "This is used by some KDE distros",
- "// FIXME": "This is disabled because breeze depends on KDecoration/Qt5...",
- "disabled": true,
- "buildsystem": "cmake-ninja",
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/KDE/breeze-gtk/archive/v5.18.90.tar.gz",
- "sha256": "73ff1fee8afb2fc498075d1693a664f6a749b763606d4548f74e225983107730"
- }
- ],
- "modules": [
- {
- "name": "extra-cmake-modules",
- "buildsystem": "cmake-ninja",
- "cleanup": ["*"],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/KDE/extra-cmake-modules/archive/v5.70.0.tar.gz",
- "sha256": "0e6d0694b2372cbdbc9e64abcaaac21196a15355b360e02e2e833885ae0c62f2"
- }
- ]
- },
- {
- "name": "breeze",
- "buildsystem": "cmake-ninja",
- "cleanup": ["*"],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/KDE/breeze/archive/v5.18.90.tar.gz",
- "sha256": "55e42656601dd79db1bc40589764606ec203c7f99c84340deed6e3847a4fdaf6"
- }
- ]
- }
- ]
- },
- {
- "name": "elementary-gtk2-theme",
- "// NOTE": "This is used by Elementary OS",
- "buildsystem": "meson",
- "cleanup": [
- "/share/themes/elementary/gtk-3.0",
- "/share/themes/elementary/plank",
- "/share/plank"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/elementary/stylesheet/archive/5.4.2.tar.gz",
- "sha256": "3bc37723daf4ce0b7c9ce4c125ef0055affe8d6654981388ec87d4a23a1ae0ec"
- }
- ]
- },
- {
- "name": "yaru-gtk2-theme",
- "// NOTE": "This is used by Ubuntu",
- "buildsystem": "meson",
- "config-opts": [
- "-Dicons=false",
- "-Dsounds=false",
- "-Dgnome-shell=false",
- "-Dsessions=false"
- ],
- "cleanup": [
- "/share/themes/Yaru*/gtk-3.0",
- "/share/themes/Yaru*/gtk-3.20",
- "/share/themes/Yaru*/unity"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/ubuntu/yaru/archive/20.10.1.tar.gz",
- "sha256": "9da2605088674edf2694a8215b7344fb5209b308dd8220ea21667a914dc8c55d"
- }
- ]
- },
- {
- "name": "greybird-gtk2-theme",
- "// NOTE": "This is used by many XFCE distros",
- "buildsystem": "meson",
- "cleanup": [
- "/share/themes/Greybird*/xfwm4",
- "/share/themes/Greybird*/gnome-shell",
- "/share/themes/Greybird*/gtk-3.0",
- "/share/themes/Greybird*/metacity-1",
- "/share/themes/Greybird*/xfce-notify-4.0",
- "/share/themes/Greybird*/plank",
- "/share/themes/Greybird*/unity",
- "/share/themes/Greybird*/*.emerald"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/shimmerproject/Greybird/archive/v3.22.12.tar.gz",
- "sha256": "410804cd5daca33cbc5c7c4a179f3a334ced87f408e515fc5d9c083a04bec4bc"
- }
- ]
- },
- {
- "name": "materia-gtk2-theme",
- "// NOTE": "This is used by Ubuntu Studio",
- "buildsystem": "meson",
- "cleanup": [
- "/share/themes/Materia*/xfwm4",
- "/share/themes/Materia*/gnome-shell",
- "/share/themes/Materia*/gtk-3.0",
- "/share/themes/Materia*/metacity-1",
- "/share/themes/Materia*/cinnamon",
- "/share/themes/Materia*/chrome",
- "/share/themes/Materia*/plank",
- "/share/themes/Materia*/unity"
- ],
- "sources": [
- {
- "type": "git",
- "url": "https://github.com/nana-4/materia-theme.git",
- "commit": "b36b379c9256b67e5f63a60c6faf6912f1845b66"
- }
- ]
- }
- ]
-} \ No newline at end of file
diff --git a/subprojects/shared-modules/gtk2/gtk2-use-adwaita-theme.patch b/subprojects/shared-modules/gtk2/gtk2-use-adwaita-theme.patch
index e0350545..916b3491 100644
--- a/subprojects/shared-modules/gtk2/gtk2-use-adwaita-theme.patch
+++ b/subprojects/shared-modules/gtk2/gtk2-use-adwaita-theme.patch
@@ -17,7 +17,7 @@ index 186a8f5cb2..f5c39b5afe 100644
+ if (var)
+ path = g_build_filename (var, "share", "themes", NULL);
+ else
-+ path = g_build_filename ("/app", "share", "themes", NULL);
++ path = g_build_filename ("/usr", "share", "themes", NULL);
+
+ return path;
+}
diff --git a/subprojects/shared-modules/gtk2/gtk2.json b/subprojects/shared-modules/gtk2/gtk2.json
index e2d92729..cb39de7d 100644
--- a/subprojects/shared-modules/gtk2/gtk2.json
+++ b/subprojects/shared-modules/gtk2/gtk2.json
@@ -68,6 +68,7 @@
},
{
"name": "ibus-gtk2",
+ "no-make-install": true,
"config-opts": [
"--disable-xim",
"--disable-dconf",
@@ -89,12 +90,12 @@
"--disable-introspection",
"--disable-python2"
],
- "make-install-args": [
- "-C", "client/gtk2"
+ "ensure-writable": [
+ "/lib/gtk-2.0/2.10.0/immodules.cache"
],
"post-install": [
- "gtk-query-immodules-2.0 > immodules.cache",
- "install immodules.cache -t $(pkg-config --variable=libdir gtk+-2.0)/gtk-2.0/2.10.0/"
+ "install -m644 --target-directory=${FLATPAK_DEST}/lib/gtk-2.0/2.10.0/immodules client/gtk2/.libs/im-ibus.so",
+ "gtk-query-immodules-2.0 > ${FLATPAK_DEST}/lib/gtk-2.0/2.10.0/immodules.cache"
],
"sources": [
{
diff --git a/subprojects/shared-modules/gtk2/murrine-engine-fix-crash.patch b/subprojects/shared-modules/gtk2/murrine-engine-fix-crash.patch
deleted file mode 100644
index 6200e771..00000000
--- a/subprojects/shared-modules/gtk2/murrine-engine-fix-crash.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-Index: gtk2-engines-murrine-0.98.2/src/murrine_style.c
-===================================================================
---- gtk2-engines-murrine-0.98.2.orig/src/murrine_style.c
-+++ gtk2-engines-murrine-0.98.2/src/murrine_style.c
-@@ -2171,6 +2171,7 @@ murrine_style_draw_layout (GtkStyle
- cairo_t *cr;
- cr = murrine_begin_paint (window, area);
- cairo_translate (cr, x+xos, y+yos);
-+ pango_cairo_update_layout (cr, layout);
- pango_cairo_layout_path (cr, layout);
- murrine_set_color_rgba (cr, &temp, 0.5);
- cairo_stroke (cr);
diff --git a/subprojects/shared-modules/libappindicator/libappindicator-fix-crash-from-incorrect-signal-emission.patch b/subprojects/shared-modules/libappindicator/libappindicator-fix-crash-from-incorrect-signal-emission.patch
deleted file mode 100644
index 28927a37..00000000
--- a/subprojects/shared-modules/libappindicator/libappindicator-fix-crash-from-incorrect-signal-emission.patch
+++ /dev/null
@@ -1,74 +0,0 @@
---- libappindicator-12.10.0/src/app-indicator.c 2012-07-11 13:28:34.415113869 -0400
-+++ wrk/src/app-indicator.c 2020-03-19 12:14:47.813191652 -0400
-@@ -443,7 +443,7 @@
- G_STRUCT_OFFSET (AppIndicatorClass, new_icon),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
-- G_TYPE_NONE, 0, G_TYPE_NONE);
-+ G_TYPE_NONE, 0);
-
- /**
- * AppIndicator::new-attention-icon:
-@@ -457,7 +457,7 @@
- G_STRUCT_OFFSET (AppIndicatorClass, new_attention_icon),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
-- G_TYPE_NONE, 0, G_TYPE_NONE);
-+ G_TYPE_NONE, 0);
-
- /**
- * AppIndicator::new-status:
-@@ -505,7 +505,7 @@
- G_STRUCT_OFFSET (AppIndicatorClass, connection_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__BOOLEAN,
-- G_TYPE_NONE, 1, G_TYPE_BOOLEAN, G_TYPE_NONE);
-+ G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
-
- /**
- * AppIndicator::new-icon-theme-path:
-@@ -1175,7 +1175,7 @@
- gchar * guide = priv->label_guide != NULL ? priv->label_guide : "";
-
- g_signal_emit(G_OBJECT(self), signals[NEW_LABEL], 0,
-- label, guide, TRUE);
-+ label, guide);
- if (priv->dbus_registration != 0 && priv->connection != NULL) {
- GError * error = NULL;
-
-@@ -1490,7 +1490,7 @@
- static void
- theme_changed_cb (GtkIconTheme * theme, gpointer user_data)
- {
-- g_signal_emit (user_data, signals[NEW_ICON], 0, TRUE);
-+ g_signal_emit (user_data, signals[NEW_ICON], 0);
-
- AppIndicator * self = (AppIndicator *)user_data;
- AppIndicatorPrivate *priv = self->priv;
-@@ -1904,7 +1904,7 @@
- }
-
- if (changed) {
-- g_signal_emit (self, signals[NEW_ATTENTION_ICON], 0, TRUE);
-+ g_signal_emit (self, signals[NEW_ATTENTION_ICON], 0);
-
- if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {
- GError * error = NULL;
-@@ -1982,7 +1982,7 @@
- }
-
- if (changed) {
-- g_signal_emit (self, signals[NEW_ICON], 0, TRUE);
-+ g_signal_emit (self, signals[NEW_ICON], 0);
-
- if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {
- GError * error = NULL;
-@@ -2048,7 +2048,7 @@
-
- self->priv->icon_theme_path = g_strdup(icon_theme_path);
-
-- g_signal_emit (self, signals[NEW_ICON_THEME_PATH], 0, self->priv->icon_theme_path, TRUE);
-+ g_signal_emit (self, signals[NEW_ICON_THEME_PATH], 0, self->priv->icon_theme_path);
-
- if (self->priv->dbus_registration != 0 && self->priv->connection != NULL) {
- GError * error = NULL;
diff --git a/subprojects/shared-modules/libappindicator/libappindicator-fix-crash-iterating-icon-themes.patch b/subprojects/shared-modules/libappindicator/libappindicator-fix-crash-iterating-icon-themes.patch
deleted file mode 100644
index 44f6fe48..00000000
--- a/subprojects/shared-modules/libappindicator/libappindicator-fix-crash-iterating-icon-themes.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- libappindicator-12.10.0/src/app-indicator.c
-+++ libappindicator-12.10.0/src/app-indicator.c
-@@ -1606,7 +1606,7 @@ status_icon_changes (AppIndicator * self, gpointer data)
- gint n_elements, i;
- gboolean found=FALSE;
- gtk_icon_theme_get_search_path(icon_theme, &path, &n_elements);
-- for (i=0; i< n_elements || path[i] == NULL; i++) {
-+ for (i=0; i< n_elements; i++) {
- if(g_strcmp0(path[i], self->priv->icon_theme_path) == 0) {
- found=TRUE;
- break;
diff --git a/subprojects/shared-modules/libappindicator/libappindicator-gtk2-12.10.json b/subprojects/shared-modules/libappindicator/libappindicator-gtk2-12.10.json
index 13ff359d..b65cfa3f 100644
--- a/subprojects/shared-modules/libappindicator/libappindicator-gtk2-12.10.json
+++ b/subprojects/shared-modules/libappindicator/libappindicator-gtk2-12.10.json
@@ -34,14 +34,6 @@
"path": "libappindicator-no-python.patch"
},
{
- "type": "patch",
- "path": "libappindicator-fix-crash-from-incorrect-signal-emission.patch"
- },
- {
- "type": "patch",
- "path": "libappindicator-fix-crash-iterating-icon-themes.patch"
- },
- {
"type": "script",
"commands": ["autoreconf -sfi"],
"dest-filename": "autogen.sh"
diff --git a/subprojects/shared-modules/libappindicator/libappindicator-gtk3-12.10.json b/subprojects/shared-modules/libappindicator/libappindicator-gtk3-12.10.json
index 133d4bee..46e6f438 100644
--- a/subprojects/shared-modules/libappindicator/libappindicator-gtk3-12.10.json
+++ b/subprojects/shared-modules/libappindicator/libappindicator-gtk3-12.10.json
@@ -34,14 +34,6 @@
"path": "libappindicator-no-python.patch"
},
{
- "type": "patch",
- "path": "libappindicator-fix-crash-from-incorrect-signal-emission.patch"
- },
- {
- "type": "patch",
- "path": "libappindicator-fix-crash-iterating-icon-themes.patch"
- },
- {
"type": "script",
"commands": ["autoreconf -sfi"],
"dest-filename": "autogen.sh"
diff --git a/subprojects/shared-modules/libappindicator/libappindicator-gtk3-introspection-12.10.json b/subprojects/shared-modules/libappindicator/libappindicator-gtk3-introspection-12.10.json
index cbe10be5..5df82527 100644
--- a/subprojects/shared-modules/libappindicator/libappindicator-gtk3-introspection-12.10.json
+++ b/subprojects/shared-modules/libappindicator/libappindicator-gtk3-introspection-12.10.json
@@ -34,14 +34,6 @@
"path": "libappindicator-no-python.patch"
},
{
- "type": "patch",
- "path": "libappindicator-fix-crash-from-incorrect-signal-emission.patch"
- },
- {
- "type": "patch",
- "path": "libappindicator-fix-crash-iterating-icon-themes.patch"
- },
- {
"type": "script",
"commands": ["autoreconf -sfi"],
"dest-filename": "autogen.sh"
diff --git a/subprojects/shared-modules/libappindicator/libappindicator.json.in b/subprojects/shared-modules/libappindicator/libappindicator.json.in
index 3731595f..2b383af7 100644
--- a/subprojects/shared-modules/libappindicator/libappindicator.json.in
+++ b/subprojects/shared-modules/libappindicator/libappindicator.json.in
@@ -34,14 +34,6 @@
"path": "libappindicator-no-python.patch"
},
{
- "type": "patch",
- "path": "libappindicator-fix-crash-from-incorrect-signal-emission.patch"
- },
- {
- "type": "patch",
- "path": "libappindicator-fix-crash-iterating-icon-themes.patch"
- },
- {
"type": "script",
"commands": ["autoreconf -sfi"],
"dest-filename": "autogen.sh"
diff --git a/subprojects/shared-modules/libsecret/libsecret-init-gcrypt-for-file-collection.patch b/subprojects/shared-modules/libsecret/libsecret-init-gcrypt-for-file-collection.patch
deleted file mode 100644
index cf47922c..00000000
--- a/subprojects/shared-modules/libsecret/libsecret-init-gcrypt-for-file-collection.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-diff --git a/libsecret/secret-file-collection.c b/libsecret/secret-file-collection.c
-index 2e90e3c..a27cf04 100644
---- a/libsecret/secret-file-collection.c
-+++ b/libsecret/secret-file-collection.c
-@@ -16,6 +16,7 @@
-
- #include "secret-file-collection.h"
-
-+#include "egg/egg-libgcrypt.h"
- #include "egg/egg-secure-memory.h"
-
- EGG_SECURE_DECLARE (secret_file_collection);
-@@ -271,6 +272,8 @@ secret_file_collection_class_init (SecretFileCollectionClass *klass)
- g_param_spec_boxed ("password", "password", "Password",
- SECRET_TYPE_VALUE,
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
-+
-+ egg_libgcrypt_initialize ();
- }
-
- static void
diff --git a/subprojects/shared-modules/libsecret/libsecret.json b/subprojects/shared-modules/libsecret/libsecret.json
index 8e5fc33f..a2d34f58 100644
--- a/subprojects/shared-modules/libsecret/libsecret.json
+++ b/subprojects/shared-modules/libsecret/libsecret.json
@@ -16,12 +16,8 @@
"sources": [
{
"type": "archive",
- "url": "https://ftp.gnome.org/pub/GNOME/sources/libsecret/0.20/libsecret-0.20.3.tar.xz",
- "sha256": "4fcb3c56f8ac4ab9c75b66901fb0104ec7f22aa9a012315a14c0d6dffa5290e4"
- },
- {
- "type": "patch",
- "path": "libsecret-init-gcrypt-for-file-collection.patch"
+ "url": "https://ftp.gnome.org/pub/GNOME/sources/libsecret/0.20/libsecret-0.20.1.tar.xz",
+ "sha256": "57f73e94ec6263a17a077fb809cf8cf424637a897a7f15b4eec42ce4aef52447"
}
]
}
diff --git a/subprojects/shared-modules/libusb/libusb.json b/subprojects/shared-modules/libusb/libusb.json
deleted file mode 100644
index 03cff446..00000000
--- a/subprojects/shared-modules/libusb/libusb.json
+++ /dev/null
@@ -1,19 +0,0 @@
-{
- "name": "libusb",
- "config-opts": [ "--disable-static" ],
- "cleanup": [
- "/lib/*.la",
- "/lib/pkgconfig",
- "/include"
- ],
- "sources": [
- {
- "type":"archive",
- "url":"https://github.com/libusb/libusb/archive/v1.0.23.tar.gz",
- "sha256": "02620708c4eea7e736240a623b0b156650c39bfa93a14bcfa5f3e05270313eba"
- }
- ],
- "post-install": [
- "install -Dm644 COPYING /app/share/licenses/libusb/COPYING"
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/dssi.json b/subprojects/shared-modules/linux-audio/dssi.json
deleted file mode 100644
index ec33fd37..00000000
--- a/subprojects/shared-modules/linux-audio/dssi.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "dssi",
- "rm-configure": true,
- "config-opts": [
- "--disable-static"
- ],
- "cleanup": [
- "/bin",
- "/include",
- "/lib/dssi",
- "/lib/pkgconfig",
- "/share/man",
- "*.la"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "http://download.sf.net/sourceforge/dssi/dssi-1.1.1.tar.gz",
- "sha256": "f2c82b073a947c8255284249097667f9b14e660bf86186f3fcd3b3b3e087814e"
- },
- {
- "type": "script",
- "commands": [
- "autoreconf -fiv"
- ],
- "dest-filename": "autogen.sh"
- }
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/fftw3f-static.json b/subprojects/shared-modules/linux-audio/fftw3f-static.json
deleted file mode 100644
index d6e095d0..00000000
--- a/subprojects/shared-modules/linux-audio/fftw3f-static.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "name": "fftw3f",
- "config-opts": [
- "--enable-threads",
- "--enable-static",
- "--disable-shared",
- "--enable-float"
- ],
- "build-options": {
- "env": {
- "CFLAGS": "-fPIC"
- },
- "arch": {
- "x86_64": {
- "config-opts": [
- "--enable-sse2",
- "--enable-avx",
- "--enable-avx-128-fma"
- ]
- }
- }
- },
- "sources": [
- {
- "type": "archive",
- "url": "http://www.fftw.org/fftw-3.3.8.tar.gz",
- "sha256": "6113262f6e92c5bd474f2875fa1b01054c4ad5040f6b0da7c03c98821d9ae303"
- }
- ],
- "cleanup": [
- "/bin",
- "/include",
- "/lib/cmake",
- "/lib/pkgconfig",
- "/share/info",
- "/share/man",
- "*.a",
- "*.la",
- "*.so"
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/fftw3f.json b/subprojects/shared-modules/linux-audio/fftw3f.json
deleted file mode 100644
index 870b6897..00000000
--- a/subprojects/shared-modules/linux-audio/fftw3f.json
+++ /dev/null
@@ -1,36 +0,0 @@
-{
- "name": "fftw3f",
- "config-opts": [
- "--enable-threads",
- "--enable-shared",
- "--disable-static",
- "--enable-float"
- ],
- "build-options": {
- "arch": {
- "x86_64": {
- "config-opts": [
- "--enable-sse2",
- "--enable-avx",
- "--enable-avx-128-fma"
- ]
- }
- }
- },
- "sources": [
- {
- "type": "archive",
- "url": "http://www.fftw.org/fftw-3.3.8.tar.gz",
- "sha256": "6113262f6e92c5bd474f2875fa1b01054c4ad5040f6b0da7c03c98821d9ae303"
- }
- ],
- "cleanup": [
- "/bin",
- "/include",
- "/lib/cmake",
- "/lib/pkgconfig",
- "/share/man",
- "*.la",
- "*.so"
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/fluidsynth2-static.json b/subprojects/shared-modules/linux-audio/fluidsynth2-static.json
deleted file mode 100644
index 6b62db8d..00000000
--- a/subprojects/shared-modules/linux-audio/fluidsynth2-static.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "name": "fluidsynth",
- "buildsystem": "cmake-ninja",
- "build-options": {
- "env": {
- "CFLAGS": "-fPIC",
- "CXXFLAGS": "-fPIC"
- }
- },
- "config-opts": [
- "-DLIB_SUFFIX=",
- "-DBUILD_SHARED_LIBS=OFF"
- ],
- "cleanup": [
- "/bin",
- "/include",
- "/lib/pkgconfig",
- "/share/man",
- "*.so",
- "*.a"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/FluidSynth/fluidsynth/archive/v2.1.3.tar.gz",
- "sha256": "645fbfd7c04543c6d3bf415eab8250527813b8dc8e6d6972dbcc8cb525e1d409"
- }
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/fluidsynth2.json b/subprojects/shared-modules/linux-audio/fluidsynth2.json
deleted file mode 100644
index 68a47759..00000000
--- a/subprojects/shared-modules/linux-audio/fluidsynth2.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "name": "fluidsynth",
- "buildsystem": "cmake-ninja",
- "config-opts": [
- "-DLIB_SUFFIX="
- ],
- "cleanup": [
- "/bin",
- "/include",
- "/lib/pkgconfig",
- "/share/man",
- "*.so"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/FluidSynth/fluidsynth/archive/v2.1.3.tar.gz",
- "sha256": "645fbfd7c04543c6d3bf415eab8250527813b8dc8e6d6972dbcc8cb525e1d409"
- }
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/jack2.json b/subprojects/shared-modules/linux-audio/jack2.json
deleted file mode 100644
index 683e7153..00000000
--- a/subprojects/shared-modules/linux-audio/jack2.json
+++ /dev/null
@@ -1,21 +0,0 @@
-{
- "name": "jack2",
- "buildsystem": "simple",
- "build-commands": [
- "./waf configure --prefix=$FLATPAK_DEST --htmldir=$FLATPAK_DEST/share/doc/jack/ --classic",
- "./waf build -j $FLATPAK_BUILDER_N_JOBS",
- "./waf install"
- ],
- "cleanup": [
- "/include",
- "/lib/pkgconfig",
- "/share/man"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/jackaudio/jack2/releases/download/v1.9.14/v1.9.14.tar.gz",
- "sha256": "a20a32366780c0061fd58fbb5f09e514ea9b7ce6e53b080a44b11a558a83217c"
- }
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/ladspa.json b/subprojects/shared-modules/linux-audio/ladspa.json
deleted file mode 100644
index 110f0b45..00000000
--- a/subprojects/shared-modules/linux-audio/ladspa.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "ladspa",
- "no-autogen": true,
- "subdir": "src",
- "make-install-args": [
- "INSTALL_PLUGINS_DIR=/app/lib/ladspa",
- "INSTALL_INCLUDE_DIR=/app/include",
- "INSTALL_BINARY_DIR=/app/bin"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "http://www.ladspa.org/download/ladspa_sdk_1.15.tgz",
- "sha256": "4229959b09d20c88c8c86f4aa76427843011705df22d9c28b38359fd1829fded"
- }
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/lash.json b/subprojects/shared-modules/linux-audio/lash.json
deleted file mode 100644
index 4d0ccb28..00000000
--- a/subprojects/shared-modules/linux-audio/lash.json
+++ /dev/null
@@ -1,41 +0,0 @@
-{
- "name": "lash",
- "rm-configure": true,
- "config-opts": [
- "--disable-static",
- "--disable-serv-inst",
- "CFLAGS=-D_GNU_SOURCE"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://download.savannah.gnu.org/releases/lash/lash-0.5.4.tar.gz",
- "sha256": "105a7da84415c4725c6bcad28e70f23aeb4534f94fc80ca262b6a2cef2226c16"
- },
- {
- "type": "patch",
- "strip-components": 0,
- "path": "patches/lash-0.5.3-no-static-lib.patch"
- },
- {
- "type": "patch",
- "path": "patches/lash-gcc47.patch"
- },
- {
- "type": "patch",
- "path": "patches/lash-linking.patch"
- },
- {
- "type": "patch",
- "strip-components": 0,
- "path": "patches/lash-configure.patch"
- },
- {
- "type": "script",
- "commands": [
- "autoreconf -fiv"
- ],
- "dest-filename": "autogen.sh"
- }
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/libinstpatch.json b/subprojects/shared-modules/linux-audio/libinstpatch.json
deleted file mode 100644
index 994e9a22..00000000
--- a/subprojects/shared-modules/linux-audio/libinstpatch.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "libinstpatch",
- "buildsystem": "cmake-ninja",
- "config-opts": [
- "-DLIB_SUFFIX="
- ],
- "cleanup": [
- "/share/doc"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/swami/libinstpatch/archive/v1.1.5.tar.gz",
- "sha256": "5fd01cd2ba7377e7a72caaf3b565d8fe088b5c8a14e0ea91516f0c87524bcf8a"
- }
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/liblo-static.json b/subprojects/shared-modules/linux-audio/liblo-static.json
deleted file mode 100644
index 7d229d36..00000000
--- a/subprojects/shared-modules/linux-audio/liblo-static.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
- "name": "liblo",
- "cleanup": [
- "/bin",
- "/include",
- "/lib/pkgconfig",
- "*.la",
- "*.a",
- "*.so"
- ],
- "build-options": {
- "env": {
- "CFLAGS": "-fPIC"
- }
- },
- "config-opts": [
- "--enable-static",
- "--disable-shared"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "http://download.sf.net/sourceforge/liblo/liblo-0.31.tar.gz",
- "sha256": "2b4f446e1220dcd624ecd8405248b08b7601e9a0d87a0b94730c2907dbccc750"
- }
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/liblo.json b/subprojects/shared-modules/linux-audio/liblo.json
deleted file mode 100644
index 17de750e..00000000
--- a/subprojects/shared-modules/linux-audio/liblo.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "name": "liblo",
- "cleanup": [
- "/bin",
- "/include",
- "/lib/pkgconfig",
- "*.la",
- "*.so"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "http://download.sf.net/sourceforge/liblo/liblo-0.31.tar.gz",
- "sha256": "2b4f446e1220dcd624ecd8405248b08b7601e9a0d87a0b94730c2907dbccc750"
- }
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/lilv.json b/subprojects/shared-modules/linux-audio/lilv.json
deleted file mode 100644
index e33bf0e3..00000000
--- a/subprojects/shared-modules/linux-audio/lilv.json
+++ /dev/null
@@ -1,100 +0,0 @@
-{
- "name": "lilv",
- "buildsystem": "simple",
- "build-commands": [
- "python3 ./waf configure --prefix=$FLATPAK_DEST",
- "python3 ./waf build -j $FLATPAK_BUILDER_N_JOBS",
- "python3 ./waf install"
- ],
- "modules": [
- {
- "name": "serd",
- "buildsystem": "simple",
- "build-commands": [
- "python3 ./waf configure --prefix=$FLATPAK_DEST",
- "python3 ./waf build -j $FLATPAK_BUILDER_N_JOBS",
- "python3 ./waf install"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://download.drobilla.net/serd-0.30.2.tar.bz2",
- "sha256": "9d3102701172804f823f2215ca3147c50eba992641f9fbe014272355f4937202"
- }
- ],
- "post-install": [
- "install -Dm644 -t /app/share/licenses/serd COPYING"
- ],
- "cleanup": [
- "/bin",
- "/include",
- "/lib/pkgconfig",
- "/share/man"
- ]
- },
- {
- "name": "sord",
- "buildsystem": "simple",
- "build-commands": [
- "python3 ./waf configure --prefix=$FLATPAK_DEST",
- "python3 ./waf build -j $FLATPAK_BUILDER_N_JOBS",
- "python3 ./waf install"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://download.drobilla.net/sord-0.16.4.tar.bz2",
- "sha256": "b15998f4e7ad958201346009477d6696e90ee5d3e9aff25e7e9be074372690d7"
- }
- ],
- "post-install": [
- "install -Dm644 -t /app/share/licenses/sord COPYING"
- ],
- "cleanup": [
- "/bin",
- "/include",
- "/lib/pkgconfig",
- "/share/man"
- ]
- },
- {
- "name": "sratom",
- "buildsystem": "simple",
- "build-commands": [
- "python3 ./waf configure --prefix=$FLATPAK_DEST",
- "python3 ./waf build -j $FLATPAK_BUILDER_N_JOBS",
- "python3 ./waf install"
- ],
- "cleanup": [
- "/include",
- "/lib/pkgconfig"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://download.drobilla.net/sratom-0.6.4.tar.bz2",
- "sha256": "146c8f14b8902ac3c8fa8c2e0a014eb8a38fab60090c5adbfbff3e3b7c5c006e"
- }
- ],
- "post-install": [
- "install -Dm644 -t /app/share/licenses/sratom COPYING"
- ]
- }
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://download.drobilla.net/lilv-0.24.6.tar.bz2",
- "sha256": "5f544cf79656e0782a03a2cc7ab1d31a93f36d71d4187bd427ade8d7b55370dc"
- }
- ],
- "post-install": [
- "install -Dm644 -t /app/share/licenses/lilv COPYING"
- ],
- "cleanup": [
- "/bin",
- "/etc",
- "/lib/pkgconfig",
- "/share/man"
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/lrdf.json b/subprojects/shared-modules/linux-audio/lrdf.json
deleted file mode 100644
index 465dd663..00000000
--- a/subprojects/shared-modules/linux-audio/lrdf.json
+++ /dev/null
@@ -1,44 +0,0 @@
-{
- "name": "lrdf",
- "rm-configure": true,
- "cleanup": [
- "/include",
- "/lib/pkgconfig"
- ],
- "modules": [
- "ladspa.json",
- {
- "name": "raptor2",
- "cleanup": [
- "/include",
- "/lib/pkgconfig"
- ],
- "config-opts": [
- "--disable-documentation",
- "--disable-static"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "http://download.librdf.org/source/raptor2-2.0.15.tar.gz",
- "sha256": "ada7f0ba54787b33485d090d3d2680533520cd4426d2f7fb4782dd4a6a1480ed"
- }
- ]
- }
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://github.com/swh/LRDF/tarball/0.5.0",
- "dest-filename": "swh-LRDF-0.5.0-0-g7ebc032.tar.gz",
- "sha256": "013002b91ef209827fe99552b8c7f0b569cddb3d6f1439bedbd8bafe1956a93c"
- },
- {
- "type": "script",
- "commands": [
- "autoreconf -fiv"
- ],
- "dest-filename": "autogen.sh"
- }
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/lv2.json b/subprojects/shared-modules/linux-audio/lv2.json
deleted file mode 100644
index 180f3272..00000000
--- a/subprojects/shared-modules/linux-audio/lv2.json
+++ /dev/null
@@ -1,26 +0,0 @@
-{
- "name": "lv2",
- "buildsystem": "simple",
- "build-commands": [
- "python3 ./waf configure --prefix=$FLATPAK_DEST --lv2dir=$FLATPAK_DEST/lib/lv2 --copy-headers",
- "python3 ./waf build -j $FLATPAK_BUILDER_N_JOBS",
- "python3 ./waf install"
- ],
- "cleanup": [
- "/bin",
- "/include",
- "/lib/pkgconfig",
- "/share"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://lv2plug.in/spec/lv2-1.18.0.tar.bz2",
- "sha256": "90a3e5cf8bdca81b49def917e89fd6bba1d5845261642cd54e7888df0320473f"
- }
- ],
- "post-install": [
- "install -Dm644 -t $FLATPAK_DEST/share/licenses/lv2 COPYING",
- "ln -sf lv2.pc $FLATPAK_DEST/lib/pkgconfig/lv2core.pc"
- ]
-}
diff --git a/subprojects/shared-modules/linux-audio/patches/lash-0.5.3-no-static-lib.patch b/subprojects/shared-modules/linux-audio/patches/lash-0.5.3-no-static-lib.patch
deleted file mode 100644
index 54d1cd7b..00000000
--- a/subprojects/shared-modules/linux-audio/patches/lash-0.5.3-no-static-lib.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- lash-1.0.pc.in~ 2007-10-07 06:33:27.000000000 -0700
-+++ lash-1.0.pc.in 2007-10-07 06:35:00.000000000 -0700
-@@ -7,6 +7,5 @@
- Description: Audio session management
- Requires: @PC_REQUIRES@
- Version: @PACKAGE_VERSION@
--Libs: -llash
--Libs.static: -lpthread -luuid
-+Libs: -llash -lpthread -luuid
- Cflags: -I${includedir}/lash-1.0
diff --git a/subprojects/shared-modules/linux-audio/patches/lash-configure.patch b/subprojects/shared-modules/linux-audio/patches/lash-configure.patch
deleted file mode 100644
index ba9bb8ba..00000000
--- a/subprojects/shared-modules/linux-audio/patches/lash-configure.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- configure.ac 2007-11-14 16:58:51.000000000 -0500
-+++ configure.ac.new 2019-01-24 13:48:46.284377086 -0500
-@@ -2,7 +2,7 @@
- AC_CONFIG_SRCDIR([lash/types.h])
- AC_CONFIG_HEADER([config.h])
- AM_INIT_AUTOMAKE
--AM_ACLOCAL_INCLUDE([m4])
-+dnl AM_ACLOCAL_INCLUDE([m4])
-
- ### Check for programs ###
- AC_LANG([C])
diff --git a/subprojects/shared-modules/linux-audio/patches/lash-gcc47.patch b/subprojects/shared-modules/linux-audio/patches/lash-gcc47.patch
deleted file mode 100644
index 41710ca5..00000000
--- a/subprojects/shared-modules/linux-audio/patches/lash-gcc47.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -rupN lash-0.5.4.old/liblash/lash.c lash-0.5.4/liblash/lash.c
---- lash-0.5.4.old/liblash/lash.c 2007-03-09 10:34:40.000000000 -0500
-+++ lash-0.5.4/liblash/lash.c 2012-07-22 18:17:46.003963521 -0400
-@@ -22,6 +22,7 @@
- #include <string.h>
- #include <strings.h>
- #include <pthread.h>
-+#include <sys/resource.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <sys/socket.h>
diff --git a/subprojects/shared-modules/linux-audio/patches/lash-linking.patch b/subprojects/shared-modules/linux-audio/patches/lash-linking.patch
deleted file mode 100644
index e46d1647..00000000
--- a/subprojects/shared-modules/linux-audio/patches/lash-linking.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-diff -rupN lash-0.5.4.old/clients/control/Makefile.am lash-0.5.4/clients/control/Makefile.am
---- lash-0.5.4.old/clients/control/Makefile.am 2007-01-13 13:20:03.000000000 -0500
-+++ lash-0.5.4/clients/control/Makefile.am 2010-02-10 03:08:04.000000000 -0500
-@@ -18,6 +18,6 @@ lash_control_CFLAGS = $(LASH_CFLAGS)
-
- lash_control_LDADD = \
- $(top_builddir)/liblash/liblash.la \
-- $(LASH_LIBS) @READLINE_LIBS@
-+ $(LASH_LIBS) @READLINE_LIBS@ -luuid
-
- endif
-diff -rupN lash-0.5.4.old/clients/control/Makefile.in lash-0.5.4/clients/control/Makefile.in
---- lash-0.5.4.old/clients/control/Makefile.in 2007-11-14 17:00:09.000000000 -0500
-+++ lash-0.5.4/clients/control/Makefile.in 2010-02-10 03:09:26.000000000 -0500
-@@ -236,7 +236,7 @@ AM_CPPFLAGS = -I$(top_srcdir)
- @HAVE_READLINE_TRUE@lash_control_CFLAGS = $(LASH_CFLAGS)
- @HAVE_READLINE_TRUE@lash_control_LDADD = \
- @HAVE_READLINE_TRUE@ $(top_builddir)/liblash/liblash.la \
--@HAVE_READLINE_TRUE@ $(LASH_LIBS) @READLINE_LIBS@
-+@HAVE_READLINE_TRUE@ $(LASH_LIBS) @READLINE_LIBS@ -luuid
-
- all: all-am
-
-diff -rupN lash-0.5.4.old/clients/panel/Makefile.am lash-0.5.4/clients/panel/Makefile.am
---- lash-0.5.4.old/clients/panel/Makefile.am 2005-09-13 01:22:59.000000000 -0400
-+++ lash-0.5.4/clients/panel/Makefile.am 2010-02-10 03:17:10.000000000 -0500
-@@ -13,7 +13,7 @@ lash_panel_CFLAGS = \
-
- lash_panel_LDADD = \
- $(top_builddir)/liblash/liblash.la \
-- $(GTK2_LIBS)
-+ $(GTK2_LIBS) -luuid
-
- if HAVE_GTK2
- bin_PROGRAMS = lash_panel
-diff -rupN lash-0.5.4.old/clients/panel/Makefile.in lash-0.5.4/clients/panel/Makefile.in
---- lash-0.5.4.old/clients/panel/Makefile.in 2007-11-14 17:00:09.000000000 -0500
-+++ lash-0.5.4/clients/panel/Makefile.in 2010-02-10 03:17:23.000000000 -0500
-@@ -230,7 +230,7 @@ lash_panel_CFLAGS = \
-
- lash_panel_LDADD = \
- $(top_builddir)/liblash/liblash.la \
-- $(GTK2_LIBS)
-+ $(GTK2_LIBS) -luuid
-
- all: all-am
-
-diff -rupN lash-0.5.4.old/clients/synth/Makefile.am lash-0.5.4/clients/synth/Makefile.am
---- lash-0.5.4.old/clients/synth/Makefile.am 2005-09-13 01:22:59.000000000 -0400
-+++ lash-0.5.4/clients/synth/Makefile.am 2010-02-10 03:22:39.000000000 -0500
-@@ -20,4 +20,4 @@ lash_synth_LDADD = \
- $(JACK_LIBS) \
- $(ALSA_LIBS) \
- $(GTK2_LIBS) \
-- -lpthread
-+ -lpthread -lm
-diff -rupN lash-0.5.4.old/clients/synth/Makefile.in lash-0.5.4/clients/synth/Makefile.in
---- lash-0.5.4.old/clients/synth/Makefile.in 2007-11-14 17:00:10.000000000 -0500
-+++ lash-0.5.4/clients/synth/Makefile.in 2010-02-10 03:22:51.000000000 -0500
-@@ -238,7 +238,7 @@ lash_synth_LDADD = \
- $(JACK_LIBS) \
- $(ALSA_LIBS) \
- $(GTK2_LIBS) \
-- -lpthread
-+ -lpthread -lm
-
- all: all-am
-
-diff -rupN lash-0.5.4.old/lashd/Makefile.am lash-0.5.4/lashd/Makefile.am
---- lash-0.5.4.old/lashd/Makefile.am 2006-09-16 16:27:46.000000000 -0400
-+++ lash-0.5.4/lashd/Makefile.am 2010-07-23 15:13:59.000000000 -0400
-@@ -32,6 +32,7 @@ lashd_LDADD = \
- $(ALSA_LIBS) \
- $(XML2_LIBS) \
- $(UUID_LIBS) \
-+ -lpthread \
- $(top_builddir)/liblash/liblash.la
-
- lashd_CFLAGS = \
-diff -rupN lash-0.5.4.old/lashd/Makefile.in lash-0.5.4/lashd/Makefile.in
---- lash-0.5.4.old/lashd/Makefile.in 2007-11-14 17:00:10.000000000 -0500
-+++ lash-0.5.4/lashd/Makefile.in 2010-07-23 15:14:29.000000000 -0400
-@@ -262,6 +262,7 @@ lashd_LDADD = \
- $(ALSA_LIBS) \
- $(XML2_LIBS) \
- $(UUID_LIBS) \
-+ -lpthread \
- $(top_builddir)/liblash/liblash.la
-
- lashd_CFLAGS = \
diff --git a/subprojects/shared-modules/linux-audio/patches/stk-install.sh b/subprojects/shared-modules/linux-audio/patches/stk-install.sh
deleted file mode 100644
index e2d9c9b7..00000000
--- a/subprojects/shared-modules/linux-audio/patches/stk-install.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-
-INCLUDE_DIR=/app/include
-DATA_DIR=/app/share
-LIB_DIR=/app/lib
-BIN_DIR=/app/bin
-
-
-
-
-install -Dm644 -t $INCLUDE_DIR/stk include/*
-install -Dm644 -t $LIB_DIR src/libstk.*
-install -Dm644 -t $DATA_DIR/stk/rawwaves rawwaves/*.raw
-
-#cp -pr projects/demo/tcl $DATA_DIR/stk/demo
-#cp -pr projects/demo/scores $DATA_DIR/stk/demo
-#cp -p projects/demo/demo $BIN_DIR/stk-demo
-#cp -p projects/demo/Md2Skini $BIN_DIR/Md2Skini
-#for f in Banded Drums Modal Physical Shakers StkDemo Voice ; do
-# chmod +x projects/demo/$f
-# sed -e 's,\./demo,$BIN_DIR/stk-demo,' -e '1i#! /bin/sh' \
-# -i projects/demo/$f
-# cp -p projects/demo/$f $DATA_DIR/stk/demo
-#done
-
-#cp -pr projects/examples/midifiles $DATA_DIR/stk/examples
-#cp -pr projects/examples/rawwaves $DATA_DIR/stk/examples
-#cp -pr projects/examples/scores $DATA_DIR/stk/examples
-#for f in sine sineosc foursine audioprobe midiprobe duplex play \
-# record inetIn inetOut rtsine crtsine bethree controlbee \
-# threebees playsmf grains ; do
-# cp -p projects/examples/$f $BIN_DIR/stk-$f
-# # absolute links, will be shortened later
-# ln -s $BIN_DIR/stk-$f $DATA_DIR/stk/examples/$f
-#done
-
-install -Dm644 -t $DATA_DIR/stk/effects projects/effects/tcl
-install -Dm644 -t $BIN_DIR/stk-effects projects/effects/effects
-sed -e 's,\./effects,$BIN_DIR/stk-effects,' -e '1i#! /bin/sh' \
- -i projects/effects/StkEffects
-install -Dm644 -t $DATA_DIR/stk/effects projects/effects/StkEffects
-
-install -Dm644 -t $DATA_DIR/stk/ragamatic projects/ragamatic/tcl
-install -Dm644 -t $DATA_DIR/stk/ragamatic projects/ragamatic/rawwaves
-install -Dm644 -t $BIN_DIR/stk-ragamat projects/ragamatic/ragamat
-sed -e 's,\./ragamat,$BIN_DIR/stk-ragamat,' -e '1i#! /bin/sh' \
- -i projects/ragamatic/Raga
-install -Dm644 -t $DATA_DIR/stk/ragamatic projects/ragamatic/Raga
-
-install -Dm644 -t $DATA_DIR/stk/eguitar projects/eguitar/tcl
-install -Dm644 -t $DATA_DIR/stk/eguitar projects/eguitar/scores
-install -Dm644 -t $BIN_DIR/stk-eguitar projects/eguitar/eguitar
-sed -e 's,\./eguitar,$BIN_DIR/stk-eguitar,' -e '1i#! /bin/sh' \
- -i projects/eguitar/ElectricGuitar
-install -Dm644 -t $DATA_DIR/stk/eguitar projects/eguitar/ElectricGuitar
diff --git a/subprojects/shared-modules/linux-audio/stk.json b/subprojects/shared-modules/linux-audio/stk.json
deleted file mode 100644
index cf4d8f93..00000000
--- a/subprojects/shared-modules/linux-audio/stk.json
+++ /dev/null
@@ -1,28 +0,0 @@
-{
- "name": "stk",
- "build-commands": [
- "make -j $FLATPAK_BUILDER_N_JOBS -C src",
- "make -j $FLATPAK_BUILDER_N_JOBS -C projects/effects libeffects",
- "make -j $FLATPAK_BUILDER_N_JOBS -C projects/ragamatic libragamat",
- "make -j $FLATPAK_BUILDER_N_JOBS -C projects/eguitar libeguitar"
- ],
- "post-install": [
- "sh ./stk-install.sh"
- ],
- "cleanup": [
- "/bin/*",
- "/include",
- "*.a"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "http://ccrma.stanford.edu/software/stk/release/stk-4.6.1.tar.gz",
- "sha256": "e77ba3c80cdd93ca02c34098b9b7f918df3d648c87f1ed5d94fe854debd6d101"
- },
- {
- "type": "file",
- "path": "patches/stk-install.sh"
- }
- ]
-}
diff --git a/subprojects/shared-modules/lua5.1/lua-5.1.5-so.patch b/subprojects/shared-modules/lua5.1/lua-5.1.5-so.patch
deleted file mode 100644
index 5fc61a08..00000000
--- a/subprojects/shared-modules/lua5.1/lua-5.1.5-so.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-diff -ur lua-5.1.4/src/Makefile lua-5.1.4-new/src/Makefile
---- lua-5.1.4/src/Makefile 2008-01-19 20:37:58.000000000 +0100
-+++ lua-5.1.4-new/src/Makefile 2012-02-23 18:26:43.000000000 +0100
-@@ -23,6 +23,7 @@
- PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
-
- LUA_A= liblua.a
-+LUA_SO= liblua.so
- CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
- lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
- lundump.o lvm.o lzio.o
-@@ -36,7 +37,7 @@
- LUAC_O= luac.o print.o
-
- ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O)
--ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
-+ALL_T= $(LUA_A) $(LUA_SO) $(LUA_T) $(LUAC_T)
- ALL_A= $(LUA_A)
-
- default: $(PLAT)
-@@ -51,6 +52,11 @@
- $(AR) $@ $?
- $(RANLIB) $@
-
-+$(LUA_SO): $(CORE_O) $(LIB_O)
-+ $(CC) -shared -ldl -Wl,-soname,$(LUA_SO).$(V) -o $@.$(R) $? -lm $(MYLDFLAGS)
-+ ln -sf $(LUA_SO).$(R) $(LUA_SO).$(V)
-+ ln -sf $(LUA_SO).$(R) $(LUA_SO)
-+
- $(LUA_T): $(LUA_O) $(LUA_A)
- $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
-
---- lua-5.1.4/Makefile 2008-08-12 02:40:48.000000000 +0200
-+++ lua-5.1.4-new/Makefile 2012-02-23 19:06:32.000000000 +0100
-@@ -53,7 +53,7 @@
- all: $(PLAT)
-
- $(PLATS) clean:
-- cd src && $(MAKE) $@
-+ cd src && $(MAKE) $@ V=$(V) R=$(R)
-
- test: dummy
- src/lua test/hello.lua
diff --git a/subprojects/shared-modules/lua5.1/lua-5.1.5.json b/subprojects/shared-modules/lua5.1/lua-5.1.5.json
deleted file mode 100644
index 896cadb9..00000000
--- a/subprojects/shared-modules/lua5.1/lua-5.1.5.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "name": "lua-5.1",
- "buildsystem": "simple",
- "build-commands": [
- "make -j $FLATPAK_BUILDER_N_JOBS CFLAGS=\"$CFLAGS -fPIC -DLUA_USE_LINUX\" linux",
- "make INSTALL_TOP=$FLATPAK_DEST TO_LIB='liblua.a liblua.so.5.1.5' install",
- "ln -sf liblua.so.5.1.5 $FLATPAK_DEST/lib/liblua.so",
- "ln -sf liblua.so.5.1.5 $FLATPAK_DEST/lib/liblua.so.5.1",
- "install -Dm0644 etc/lua.pc $FLATPAK_DEST/lib/pkgconfig/lua.pc",
- "ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua51.pc",
- "ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua5.1.pc",
- "ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua-5.1.pc"
- ],
- "sources": [
- {
- "type": "archive",
- "url": "https://www.lua.org/ftp/lua-5.1.5.tar.gz",
- "sha256": "2640fc56a795f29d28ef15e13c34a47e223960b0240e8cb0a82d9b0738695333"
- },
- {
- "type": "patch",
- "path": "lua-5.1.5-so.patch"
- },
- {
- "type": "shell",
- "commands": [
- "sed -i \"s|/usr/local|$FLATPAK_DEST|\" etc/lua.pc src/luaconf.h"
- ]
- }
- ],
- "cleanup": [
- "*.a",
- "/bin",
- "/include",
- "/lib/pkgconfig",
- "/man"
- ]
-}
diff --git a/subprojects/shared-modules/lua5.3/lua-5.3.0-autotoolize.patch b/subprojects/shared-modules/lua5.3/lua-5.3.0-autotoolize.patch
new file mode 100644
index 00000000..3e4723a5
--- /dev/null
+++ b/subprojects/shared-modules/lua5.3/lua-5.3.0-autotoolize.patch
@@ -0,0 +1,192 @@
+diff -up lua-5.3.0/configure.ac.autoxxx lua-5.3.0/configure.ac
+--- lua-5.3.0/configure.ac.autoxxx 2015-01-15 10:20:03.826889574 -0500
++++ lua-5.3.0/configure.ac 2015-01-15 10:20:03.826889574 -0500
+@@ -0,0 +1,69 @@
++AC_PREREQ(2.59)
++AC_INIT([lua], [5.3.0], [https://bugzilla.redhat.com/], [lua-at], [http://www.lua.org])
++AC_SUBST([MAJOR_VERSION], [5.3])
++
++AC_CONFIG_HEADERS([config.h])
++AC_CONFIG_SRCDIR([src/lapi.c])
++
++AM_INIT_AUTOMAKE([1.9 foreign])
++
++AC_PROG_CC
++AC_PROG_LIBTOOL
++
++AC_ARG_WITH(
++ [readline],
++ [AC_HELP_STRING([--with-readline], [Use readline for interpreter input [default=yes]])],
++ [use_readline=$withval],
++ [use_readline=yes]
++)
++
++LUA_LIBS="-lm"
++
++# Check for readline
++READLINE_DEFS="#undef LUA_USE_READLINE"
++if test "x$use_readline" == "xyes"; then
++ AC_CHECK_LIB([readline], [readline], [:], [use_readline=no], [-lncurses])
++ AC_CHECK_HEADERS([readline/readline.h readline/history.h], [], [use_readline=no])
++ if test "x$use_readline" == "xno"; then
++ AC_MSG_WARN([readline headers could not be found, disabling readline support])
++ else
++ READLINE_DEFS="#define LUA_USE_READLINE"
++ READLINE_LIBS="-lreadline -lncurses"
++ fi
++fi
++AC_SUBST(READLINE_DEFS)
++AC_SUBST(READLINE_LIBS)
++
++case "$host" in
++ *-mingw*) use_os=win32 ;;
++ *-darwin*) use_os=macosx ;;
++ *) use_os=posix ;;
++esac
++
++POSIX_DEFS="#undef LUA_USE_POSIX"
++LUA_DL_DEFS="#undef LUA_USE_DLOPEN"
++LUA_BUILD_AS_DLL_DEFS="#undef LUA_BUILD_AS_DLL"
++
++if test "x$use_os" == "xwin32"; then
++ LUA_BUILD_AS_DLL_DEFS="#define LUA_BUILD_AS_DLL"
++elif test "x$use_os" == "xmacosx"; then
++ POSIX_DEFS="#define LUA_USE_POSIX"
++ LUA_DL_DEFS="#define LUA_DL_DYLD"
++elif test "x$use_os" == "xposix"; then
++ POSIX_DEFS="#define LUA_USE_POSIX"
++ LUA_DL_DEFS="#define LUA_DL_DLOPEN"
++ LUA_LIBS="$LUA_LIBS -ldl"
++fi
++AC_SUBST(POSIX_DEFS)
++AC_SUBST(LUA_DL_DEFS)
++AC_SUBST(LUA_BUILD_AS_DLL_DEFS)
++
++AC_SUBST(LUA_LIBS)
++
++AC_CONFIG_FILES([Makefile
++ src/Makefile
++ src/lua.pc
++ src/luaconf.h.template
++ doc/Makefile
++])
++AC_OUTPUT
+diff -up lua-5.3.0/doc/Makefile.am.autoxxx lua-5.3.0/doc/Makefile.am
+--- lua-5.3.0/doc/Makefile.am.autoxxx 2015-01-15 10:20:03.826889574 -0500
++++ lua-5.3.0/doc/Makefile.am 2015-01-15 10:20:03.826889574 -0500
+@@ -0,0 +1,4 @@
++man1_MANS = lua.1 luac.1
++
++EXTRA_DIST = \
++ contents.html logo.gif lua.1 luac.1 lua.css manual.css manual.html osi-certified-72x60.png readme.html
+diff -up lua-5.3.0/Makefile.am.autoxxx lua-5.3.0/Makefile.am
+--- lua-5.3.0/Makefile.am.autoxxx 2015-01-15 10:20:03.826889574 -0500
++++ lua-5.3.0/Makefile.am 2015-01-15 10:20:03.826889574 -0500
+@@ -0,0 +1,3 @@
++SUBDIRS = src doc
++
++EXTRA_DIST = README
+diff -up lua-5.3.0/src/.gitignore.autoxxx lua-5.3.0/src/.gitignore
+--- lua-5.3.0/src/.gitignore.autoxxx 2015-01-15 10:20:03.826889574 -0500
++++ lua-5.3.0/src/.gitignore 2015-01-15 10:20:03.826889574 -0500
+@@ -0,0 +1,5 @@
++lua
++lua.pc
++luac
++luaconf.h
++luaconf.h.template
+diff -up lua-5.3.0/src/luaconf.h.template.in.autoxxx lua-5.3.0/src/luaconf.h.template.in
+--- lua-5.3.0/src/luaconf.h.template.in.autoxxx 2015-01-15 10:20:03.828889562 -0500
++++ lua-5.3.0/src/luaconf.h.template.in 2015-01-15 10:22:37.420027778 -0500
+@@ -11,6 +11,11 @@
+ #include <limits.h>
+ #include <stddef.h>
+
++@POSIX_DEFS@
++@LUA_DL_DEFS@
++@LUA_BUILD_AS_DLL_DEFS@
++@READLINE_DEFS@
++
+
+ /*
+ ** ===================================================================
+@@ -175,9 +180,9 @@
+
+ #else /* }{ */
+
+-#define LUA_ROOT "/usr/local/"
+-#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/"
+-#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/"
++#define LUA_ROOT "@prefix@/"
++#define LUA_LDIR "@pkgdatadir@/lua/" LUA_VDIR "/"
++#define LUA_CDIR "@libdir@/lua/" LUA_VDIR "/"
+ #define LUA_PATH_DEFAULT \
+ LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \
+diff -up lua-5.3.0/src/lua.pc.in.autoxxx lua-5.3.0/src/lua.pc.in
+--- lua-5.3.0/src/lua.pc.in.autoxxx 2015-01-15 10:20:03.827889568 -0500
++++ lua-5.3.0/src/lua.pc.in 2015-01-15 10:20:03.827889568 -0500
+@@ -0,0 +1,13 @@
++V= @MAJOR_VERSION@
++R= @VERSION@
++prefix= @prefix@
++exec_prefix=${prefix}
++libdir= @libdir@
++includedir=${prefix}/include
++
++Name: Lua
++Description: An Extensible Extension Language
++Version: ${R}
++Requires:
++Libs: -llua @LUA_LIBS@
++Cflags: -I${includedir}
+diff -up lua-5.3.0/src/Makefile.am.autoxxx lua-5.3.0/src/Makefile.am
+--- lua-5.3.0/src/Makefile.am.autoxxx 2015-01-15 10:20:03.826889574 -0500
++++ lua-5.3.0/src/Makefile.am 2015-01-15 10:20:03.826889574 -0500
+@@ -0,0 +1,46 @@
++AM_CFLAGS = -Wall
++
++include_HEADERS = lua.h lualib.h lauxlib.h lua.hpp
++
++nodist_include_HEADERS = luaconf.h
++
++lib_LTLIBRARIES = liblua.la
++liblua_la_LDFLAGS = -release @MAJOR_VERSION@
++liblua_la_SOURCES = \
++ lapi.c lauxlib.c lbaselib.c lbitlib.c lcode.c lcorolib.c lctype.c ldblib.c \
++ ldebug.c ldo.c ldump.c lfunc.c lgc.c linit.c liolib.c llex.c lmathlib.c lmem.c \
++ loadlib.c lobject.c lopcodes.c loslib.c lparser.c lstate.c lstring.c lstrlib.c \
++ ltable.c ltablib.c ltm.c lundump.c lutf8lib.c lvm.c lzio.c \
++ lapi.h lcode.h lctype.h ldebug.h ldo.h lfunc.h lgc.h llex.h llimits.h \
++ lmem.h lobject.h lopcodes.h lparser.h lstate.h lstring.h ltable.h ltm.h \
++ lundump.h lvm.h lzio.h
++
++pkgconfigdir = $(libdir)/pkgconfig
++pkgconfig_DATA = lua.pc
++
++bin_PROGRAMS = lua luac
++
++lua_SOURCES = lua.c
++lua_LDADD = liblua.la @LUA_LIBS@ @READLINE_LIBS@
++lua_DEPENDENCIES = liblua.la
++
++luac_SOURCES = luac.c
++# Statically link liblua against luac since luac uses symbols not exported in liblua
++luac_LDADD = .libs/liblua.a @LUA_LIBS@
++luac_DEPENDENCIES = liblua.la
++
++EXTRA_DIST = luaconf.h.template
++BUILT_SOURCES = luaconf.h
++CLEANFILES = luaconf.h luaconf.h.template
++
++readline_defs = @READLINE_DEFS@
++
++edit = sed \
++ -e 's,%prefix%,$(prefix),g' \
++ -e 's,%lua_datadir%,$(datadir),g' \
++ -e 's,%lua_libdir%,$(libdir),g'
++
++luaconf.h : luaconf.h.template
++ rm -f $@ $@.tmp
++ $(edit) $< >$@.tmp
++ mv $@.tmp $@
diff --git a/subprojects/shared-modules/lua5.3/lua-5.3.0-configure-compat-module.patch b/subprojects/shared-modules/lua5.3/lua-5.3.0-configure-compat-module.patch
new file mode 100644
index 00000000..bd5d41d4
--- /dev/null
+++ b/subprojects/shared-modules/lua5.3/lua-5.3.0-configure-compat-module.patch
@@ -0,0 +1,35 @@
+diff -up lua-5.2.2/configure.ac.compat-module lua-5.2.2/configure.ac
+--- lua-5.2.2/configure.ac.compat-module 2013-05-10 10:16:05.344137597 -0400
++++ lua-5.2.2/configure.ac 2013-05-10 10:16:05.357137596 -0400
+@@ -11,6 +11,20 @@ AC_PROG_CC
+ AC_PROG_LIBTOOL
+
+ AC_ARG_WITH(
++ [compat-module],
++ [AC_HELP_STRING([--with-compat-module], [Enable LUA_COMPAT_MODULE functions [default=no]])],
++ [use_compat_module=$withval],
++ [use_compat_module=no]
++)
++
++COMPAT_DEFS="#undef LUA_COMPAT_ALL"
++if test "x$use_compat_module" == "xyes"; then
++ COMPAT_DEFS="#define LUA_COMPAT_5_1
++#define LUA_COMPAT_5_2"
++fi
++AC_SUBST(COMPAT_DEFS)
++
++AC_ARG_WITH(
+ [readline],
+ [AC_HELP_STRING([--with-readline], [Use readline for interpreter input [default=yes]])],
+ [use_readline=$withval],
+diff -up lua-5.2.2/src/luaconf.h.template.in.compat-module lua-5.2.2/src/luaconf.h.template.in
+--- lua-5.2.2/src/luaconf.h.template.in.compat-module 2013-05-10 10:25:42.586116963 -0400
++++ lua-5.2.2/src/luaconf.h.template.in 2013-05-10 10:26:29.957115269 -0400
+@@ -15,6 +15,7 @@
+ @LUA_DL_DEFS@
+ @LUA_BUILD_AS_DLL_DEFS@
+ @READLINE_DEFS@
++@COMPAT_DEFS@
+
+
+ /*
diff --git a/subprojects/shared-modules/lua5.3/lua-5.3.0-idsize.patch b/subprojects/shared-modules/lua5.3/lua-5.3.0-idsize.patch
new file mode 100644
index 00000000..16107fe2
--- /dev/null
+++ b/subprojects/shared-modules/lua5.3/lua-5.3.0-idsize.patch
@@ -0,0 +1,12 @@
+diff -up lua-5.3.0/src/luaconf.h.template.in.idsize lua-5.3.0/src/luaconf.h.template.in
+--- lua-5.3.0/src/luaconf.h.template.in.idsize 2015-01-15 10:23:20.515801344 -0500
++++ lua-5.3.0/src/luaconf.h.template.in 2015-01-15 10:23:48.955651916 -0500
+@@ -693,7 +693,7 @@
+ @@ of a function in debug information.
+ ** CHANGE it if you want a different size.
+ */
+-#define LUA_IDSIZE 60
++#define LUA_IDSIZE 512
+
+
+ /*
diff --git a/subprojects/shared-modules/lua5.3/lua-5.3.5.json b/subprojects/shared-modules/lua5.3/lua-5.3.5.json
index c789fd65..fd5f2682 100644
--- a/subprojects/shared-modules/lua5.3/lua-5.3.5.json
+++ b/subprojects/shared-modules/lua5.3/lua-5.3.5.json
@@ -1,17 +1,7 @@
{
"name": "lua-5.3",
- "buildsystem": "simple",
- "build-commands": [
- "make -j $FLATPAK_BUILDER_N_JOBS CFLAGS=\"$CFLAGS -fPIC -DLUA_USE_LINUX\" linux",
- "make TO_LIB=liblua.so.5.3.5 INSTALL_TOP=$FLATPAK_DEST install",
- "ln -sf liblua.so.5.3.5 $FLATPAK_DEST/lib/liblua.so",
- "ln -sf liblua.so.5.3.5 $FLATPAK_DEST/lib/liblua.so.5.3",
- "make INSTALL_TOP=${FLATPAK_DEST} pc > lua.pc",
- "cat lua.pc.in >> lua.pc",
- "install -Dm644 lua.pc $FLATPAK_DEST/lib/pkgconfig/lua.pc",
- "ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua53.pc",
- "ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua5.3.pc",
- "ln -sf lua.pc $FLATPAK_DEST/lib/pkgconfig/lua-5.3.pc"
+ "config-opts": [
+ "--with-compat-module"
],
"sources": [
{
@@ -20,27 +10,25 @@
"sha256": "0c2eed3f960446e1a3e4b9a1ca2f3ff893b6ce41942cf54d5dd59ab4b3b058ac"
},
{
+ "type": "shell",
+ "commands": [ "mv src/luaconf.h src/luaconf.h.template.in" ]
+ },
+ {
"type": "patch",
- "path": "makefile-add-liblua.so-rule.patch"
+ "path": "lua-5.3.0-autotoolize.patch"
},
{
- "type": "file",
- "path": "lua.pc.in"
+ "type": "patch",
+ "path": "lua-5.3.0-idsize.patch"
+ },
+ {
+ "type": "patch",
+ "path": "lua-5.3.0-configure-compat-module.patch"
},
{
"type": "shell",
- "commands": [
- "sed -i \"s|/usr/local/|$FLATPAK_DEST/|;s|LUA_IDSIZE 60|LUA_IDSIZE 512|\" src/luaconf.h",
- "# Lua 5.3.5 has wrong release version in its Makefile. Fix it.",
- "sed 's/^R= \$V.4/R= \$V.5/' -i Makefile",
- "sed -i '12 a\\\\n#define LUA_COMPAT_5_1\\n#define LUA_COMPAT_5_2' src/luaconf.h"
- ]
+ "commands": [ "autoreconf -i" ]
}
],
- "cleanup": [
- "/bin",
- "/include",
- "/lib/pkgconfig",
- "/share/man"
- ]
+ "cleanup": [ "/bin", "/include", "/lib/pkgconfig", "/lib/*.a", "/lib/*.la", "/share/man" ]
}
diff --git a/subprojects/shared-modules/lua5.3/lua.pc.in b/subprojects/shared-modules/lua5.3/lua.pc.in
deleted file mode 100644
index 6698f8bc..00000000
--- a/subprojects/shared-modules/lua5.3/lua.pc.in
+++ /dev/null
@@ -1,8 +0,0 @@
-exec_prefix=${prefix}
-
-Name: Lua
-Description: An Extensible Extension Language
-Version: ${version}
-Requires:
-Libs: -L${libdir} -llua -lm
-Cflags: -I${includedir} \ No newline at end of file
diff --git a/subprojects/shared-modules/lua5.3/makefile-add-liblua.so-rule.patch b/subprojects/shared-modules/lua5.3/makefile-add-liblua.so-rule.patch
deleted file mode 100644
index f675d4d4..00000000
--- a/subprojects/shared-modules/lua5.3/makefile-add-liblua.so-rule.patch
+++ /dev/null
@@ -1,47 +0,0 @@
-diff --git a/Makefile b/Makefile
-index 7fa91c8..dccf485 100644
---- a/Makefile
-+++ b/Makefile
-@@ -52,7 +52,7 @@ R= $V.0
- all: $(PLAT)
-
- $(PLATS) clean:
-- cd src && $(MAKE) $@
-+ cd src && $(MAKE) $@ V=$(V) R=$(R)
-
- test: dummy
- src/lua -v
-diff --git a/src/Makefile b/src/Makefile
-index 2e7a412..fa5769f 100644
---- a/src/Makefile
-+++ b/src/Makefile
-@@ -29,6 +29,7 @@ MYOBJS=
- PLATS= aix bsd c89 freebsd generic linux macosx mingw posix solaris
-
- LUA_A= liblua.a
-+LUA_SO= liblua.so
- CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \
- lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
- ltm.o lundump.o lvm.o lzio.o
-@@ -43,7 +44,7 @@ LUAC_T= luac
- LUAC_O= luac.o
-
- ALL_O= $(BASE_O) $(LUA_O) $(LUAC_O)
--ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
-+ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T) $(LUA_SO)
- ALL_A= $(LUA_A)
-
- # Targets start here.
-@@ -59,6 +60,12 @@ $(LUA_A): $(BASE_O)
- $(AR) $@ $(BASE_O)
- $(RANLIB) $@
-
-+$(LUA_SO): $(CORE_O) $(LIB_O)
-+ $(CC) -shared -ldl -Wl,-soname,$(LUA_SO).$(V) -o $@.$(R) $? -lm $(MYLDFLAGS)
-+ ln -sf $(LUA_SO).$(R) $(LUA_SO).$(V)
-+ ln -sf $(LUA_SO).$(R) $(LUA_SO)
-+
-+
- $(LUA_T): $(LUA_O) $(LUA_A)
- $(CC) -o $@ $(LDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
- \ No newline at end of file
diff --git a/subprojects/shared-modules/python2.7/python-2.7.json b/subprojects/shared-modules/python2.7/python-2.7.json
index afdef902..14253764 100644
--- a/subprojects/shared-modules/python2.7/python-2.7.json
+++ b/subprojects/shared-modules/python2.7/python-2.7.json
@@ -3,8 +3,8 @@
"sources": [
{
"type": "archive",
- "url": "https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tar.xz",
- "sha256": "b62c0e7937551d0cc02b8fd5cb0f544f9405bafc9a54d3808ed4594812edef43"
+ "url": "https://www.python.org/ftp/python/2.7.17/Python-2.7.17.tar.xz",
+ "sha256": "4d43f033cdbd0aa7b7023c81b0e986fd11e653b5248dac9144d508f11812ba41"
}
],
"config-opts": [
diff --git a/subprojects/shared-modules/qt4/fixgcc9.patch b/subprojects/shared-modules/qt4/fixgcc9.patch
deleted file mode 100644
index 6501a83c..00000000
--- a/subprojects/shared-modules/qt4/fixgcc9.patch
+++ /dev/null
@@ -1,31 +0,0 @@
---- qt-everywhere-opensource-src-4.8.7/src/corelib/global/qglobal.h 2015-05-07 16:14:48.000000000 +0200
-+++ qt-everywhere-opensource-src-4.8.7-gcc9/src/corelib/global/qglobal.h 2020-05-28 16:24:45.160340385 +0200
-@@ -2482,22 +2482,22 @@
-
- #endif /* Q_NO_TYPESAFE_FLAGS */
-
--#if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && !defined(Q_CC_RVCT)
-+#if (defined(Q_CC_GNU) && !defined(Q_CC_RVCT))
- /* make use of typeof-extension */
- template <typename T>
- class QForeachContainer {
- public:
-- inline QForeachContainer(const T& t) : c(t), brk(0), i(c.begin()), e(c.end()) { }
-+ inline QForeachContainer(const T& t) : c(t), i(c.begin()), e(c.end()), control(1) { }
- const T c;
-- int brk;
- typename T::const_iterator i, e;
-+ int control;
- };
-
- #define Q_FOREACH(variable, container) \
- for (QForeachContainer<__typeof__(container)> _container_(container); \
-- !_container_.brk && _container_.i != _container_.e; \
-- __extension__ ({ ++_container_.brk; ++_container_.i; })) \
-- for (variable = *_container_.i;; __extension__ ({--_container_.brk; break;}))
-+ _container_.control && _container_.i != _container_.e; \
-+ ++_container_.i, _container_.control ^= 1) \
-+ for (variable = *_container_.i; _container_.control; _container_.control = 0)
-
- #else
-
diff --git a/subprojects/shared-modules/qt4/qt4-4.8.7-minimal.json b/subprojects/shared-modules/qt4/qt4-4.8.7-minimal.json
index f0a192cf..fe7b74a4 100644
--- a/subprojects/shared-modules/qt4/qt4-4.8.7-minimal.json
+++ b/subprojects/shared-modules/qt4/qt4-4.8.7-minimal.json
@@ -77,10 +77,6 @@
"path": "disable-sslv3.patch"
},
{
- "type": "patch",
- "path": "fixgcc9.patch"
- },
- {
"type": "shell",
"commands": [
"sed -i \"s|-O2|${CXXFLAGS}|\" mkspecs/common/{g++,gcc}-base.conf",