billreminder r645 - in trunk: . src/gui src/gui/widgets



Author: ogmaciel
Date: Wed Sep 24 14:41:47 2008
New Revision: 645
URL: http://svn.gnome.org/viewvc/billreminder?rev=645&view=rev

Log:
Added the new filtering widget by Wilson Jr.

Added:
   trunk/src/gui/widgets/SearchEntry.py
Modified:
   trunk/ChangeLog
   trunk/src/gui/maindialog.py
   trunk/src/gui/widgets/Makefile.am
   trunk/src/gui/widgets/calendarwidget.py
   trunk/src/gui/widgets/genericlistview.py

Modified: trunk/src/gui/maindialog.py
==============================================================================
--- trunk/src/gui/maindialog.py	(original)
+++ trunk/src/gui/maindialog.py	Wed Sep 24 14:41:47 2008
@@ -17,6 +17,7 @@
 from gui.widgets.trayicon import NotifyIcon
 from gui.widgets.chartwidget import ChartWidget
 from gui.widgets.calendarwidget import CalendarWidget
+from gui.widgets.SearchEntry import SearchEntry
 
 # Import data model modules
 from lib.bill import Bill
@@ -40,6 +41,8 @@
 from lib.common import USER_CFG_PATH
 from os.path import exists, join
 
+SEARCH_COLUMNS = (2, 3, 4, 5, 6)
+
 class MainDialog:
 
     menu_ui = '''
@@ -71,6 +74,8 @@
             </menubar>
         </ui>'''
 
+    search_text = ""
+
     def __init__(self):
         if exists(join(USER_CFG_PATH, CFG_NAME)):
             from lib.migrate_to_gconf import migrate
@@ -94,6 +99,8 @@
         self.list.connect('cursor_changed', self._on_list_cursor_changed)
         self.list.connect('row_activated', self._on_list_row_activated)
         self.list.connect('button_press_event', self._on_list_button_press_event)
+        self.list.filtered_model.set_visible_func(
+            self.on_filtered_model_visible_cb)
 
         # Toolbar
         self.toolbar = Toolbar()
@@ -117,12 +124,31 @@
         self.statusbar = Statusbar()
 
         # Calendar
-        self.calbox = gtk.VBox(homogeneous=False, spacing=1)
+        self.calbox = gtk.HBox(homogeneous=False, spacing=4)
         self.calendar = CalendarWidget()
         self.calendar.connect("date_changed", self._on_calendar_month_changed)
         ## Pack it all up
-        self.calbox.pack_start(self.calendar,
-           expand=True, fill=True, padding=2)
+        self.calbox.pack_start(self.calendar, expand=True, fill=True)
+
+        ## Search Entry
+
+        self.filter_hbox = gtk.HBox(homogeneous=False, spacing=4)
+        self.filter_hbox.pack_start(gtk.Label(), expand=True, fill=True)
+        self.filter_hbox.pack_start(gtk.Label(), expand=True, fill=True)
+        search_label = gtk.Label()
+        search_label.set_markup_with_mnemonic (_("<b>F_ilter:</b>"))
+
+        self.filter_hbox.pack_start(search_label, expand=False, fill=True)
+
+        self.search_entry = SearchEntry(gtk.icon_theme_get_default())
+        self.search_entry.connect("terms-changed", self.on_terms_changed)
+
+        self.filter_hbox.pack_start(self.search_entry, expand=False, fill=True)
+
+        search_label.set_mnemonic_widget(self.search_entry)
+
+        #self.calbox.pack_start(self.filter_hbox, expand=True)
+
         #self.calendar.mark_day(datetime.datetime.today().day)
 
         # Chart
@@ -135,6 +161,8 @@
             expand=False, fill=True, padding=4)
         self.box.pack_start(self.listbox,
             expand=True, fill=True, padding=4)
