diff options
author | Simon McVittie <smcv@debian.org> | 2020-09-18 09:10:05 +0100 |
---|---|---|
committer | Simon McVittie <smcv@debian.org> | 2020-09-18 09:10:05 +0100 |
commit | 394bfdcf06d34d836d0991ce79ab2f9e48c8bcc7 (patch) | |
tree | 15276ec0f4ad5f44ddeaeafd98011ce803efbc59 | |
parent | 53af09494d1c7b1dca4d98662380383bf84ad7a7 (diff) | |
parent | 9214c96178439e8c02fcaa4d81c5a8a1fbeaaf6e (diff) |
New upstream version 3.38.0
166 files changed, 6708 insertions, 7075 deletions
@@ -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 @@ -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 @@ -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çó" @@ -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" @@ -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" @@ -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" @@ -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] "{} Ï„ÏαγοÏδι" @@ -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" @@ -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 {}" @@ -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] "{} آهنگ" @@ -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" @@ -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" @@ -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" @@ -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" @@ -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" @@ -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" @@ -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" @@ -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" @@ -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 "å†ç”Ÿä¸ã®æ›²ã®é€šçŸ¥ã‚’有効ã«ã™ã‚‹ã‹ã©ã†ã‹ã®è¨å®šã§ã™ã€‚" @@ -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] "{} өлең" @@ -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] "노래 {}곡" @@ -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" @@ -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@" @@ -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" @@ -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" @@ -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" @@ -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" @@ -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" @@ -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" @@ -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] "{} пеÑма" @@ -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" @@ -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" @@ -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", |