[gnome-music/wip/mschraal/gtk4-v3: 4/187] Replace Gfm with GTK listmodels




commit bcf5895fa8992d95463fcb119f81246e636f486c
Author: Marinus Schraal <mschraal gnome org>
Date:   Wed Oct 30 22:47:45 2019 +0100

    Replace Gfm with GTK listmodels
    
    * Use filters and sorters
    * Drop wrapper use for sorter
    * Fix sorter callback arguments

 gnomemusic/corealbum.py                         |  15 +--
 gnomemusic/coreartist.py                        |  19 ++--
 gnomemusic/coredisc.py                          |  18 +--
 gnomemusic/coregrilo.py                         |  12 +-
 gnomemusic/coremodel.py                         | 144 ++++++++++++------------
 gnomemusic/grilowrappers/grlsearchwrapper.py    |   8 +-
 gnomemusic/grilowrappers/grltrackerplaylists.py |  26 +++--
 gnomemusic/grilowrappers/grltrackerwrapper.py   |  48 ++++----
 gnomemusic/player.py                            |  13 ++-
 gnomemusic/songliststore.py                     |  13 ++-
 gnomemusic/utils.py                             |  32 +++---
 gnomemusic/views/searchview.py                  |   8 +-
 gnomemusic/widgets/albumwidget.py               |   4 +-
 13 files changed, 189 insertions(+), 171 deletions(-)
---
diff --git a/gnomemusic/corealbum.py b/gnomemusic/corealbum.py
index 6db2c051b..7e2181e4e 100644
--- a/gnomemusic/corealbum.py
+++ b/gnomemusic/corealbum.py
@@ -23,8 +23,8 @@
 # delete this exception statement from your version.
 
 import gi
-gi.require_versions({"Gfm": "0.1", "Grl": "0.3"})
-from gi.repository import Gfm, Gio, Grl, GObject
+gi.require_versions({"Grl": "0.3"})
+from gi.repository import Gio, Grl, Gtk, GObject
 
 import gnomemusic.utils as utils
 
@@ -73,20 +73,21 @@ class CoreAlbum(GObject.GObject):
 
     def _get_album_model(self):
         disc_model = Gio.ListStore()
-        disc_model_sort = Gfm.SortListModel.new(disc_model)
+        disc_model_sort = Gtk.SortListModel.new(disc_model)
 
-        def _disc_order_sort(disc_a, disc_b):
+        def _disc_order_sort(disc_a, disc_b, data=None):
             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))