+        self.box.pack_start(self.filter_hbox,
+            expand=False, fill=True, padding=2)
         self.box.pack_start(self.chart,
             expand=True, fill=True, padding=2)
         self.box.pack_start(self.statusbar,
@@ -585,6 +613,24 @@
         else:
             self.toolbar.hide_all()
             self.gconf_client.set_bool(GCONF_GUI_PATH + "show_toolbar", False)
+    
+    def on_terms_changed(self, widget, text):
+        self.search_text = text
+        self.list.filtered_model.refilter()
+        #self.filtred_model.refilter()
+    
+    def on_filtered_model_visible_cb(self, model, iter):
+        if self.search_text == "":
+            return True
+        
+        t = False
+        for col in SEARCH_COLUMNS:
+            x = model.get_value(iter, col)
+            if x and self.search_text in x:
+                t = True
+                break
+        
+        return t
 
 def main():
     gtk.main()

Modified: trunk/src/gui/widgets/Makefile.am
==============================================================================
--- trunk/src/gui/widgets/Makefile.am	(original)
+++ trunk/src/gui/widgets/Makefile.am	Wed Sep 24 14:41:47 2008
@@ -3,6 +3,9 @@
 billreminder_widgetsdir = $(pythondir)/billreminder/gui/widgets
 billreminder_widgets_PYTHON = \
 	__init__.py \
+	calendarwidget.py \
+	charting.py \
+	chartwidget.py \
 	datebutton.py \
 	genericlistview.py \
 	statusbar.py \
@@ -10,6 +13,7 @@
 	toolbar.py \
 	trayicon.py \
 	viewbill.py \
-	viewcategory.py
+	viewcategory.py \
+	SearchEntry.py
 
 

Added: trunk/src/gui/widgets/SearchEntry.py
==============================================================================
--- (empty file)
+++ trunk/src/gui/widgets/SearchEntry.py	Wed Sep 24 14:41:47 2008
@@ -0,0 +1,184 @@
+# coding: utf-8
+#
+# SearchEntry - An enhanced search entry with alternating background colouring 
+#               and timeout support
+#
+# Copyright (C) 2007 Sebastian Heinlein
+#               2007 Canonical Ltd.
+#               2007 OpenLanhouse
+#
+# Authors:
+#  Sebastian Heinlein <glatzor ubuntu com>
+#
+# This program 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.
+#
+# This program 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
+# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307 USA
+
+import gtk
+import gobject
+
+try:
+    import sexy
+    sexy_avail = True
+    
+except:
+    sexy_avail = False
+    
+    class sexy: #Gambiarra
+        class IconEntry:
+            def __init__(self):
+                pass
+
+
+class SexyEntry(sexy.IconEntry, gobject.GObject):
+    __gsignals__ = {'terms-changed':(gobject.SIGNAL_RUN_FIRST,
+                                     gobject.TYPE_NONE,
+                                     (gobject.TYPE_STRING,))}
+
+    def __init__(self, icon_theme):
+        """
+        Creates an enhanced IconEntry that supports a time out when typing
+        and uses a different background colour when the search is active
+        """
+        sexy.IconEntry.__init__(self)
+        self.__gobject_init__()
+        self._handler_changed = self.connect_after("changed",
+                                                   self._on_changed)
+        self.connect("icon-pressed", self._on_icon_pressed)
+        
+        image = gtk.Image()
+        pixbuf = icon_theme.load_icon(gtk.STOCK_FIND,
+                                      gtk.ICON_SIZE_MENU,
+                                      0)
+        image.set_from_pixbuf(pixbuf)
+        
+        image2 = gtk.Image()
+        pixbuf2 = icon_theme.load_icon(gtk.STOCK_CLEAR,
+                                      gtk.ICON_SIZE_MENU,
+                                      0)
+        image2.set_from_pixbuf(pixbuf2)
+        
+        self.set_icon(sexy.ICON_ENTRY_PRIMARY, image)
+        self.set_icon(sexy.ICON_ENTRY_SECONDARY, image2)
+        self.set_icon_highlight(sexy.ICON_ENTRY_SECONDARY, True)
+
+        # Do not draw a yellow bg if an a11y theme is used
+        settings = gtk.settings_get_default()
+        theme = settings.get_property("gtk-theme-name")
+        self._a11y = theme.startswith("HighContrast") or\
+                     theme.startswith("LowContrast")
+
+        self._timeout_id = 0
+
+    def _on_icon_pressed(self, widget, icon, mouse_button):
+        """
+        Emit the terms-changed signal without any time out when the clear
+        button was clicked
+        """
+        if icon == sexy.ICON_ENTRY_SECONDARY:
+            self.handler_block(self._handler_changed)
+            self.set_text("")
+            self._check_style()
+            self.handler_unblock(self._handler_changed)
+            self.emit("terms-changed", self.get_text())
+
+    def _on_changed(self, widget):
+        """
+        Call the actual search method after a small timeout to allow the user
+        to enter a longer search term
+        """
+        self._check_style()
+        if self._timeout_id > 0:
+            gobject.source_remove(self._timeout_id)
+        #FIXME: Could be of use for a11y
+        #timeout = self.config.get_int("/apps/gnome-app-install/search-timeout")
+        timeout = 1000
+        self._timeout_id = gobject.timeout_add(timeout,
+                            lambda: self.emit("terms-changed", self.get_text()))
+
+    def _check_style(self):
+        
+        if self._a11y == True:
+            return
+        if self.get_text() == "":
+            self.modify_base(gtk.STATE_NORMAL, None)
+        else:
+            self.modify_base(gtk.STATE_NORMAL,
+                             gtk.gdk.Color(63479, 63479, 48830))
+
+class NormalEntry(gtk.Entry, gobject.GObject):
+    __gsignals__ = {'terms-changed':(gobject.SIGNAL_RUN_FIRST,
+                                     gobject.TYPE_NONE,
+                                     (gobject.TYPE_STRING,))}
+
+    def __init__(self, icon_theme):
+        """
+        Creates an enhanced IconEntry that supports a time out when typing
+        and uses a different background colour when the search is active
+        """
+        gtk.Entry.__init__(self)
+        self.__gobject_init__()
+        self._handler_changed = self.connect_after("changed",
+                                                   self._on_changed)
+
+        # Do not draw a yellow bg if an a11y theme is used
+        settings = gtk.settings_get_default()
+        theme = settings.get_property("gtk-theme-name")
+        self._a11y = theme.startswith("HighContrast") or\
+                     theme.startswith("LowContrast")
+
+        self._timeout_id = 0
+
+    def _on_icon_pressed(self, widget, icon, mouse_button):
+        """
+        Emit the terms-changed signal without any time out when the clear
+        button was clicked
+        """
+        if icon == sexy.ICON_ENTRY_SECONDARY:
+            self.handler_block(self._handler_changed)
+            self.set_text("")
+            self._check_style()
+            self.handler_unblock(self._handler_changed)
+            self.emit("terms-changed", self.get_text())
+
+    def _on_changed(self, widget):
+        """
+        Call the actual search method after a small timeout to allow the user
+        to enter a longer search term
+        """
+        self._check_style()
+        if self._timeout_id > 0:
+            gobject.source_remove(self._timeout_id)
+        
+        timeout = 1000
+        self._timeout_id = gobject.timeout_add(timeout,
+                            lambda: self.emit("terms-changed", self.get_text()))
+
+    def _check_style(self):
+        """
+        Use a different background colour if a search is active
+        """
+        # Based on the Rhythmbox code
+        yellowish = gtk.gdk.Color(63479, 63479, 48830)
+        if self._a11y == True:
+            return
+        if self.get_text() == "":
+            self.modify_base(gtk.STATE_NORMAL, None)
+        else:
+            self.modify_base(gtk.STATE_NORMAL, yellowish)
+
+
+if sexy_avail:
+    SearchEntry = SexyEntry
+else:
+    SearchEntry = NormalEntry

Modified: trunk/src/gui/widgets/calendarwidget.py
==============================================================================
--- trunk/src/gui/widgets/calendarwidget.py	(original)
+++ trunk/src/gui/widgets/calendarwidget.py	Wed Sep 24 14:41:47 2008
@@ -71,6 +71,9 @@
         self.yearSpinner.set_snap_to_ticks(True)
         self.yearSpinner.connect("changed", self._on_yearSpinner_changed)
 
+        label1.set_mnemonic_widget(self.monthSelector)
+        label2.set_mnemonic_widget(self.yearSpinner)
+
         placeHolder2 = gtk.Label()
 
         self.pack_start(label1, expand=False, fill=False, padding=4)

Modified: trunk/src/gui/widgets/genericlistview.py
==============================================================================
--- trunk/src/gui/widgets/genericlistview.py	(original)
+++ trunk/src/gui/widgets/genericlistview.py	Wed Sep 24 14:41:47 2008
@@ -95,8 +95,12 @@
 
         # Defines the TreeStore
         self.listStore = gtk.TreeStore(*dataTypes)
+        self.filtered_model = self.listStore.filter_new()
+        
+        self.sorted_model = gtk.TreeModelSort(self.filtered_model)
+        
         # Associates the listStore to the ListView object
-        self.set_model(self.listStore)
+        self.set_model(self.sorted_model)
 
         # Add columns to the List
         for column in treeViewColumns:



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