[gnome-music] view: Add Search view



commit bb8b6cdde0eb40c23371ff2967ce5af455442d5b
Author: Arnel Borja <arnelborja src gnome org>
Date:   Sun May 4 00:09:15 2014 +0800

    view: Add Search view

 gnomemusic/searchbar.py |   23 +------
 gnomemusic/view.py      |  156 +++++++++++++++++++++++++++++++++++++++++++++++
 gnomemusic/window.py    |    4 +-
 3 files changed, 163 insertions(+), 20 deletions(-)
---
diff --git a/gnomemusic/searchbar.py b/gnomemusic/searchbar.py
index 4ba34a7..18375f2 100644
--- a/gnomemusic/searchbar.py
+++ b/gnomemusic/searchbar.py
@@ -188,7 +188,6 @@ class Searchbar(Gd.Revealer):
         self._search_entry = Gd.TaggedEntry(width_request=500, halign=Gtk.Align.CENTER)
         self._search_entry.connect("changed", self.search_entry_timeout)
         self._search_entry.show()
-        self.connect("notify::child-revealed", self.prepare_search_filter)
         self._searchContainer.add(self._search_entry)
 
         self._dropDownButtonArrow = Gtk.Arrow(arrow_type=Gtk.ArrowType.DOWN, shadow_type=Gtk.ShadowType.NONE)
@@ -212,7 +211,6 @@ class Searchbar(Gd.Revealer):
         item.set_expand(True)
         item.show()
         toolbar.insert(item, 0)
-        self.view = None
         item.add(self._searchContainer)
 
     @log
@@ -224,13 +222,6 @@ class Searchbar(Gd.Revealer):
         tag.manager.reset_to_default()
 
     @log
-    def prepare_search_filter(self, widget, data):
-        self.view = self.stack_switcher.get_stack().get_visible_child()
-        if self.view.header_bar._state == 0:
-            # album was selected on album view, view needs to be redefined
-            self.view = self.view._albumWidget
-
-    @log
     def search_entry_timeout(self, widget):
         if self.timeout:
             GLib.source_remove(self.timeout)
@@ -260,17 +251,11 @@ class Searchbar(Gd.Revealer):
         }
 
         fields_filter = self.dropdown.searchFieldsManager.get_active()
+        search_term = self._search_entry.get_text()
 
-        self.search_term = self._search_entry.get_text()
-        if self.view:
-            self.view._model.clear()
-            # Check that current source can do Query
-            if grilo.search_source.supported_operations() & Grl.SupportedOps.QUERY:
-                query = query_matcher[self.view.__class__.__name__][fields_filter](self.search_term)
-                grilo.populate_custom_query(query, self.view._add_item)
-            else:
-                # nope, can't do - reverting to Search
-                grilo.search(self.search_term, self.view._add_item)
+        view = self.stack_switcher.get_stack().get_child_by_name('search')
+        self.stack_switcher.get_stack().set_visible_child(view)
+        view.set_search_text(search_term, fields_filter)
 
     @log
     def show_bar(self, show):
diff --git a/gnomemusic/view.py b/gnomemusic/view.py
index ad010a4..aff11f4 100644
--- a/gnomemusic/view.py
+++ b/gnomemusic/view.py
@@ -43,6 +43,7 @@ from gi.repository import Tracker
 
 from gettext import gettext as _, ngettext
 from gnomemusic.grilo import grilo
+from gnomemusic.query import Query
 from gnomemusic.toolbar import ToolbarState
 import gnomemusic.widgets as Widgets
 from gnomemusic.playlists import Playlists
@@ -1152,3 +1153,158 @@ class Playlist(ViewContainer):
     def get_selected_track_uris(self, callback):
         callback([self._model.get_value(self._model.get_iter(path), 5).get_url()
                   for path in self.view.get_selection()])