+        disc_sorter = Gtk.CustomSorter()
+        disc_sorter.set_sort_func(_disc_order_sort)
+        disc_model_sort.set_sorter(disc_sorter)
 
         self._coregrilo.get_album_discs(self.props.media, disc_model)
 
         return disc_model_sort
 
     @GObject.Property(
-        type=Gfm.SortListModel, default=None,
+        type=Gtk.SortListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def model(self):
         if self._model is None:
diff --git a/gnomemusic/coreartist.py b/gnomemusic/coreartist.py
index 62915a9f0..90a38d3d9 100644
--- a/gnomemusic/coreartist.py
+++ b/gnomemusic/coreartist.py
@@ -23,8 +23,8 @@
 # delete this exception statement from your version.
 
 import gi
-gi.require_versions({"Gfm": "0.1", "Grl": "0.3"})
-from gi.repository import Gfm, Grl, GObject
+gi.require_versions({"Grl": "0.3"})
+from gi.repository import Grl, Gtk, GObject
 
 from gnomemusic.artistart import ArtistArt
 import gnomemusic.utils as utils
@@ -59,24 +59,25 @@ class CoreArtist(GObject.GObject):
         self.props.artist = utils.get_artist_name(media)
 
     def _get_artist_album_model(self):
-        albums_model_filter = Gfm.FilterListModel.new(
+        albums_model_filter = Gtk.FilterListModel.new(
             self._coremodel.props.albums)
-        albums_model_filter.set_filter_func(lambda a: False)
+        albums_model_filter.set_filter(Gtk.AnyFilter())
 
-        albums_model_sort = Gfm.SortListModel.new(albums_model_filter)
+        albums_model_sort = Gtk.SortListModel.new(albums_model_filter)
 
         self._coregrilo.get_artist_albums(
             self.props.media, albums_model_filter)
 
-        def _album_sort(album_a, album_b):
+        def _album_sort(album_a, album_b, data=None):
             return album_a.props.year > album_b.props.year
 
-        albums_model_sort.set_sort_func(
-            utils.wrap_list_store_sort_func(_album_sort))
+        albums_sorter = Gtk.CustomSorter()
+        albums_sorter.set_sort_func(_album_sort)
+        albums_model_sort.set_sorter(albums_sorter)
 
         return albums_model_sort
 
-    @GObject.Property(type=Gfm.SortListModel, default=None)
+    @GObject.Property(type=Gtk.SortListModel, default=None)
     def model(self):
         if self._model is None:
             self._model = self._get_artist_album_model()
diff --git a/gnomemusic/coredisc.py b/gnomemusic/coredisc.py
index 4446a6a22..09780018b 100644
--- a/gnomemusic/coredisc.py
+++ b/gnomemusic/coredisc.py
@@ -22,9 +22,7 @@
 # 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, Gio, Gfm, Grl
-
-import gnomemusic.utils as utils
+from gi.repository import GObject, Gio, Grl, Gtk
 
 
 class CoreDisc(GObject.GObject):
@@ -59,16 +57,18 @@ class CoreDisc(GObject.GObject):
 
     @GObject.Property(type=Gio.ListModel, default=None)
     def model(self):
-        def _disc_sort(song_a, song_b):
+        def _disc_sort(song_a, song_b, data=None):
             return song_a.props.track_number - song_b.props.track_number
 
         if self._model is None:
-            self._filter_model = Gfm.FilterListModel.new(
+            self._filter_model = Gtk.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(
-                utils.wrap_list_store_sort_func(_disc_sort))
+            self._filter_model.set_filter(Gtk.AnyFilter())
+
+            self._model = Gtk.SortListModel.new(self._filter_model)
+            disc_sorter = Gtk.CustomSorter()
+            disc_sorter.set_sort_func(_disc_sort)
+            self._model.set_sorter(disc_sorter)
 
             self._model.connect("items-changed", self._on_disc_changed)
 
diff --git a/gnomemusic/coregrilo.py b/gnomemusic/coregrilo.py
index 002d5b921..ea5779392 100644
--- a/gnomemusic/coregrilo.py
+++ b/gnomemusic/coregrilo.py
@@ -25,8 +25,8 @@
 import weakref
 
 import gi
-gi.require_versions({"Grl": "0.3", "Gfm": "0.1"})
-from gi.repository import Grl, GLib, GObject, Gfm
+gi.require_version("Grl", "0.3")
+from gi.repository import Grl, GLib, GObject, Gtk
 
 from gnomemusic.grilowrappers.grlsearchwrapper import GrlSearchWrapper
 from gnomemusic.grilowrappers.grltrackerwrapper import GrlTrackerWrapper
@@ -178,7 +178,7 @@ class CoreGrilo(GObject.GObject):
         """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
+        :param Gtk.FilterListModel filter_model: The model to fill
         """
         source = media.get_source()
         self._wrappers[source].get_artist_albums(media, filter_model)
@@ -187,19 +187,19 @@ class CoreGrilo(GObject.GObject):
         """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
+        :param Gtk.SortListModel disc_model: The model to fill
         """
         source = media.get_source()
         self._wrappers[source].get_album_discs(media, disc_model)
 
     def get_album_disc(
             self, media: Grl.Media, discnr: int,
-            model: Gfm.FilterListModel) -> None:
+            model: Gtk.FilterListModel) -> None:
         """Get all songs from an album disc
 
         :param Grl.Media media: An album
         :param int discnr: The disc number
-        :param Gfm.FilterListModel model: The model to fill
+        :param Gtk.FilterListModel model: The model to fill
         """
         source = media.get_source()
         self._wrappers[source].get_album_disc(media, discnr, model)
diff --git a/gnomemusic/coremodel.py b/gnomemusic/coremodel.py
index b9110a8d4..a248cd955 100644
--- a/gnomemusic/coremodel.py
+++ b/gnomemusic/coremodel.py
@@ -26,9 +26,7 @@ from __future__ import annotations
 from typing import Optional, Union
 import typing
 
-import gi
-gi.require_version("Gfm", "0.1")
-from gi.repository import GLib, GObject, Gio, Gfm, Gtk
+from gi.repository import GLib, GObject, Gio, Gtk
 
 from gnomemusic.corealbum import CoreAlbum
 from gnomemusic.coreartist import CoreArtist
@@ -85,86 +83,88 @@ class CoreModel(GObject.GObject):
         """
         super().__init__()
 
-        self._flatten_model: Optional[Gfm.FlattenListModel] = None
+        self._flatten_model: Optional[Gtk.FlattenListModel] = None
         self._player_signal_id = 0
         self._current_playlist_model: Optional[Union[
-            Gfm.FlattenListModel, Gfm.SortListModel, Gio.ListModel]] = None
+            Gtk.FlattenListModel, Gtk.SortListModel, Gio.ListModel]] = None
         self._previous_playlist_model: Optional[Union[
-            Gfm.FlattenListModel, Gfm.SortListModel, Gio.ListModel]] = None
+            Gtk.FlattenListModel, Gtk.SortListModel, Gio.ListModel]] = None
 
         self._songs_model_proxy: Gio.ListStore = Gio.ListStore.new(
             Gio.ListModel)
-        self._songs_model: Gfm.FlattenListModel = Gfm.FlattenListModel.new(
-            CoreSong, self._songs_model_proxy)
+        self._songs_model: Gtk.FlattenListModel = Gtk.FlattenListModel.new(
+            self._songs_model_proxy)
         self._songliststore = SongListStore(self._songs_model)
 
         self._application = application
 
         self._albums_model_proxy: Gio.ListStore = Gio.ListStore.new(
             Gio.ListModel)
-        self._albums_model: Gfm.FlattenListModel = Gfm.FlattenListModel.new(
-            CoreAlbum, self._albums_model_proxy)
-        self._albums_model_sort: Gfm.SortListModel = Gfm.SortListModel.new(
+        self._albums_model: Gtk.FlattenListModel = Gtk.FlattenListModel.new(
+            self._albums_model_proxy)
+        self._albums_model_sort: Gtk.SortListModel = Gtk.SortListModel.new(
             self._albums_model)
-        self._albums_model_sort.set_sort_func(
-            utils.wrap_list_store_sort_func(self._albums_sort))
+        albums_sorter = Gtk.CustomSorter()
+        albums_sorter.set_sort_func(self._albums_sort)
+        self._albums_model_sort.set_sorter(albums_sorter)
 
         self._artists_model_proxy: Gio.ListStore = Gio.ListStore.new(
             Gio.ListModel)
-        self._artists_model: Gfm.FlattenListModel = Gfm.FlattenListModel.new(
-            CoreArtist, self._artists_model_proxy)
-        self._artists_model_sort: Gfm.SortListModel = Gfm.SortListModel.new(
+        self._artists_model: Gtk.FlattenListModel = Gtk.FlattenListModel.new(
+            self._artists_model_proxy)
+        self._artists_model_sort: Gtk.SortListModel = Gtk.SortListModel.new(
             self._artists_model)
-        self._artists_model_sort.set_sort_func(
-            utils.wrap_list_store_sort_func(self._artist_sort))
+        artists_sorter = Gtk.CustomSorter()
+        artists_sorter.set_sort_func(self._artist_sort)
+        self._artists_model_sort.set_sorter(artists_sorter)
 
         self._playlist_model: Gio.ListStore = Gio.ListStore.new(CoreSong)
-        self._playlist_model_sort: Gfm.SortListModel = Gfm.SortListModel.new(
+        self._playlist_model_sort: Gtk.SortListModel = Gtk.SortListModel.new(
             self._playlist_model)
-        self._playlist_model_recent: Gfm.SliceListModel = (
-            Gfm.SliceListModel.new(
+        self._playlist_model_recent: Gtk.SliceListModel = (
+            Gtk.SliceListModel.new(
                 self._playlist_model_sort, 0, self._recent_size))
         self._active_core_object: Optional[Union[
             CoreAlbum, CoreArtist, Playlist]] = None
 
         self._songs_search_proxy: Gio.ListStore = Gio.ListStore.new(
-            Gfm.FilterListModel)
-        self._songs_search_flatten: Gfm.FlattenListModel = (
-            Gfm.FlattenListModel.new(CoreSong))
+            Gtk.FilterListModel)
+        self._songs_search_flatten: Gtk.FlattenListModel = (
+            Gtk.FlattenListModel())
         self._songs_search_flatten.set_model(self._songs_search_proxy)
 
         self._albums_search_proxy: Gio.Liststore = Gio.ListStore.new(
-            Gfm.FilterListModel)
-        self._albums_search_flatten: Gfm.FlattenListModel = (
-            Gfm.FlattenListModel.new(CoreAlbum))
+            Gtk.FilterListModel)
+        self._albums_search_flatten: Gtk.FlattenListModel = (
+            Gtk.FlattenListModel())
         self._albums_search_flatten.set_model(self._albums_search_proxy)
-
-        self._albums_search_filter: Gfm.FilterListModel = (
-            Gfm.FilterListModel.new(self._albums_search_flatten))
+        self._albums_search_filter: Gtk.FilterListModel = (
+            Gtk.FilterListModel.new(Gtk.AnyFilter()))
 
         self._artists_search_proxy: Gio.Liststore = Gio.ListStore.new(
-            Gfm.FilterListModel)
-        self._artists_search_flatten: Gfm.FlattenListModel = (
-            Gfm.FlattenListModel.new(CoreArtist))
+            Gtk.FilterListModel)
+        self._artists_search_flatten: Gtk.FlattenListModel = (
+            Gtk.FlattenListModel())
         self._artists_search_flatten.set_model(self._artists_search_proxy)
-
-        self._artists_search_filter: Gfm.FilterListModel = (
-            Gfm.FilterListModel.new(self._artists_search_flatten))
+        self._artists_search_filter: Gtk.FilterListModel = (
+            Gtk.FilterListModel.new(Gtk.AnyFilter()))
 
         self._playlists_model: Gio.ListStore = Gio.ListStore.new(Playlist)
-        self._playlists_model_filter: Gfm.FilterListModel = (
-            Gfm.FilterListModel.new(self._playlists_model))
-        self._playlists_model_sort: Gfm.SortListModel = Gfm.SortListModel.new(
+        self._playlists_model_filter: Gtk.FilterListModel = (
+            Gtk.FilterListModel.new(self._playlists_model))
+        self._playlists_model_sort: Gtk.SortListModel = Gtk.SortListModel.new(
             self._playlists_model_filter)
-        self._playlists_model_sort.set_sort_func(
-            utils.wrap_list_store_sort_func(self._playlists_sort))
-
-        self._user_playlists_model_filter: Gfm.FilterListModel = (
-            Gfm.FilterListModel.new(self._playlists_model))
-        self._user_playlists_model_sort: Gfm.SortListModel = (
-            Gfm.SortListModel.new(self._user_playlists_model_filter))
-        self._user_playlists_model_sort.set_sort_func(
-            utils.wrap_list_store_sort_func(self._playlists_sort))
+        playlists_sorter = Gtk.CustomSorter()
+        playlists_sorter.set_sort_func(self._playlists_sort)
+        self._playlists_model_sort.set_sorter(playlists_sorter)
+
+        self._user_playlists_model_filter: Gtk.FilterListModel = (
+            Gtk.FilterListModel.new(self._playlists_model))
+        self._user_playlists_model_sort: Gtk.SortListModel = (
+            Gtk.SortListModel.new(self._user_playlists_model_filter))
+        user_playlists_sorter = Gtk.CustomSorter()
+        user_playlists_sorter.set_sort_func(self._playlists_sort)
+        self._user_playlists_model_sort.set_sorter(user_playlists_sorter)
 
         self._search: Search = application.props.search
 
@@ -186,15 +186,15 @@ class CoreModel(GObject.GObject):
     def _filter_selected(self, coresong):
         return coresong.props.selected
 
-    def _albums_sort(self, album_a, album_b):
+    def _albums_sort(self, album_a, album_b, data=None):
         return utils.natural_sort_names(
             album_a.props.title, album_b.props.title)
 
-    def _artist_sort(self, artist_a, artist_b):
+    def _artist_sort(self, artist_a, artist_b, data=None):
         return utils.natural_sort_names(
             artist_a.props.artist, artist_b.props.artist)
 
-    def _playlists_sort(self, playlist_a, playlist_b):
+    def _playlists_sort(self, playlist_a, playlist_b, data=None):
         if playlist_a.props.is_smart:
             if not playlist_b.props.is_smart:
                 return -1
@@ -260,8 +260,7 @@ class CoreModel(GObject.GObject):
             for disc in model:
                 proxy_model.append(disc.props.model)
 
-            self._flatten_model = Gfm.FlattenListModel.new(
-                CoreSong, proxy_model)
+            self._flatten_model = Gtk.FlattenListModel.new(proxy_model)
             self._current_playlist_model = self._flatten_model
 
             for model_song in self._flatten_model:
@@ -276,8 +275,7 @@ class CoreModel(GObject.GObject):
                 for disc in artist_album.model:
                     proxy_model.append(disc.props.model)
 
-            self._flatten_model = Gfm.FlattenListModel.new(
-                CoreSong, proxy_model)
+            self._flatten_model = Gtk.FlattenListModel.new(proxy_model)
             self._current_playlist_model = self._flatten_model
 
             for model_song in self._flatten_model:
@@ -363,7 +361,7 @@ class CoreModel(GObject.GObject):
         return self._songs_model
 
     @GObject.Property(
-        type=Gfm.FlattenListModel, default=None,
+        type=Gtk.FlattenListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def songs_proxy(self):
         return self._songs_model_proxy
@@ -374,7 +372,7 @@ class CoreModel(GObject.GObject):
         return self._albums_model
 
     @GObject.Property(
-        type=Gfm.FlattenListModel, default=None,
+        type=Gtk.FlattenListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def albums_proxy(self):
         return self._albums_model_proxy
@@ -385,7 +383,7 @@ class CoreModel(GObject.GObject):
         return self._artists_model
 
     @GObject.Property(
-        type=Gfm.FlattenListModel, default=None,
+        type=Gtk.FlattenListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def artists_proxy(self):
         return self._artists_model_proxy
@@ -396,25 +394,25 @@ class CoreModel(GObject.GObject):
         return self._playlist_model
 
     @GObject.Property(
-        type=Gfm.SortListModel, default=None,
+        type=Gtk.SortListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def albums_sort(self):
         return self._albums_model_sort
 
     @GObject.Property(
-        type=Gfm.SortListModel, default=None,
+        type=Gtk.SortListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def artists_sort(self):
         return self._artists_model_sort
 
     @GObject.Property(
-        type=Gfm.SortListModel, default=None,
+        type=Gtk.SortListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def playlist_sort(self):
         return self._playlist_model_sort
 
     @GObject.Property(
-        type=Gfm.SliceListModel, default=None,
+        type=Gtk.SliceListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def recent_playlist(self):
         return self._playlist_model_recent
@@ -426,7 +424,7 @@ class CoreModel(GObject.GObject):
         return self._recent_size // 2
 
     @GObject.Property(
-        type=Gfm.FilterListModel, default=None,
+        type=Gtk.FilterListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def songs_search(self):
         return self._songs_search_flatten
@@ -438,13 +436,13 @@ class CoreModel(GObject.GObject):
         return self._songs_search_proxy
 
     @GObject.Property(
-        type=Gfm.FlattenListModel, default=None,
+        type=Gtk.FlattenListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
-    def albums_search(self) -> Gfm.FlattenListModel:
+    def albums_search(self) -> Gtk.FlattenListModel:
         return self._albums_search_flatten
 
     @GObject.Property(
-        type=Gfm.FilterListModel, default=None,
+        type=Gtk.FilterListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def albums_search_filter(self):
         return self._albums_search_filter
@@ -455,13 +453,13 @@ class CoreModel(GObject.GObject):
         return self._albums_search_proxy
 
     @GObject.Property(
-        type=Gfm.FlattenListModel, default=None,
+        type=Gtk.FlattenListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
-    def artists_search(self) -> Gfm.FlattenListModel:
+    def artists_search(self) -> Gtk.FlattenListModel:
         return self._artists_search_flatten
 
     @GObject.Property(
-        type=Gfm.FilterListModel, default=None,
+        type=Gtk.FilterListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def artists_search_filter(self):
         return self._artists_search_filter
@@ -482,25 +480,25 @@ class CoreModel(GObject.GObject):
         return self._playlists_model
 
     @GObject.Property(
-        type=Gfm.SortListModel, default=None,
+        type=Gtk.SortListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def playlists_sort(self):
         return self._playlists_model_sort
 
     @GObject.Property(
-        type=Gfm.SortListModel, default=None,
+        type=Gtk.SortListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def playlists_filter(self):
         return self._playlists_model_filter
 
     @GObject.Property(
-        type=Gfm.SortListModel, default=None,
+        type=Gtk.SortListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def user_playlists_sort(self):
         return self._user_playlists_model_sort
 
     @GObject.Property(
-        type=Gfm.SortListModel, default=None,
+        type=Gtk.SortListModel, default=None,
         flags=GObject.ParamFlags.READABLE)
     def user_playlists_filter(self):
         return self._user_playlists_model_filter
diff --git a/gnomemusic/grilowrappers/grlsearchwrapper.py b/gnomemusic/grilowrappers/grlsearchwrapper.py
index 5a90fa6f9..9db9149ec 100644
--- a/gnomemusic/grilowrappers/grlsearchwrapper.py
+++ b/gnomemusic/grilowrappers/grlsearchwrapper.py
@@ -23,8 +23,8 @@
 # delete this exception statement from your version.
 
 import gi
-gi.require_versions({"Gfm": "0.1", "Grl": "0.3"})
-from gi.repository import Gfm, Gio, Grl, GObject
+gi.require_versions({"Grl": "0.3"})
+from gi.repository import Gio, Grl, Gtk, GObject
 
 from gnomemusic.coresong import CoreSong
 
@@ -75,9 +75,9 @@ class GrlSearchWrapper(GObject.GObject):
         self._song_search_store = Gio.ListStore.new(CoreSong)
         # FIXME: Workaround for adding the right list type to the proxy
         # list model.
-        self._song_search_model = Gfm.FilterListModel.new(
+        self._song_search_model = Gtk.FilterListModel.new(
             self._song_search_store)
-        self._song_search_model.set_filter_func(lambda a: True)
+        self._song_search_model.set_filter(Gtk.AnyFilter())
         self._song_search_proxy.append(self._song_search_model)
 
         self._fast_options = Grl.OperationOptions()
diff --git a/gnomemusic/grilowrappers/grltrackerplaylists.py b/gnomemusic/grilowrappers/grltrackerplaylists.py
index 9e8f26344..4d80aa493 100644
--- a/gnomemusic/grilowrappers/grltrackerplaylists.py
+++ b/gnomemusic/grilowrappers/grltrackerplaylists.py
@@ -27,8 +27,8 @@ import time
 from gettext import gettext as _
 
 import gi
-gi.require_versions({"Grl": "0.3"})
-from gi.repository import Gio, Grl, GLib, GObject, Tracker
+gi.require_versions({"Grl": "0.3", "Tracker": "3.0"})
+from gi.repository import Gio, Grl, Gtk, GLib, GObject, Tracker
 
 from gnomemusic.coresong import CoreSong
 import gnomemusic.utils as utils
@@ -68,7 +68,9 @@ class GrlTrackerPlaylists(GObject.GObject):
         self._notificationmanager = application.props.notificationmanager
         self._window = application.props.window
 
-        self._user_model_filter.set_filter_func(self._user_playlists_filter)
+        user_playlists_filter = Gtk.CustomFilter()
+        user_playlists_filter.set_filter_func(self._user_playlists_filter)
+        self._user_model_filter.set_filter(user_playlists_filter)
 
         self._fast_options = Grl.OperationOptions()
         self._fast_options.set_resolution_flags(
@@ -146,7 +148,9 @@ class GrlTrackerPlaylists(GObject.GObject):
         :param Playlist playlist: playlist
         """
         self._pls_todelete.append(playlist)
-        self._model_filter.set_filter_func(self._playlists_filter)
+        playlists_filter = Gtk.CustomFilter()
+        playlists_filter.set_filter_func(self._playlists_filter)
+        self._model_filter.set_filter(playlists_filter)
 
     def finish_playlist_deletion(self, playlist, deleted):
         """Removes playlist from the list of playlists to delete
@@ -154,11 +158,15 @@ class GrlTrackerPlaylists(GObject.GObject):
         :param Playlist playlist: playlist
         :param bool deleted: indicates if the playlist has been deleted
         """
+        playlists_filter = Gtk.CustomFilter()
+        playlists_filter.set_filter_func(self._playlists_filter)
+        user_playlists_filter = Gtk.CustomFilter()
+        user_playlists_filter.set_filter_func(self._playlists_filter)
+
         self._pls_todelete.remove(playlist)
         if deleted is False:
-            self._model_filter.set_filter_func(self._playlists_filter)
-            self._user_model_filter.set_filter_func(
-                self._user_playlists_filter)
+            self._model_filter.set_filter(playlists_filter)
+            self._user_model_filter.set_filter(user_playlists_filter)
             return
 
         def _delete_cb(conn, res, data):
@@ -173,7 +181,9 @@ class GrlTrackerPlaylists(GObject.GObject):
                         self._model.remove(idx)
                         break
 
-            self._model_filter.set_filter_func(self._playlists_filter)
+            playlists_filter = Gtk.CustomFilter()
+            playlists_filter.set_filter_func(self._playlists_filter)
+            self._model_filter.set_filter(playlists_filter)
             self._notificationmanager.pop_loading()
 
         self._notificationmanager.push_loading()
diff --git a/gnomemusic/grilowrappers/grltrackerwrapper.py b/gnomemusic/grilowrappers/grltrackerwrapper.py
index 8fe8f5dd2..111c24c3a 100644
--- a/gnomemusic/grilowrappers/grltrackerwrapper.py
+++ b/gnomemusic/grilowrappers/grltrackerwrapper.py
@@ -27,8 +27,8 @@ from typing import Callable, Dict, List, Optional
 import typing
 
 import gi
-gi.require_versions({"Gfm": "0.1", "Grl": "0.3", "Tracker": "3.0"})
-from gi.repository import Gfm, Gio, Grl, GLib, GObject, Tracker
+gi.require_versions({"Grl": "0.3", "Tracker": "3.0"})
+from gi.repository import Grl, Gio, Gtk, GLib, GObject, Tracker
 
 from gnomemusic.asyncqueue import AsyncQueue
 from gnomemusic.corealbum import CoreAlbum
@@ -126,19 +126,19 @@ class GrlTrackerWrapper(GObject.GObject):
         self._notificationmanager: NotificationManager = (
             application.props.notificationmanager)
 
-        self._songs_search: Gfm.FilterListModel = Gfm.FilterListModel.new(
+        self._songs_search: Gtk.FilterListModel = Gtk.FilterListModel.new(
             self._songs_model)
-        self._songs_search.set_filter_func(lambda a: False)
+        self._songs_search.set_filter(Gtk.AnyFilter())
         cm.props.songs_search_proxy.append(self._songs_search)
 
-        self._albums_search: Gfm.FilterListModel = Gfm.FilterListModel.new(
+        self._albums_search: Gtk.FilterListModel = Gtk.FilterListModel.new(
             self._albums_model)
-        self._albums_search.set_filter_func(lambda a: False)
+        self._albums_search.set_filter(Gtk.AnyFilter())
         cm.props.albums_search_proxy.append(self._albums_search)
 
-        self._artists_search: Gfm.FilterListModel = Gfm.FilterListModel.new(
+        self._artists_search: Gtk.FilterListModel = Gtk.FilterListModel.new(
             self._artists_model)
-        self._artists_search.set_filter_func(lambda a: False)
+        self._artists_search.set_filter(Gtk.AnyFilter())
         cm.props.artists_search_proxy.append(self._artists_search)
 
         self._fast_options: Grl.OperationOptions = Grl.OperationOptions()
@@ -667,11 +667,11 @@ class GrlTrackerWrapper(GObject.GObject):
             query, metadata_keys, self._fast_options, _add_to_artists_model)
 
     def get_artist_albums(
-            self, media: Grl.Source, model: Gfm.FilterListModel) -> None:
+            self, media: Grl.Source, model: Gtk.FilterListModel) -> None:
         """Get all albums by an artist
 
         :param Grl.Media media: The media with the artist id
-        :param Gfm.FilterListModel model: The model to fill
+        :param Gtk.FilterListModel model: The model to fill
         """
         self._notificationmanager.push_loading()
         artist_id = media.get_id()
@@ -720,7 +720,9 @@ class GrlTrackerWrapper(GObject.GObject):
                 return
 
             if not media:
-                model.set_filter_func(albums_filter, albums)
+                custom_filter = Gtk.CustomFilter()
+                custom_filter.set_filter_func(albums_filter, albums)
+                model.set_filter(custom_filter)
                 self._notificationmanager.pop_loading()
                 return
 
@@ -738,11 +740,11 @@ class GrlTrackerWrapper(GObject.GObject):
             query, [Grl.METADATA_KEY_TITLE], self._fast_options, query_cb)
 
     def get_album_discs(
-            self, media: Grl.Media, disc_model: Gfm.SortListModel) -> None:
+            self, media: Grl.Media, disc_model: Gtk.SortListModel) -> None:
         """Get all discs of an album
 
         :param Grl.Media media: The media with the album id
-        :param Gfm.SortListModel disc_model: The model to fill
+        :param Gtk.SortListModel disc_model: The model to fill
         """
         self._notificationmanager.push_loading()
         album_id = media.get_id()
@@ -797,12 +799,12 @@ class GrlTrackerWrapper(GObject.GObject):
 
     def get_album_disc(
             self, media: Grl.Media, disc_nr: int,
-            model: Gfm.FilterListModel) -> None:
+            model: Gtk.FilterListModel) -> None:
         """Get all songs of an album disc
 
         :param Grl.Media media: The media with the album id
         :param int disc_nr: The disc number
-        :param Gfm.FilterListModel model: The model to fill
+        :param Gtk.FilterListModel model: The model to fill
         """
         album_id = media.get_id()
 
