[gnome-music] Rework search state handling



commit fdf9b113cff80c4aad1e7793feca8a0b88757efc
Author: ymdatta <ymdatta protonmail com>
Date:   Tue Nov 6 10:28:40 2018 +0530

    Rework search state handling
    
    Search is currently an intertwined part of SearchView. As a first cleaning
    step create a search-state property and use it to communicate state changes
    between SearchView and SearchBar.

 gnomemusic/search.py            | 39 +++++++++++++++++++++++++++++++++++++++
 gnomemusic/views/searchview.py  | 30 +++++++++++++-----------------
 gnomemusic/widgets/searchbar.py | 16 +++++++++++++---
 gnomemusic/window.py            |  3 +++
 4 files changed, 68 insertions(+), 20 deletions(-)
---
diff --git a/gnomemusic/search.py b/gnomemusic/search.py
new file mode 100644
index 00000000..78000f76
--- /dev/null
+++ b/gnomemusic/search.py
@@ -0,0 +1,39 @@
+# Copyright 2018 The GNOME Music developers
+#
+# GNOME Music is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# GNOME Music is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with GNOME Music; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# The GNOME Music authors hereby grant permission for non-GPL compatible
+# GStreamer plugins to be used and distributed together with GStreamer
+# and GNOME Music.  This permission is above and beyond the permissions
+# granted by the GPL license by which GNOME Music is covered.  If you
+# modify this code, you may extend this exception to your version of the
+# code, but you are not obligated to do so.  If you do not wish to do so,
+# delete this exception statement from your version.
+
+from enum import IntEnum
+
+
+class Search():
+
+    class State(IntEnum):
+        """States the Search can have
+
+           NONE: No ongoing search.
+           RESULT: Search with result.
+           NO_RESULT: Search without result.
+        """
+        NONE = 0
+        RESULT = 1
+        NO_RESULT = 2
diff --git a/gnomemusic/views/searchview.py b/gnomemusic/views/searchview.py
index 8dfcd4a1..f2e72e89 100644
--- a/gnomemusic/views/searchview.py
+++ b/gnomemusic/views/searchview.py
@@ -34,6 +34,7 @@ from gnomemusic.player import ValidationStatus, PlayerPlaylist
 from gnomemusic.playlists import Playlists
 from gnomemusic.query import Query
 from gnomemusic.utils import View
+from gnomemusic.search import Search
 from gnomemusic.views.baseview import BaseView
 from gnomemusic.widgets.headerbar import HeaderBar
 from gnomemusic.widgets.albumwidget import AlbumWidget
@@ -45,9 +46,7 @@ playlists = Playlists.get_default()
 
 class SearchView(BaseView):
 
-    __gsignals__ = {
-        'no-music-found': (GObject.SignalFlags.RUN_FIRST, None, ())
-    }
+    search_state = GObject.Property(type=int, default=Search.State.NONE)
 
     def __repr__(self):
         return '<SearchView>'
@@ -65,7 +64,6 @@ class SearchView(BaseView):
         self._filter_model = None
 
         self.previous_view = None
-        self.connect('no-music-found', self._no_music_found_callback)
 
         self._albums_selected = []
         self._albums = {}
@@ -100,11 +98,6 @@ class SearchView(BaseView):
 
         view_container.add(self._view)
 
-    @log
-    def _no_music_found_callback(self, view):
-        # FIXME: call into private members
-        self._window._stack.set_visible_child_name("emptyview")
-
     @log
     def _back_button_clicked(self, widget, data=None):
         self._searchbar.reveal(True, False)
@@ -145,7 +138,8 @@ class SearchView(BaseView):
             self._headerbar.props.title = title
             self._headerbar.props.subtitle = artist
             self.set_visible_child(self._album_widget)
-            self._searchbar.reveal(False)
+            self.props.search_state = Search.State.NONE
+
         elif self.model[_iter][12] == 'artist':
             artist = self.model[_iter][2]
             albums = self._artists[artist.casefold()]['albums']
