Ticket #3838: 0002-Add-feedback-in-Home-View-List-View-when-there-are-n.patch

File 0002-Add-feedback-in-Home-View-List-View-when-there-are-n.patch, 8.6 KB (added by manuq, 12 years ago)

Proposed patch.

  • src/jarabe/desktop/activitieslist.py

    From 0051beee3c518a5c25c5142d2a8697a2e9906ea2 Mon Sep 17 00:00:00 2001
    From: =?UTF-8?q?Manuel=20Qui=C3=B1ones?= <manuq@laptop.org>
    Date: Tue, 18 Sep 2012 10:25:19 -0300
    Subject: [PATCH sugar 2/2] Add feedback in Home View, List View when there
     are no matching entries - SL #3838
    MIME-Version: 1.0
    Content-Type: text/plain; charset=UTF-8
    Content-Transfer-Encoding: 8bit
    Mail-Followup-To: <sugar-devel@lists.sugarlabs.org>
    
    The scrolled window widget that contains the list of activities is
    replaced by a message box when there are no matching entries.  This is
    the same as the Journal does.  An alert can be packed also, so we use
    pack_end to add the message box or the list of activities again.
    
    Use Gtk.TreeModel.iter_n_children() [1] to count the matches, note
    that this work only for tree model lists.
    
    The message box widget is copied from the Journal listview.  Is done
    in a separate class and can be generalized later.  The only important
    change here is the icon colors: to make the 'system-search' icon look
    ok, the stroke color and fill color were switched.
    
    [1] http://developer.gnome.org/gtk3/stable/GtkTreeModel.html#gtk-tree-model-iter-n-children
    
    Signed-off-by: Manuel Quiñones <manuq@laptop.org>
    ---
     src/jarabe/desktop/activitieslist.py | 102 +++++++++++++++++++++++++++++++----
     src/jarabe/desktop/homebox.py        |   1 +
     src/jarabe/desktop/viewtoolbar.py    |   9 ++++
     3 files changed, 103 insertions(+), 9 deletions(-)
    
    diff --git a/src/jarabe/desktop/activitieslist.py b/src/jarabe/desktop/activitieslist.py
    index ab62b58..6731df3 100644
    a b import os 
    1919import logging
    2020from gettext import gettext as _
    2121
     22import glib
    2223from gi.repository import GObject
    2324from gi.repository import Pango
    2425from gi.repository import GConf
    from sugar3.graphics.icon import Icon, CellRendererIcon 
    3132from sugar3.graphics.xocolor import XoColor
    3233from sugar3.graphics.menuitem import MenuItem
    3334from sugar3.graphics.alert import Alert
     35from sugar3.graphics.icon import EventIcon
    3436
    3537from jarabe.model import bundleregistry
    3638from jarabe.view.palettes import ActivityPalette
    class ActivitiesTreeView(Gtk.TreeView): 
    5052
    5153        self._query = ''
    5254
    53         self.modify_base(Gtk.StateType.NORMAL, style.COLOR_WHITE.get_gdk_color())
     55        self.modify_base(Gtk.StateType.NORMAL,
     56                         style.COLOR_WHITE.get_gdk_color())
    5457        self.set_headers_visible(False)
    5558        selection = self.get_selection()
    5659        selection.set_mode(Gtk.SelectionMode.NONE)
    class ActivitiesTreeView(Gtk.TreeView): 
    147150        misc.launch(bundle)
    148151
    149152    def set_filter(self, query):
     153        """Set a new query and refilter the model, return the number
     154        of matching activities.
     155
     156        """
    150157        self._query = query.lower()
    151158        self.get_model().refilter()
     159        matches = self.get_model().iter_n_children(None)
     160        return matches
    152161
    153162    def __model_visible_cb(self, model, tree_iter, data):
    154163        title = model[tree_iter][ListModel.COLUMN_TITLE]
    class CellRendererActivityIcon(CellRendererIcon): 
    296305        self.emit('erase-activated', bundle_id)
    297306
    298307
     308class ClearMessageBox(Gtk.EventBox):
     309    def __init__(self, message, button_callback):
     310        Gtk.EventBox.__init__(self)
     311
     312        self.modify_bg(Gtk.StateType.NORMAL,
     313                       style.COLOR_WHITE.get_gdk_color())
     314
     315        alignment = Gtk.Alignment.new(0.5, 0.5, 0.1, 0.1)
     316        self.add(alignment)
     317        alignment.show()
     318
     319        box = Gtk.VBox()
     320        alignment.add(box)
     321        box.show()
     322
     323        icon = EventIcon(pixel_size=style.LARGE_ICON_SIZE,
     324                         icon_name='system-search',
     325                         stroke_color=style.COLOR_TRANSPARENT.get_svg(),
     326                         fill_color=style.COLOR_BUTTON_GREY.get_svg())
     327        box.pack_start(icon, expand=True, fill=False, padding=0)
     328        icon.show()
     329
     330        label = Gtk.Label()
     331        color = style.COLOR_BUTTON_GREY.get_html()
     332        label.set_markup('<span weight="bold" color="%s">%s</span>' % ( \
     333                color, glib.markup_escape_text(message)))
     334        box.pack_start(label, expand=True, fill=False, padding=0)
     335        label.show()
     336
     337        button = Gtk.Button(label=_('Clear search'))
     338        button.connect('clicked', button_callback)
     339        button.props.image = Icon(icon_name='dialog-cancel',
     340                                  icon_size=Gtk.IconSize.BUTTON)
     341        box.pack_start(button, expand=True, fill=False, padding=0)
     342        button.show()
     343
     344
    299345class ActivitiesList(Gtk.VBox):
    300346    __gtype_name__ = 'SugarActivitiesList'
    301347
     348    __gsignals__ = {
     349        'clear-clicked': (GObject.SignalFlags.RUN_FIRST, None, ([])),
     350    }
     351
    302352    def __init__(self):
    303353        logging.debug('STARTUP: Loading the activities list')
    304354
    305355        Gtk.VBox.__init__(self)
    306356
    307         scrolled_window = Gtk.ScrolledWindow()
    308         scrolled_window.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
    309         scrolled_window.set_shadow_type(Gtk.ShadowType.NONE)
    310         scrolled_window.connect('key-press-event', self.__key_press_event_cb)
    311         self.pack_start(scrolled_window, True, True, 0)
    312         scrolled_window.show()
     357        self._scrolled_window = Gtk.ScrolledWindow()
     358        self._scrolled_window.set_policy(Gtk.PolicyType.NEVER,
     359                                         Gtk.PolicyType.AUTOMATIC)
     360        self._scrolled_window.set_shadow_type(Gtk.ShadowType.NONE)
     361        self._scrolled_window.connect('key-press-event',
     362                                      self.__key_press_event_cb)
     363        self.pack_start(self._scrolled_window, True, True, 0)
     364        self._scrolled_window.show()
    313365
    314366        self._tree_view = ActivitiesTreeView()
    315367        self._tree_view.connect('erase-activated', self.__erase_activated_cb)
    316         scrolled_window.add(self._tree_view)
     368        self._scrolled_window.add(self._tree_view)
    317369        self._tree_view.show()
    318370
    319371        self._alert = None
     372        self._clear_message_box = None
    320373
    321374    def set_filter(self, query):
    322         self._tree_view.set_filter(query)
     375        matches = self._tree_view.set_filter(query)
     376        if matches == 0:
     377            self._show_clear_message()
     378        else:
     379            self._hide_clear_message()
    323380
    324381    def __key_press_event_cb(self, scrolled_window, event):
    325382        keyname = Gdk.keyval_name(event.keyval)
    class ActivitiesList(Gtk.VBox): 
    339396
    340397        return True
    341398
     399    def _show_clear_message(self):
     400        if self._clear_message_box in self.get_children():
     401            return
     402        if self._scrolled_window in self.get_children():
     403            self.remove(self._scrolled_window)
     404
     405        self._clear_message_box = ClearMessageBox(
     406            message=_('No matching activities'),
     407            button_callback=self.__clear_button_clicked_cb)
     408
     409        self.pack_end(self._clear_message_box, True, True, 0)
     410        self._clear_message_box.show()
     411
     412    def __clear_button_clicked_cb(self, button):
     413        self.emit('clear-clicked')
     414
     415    def _hide_clear_message(self):
     416        if self._scrolled_window in self.get_children():
     417            return
     418        if self._clear_message_box in self.get_children():
     419            self.remove(self._clear_message_box)
     420
     421        self._clear_message_box = None
     422
     423        self.pack_end(self._scrolled_window, True, True, 0)
     424        self._scrolled_window.show()
     425
    342426    def add_alert(self, alert):
    343427        if self._alert is not None:
    344428            self.remove_alert()
  • src/jarabe/desktop/homebox.py

    diff --git a/src/jarabe/desktop/homebox.py b/src/jarabe/desktop/homebox.py
    index 875ecf6..17bb609 100644
    a b class HomeBox(Gtk.VBox): 
    4545
    4646        toolbar.connect('query-changed', self.__toolbar_query_changed_cb)
    4747        toolbar.connect('view-changed', self.__toolbar_view_changed_cb)
     48        toolbar.attach_to_clear(self._list_view)
    4849
    4950        self._set_view(_FAVORITES_VIEW)
    5051        self._query = ''
  • src/jarabe/desktop/viewtoolbar.py

    diff --git a/src/jarabe/desktop/viewtoolbar.py b/src/jarabe/desktop/viewtoolbar.py
    index 340ab73..59798c6 100644
    a b class ViewToolbar(Gtk.Toolbar): 
    9292        self._favorites_button.hide()
    9393        self._list_button.hide()
    9494
     95    def attach_to_clear(self, widget):
     96        widget.connect('clear-clicked', self.__clear_clicked_cb)
     97
     98    def __clear_clicked_cb(self, widget):
     99        self.clear_query()
     100
     101    def clear_query(self):
     102        self.search_entry.props.text = ''
     103
    95104    def _add_separator(self, expand=False):
    96105        separator = Gtk.SeparatorToolItem()
    97106        separator.props.draw = False