@@ -881,7 +883,9 @@ class GrlTrackerWrapper(GObject.GObject):
                 return
 
             if media is None:
-                model.set_filter_func(_filter_func)
+                custom_filter = Gtk.CustomFilter()
+                custom_filter.set_filter_func(_filter_func)
+                model.set_filter(custom_filter)
                 return
 
             disc_song_ids.append(media.get_source() + media.get_id())
@@ -967,7 +971,9 @@ class GrlTrackerWrapper(GObject.GObject):
                 return
 
             if not media:
-                self._artists_search.set_filter_func(artist_filter)
+                custom_filter = Gtk.CustomFilter()
+                custom_filter.set_filter_func(artist_filter)
+                self._artists_search.set_filter(custom_filter)
                 self._notificationmanager.pop_loading()
                 return
 
@@ -1036,7 +1042,9 @@ class GrlTrackerWrapper(GObject.GObject):
                 return
 
             if not media:
-                self._albums_search.set_filter_func(album_filter)
+                custom_filter = Gtk.CustomFilter()
+                custom_filter.set_filter_func(album_filter)
+                self._albums_search.set_filter(custom_filter)
                 self._notificationmanager.pop_loading()
                 return
 
@@ -1110,7 +1118,9 @@ class GrlTrackerWrapper(GObject.GObject):
                 return
 
             if not media:
