[gnome-music/wip/mschraal/core] searchview: Add artists results
- From: Marinus Schraal <mschraal src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-music/wip/mschraal/core] searchview: Add artists results
- Date: Mon, 1 Jul 2019 12:57:19 +0000 (UTC)
commit 6dc0c1c4b7056fdb583582709fcb97b52cbc6026
Author: Marinus Schraal <mschraal gnome org>
Date: Mon Jul 1 14:11:34 2019 +0200
searchview: Add artists results
gnomemusic/coremodel.py | 7 ++++
gnomemusic/grilowrappers/grltrackersource.py | 55 ++++++++++++++++++++++++++++
gnomemusic/views/searchview.py | 45 +++++++++++++++++++++++
3 files changed, 107 insertions(+)
---
diff --git a/gnomemusic/coremodel.py b/gnomemusic/coremodel.py
index 59674123..02dbe01c 100644
--- a/gnomemusic/coremodel.py
+++ b/gnomemusic/coremodel.py
@@ -60,6 +60,10 @@ class CoreModel(GObject.GObject):
self._album_model)
self._album_search_model.set_filter_func(lambda a: False)
+ self._artist_search_model = Dazzle.ListModelFilter.new(
+ self._artist_model)
+ self._artist_search_model.set_filter_func(lambda a: False)
+
print("PLAYLIST_MODEL", self._playlist_model)
self._grilo = CoreGrilo(
self, self._model, self._album_model, self._artist_model,
@@ -205,5 +209,8 @@ class CoreModel(GObject.GObject):
def get_album_search_model(self):
return self._album_search_model
+ def get_artist_search_model(self):
+ return self._artist_search_model
+
def search(self, text):
self._grilo.search(text)
diff --git a/gnomemusic/grilowrappers/grltrackersource.py b/gnomemusic/grilowrappers/grltrackersource.py
index 8af63a3e..621a932e 100644
--- a/gnomemusic/grilowrappers/grltrackersource.py
+++ b/gnomemusic/grilowrappers/grltrackersource.py
@@ -46,6 +46,7 @@ class GrlTrackerSource(GObject.GObject):
self._hash = {}
self._song_search_model = song_search_model
self._album_search_model = album_search_model
+ self._artist_search_model = self._coremodel.get_artist_search_model()
self._fast_options = Grl.OperationOptions()
self._fast_options.set_resolution_flags(
@@ -584,3 +585,57 @@ class GrlTrackerSource(GObject.GObject):
self._source.query(
query, self.METADATA_KEYS, options, albums_search_cb)
+
+ # Artist search
+
+ query = """
+ SELECT DISTINCT
+ rdf:type(?artist)
+ tracker:id(?artist) AS ?id
+ {
+ ?song a nmm:MusicPiece ;
+ nmm:musicAlbum ?album ;
+ nmm:performer ?artist .
+ 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")
+ )
+ }
+ """.replace('\n', ' ').strip() % {'name': term}
+
+ artist_filter_ids = []
+
+ def artist_filter(coreartist):
+ return coreartist.media.get_id() in artist_filter_ids
+
+ def artist_search_cb(source, op_id, media, data, error):
+ if error:
+ print("ERROR", error)
+ return
+
+ if not media:
+ self._artist_search_model.set_filter_func(artist_filter)
+ return
+
+ artist_filter_ids.append(media.get_id())
+
+ options = self._fast_options.copy()
+
+ self._source.query(
+ query, self.METADATA_KEYS, options, artist_search_cb)
diff --git a/gnomemusic/views/searchview.py b/gnomemusic/views/searchview.py
index 5fecb8b0..00eadd3b 100644
--- a/gnomemusic/views/searchview.py
+++ b/gnomemusic/views/searchview.py
@@ -58,6 +58,7 @@ class SearchView(BaseView):
self._coremodel = window._app._coremodel
self._model = self._coremodel.get_songs_search_model()
self._album_model = self._coremodel.get_album_search_model()
+ self._artist_model = self._coremodel.get_artist_search_model()
super().__init__('search', None, window)
# self._add_list_renderers()
@@ -110,8 +111,13 @@ class SearchView(BaseView):
self._album_flowbox.connect(
"child-activated", self._on_album_activated)
+ self._artist_listbox = Gtk.ListBox()
+ self._artist_listbox.bind_model(
+ self._artist_model, self._create_artist_widget)
+
self._all_results_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self._all_results_box.pack_start(self._album_flowbox, True, True, 0)
+ self._all_results_box.pack_start(self._artist_listbox, True, True, 0)
self._all_results_box.pack_start(self._songs_listbox, True, True, 0)
# self._ctrl = Gtk.GestureMultiPress().new(self._view)
@@ -167,6 +173,26 @@ class SearchView(BaseView):
return album_widget
+ def _create_artist_widget(self, coresong):
+ # FIXME: Hacky quick 'artist' widget. Needs its own tile.
+ song_widget = SongWidget(coresong.props.media)
+ song_widget._title_label.props.label = coresong.props.artist
+ song_widget.props.show_duration = False
+ song_widget.props.show_favorite = False
+ song_widget.props.show_song_number = False
+ song_widget.coreartist = coresong
+
+ self.bind_property(
+ "selection-mode", song_widget, "selection-mode",
+ GObject.BindingFlags.BIDIRECTIONAL
+ | GObject.BindingFlags.SYNC_CREATE)
+
+ song_widget.connect('button-release-event', self._artist_activated)
+
+ song_widget.show_all()
+
+ return song_widget
+
def _song_activated(self, widget, event):
mod_mask = Gtk.accelerator_get_default_mod_mask()
if ((event.get_state() & mod_mask) == Gdk.ModifierType.CONTROL_MASK
@@ -205,6 +231,25 @@ class SearchView(BaseView):
self.set_visible_child(self._album_widget)
+ def _artist_activated(self, widget, event):
+ 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
+
+ (_, button) = event.get_button()
+ if (button == Gdk.BUTTON_PRIMARY
+ and not self.props.selection_mode):
+ # self.emit('song-activated', widget)
+ pass
+
+ # FIXME: Need to ignore the event from the checkbox.
+ # if self.props.selection_mode:
+ # widget.props.selected = not widget.props.selected
+
+ return True
+
def _child_select(self, child, value):
widget = child.get_child()
widget.props.selected = value
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]