@@ -164,7 +158,7 @@ class SearchView(BaseView):
             self._headerbar.props.state = HeaderBar.State.SEARCH
             self._headerbar.props.title = artist
             self.set_visible_child(self._artist_albums_widget)
-            self._searchbar.reveal(False)
+            self.props.search_state = Search.State.NONE
         elif self.model[_iter][12] == 'song':
             if self.model[_iter][11] != ValidationStatus.FAILED:
                 c_iter = self._songs_model.convert_child_iter_to_iter(_iter)[1]
@@ -225,7 +219,7 @@ class SearchView(BaseView):
         if not item:
             if (grilo._search_callback_counter == 0
                     and grilo.search_source):
-                self.emit('no-music-found')
+                self.props.search_state = Search.State.NO_RESULT
             return
 
         if data != self.model:
@@ -270,11 +264,13 @@ class SearchView(BaseView):
             + self.model.iter_n_children(self._head_iters[3])
         )
 
-        if (category == 'song'
-                and self._items_found == 0
-                and remaining == 0):
-            if grilo.search_source:
-                self.emit('no-music-found')
+        if (category == 'song'):
+            if remaining != 0:
+                self.props.search_state = Search.State.RESULT
+            else:
+                if self._items_found == 0:
+                    if grilo.search_source:
+                        self.props.search_state = Search.State.NO_RESULT
 
         # We need to remember the view before the search view
         emptysearchview = self._window.views[View.EMPTY]
diff --git a/gnomemusic/widgets/searchbar.py b/gnomemusic/widgets/searchbar.py
index 354b3ff9..b8313e7e 100644
--- a/gnomemusic/widgets/searchbar.py
+++ b/gnomemusic/widgets/searchbar.py
@@ -1,6 +1,4 @@
-# Copyright (c) 2013 Seif Lotfy <seif lotfy com>
-# Copyright (c) 2013 Vadim Rutkovsky <vrutkovs redhat com>
-# Copyright (c) 2014 Arnel A. Borja <kyoushuu yahoo com>
+# Copyright 2018 The GNOME Music developers
 #
 # GNOME Music is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -35,6 +33,7 @@ from gi.repository.Gd import TaggedEntry  # noqa: F401
 
 from gnomemusic import log
 from gnomemusic.grilo import grilo
+from gnomemusic.search import Search
 
 
 class BaseModelColumns(IntEnum):
@@ -324,6 +323,7 @@ class Searchbar(Gtk.SearchBar):
     _search_entry = Gtk.Template.Child()
     _drop_down_button = Gtk.Template.Child()
 
+    search_state = GObject.Property(type=int, default=Search.State.NONE)
     stack = GObject.Property(type=Gtk.Stack)
 
     def __repr__(self):
@@ -338,6 +338,7 @@ class Searchbar(Gtk.SearchBar):
 
         self._dropdown = DropDown()
         self._dropdown.initialize_filters(self)
+        self.connect('notify::search-state', self._search_state_changed)
 
     @Gtk.Template.Callback()
     @log
@@ -395,6 +396,15 @@ class Searchbar(Gtk.SearchBar):
         else:
             self._drop_down_button.set_active(False)
 
+    @log
+    def _search_state_changed(self, klass, data):
+        search_state = self.props.search_state
+
+        if search_state == Search.State.NONE:
+            self.reveal(False)
+        elif search_state == Search.State.NO_RESULT:
+            self.props.stack.set_visible_child_name('emptyview')
+
     @log
     def toggle(self):
         """Toggle the searchbar showing"""
diff --git a/gnomemusic/window.py b/gnomemusic/window.py
index 82dfba5d..e77d0461 100644
--- a/gnomemusic/window.py
+++ b/gnomemusic/window.py
@@ -260,6 +260,9 @@ class Window(Gtk.ApplicationWindow):
 
         self._stack.set_visible_child(self.views[View.ALBUM])
 
+        self.views[View.SEARCH].bind_property(
+            'search-state', self._searchbar, 'search-state')
+
     @log
     def _select_all(self, action=None, param=None):
         if not self.props.selection_mode:


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