-                self._songs_search.set_filter_func(songs_filter)
+                custom_filter = Gtk.CustomFilter()
+                custom_filter.set_filter_func(songs_filter)
+                self._songs_search.set_filter(custom_filter)
                 self._notificationmanager.pop_loading()
                 return
 
diff --git a/gnomemusic/player.py b/gnomemusic/player.py
index 372d30103..4b0bdf162 100644
--- a/gnomemusic/player.py
+++ b/gnomemusic/player.py
@@ -30,12 +30,11 @@ import typing
 
 import gi
 gi.require_version('GstPbutils', '1.0')
-from gi.repository import GObject, GstPbutils
+from gi.repository import GObject, GstPbutils, Gtk
 
 from gnomemusic.coresong import CoreSong
 from gnomemusic.gstplayer import GstPlayer, Playback
 from gnomemusic.widgets.songwidget import SongWidget
-import gnomemusic.utils as utils
 
 
 class RepeatMode(Enum):
@@ -277,16 +276,18 @@ class PlayerPlaylist(GObject.GObject):
         self._model_recent.set_offset(offset)
 
     def _on_repeat_mode_changed(self, klass, param):
-        def _shuffle_sort(song_a, song_b):
+        def _shuffle_sort(song_a, song_b, data=None):
             return song_a.shuffle_pos < song_b.shuffle_pos
 
         if self.props.repeat_mode == RepeatMode.SHUFFLE:
             for idx, coresong in enumerate(self._model):
                 coresong.update_shuffle_pos()
