Hello community, here is the log from the commit of package lollypop for openSUSE:Factory checked in at 2015-12-09 19:51:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/lollypop (Old) and /work/SRC/openSUSE:Factory/.lollypop.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "lollypop" Changes: -------- --- /work/SRC/openSUSE:Factory/lollypop/lollypop.changes 2015-12-01 09:19:11.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.lollypop.new/lollypop.changes 2015-12-09 22:24:20.000000000 +0100 @@ -1,0 +2,12 @@ +Sat Dec 5 11:01:42 UTC 2015 - badshah...@gmail.com + +- Update to version 0.9.74: + + Fix issue in scanner. +- Changes from version 0.9.72: + + Handle artist sort order tag. + + Fix search dialog. + + Allow popover in search dialog (Gtk 3.18). +- Changes from version 0.9.71: + + Fix issue in fullscreen. + +------------------------------------------------------------------- Old: ---- lollypop-0.9.70.tar.xz New: ---- lollypop-0.9.74.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ lollypop.spec ++++++ --- /var/tmp/diff_new_pack.NhtbiM/_old 2015-12-09 22:24:21.000000000 +0100 +++ /var/tmp/diff_new_pack.NhtbiM/_new 2015-12-09 22:24:21.000000000 +0100 @@ -22,7 +22,7 @@ Name: lollypop Summary: GNOME music playing application License: GPL-3.0+ -Version: 0.9.70 +Version: 0.9.74 Release: 0 Url: https://github.com/gnumdk/lollypop Source0: https://github.com/gnumdk/lollypop/releases/download/%{version}/%{name}-%{version}.tar.xz ++++++ lollypop-0.9.70.tar.xz -> lollypop-0.9.74.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/Makefile.in new/lollypop-0.9.74/Makefile.in --- old/lollypop-0.9.70/Makefile.in 2015-11-25 16:42:35.000000000 +0100 +++ new/lollypop-0.9.74/Makefile.in 2015-12-04 09:18:38.000000000 +0100 @@ -195,7 +195,8 @@ DIST_SUBDIRS = $(SUBDIRS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/config.h.in AUTHORS \ COPYING ChangeLog INSTALL NEWS README TODO compile \ - config.guess config.sub install-sh ltmain.sh missing + config.guess config.sub install-sh ltmain.sh missing \ + py-compile DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/configure new/lollypop-0.9.74/configure --- old/lollypop-0.9.70/configure 2015-11-25 16:42:33.000000000 +0100 +++ new/lollypop-0.9.74/configure 2015-12-04 09:18:39.000000000 +0100 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for lollypop 0.9.70. +# Generated by GNU Autoconf 2.69 for lollypop 0.9.74. # # Report bugs to <https://github.com/gnumdk/lollypop>. # @@ -590,8 +590,8 @@ # Identity of this package. PACKAGE_NAME='lollypop' PACKAGE_TARNAME='lollypop' -PACKAGE_VERSION='0.9.70' -PACKAGE_STRING='lollypop 0.9.70' +PACKAGE_VERSION='0.9.74' +PACKAGE_STRING='lollypop 0.9.74' PACKAGE_BUGREPORT='https://github.com/gnumdk/lollypop' PACKAGE_URL='https://github.com/gnumdk/lollypop' @@ -1396,7 +1396,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures lollypop 0.9.70 to adapt to many kinds of systems. +\`configure' configures lollypop 0.9.74 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1466,7 +1466,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of lollypop 0.9.70:";; + short | recursive ) echo "Configuration of lollypop 0.9.74:";; esac cat <<\_ACEOF @@ -1589,7 +1589,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -lollypop configure 0.9.70 +lollypop configure 0.9.74 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1867,7 +1867,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by lollypop $as_me 0.9.70, which was +It was created by lollypop $as_me 0.9.74, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2734,7 +2734,7 @@ # Define the identity of the package. PACKAGE='lollypop' - VERSION='0.9.70' + VERSION='0.9.74' cat >>confdefs.h <<_ACEOF @@ -13838,7 +13838,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by lollypop $as_me 0.9.70, which was +This file was extended by lollypop $as_me 0.9.74, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -13905,7 +13905,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -lollypop config.status 0.9.70 +lollypop config.status 0.9.74 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/configure.ac new/lollypop-0.9.74/configure.ac --- old/lollypop-0.9.70/configure.ac 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/configure.ac 2015-12-04 09:17:53.000000000 +0100 @@ -1,6 +1,6 @@ AC_PREREQ(2.63) AC_INIT([lollypop], - [0.9.70], + [0.9.74], [https://github.com/gnumdk/lollypop], [lollypop], [https://github.com/gnumdk/lollypop]) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/data/AboutDialog.ui new/lollypop-0.9.74/data/AboutDialog.ui --- old/lollypop-0.9.70/data/AboutDialog.ui 2015-11-25 16:42:43.000000000 +0100 +++ new/lollypop-0.9.74/data/AboutDialog.ui 2015-12-04 09:18:45.000000000 +0100 @@ -7,7 +7,7 @@ <property name="modal">True</property> <property name="type_hint">normal</property> <property name="program_name">Lollypop</property> - <property name="version">0.9.70</property> + <property name="version">0.9.74</property> <property name="copyright">Copyright © 2014-2015 Cédric Bellegarde</property> <property name="comments" translatable="yes">A music player for GNOME.</property> <property name="website">https://github.com/gnumdk/lollypop</property> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/data/SettingsDialog.ui new/lollypop-0.9.74/data/SettingsDialog.ui --- old/lollypop-0.9.70/data/SettingsDialog.ui 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/data/SettingsDialog.ui 2015-12-03 16:35:34.000000000 +0100 @@ -5,12 +5,12 @@ <object class="GtkHeaderBar" id="header_bar"> <property name="visible">True</property> <property name="can_focus">False</property> - <property name="title">Preferences</property> + <property name="title" translatable="yes">Preferences</property> <property name="show_close_button">True</property> </object> <object class="GtkWindow" id="settings_dialog"> - <property name="can_focus">False</property> <property name="title" translatable="yes">Preferences</property> + <property name="can_focus">False</property> <property name="modal">True</property> <property name="window_position">center-on-parent</property> <property name="default_width">600</property> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/collectionscanner.py new/lollypop-0.9.74/src/collectionscanner.py --- old/lollypop-0.9.70/src/collectionscanner.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/collectionscanner.py 2015-12-02 12:34:15.000000000 +0100 @@ -221,6 +221,7 @@ title = self.get_title(tags, filepath) artists = self.get_artists(tags) + sortname = self.get_artist_sortname(tags) album_artist = self.get_album_artist(tags) album_name = self.get_album_name(tags) genres = self.get_genres(tags) @@ -230,12 +231,13 @@ duration = int(infos.get_duration()/1000000000) (artist_ids, new_artist_ids) = self.add_artists(artists, - album_artist) - + album_artist, + sortname) (album_artist_id, new) = self.add_album_artist(album_artist) if new: new_artist_ids.append(album_artist_id) + # Check for album artist, if none, use first available artist no_album_artist = False if album_artist_id is None: album_artist_id = artist_ids[0] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/container.py new/lollypop-0.9.74/src/container.py --- old/lollypop-0.9.70/src/container.py 2015-11-25 17:01:21.000000000 +0100 +++ new/lollypop-0.9.74/src/container.py 2015-12-02 12:34:15.000000000 +0100 @@ -280,8 +280,6 @@ vgrid.add(self._progress) vgrid.show() - separator = Gtk.Separator() - separator.show() self._paned_list_view.add1(self._list_two) self._paned_list_view.add2(vgrid) self._paned_main_list.add1(self._list_one) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/database.py new/lollypop-0.9.74/src/database.py --- old/lollypop-0.9.70/src/database.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/database.py 2015-12-02 12:34:15.000000000 +0100 @@ -40,7 +40,8 @@ popularity INT NOT NULL, mtime INT NOT NULL)''' create_artists = '''CREATE TABLE artists (id INTEGER PRIMARY KEY, - name TEXT NOT NULL)''' + name TEXT NOT NULL, + sortname TEXT NOT NULL)''' create_genres = '''CREATE TABLE genres (id INTEGER PRIMARY KEY, name TEXT NOT NULL)''' create_album_genres = '''CREATE TABLE album_genres ( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/database_albums.py new/lollypop-0.9.74/src/database_albums.py --- old/lollypop-0.9.70/src/database_albums.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/database_albums.py 2015-12-02 12:34:15.000000000 +0100 @@ -16,7 +16,6 @@ from lollypop.sqlcursor import SqlCursor from lollypop.define import Lp, Type -from lollypop.utils import translate_artist_name class AlbumsDatabase: @@ -282,7 +281,7 @@ artists.rowid", (album_id,)) v = result.fetchone() if v is not None: - return translate_artist_name(v[0]) + return v[0] return _("Compilation") @@ -575,21 +574,23 @@ result = [] # Get albums for all artists if artist_id is None and genre_id is None: - result = sql.execute("SELECT albums.rowid FROM albums, artists\ - WHERE artists.rowid=albums.artist_id\ - ORDER BY artists.name COLLATE NOCASE,\ - albums.year,\ - albums.name COLLATE NOCASE") + result = sql.execute( + "SELECT albums.rowid FROM albums, artists\ + WHERE artists.rowid=albums.artist_id\ + ORDER BY artists.sortname COLLATE NOCASE,\ + albums.year,\ + albums.name COLLATE NOCASE") # Get albums for genre elif artist_id is None: - result = sql.execute("SELECT albums.rowid FROM albums,\ - album_genres, artists\ - WHERE album_genres.genre_id=?\ - AND artists.rowid=artist_id\ - AND album_genres.album_id=albums.rowid\ - ORDER BY artists.name COLLATE NOCASE,\ - albums.year,\ - albums.name COLLATE NOCASE", (genre_id,)) + result = sql.execute( + "SELECT albums.rowid FROM albums,\ + album_genres, artists\ + WHERE album_genres.genre_id=?\ + AND artists.rowid=artist_id\ + AND album_genres.album_id=albums.rowid\ + ORDER BY artists.sortname COLLATE NOCASE,\ + albums.year,\ + albums.name COLLATE NOCASE", (genre_id,)) # Get albums for artist elif genre_id is None: result = sql.execute("SELECT rowid FROM albums\ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/database_artists.py new/lollypop-0.9.74/src/database_artists.py --- old/lollypop-0.9.70/src/database_artists.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/database_artists.py 2015-12-02 12:34:15.000000000 +0100 @@ -15,7 +15,7 @@ from lollypop.sqlcursor import SqlCursor from lollypop.define import Lp, Type -from lollypop.utils import translate_artist_name, format_artist_name +from lollypop.utils import format_artist_name class ArtistsDatabase: @@ -29,18 +29,49 @@ """ pass - def add(self, name): + def add(self, name, sortname): """ Add a new artist to database - @param Artist name as string + @param artist name as string + @param sortname as string @return inserted rowid as int @warning: commit needed """ + if sortname == "": + sortname = format_artist_name(name) with SqlCursor(Lp().db) as sql: - result = sql.execute("INSERT INTO artists (name) VALUES (?)", - (name,)) + result = sql.execute("INSERT INTO artists (name, sortname)\ + VALUES (?, ?)", + (name, sortname)) return result.lastrowid + def set_sortname(self, artist_id, sortname): + """ + Set sort name + @param id as int + @param sort name a str + @warning: commit needed + """ + with SqlCursor(Lp().db) as sql: + result = sql.execute("UPDATE artists\ + SET sortname=?\ + WHERE rowid=?", + (sortname, artist_id)) + + def get_sortname(self, artist_id): + """ + Return sortname + @param artist id as int + @return sortname as string + """ + with SqlCursor(Lp().db) as sql: + result = sql.execute("SELECT sortname from artists\ + WHERE rowid=?", (artist_id,)) + v = result.fetchone() + if v is not None: + return v[0] + return self.get_name(artist_id) + def get_id(self, name): """ Get artist id @@ -69,7 +100,7 @@ (artist_id,)) v = result.fetchone() if v is not None: - return translate_artist_name(v[0]) + return v[0] return _("Unknown") def get_albums(self, artist_id): @@ -111,11 +142,12 @@ result = [] if genre_id == Type.ALL or genre_id is None: # Only artist that really have an album - result = sql.execute("SELECT DISTINCT artists.rowid,\ - artists.name\ - FROM artists, albums\ - WHERE albums.artist_id = artists.rowid\ - ORDER BY artists.name COLLATE NOCASE") + result = sql.execute( + "SELECT DISTINCT artists.rowid,\ + artists.name\ + FROM artists, albums\ + WHERE albums.artist_id = artists.rowid\ + ORDER BY artists.sortname COLLATE NOCASE") else: result = sql.execute("SELECT DISTINCT artists.rowid,\ artists.name\ @@ -123,9 +155,9 @@ WHERE artists.rowid == albums.artist_id\ AND album_genres.genre_id=?\ AND album_genres.album_id=albums.rowid\ - ORDER BY artists.name\ + ORDER BY artists.sortname\ COLLATE NOCASE", (genre_id,)) - return [(row[0], translate_artist_name(row[1])) for row in result] + return [(row[0], row[1]) for row in result] def exists(self, artist_id): """ @@ -149,9 +181,7 @@ with SqlCursor(Lp().db) as sql: result = sql.execute("SELECT rowid FROM artists\ WHERE name LIKE ?\ - LIMIT 25", ('%' + - format_artist_name(string) + - '%',)) + LIMIT 25", ('%' + string + '%',)) return list(itertools.chain(*result)) def count(self): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/database_tracks.py new/lollypop-0.9.74/src/database_tracks.py --- old/lollypop-0.9.70/src/database_tracks.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/database_tracks.py 2015-12-02 12:34:15.000000000 +0100 @@ -17,7 +17,6 @@ from lollypop.sqlcursor import SqlCursor from lollypop.define import Lp, Type -from lollypop.utils import translate_artist_name class TracksDatabase: @@ -150,7 +149,7 @@ """ with SqlCursor(Lp().db) as sql: result = sql.execute("SELECT rowid FROM tracks\ - WHERE name =?\ + WHERE name = ?\ AND album_id = ?", (name, album_id)) v = result.fetchone() @@ -251,7 +250,7 @@ WHERE track_artists.track_id=?\ AND track_artists.artist_id=artists.rowid", (track_id,)) - artists = [translate_artist_name(row[0]) for row in result] + artists = [row[0] for row in result] return ", ".join(artists) def get_genre_ids(self, track_id): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/database_upgrade.py new/lollypop-0.9.74/src/database_upgrade.py --- old/lollypop-0.9.70/src/database_upgrade.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/database_upgrade.py 2015-12-02 12:34:15.000000000 +0100 @@ -1,4 +1,3 @@ -#!/usr/bin/python # Copyright (c) 2014-2015 Cedric Bellegarde <cedric.bellega...@adishatz.org> # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -12,6 +11,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. from lollypop.sqlcursor import SqlCursor +from lollypop.utils import translate_artist_name class DatabaseUpgrade: @@ -30,8 +30,9 @@ # Here are schema upgrade, key is database version, # value is sql request self._UPGRADES = { - 1: "update tracks set duration=CAST(duration as INTEGER);", - 2: "update albums set artist_id=-2001 where artist_id=-999;" + 1: "UPDATE tracks SET duration=CAST(duration as INTEGER);", + 2: "UPDATE albums SET artist_id=-2001 where artist_id=-999;", + 3: self._upgrade_3 } """ @@ -49,8 +50,31 @@ with SqlCursor(self._db) as sql: for i in range(self._version+1, len(self._UPGRADES)+1): try: - sql.execute(self._UPGRADES[i]) + if isinstance(self._UPGRADES[i], str): + sql.execute(self._UPGRADES[i]) + else: + self._UPGRADES[i]() except Exception as e: print("Database upgrade failed: ", e) sql.commit() return len(self._UPGRADES) + +####################### +# PRIVATE # +####################### + def _upgrade_3(self): + """ + Add a sorted field to artists + """ + with SqlCursor(self._db) as sql: + sql.execute("ALTER TABLE artists ADD sortname TEXT") + result = sql.execute("SELECT DISTINCT artists.rowid,\ + artists.name\ + FROM artists") + for row in result: + translated = translate_artist_name(row[1]) + sql.execute("UPDATE artists SET name=? WHERE rowid=?", + (translated, row[0])) + sql.execute("UPDATE artists SET sortname=? WHERE rowid=?", + (row[1], row[0])) + sql.commit() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/fullscreen.py new/lollypop-0.9.74/src/fullscreen.py --- old/lollypop-0.9.70/src/fullscreen.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/fullscreen.py 2015-12-02 12:34:15.000000000 +0100 @@ -44,6 +44,16 @@ builder.add_from_resource('/org/gnome/Lollypop/FullScreen.ui') builder.connect_signals(self) + # Calculate cover size + screen = Gdk.Screen.get_default() + monitor = screen.get_primary_monitor() + geometry = screen.get_monitor_geometry(monitor) + # We want 500 and 200 in full hd + if geometry.width > geometry.height: + self._artsize = int(ArtSize.MONSTER*geometry.width/1920) + else: + self._artsize = int(ArtSize.MONSTER*geometry.height/1920) + self._play_btn = builder.get_object('play_btn') self._next_btn = builder.get_object('next_btn') self._prev_btn = builder.get_object('prev_btn') @@ -75,11 +85,14 @@ self._on_current_changed) self._signal2_id = Lp().player.connect('status-changed', self._on_status_changed) - if is_playing: - self._change_play_btn_status(self._pause_image, _('Pause')) - self._on_current_changed(Lp().player) - else: + if Lp().player.current_track is None: Lp().player.set_party(True) + else: + if is_playing: + self._change_play_btn_status(self._pause_image, _('Pause')) + else: + self._on_status_changed(Lp().player) + self._on_current_changed(Lp().player) if self._timeout1 is None: self._timeout1 = GLib.timeout_add(1000, self._update_position) Gtk.Window.do_show(self) @@ -175,14 +188,14 @@ self._progress.hide() surface = Lp().art.get_radio_artwork( player.current_track.artist, - ArtSize.MONSTER*self.get_scale_factor()) + self._artsize*self.get_scale_factor()) else: self._timelabel.show() self._total_time_label.show() self._progress.show() surface = Lp().art.get_album_artwork( player.current_track.album, - ArtSize.MONSTER*self.get_scale_factor()) + self._artsize*self.get_scale_factor()) self._cover.set_from_surface(surface) del surface diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/mpd.py new/lollypop-0.9.74/src/mpd.py --- old/lollypop-0.9.70/src/mpd.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/mpd.py 2015-12-02 12:34:15.000000000 +0100 @@ -21,7 +21,7 @@ from lollypop.define import Lp, Type from lollypop.objects import Track from lollypop.database_mpd import MpdDatabase -from lollypop.utils import translate_artist_name, format_artist_name, get_ip +from lollypop.utils import get_ip class MpdHandler(socketserver.StreamRequestHandler): @@ -161,7 +161,7 @@ if args[i].lower() == 'album': album = args[i+1] elif args[i].lower() == 'artist': - artist = format_artist_name(args[i+1]) + artist = args[i+1] elif args[i].lower() == 'genre': genre = args[i+1] elif args[i].lower() == 'date': @@ -330,10 +330,10 @@ if i % 2: album = args[i+1] else: - artist = format_artist_name(args[i+1]) + artist = args[i+1] elif args[i].lower() == 'artist' or\ args[i].lower() == 'albumartist': - artist = format_artist_name(args[i+1]) + artist = args[i+1] elif args[i].lower() == 'genre': genre = args[i+1] elif args[i].lower() == 'date': @@ -361,7 +361,7 @@ msg += "Album: "+album+"\n" elif args[0].lower() == 'artist': for artist in self.server.mpddb.get_artists_names(genre_id): - msg += "Artist: "+translate_artist_name(artist)+"\n" + msg += "Artist: "+artist+"\n" elif args[0].lower() == 'genre': results = Lp().genres.get_names() for name in results: @@ -396,9 +396,9 @@ msg += "file: %s\nArtist: %s\nAlbum: %s\nAlbumArtist: %s\ \nTitle: %s\nDate: %s\nGenre: %s\nTime: %s\nId: %s\nPos: %s\nTrack: %s\n" % ( path, - translate_artist_name(artist), + artist, album, - translate_artist_name(album_artist), + album_artist, title, date, genre, @@ -919,7 +919,7 @@ album = args[i+1] elif args[i].lower() == 'artist' or\ args[i].lower() == 'albumartist': - artist = format_artist_name(args[i+1]) + artist = args[i+1] elif args[i].lower() == 'genre': genre = args[i+1] elif args[i].lower() == 'date': @@ -1158,7 +1158,7 @@ album = args[i+1] elif args[i].lower() == 'artist' or\ args[i].lower() == 'albumartist': - artist = format_artist_name(args[i+1]) + artist = args[i+1] elif args[i].lower() == 'genre': genre = args[i+1] elif args[i].lower() == 'date': diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/player_rg.py new/lollypop-0.9.74/src/player_rg.py --- old/lollypop-0.9.70/src/player_rg.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/player_rg.py 2015-12-02 12:34:15.000000000 +0100 @@ -47,9 +47,10 @@ print("please check your gstreamer installation...") return - self._rgvolume.props.album_mode = 1 - self._rgvolume.props.pre_amp = Lp().settings.get_value( - "replaygain").get_double() + if self._rgvolume is not None: + self._rgvolume.props.album_mode = 1 + self._rgvolume.props.pre_amp = Lp().settings.get_value( + "replaygain").get_double() self._rgfilter.add(self._rgvolume) self._rgfilter.add(self._rg_audioconvert1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/player_shuffle.py new/lollypop-0.9.74/src/player_shuffle.py --- old/lollypop-0.9.70/src/player_shuffle.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/player_shuffle.py 2015-12-02 12:34:15.000000000 +0100 @@ -103,11 +103,12 @@ """ self.reset_history() - if party: - self.context.next = NextContext.NONE - self._rgvolume.props.album_mode = 0 - else: - self._rgvolume.props.album_mode = 1 + if self._rgvolume is not None: + if party: + self.context.next = NextContext.NONE + self._rgvolume.props.album_mode = 0 + else: + self._rgvolume.props.album_mode = 1 self._is_party = party @@ -152,11 +153,12 @@ """ self._shuffle = Lp().settings.get_enum('shuffle') - if self._shuffle in [Shuffle.TRACKS, Shuffle.TRACKS_ARTIST] or\ - self._user_playlist: - self._rgvolume.props.album_mode = 0 - else: - self._rgvolume.props.album_mode = 1 + if self._rgvolume is not None: + if self._shuffle in [Shuffle.TRACKS, Shuffle.TRACKS_ARTIST] or\ + self._user_playlist: + self._rgvolume.props.album_mode = 0 + else: + self._rgvolume.props.album_mode = 1 if self._user_playlist: self._shuffle_playlist() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/pop_externals.py new/lollypop-0.9.74/src/pop_externals.py --- old/lollypop-0.9.70/src/pop_externals.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/pop_externals.py 2015-12-03 16:15:31.000000000 +0100 @@ -27,6 +27,7 @@ Init popover """ Gtk.Popover.__init__(self) + self.set_position(Gtk.PositionType.BOTTOM) self.connect('unmap', self._on_self_unmap) builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/ExternalsPopover.ui') diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/pop_infos.py new/lollypop-0.9.74/src/pop_infos.py --- old/lollypop-0.9.70/src/pop_infos.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/pop_infos.py 2015-12-03 16:30:38.000000000 +0100 @@ -55,7 +55,8 @@ @param artist id as int @param show albums as bool """ - Gtk.Bin.__init__(self) + Gtk.Popover.__init__(self) + self.set_position(Gtk.PositionType.BOTTOM) self.connect('map', self._on_self_map) self.connect('unmap', self._on_self_unmap) self._artist_id = artist_id @@ -82,15 +83,20 @@ self._stack.get_child_by_name('wikia').destroy() if InfosPopover.WebView is None: self._stack.get_child_by_name('duck').destroy() + self._stack.set_visible_child_name( + Lp().settings.get_value('infoswitch').get_string()) + def do_show(self): + """ + Set widget size + """ size_setting = Lp().settings.get_value('window-size') if isinstance(size_setting[1], int): self.set_size_request(size_setting[0]*0.6, size_setting[1]*0.7) else: self.set_size_request(700, 600) - self._stack.set_visible_child_name( - Lp().settings.get_value('infoswitch').get_string()) + Gtk.Popover.do_show(self) def do_get_preferred_width(self): """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/pop_menu.py new/lollypop-0.9.74/src/pop_menu.py --- old/lollypop-0.9.70/src/pop_menu.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/pop_menu.py 2015-12-02 12:34:15.000000000 +0100 @@ -10,12 +10,14 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -from gi.repository import Gio, GLib +from gi.repository import Gio, GLib, Gtk from shutil import which from gettext import gettext as _ from threading import Thread +from lollypop.widgets_rating import RatingWidget +from lollypop.widgets_loved import LovedWidget from lollypop.define import Lp, NextContext from lollypop.objects import Track from lollypop import utils @@ -354,18 +356,17 @@ Contextual menu for toolbar """ - def __init__(self, object_id, genre_id): + def __init__(self, object_id): """ Init menu model @param object id as int - @param genre id as int """ Gio.Menu.__init__(self) if not Lp().player.is_party(): self.insert_section(0, _("Playback"), PlaybackMenu()) self.insert_section(1, _("Playlists"), - PlaylistsMenu(object_id, genre_id, False)) + PlaylistsMenu(object_id, None, False)) class EditMenu(BaseMenu): @@ -449,17 +450,69 @@ class TrackMenu(Gio.Menu): """ - Contextual menu for track + Contextual menu for a track """ - def __init__(self, object_id, genre_id): + def __init__(self, object_id): """ Init menu model @param object id as int - @param genre id as int """ Gio.Menu.__init__(self) self.insert_section(0, _("Queue"), - QueueMenu(object_id, genre_id, False)) + QueueMenu(object_id, None, False)) self.insert_section(1, _("Playlists"), - PlaylistsMenu(object_id, genre_id, False)) + PlaylistsMenu(object_id, None, False)) + + +class TrackMenuPopover(Gtk.Popover): + """ + Contextual menu widget for a track + """ + + def __init__(self, object_id, menu): + """ + Init widget + @param object id as int + @param menu as Gio.Menu + """ + Gtk.Popover.__init__(self) + self.bind_model(menu, None) + + rating = RatingWidget(Track(object_id)) + rating.set_margin_top(5) + rating.set_margin_bottom(5) + rating.set_property('halign', Gtk.Align.START) + rating.set_property('hexpand', True) + rating.show() + + loved = LovedWidget(object_id) + loved.set_margin_end(5) + loved.set_margin_top(5) + loved.set_margin_bottom(5) + loved.set_property('halign', Gtk.Align.END) + loved.set_property('hexpand', True) + loved.show() + + # Hack to add two widgets in popover + # Use a Gtk.PopoverMenu later (GTK>3.16 available on Debian stable) + grid = Gtk.Grid() + grid.set_orientation(Gtk.Orientation.VERTICAL) + + stack = Gtk.Stack() + stack.add_named(grid, 'main') + stack.show_all() + + menu_widget = self.get_child() + menu_widget.reparent(grid) + + separator = Gtk.Separator() + separator.show() + + grid.add(separator) + hgrid = Gtk.Grid() + hgrid.add(rating) + hgrid.add(loved) + hgrid.show() + grid.add(hgrid) + self.add(stack) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/pop_queue.py new/lollypop-0.9.74/src/pop_queue.py --- old/lollypop-0.9.70/src/pop_queue.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/pop_queue.py 2015-12-03 16:29:21.000000000 +0100 @@ -29,6 +29,7 @@ Init Popover """ Gtk.Popover.__init__(self) + self.set_position(Gtk.PositionType.BOTTOM) self.connect('map', self._on_map) self.connect('unmap', self._on_unmap) self._timeout = None @@ -74,11 +75,16 @@ self.add(self._widget) + def do_show(self): + """ + Set widget size + """ size_setting = Lp().settings.get_value('window-size') if isinstance(size_setting[1], int): - self.set_size_request(420, size_setting[1]*0.7) + self.set_size_request(400, size_setting[1]*0.7) else: - self.set_size_request(420, 600) + self.set_size_request(400, 600) + Gtk.Popover.do_show(self) def populate(self): """ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/pop_search.py new/lollypop-0.9.74/src/pop_search.py --- old/lollypop-0.9.70/src/pop_search.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/pop_search.py 2015-12-03 16:29:09.000000000 +0100 @@ -17,6 +17,8 @@ from lollypop.define import Lp, ArtSize, Type from lollypop.objects import Track, Album +from lollypop.pop_menu import TrackMenuPopover, TrackMenu +from lollypop.widgets_album_context import AlbumPopoverWidget class SearchRow(Gtk.ListBoxRow): @@ -88,7 +90,6 @@ @param button as Gtk.Button """ Lp().window.show_playlist_manager(self.id, None, not self.is_track) - self._parent.hide() def _on_queue_clicked(self, button): """ @@ -145,6 +146,7 @@ @param parent as Gtk.Widget """ Gtk.Popover.__init__(self) + self.set_position(Gtk.PositionType.BOTTOM) self.connect('map', self._on_map) self.connect('unmap', self._on_unmap) self._parent = parent @@ -161,17 +163,23 @@ self._new_btn = builder.get_object('new_btn') self._view = Gtk.ListBox() + self._view.connect("button-press-event", self._on_button_press) self._view.connect("row-activated", self._on_activate) self._view.show() builder.get_object('scrolled').add(self._view) self.add(builder.get_object('widget')) + def do_show(self): + """ + Set widget size + """ size_setting = Lp().settings.get_value('window-size') if isinstance(size_setting[1], int): self.set_size_request(400, size_setting[1]*0.7) else: self.set_size_request(400, 600) + Gtk.Popover.do_show(self) ####################### # PRIVATE # @@ -314,7 +322,7 @@ track_id = object_id elif track_id is None: track_id = tracks[0].id - GLib.idle_add(self._set_user_playlist, tracks, track_id) + GLib.idle_add(self._set_user_playlist_by_tracks, tracks, track_id) def _new_playlist(self): """ @@ -383,17 +391,6 @@ t.daemon = True t.start() - def _on_activate(self, widget, row): - """ - Play searched item when selected - If item is an album, play first track - @param widget as Gtk.ListBox - @param row as SearchRow - """ - t = Thread(target=self._play_search, args=(row.id, row.is_track)) - t.daemon = True - t.start() - def _on_play_btn_clicked(self, button): """ Start playback base on current search @@ -411,3 +408,38 @@ t = Thread(target=self._new_playlist) t.daemon = True t.start() + + def _on_activate(self, widget, row): + """ + Play searched item when selected + If item is an album, play first track + @param widget as Gtk.ListBox + @param row as SearchRow + """ + t = Thread(target=self._play_search, args=(row.id, row.is_track)) + t.daemon = True + t.start() + + def _on_button_press(self, widget, event): + """ + Store pressed button + @param widget as Gtk.ListBox + @param event as Gdk.EventButton + """ + if event.button != 1 and\ + Gtk.get_minor_version() > 16: + rect = widget.get_allocation() + rect.x = event.x + rect.y = event.y + rect.width = rect.height = 1 + row = widget.get_row_at_y(event.y) + if row.is_track: + popover = TrackMenuPopover(row.id, TrackMenu(row.id)) + popover.set_relative_to(widget) + popover.set_pointing_to(rect) + popover.show() + else: + popover = AlbumPopoverWidget(row.id, None) + popover.set_relative_to(widget) + popover.set_pointing_to(rect) + popover.show() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/selectionlist.py new/lollypop-0.9.74/src/selectionlist.py --- old/lollypop-0.9.70/src/selectionlist.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/selectionlist.py 2015-12-02 12:34:15.000000000 +0100 @@ -14,7 +14,6 @@ from cgi import escape -from lollypop.utils import format_artist_name from lollypop.define import Type, Lp @@ -81,7 +80,7 @@ self._timeout = None self._to_select_id = Type.NONE self._updating = False # Sort disabled if False - self._is_artists = False # for string translation + self._is_artists = False self._popover = SelectionPopover() builder = Gtk.Builder() builder.add_from_resource('/org/gnome/Lollypop/SelectionList.ui') @@ -321,8 +320,6 @@ a_index = model.get_value(itera, 0) b_index = model.get_value(iterb, 0) - a = format_artist_name(model.get_value(itera, 1)) - b = format_artist_name(model.get_value(iterb, 1)) # Static vs static if a_index < 0 and b_index < 0: @@ -335,6 +332,12 @@ return False # String comparaison for non static else: + if self._is_artists: + a = Lp().artists.get_sortname(a_index) + b = Lp().artists.get_sortname(b_index) + else: + a = model.get_value(itera, 1) + b = model.get_value(iterb, 1) return a.lower() > b.lower() def _row_separator_func(self, model, iterator): @@ -427,8 +430,6 @@ text = self._model.get_value(row_iter, 1) if text: - if self._is_artists: - text = format_artist_name(text) self._popover.set_text(" %s " % text[0].upper()) self._popover.set_relative_to(self) r = Gdk.Rectangle() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/sqlcursor.py new/lollypop-0.9.74/src/sqlcursor.py --- old/lollypop-0.9.70/src/sqlcursor.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/sqlcursor.py 2015-12-02 12:34:15.000000000 +0100 @@ -37,7 +37,7 @@ def __enter__(self): """ - Store cursor if created, return thread+object cursor + Return cursor for thread, create a new one if needed """ name = current_thread().getName() + self._obj.__class__.__name__ if name not in Lp().cursors: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/tagreader.py new/lollypop-0.9.74/src/tagreader.py --- old/lollypop-0.9.70/src/tagreader.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/tagreader.py 2015-12-04 09:12:55.000000000 +0100 @@ -96,6 +96,18 @@ artists += ";" return artists + def get_artist_sortname(self, tags): + """ + Return artist sort name + @param tags as Gst.TagList + @return artist sort name as string + """ + if tags is not None: + (exist, sortname) = tags.get_string_index('artist-sortname', 0) + if not exist: + sortname = "" + return sortname + def get_album_artist(self, tags): """ Return album artist for tags @@ -195,25 +207,27 @@ year = None return year - def add_artists(self, artists, album_artist): + def add_artists(self, artists, album_artist, sortname): """ Add artists to db @param artists as [string] @param album artist as string + @param sortname as string @commit needed @param return ([artist ids as int], [new artist ids as int]) """ new_artist_ids = [] # Get all artist ids artist_ids = [] - for word in artists.split(';'): - artist = format_artist_name(word) + for artist in artists.split(';'): # Get artist id, add it if missing artist_id = Lp().artists.get_id(artist) if artist_id is None: - artist_id = Lp().artists.add(artist) + artist_id = Lp().artists.add(artist, sortname) if artist == album_artist: new_artist_ids.append(artist_id) + elif sortname != "": + Lp().artists.set_sortname(artist_id, sortname) artist_ids.append(artist_id) return (artist_ids, new_artist_ids) @@ -227,11 +241,12 @@ album_artist_id = None new = False if album_artist: - album_artist = format_artist_name(album_artist) # Get album artist id, add it if missing album_artist_id = Lp().artists.get_id(album_artist) if album_artist_id is None: - album_artist_id = Lp().artists.add(album_artist) + album_artist_id = Lp().artists.add(album_artist, + format_artist_name( + album_artist)) new = True return (album_artist_id, new) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/toolbar_infos.py new/lollypop-0.9.74/src/toolbar_infos.py --- old/lollypop-0.9.70/src/toolbar_infos.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/toolbar_infos.py 2015-12-02 12:34:43.000000000 +0100 @@ -15,6 +15,7 @@ from lollypop.widgets_rating import RatingWidget from lollypop.widgets_loved import LovedWidget +from lollypop.pop_menu import TrackMenuPopover, TrackMenu from lollypop.pop_tunein import TuneinPopover from lollypop.pop_externals import ExternalsPopover from lollypop.pop_infos import InfosPopover @@ -150,40 +151,11 @@ self._pop_infos.set_relative_to(self._infobox) self._pop_infos.show() elif Lp().player.current_track.id >= 0: - menu = PopToolbarMenu(Lp().player.current_track.id, None) - popover = Gtk.Popover.new_from_model(eventbox, menu) - rating = RatingWidget(Lp().player.current_track) - rating.set_margin_top(5) - rating.set_margin_bottom(5) - rating.set_property('halign', Gtk.Align.START) - rating.set_property('hexpand', True) - rating.show() - loved = LovedWidget(Lp().player.current_track.id) - loved.set_margin_end(5) - loved.set_margin_top(5) - loved.set_margin_bottom(5) - loved.set_property('halign', Gtk.Align.END) - loved.set_property('hexpand', True) - loved.show() - # Hack to add two widgets in popover - # Use a Gtk.PopoverMenu later - # (GTK>3.16 available on Debian stable) - stack = Gtk.Stack() - grid = Gtk.Grid() - grid.set_orientation(Gtk.Orientation.VERTICAL) - stack.add_named(grid, 'main') - stack.show_all() - menu_widget = popover.get_child() - menu_widget.reparent(grid) - separator = Gtk.Separator() - separator.show() - grid.add(separator) - hgrid = Gtk.Grid() - hgrid.add(rating) - hgrid.add(loved) - hgrid.show() - grid.add(hgrid) - popover.add(stack) + menu = PopToolbarMenu(Lp().player.current_track.id) + popover = TrackMenuPopover( + Lp().player.current_track.id, + PopToolbarMenu(Lp().player.current_track.id)) + popover.set_relative_to(self._infobox) popover.show() return True diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/view_albums.py new/lollypop-0.9.74/src/view_albums.py --- old/lollypop-0.9.70/src/view_albums.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/view_albums.py 2015-12-02 12:34:15.000000000 +0100 @@ -201,8 +201,17 @@ self._genre_id) popover.set_relative_to(album_widget) popover.set_pointing_to(self._press_rect) + self._context_widget = popover.get_widget() + popover.connect('destroy', self._on_popover_destroyed) popover.show() + def _on_popover_destroyed(self, popover): + """ + Remove from context + @param popover as AlbumPopoverWidget + """ + self._context_widget = None + def _on_button_press(self, flowbox, event): """ Store pressed button diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/widgets_album_context.py new/lollypop-0.9.74/src/widgets_album_context.py --- old/lollypop-0.9.70/src/widgets_album_context.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/widgets_album_context.py 2015-12-02 12:34:15.000000000 +0100 @@ -94,6 +94,13 @@ width = 500 return (width, width) + def get_widget(self): + """ + Return widget + @return widget as AlbumContextWidget + """ + return self._widget + ####################### # PRIVATE # ####################### diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/lollypop-0.9.70/src/widgets_track.py new/lollypop-0.9.74/src/widgets_track.py --- old/lollypop-0.9.70/src/widgets_track.py 2015-11-25 16:41:08.000000000 +0100 +++ new/lollypop-0.9.74/src/widgets_track.py 2015-12-02 12:34:15.000000000 +0100 @@ -13,10 +13,8 @@ from gi.repository import GObject, Gtk from lollypop.define import Lp, ArtSize, Type -from lollypop.pop_menu import TrackMenu +from lollypop.pop_menu import TrackMenuPopover, TrackMenu from lollypop.widgets_indicator import IndicatorWidget -from lollypop.widgets_rating import RatingWidget -from lollypop.widgets_loved import LovedWidget from lollypop.utils import seconds_to_string, rgba_to_hex from lollypop.objects import Track, Album from lollypop import utils @@ -235,11 +233,12 @@ self._indicator = IndicatorWidget() self._builder.get_object('grid').attach(self._indicator, 0, 0, 1, 1) menu_btn = self._builder.get_object('menu') - self._show_menu = show_menu # TODO: Remove this test later if show_menu or Gtk.get_minor_version() > 16: menu_btn.show() + self._show_menu = True else: + self._show_menu = False menu_btn.hide() Row.__init__(self, show_loved) @@ -285,53 +284,14 @@ @param xcoordinate as int (or None) @param ycoordinate as int (or None) """ - menu = TrackMenu(self._object_id, None) - popover = Gtk.Popover.new_from_model(widget, menu) + popover = TrackMenuPopover(self._object_id, TrackMenu(self._object_id)) + popover.set_relative_to(widget) if xcoordinate is not None and ycoordinate is not None: rect = widget.get_allocation() rect.x = xcoordinate rect.y = ycoordinate rect.width = rect.height = 1 popover.set_pointing_to(rect) - - rating = RatingWidget(self._object) - rating.set_margin_top(5) - rating.set_margin_bottom(5) - rating.set_property('halign', Gtk.Align.START) - rating.set_property('hexpand', True) - rating.show() - - loved = LovedWidget(self._object_id) - loved.set_margin_end(5) - loved.set_margin_top(5) - loved.set_margin_bottom(5) - loved.set_property('halign', Gtk.Align.END) - loved.set_property('hexpand', True) - loved.show() - - # Hack to add two widgets in popover - # Use a Gtk.PopoverMenu later (GTK>3.16 available on Debian stable) - grid = Gtk.Grid() - grid.set_orientation(Gtk.Orientation.VERTICAL) - - stack = Gtk.Stack() - stack.add_named(grid, 'main') - stack.show_all() - - menu_widget = popover.get_child() - menu_widget.reparent(grid) - - separator = Gtk.Separator() - separator.show() - - grid.add(separator) - hgrid = Gtk.Grid() - hgrid.add(rating) - hgrid.add(loved) - hgrid.show() - grid.add(hgrid) - - popover.add(stack) popover.connect('closed', self._on_closed) self.get_style_context().add_class('track-menu-selected') popover.show()