+
+
+class Search(ViewContainer):
+    @log
+    def __init__(self, header_bar, selection_toolbar, player):
+        ViewContainer.__init__(self, 'search', None, header_bar, selection_toolbar, Gd.MainViewType.LIST)
+        self._items = {}
+        self.isStarred = None
+        self.iter_to_clean = None
+        self._iconHeight = 48
+        self._iconWidth = 48
+        self.cache = albumArtCache.get_default()
+        self._symbolicIcon = self.cache.get_default_icon(self._iconHeight,
+                                                         self._iconWidth)
+        self._add_list_renderers()
+        self.player = player
+        self.head_iters = [None, None, None, None]
+
+        self.view.get_generic_view().set_show_expanders(False)
+
+    @log
+    def _on_item_activated(self, widget, id, path):
+        pass
+
+    def _add_item(self, source, param, item, remaining=0, data=None):
+        if data is None:
+            return
+
+        model, category = data
+        if not item or model != self._model:
+            return
+
+        self._offset += 1
+        title = albumArtCache.get_media_title(item)
+        item.set_title(title)
+        artist = item.get_string(Grl.METADATA_KEY_ARTIST) \
+            or item.get_author() \
+            or _("Unknown Artist")
+
+        group = 0 if category == 'album' else \
+                1 if category == 'artist' else \
+                2 if category == 'song' else 3
+
+        _iter = self._model.insert_with_values(
+            self.head_iters[group], -1,
+            [0, 2, 3, 4, 5, 8, 9, 10, 11],
+            [str(item.get_id()), title, artist,
+            self._symbolicIcon, item, self.nowPlayingIconName, False, False, category])
+        albumArtCache.get_default().lookup(
+            item, self._iconWidth, self._iconHeight, self._on_lookup_ready,
+            _iter, artist, title)
+
+        if category == 'song':
+            self.player.discover_item(item, self._on_discovered, _iter)
+
+        self.view.get_generic_view().expand_all()
+
+    @log
+    def _add_list_renderers(self):
+        list_widget = self.view.get_generic_view()
+        cols = list_widget.get_columns()
+
+        title_renderer = Gtk.CellRendererText(
+            xpad=12,
+            xalign=0.0,
+            yalign=0.5,
+            height=32,
+            ellipsize=Pango.EllipsizeMode.END,
+            weight=Pango.Weight.BOLD
+        )
+        list_widget.add_renderer(title_renderer,
+                                 self._on_list_widget_title_render, None)
+        cols[0].add_attribute(title_renderer, 'text', 2)
+
+        cells = cols[0].get_cells()
+        cols[0].reorder(cells[0], -1)
+        cols[0].set_cell_data_func(cells[0], self._on_list_widget_selection_render, None)
+
+    def _on_list_widget_selection_render(self, col, cell, model, _iter, data):
+        cell.set_visible(self.view.get_selection_mode() and model.iter_parent(_iter) is not None)
+
+    def _on_list_widget_title_render(self, col, cell, model, _iter, data):
+        cells = col.get_cells()
+        cells[0].set_visible(model.iter_parent(_iter) is not None)
+        cells[1].set_visible(model.iter_parent(_iter) is not None)
+        cells[2].set_visible(model.iter_parent(_iter) is None)
+
+    @log
+    def populate(self):
+        pass
+
+    @log
+    def get_selected_track_uris(self, callback):
+        pass
+
+    @log
+    def _filter_visible_func(self, model, _iter, data=None):
+        return model.iter_parent(_iter) is not None or model.iter_has_child(_iter)
+
+    @log
+    def set_search_text(self, search_term, fields_filter):
+        query_matcher = {
+            'album': {
+                'search_all': Query.get_albums_with_any_match,
+                'search_artist': Query.get_albums_with_artist_match,
+                'search_album': Query.get_albums_with_album_match,
+                'search_track': Query.get_albums_with_track_match,
+            },
+            'artist': {
+                'search_all': Query.get_artists_with_any_match,
+                'search_artist': Query.get_artists_with_artist_match,
+                'search_album': Query.get_artists_with_album_match,
+                'search_track': Query.get_artists_with_track_match,
+            },
+            'song': {
+                'search_all': Query.get_songs_with_any_match,
+                'search_artist': Query.get_songs_with_artist_match,
+                'search_album': Query.get_songs_with_album_match,
+                'search_track': Query.get_songs_with_track_match,
+            },
+        }
+
+        self._model = Gtk.TreeStore(
+            GObject.TYPE_STRING,
+            GObject.TYPE_STRING,
+            GObject.TYPE_STRING,    # item title or header text
+            GObject.TYPE_STRING,    # artist for albums and songs
+            GdkPixbuf.Pixbuf,       # album art
+            GObject.TYPE_OBJECT,    # item
+            GObject.TYPE_BOOLEAN,
+            GObject.TYPE_INT,
+            GObject.TYPE_STRING,
+            GObject.TYPE_BOOLEAN,
+            GObject.TYPE_BOOLEAN,
+            GObject.TYPE_STRING     # type
+        )
+        self.filter_model = self._model.filter_new(None)
+        self.filter_model.set_visible_func(self._filter_visible_func)
+        self.view.set_model(self.filter_model)
+
+        albums_iter = self._model.insert_with_values(None, -1, [2], ['Albums'])
+        artists_iter = self._model.insert_with_values(None, -1, [2], ['Artists'])
+        songs_iter = self._model.insert_with_values(None, -1, [2], ['Songs'])
+        playlists_iter = self._model.insert_with_values(None, -1, [2], ['Playlists'])
+
+        self.head_iters = [albums_iter, artists_iter, songs_iter, playlists_iter]
+
+        # Check that current source can do Query
+        if grilo.search_source.supported_operations() & Grl.SupportedOps.QUERY:
+            for category in ('album', 'artist', 'song'):
+                query = query_matcher[category][fields_filter](search_term)
+                grilo.populate_custom_query(query, self._add_item, -1, [self._model, category])
+        else:
+            # nope, can't do - reverting to Search
+            grilo.search(search_term, self._add_item)
diff --git a/gnomemusic/window.py b/gnomemusic/window.py
index 5ea5567..a3e62d7 100644
--- a/gnomemusic/window.py
+++ b/gnomemusic/window.py
@@ -229,6 +229,7 @@ class Window(Gtk.ApplicationWindow):
         self.views.append(Views.Artists(self.toolbar, self.selection_toolbar, self.player))
         self.views.append(Views.Songs(self.toolbar, self.selection_toolbar, self.player))
         self.views.append(Views.Playlist(self.toolbar, self.selection_toolbar, self.player))
+        self.views.append(Views.Search(self.toolbar, self.selection_toolbar, self.player))
 
         for i in self.views:
             if i.title:
@@ -326,7 +327,8 @@ class Window(Gtk.ApplicationWindow):
            stack.get_visible_child() == self.views[3]:
             stack.get_visible_child().stack.set_visible_child_name('dummy')
             stack.get_visible_child().stack.set_visible_child_name('sidebar')
-        self.toolbar.searchbar.show_bar(False)
+        if stack.get_visible_child() != self.views[4]:
+            self.toolbar.searchbar.show_bar(False)
 
     @log
     def _toggle_view(self, btn, i):


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