-            self._model.set_sort_func(
-                utils.wrap_list_store_sort_func(_shuffle_sort))
+
+            songs_sorter = Gtk.CustomSorter()
+            songs_sorter.set_sort_func(_shuffle_sort)
+            self._model.set_sorter(songs_sorter)
         elif self.props.repeat_mode in [RepeatMode.NONE, RepeatMode.ALL]:
-            self._model.set_sort_func(None)
+            self._model.set_sorter(None)
 
     def _validate_song(self, coresong):
         # Song is being processed or has already been processed.
diff --git a/gnomemusic/songliststore.py b/gnomemusic/songliststore.py
index ecd0c77c0..470959702 100644
--- a/gnomemusic/songliststore.py
+++ b/gnomemusic/songliststore.py
@@ -22,7 +22,7 @@
 # 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 Gfm, Gio, GObject, Gtk
+from gi.repository import Gio, GObject, Gtk
 
 import gnomemusic.utils as utils
 
@@ -36,9 +36,10 @@ class SongListStore(Gtk.ListStore):
         """
         super().__init__()
 
-        self._model = Gfm.SortListModel.new(model)
-        self._model.set_sort_func(
-            utils.wrap_list_store_sort_func(self._songs_sort))
+        self._model = Gtk.SortListModel.new(model)
+        sorter = Gtk.CustomSorter()
+        sorter.set_sort_func(self._songs_sort)
+        self._model.set_sorter(sorter)
 
         self.set_column_types([
             GObject.TYPE_STRING,    # play or invalid icon
@@ -55,7 +56,7 @@ class SongListStore(Gtk.ListStore):
 
         self._model.connect("items-changed", self._on_items_changed)
 
-    def _songs_sort(self, song_a, song_b):
+    def _songs_sort(self, song_a, song_b, data=None):
         title_a = song_a.props.title
         title_b = song_b.props.title
         song_cmp = (utils.normalize_caseless(title_a)
@@ -111,6 +112,6 @@ class SongListStore(Gtk.ListStore):
         """Gets the model of songs sorted.
 
         :returns: a list model of sorted songs
-        :rtype: Gfm.SortListModel
+        :rtype: Gtk.SortListModel
         """
         return self._model
diff --git a/gnomemusic/utils.py b/gnomemusic/utils.py
index c2762cf06..76c9e3017 100644
--- a/gnomemusic/utils.py
+++ b/gnomemusic/utils.py
@@ -23,12 +23,12 @@
 # delete this exception statement from your version.
 
 from enum import Enum, IntEnum
+from typing import List
 import re
 import unicodedata
 
 from gettext import gettext as _
-from gi.repository import Gio, GLib
-from gi._gi import pygobject_new_full
+from gi.repository import Gio, GLib, Gtk
 
 from gnomemusic.musiclogger import MusicLogger
 
@@ -178,7 +178,7 @@ def normalize_caseless(text):
     return unicodedata.normalize("NFKD", text.casefold())
 
 
-def natural_sort_names(name_a, name_b):
+def natural_sort_names(name_a: str, name_b: str) -> int:
     """Natural order comparison of two strings.
 
     A natural order is an alphabetical order which takes into account
@@ -189,22 +189,18 @@ def natural_sort_names(name_a, name_b):
 
     :param str name_a: first string to compare
     :param str name_b: second string to compare
-    :returns: False if name_a should be before name_b. True otherwise.
-    :rtype: boolean
+    :returns: Gtk Ordering
+    :rtype: int
     """
-    def _extract_numbers(text):
+    def _extract_numbers(text: str) -> List[str]:
         return [int(tmp) if tmp.isdigit() else tmp
                 for tmp in re.split(r"(\d+)", normalize_caseless(text))]
 
-    return _extract_numbers(name_b) < _extract_numbers(name_a)
-
-
-def wrap_list_store_sort_func(func):
-    """PyGI wrapper for SortListModel set_sort_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
+    extract_a = _extract_numbers(name_a)
+    extract_b = _extract_numbers(name_b)
+    if extract_a < extract_b:
+        return Gtk.Ordering.SMALLER
+    elif extract_a > extract_b:
+        return Gtk.Ordering.LARGER
+    else:
+        return Gtk.Ordering.EQUAL
diff --git a/gnomemusic/views/searchview.py b/gnomemusic/views/searchview.py
index e9d2cca23..cc36dd381 100644
--- a/gnomemusic/views/searchview.py
+++ b/gnomemusic/views/searchview.py
@@ -96,13 +96,13 @@ class SearchView(Gtk.Stack):
         self._model = self._coremodel.props.songs_search
         self._album_model = self._coremodel.props.albums_search
         self._album_filter = self._coremodel.props.albums_search_filter
-        self._album_filter.set_filter_func(
-            self._core_filter, self._album_model, 12)
+        # self._album_filter.set_filter_func(
+        #     self._core_filter, self._album_model, 12)
 
         self._artist_model = self._coremodel.props.artists_search
         self._artist_filter = self._coremodel.props.artists_search_filter
-        self._artist_filter.set_filter_func(
-            self._core_filter, self._artist_model, 6)
+        # self._artist_filter.set_filter_func(
+        #     self._core_filter, self._artist_model, 6)
 
         self._model.connect_after(
             "items-changed", self._on_model_items_changed)
diff --git a/gnomemusic/widgets/albumwidget.py b/gnomemusic/widgets/albumwidget.py
index 03f8c254e..c22b2f0a4 100644
--- a/gnomemusic/widgets/albumwidget.py
+++ b/gnomemusic/widgets/albumwidget.py
@@ -27,7 +27,7 @@ from gettext import ngettext
 from typing import Optional, Union
 import typing
 
-from gi.repository import Gfm, Gio, GLib, GObject, Gtk, Handy
+from gi.repository import Gio, GLib, GObject, Gtk, Handy
 
 from gnomemusic.corealbum import CoreAlbum
 from gnomemusic.utils import ArtSize, DefaultIconType
@@ -203,7 +203,7 @@ class AlbumWidget(Handy.Clamp):
         return disc_box
 
     def _on_model_items_changed(
-            self, model: Gfm.SortListModel, position: int, removed: int,
+            self, model: Gtk.SortListModel, position: int, removed: int,
             added: int) -> None:
         n_items: int = model.get_n_items()
         if n_items == 1:


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]