billreminder r661 - in trunk: . src/daemon src/gui src/gui/widgets src/lib



Author: ogmaciel
Date: Mon Sep 29 18:19:31 2008
New Revision: 661
URL: http://svn.gnome.org/viewvc/billreminder?rev=661&view=rev

Log:
Integration of timeline widget into the main dialog.

Modified:
   trunk/ChangeLog
   trunk/src/daemon/dbus_manager.py
   trunk/src/gui/maindialog.py
   trunk/src/gui/widgets/timeline.py
   trunk/src/lib/actions.py
   trunk/src/lib/dbus_actions.py
   trunk/src/lib/scheduler.py

Modified: trunk/src/daemon/dbus_manager.py
==============================================================================
--- trunk/src/daemon/dbus_manager.py	(original)
+++ trunk/src/daemon/dbus_manager.py	Mon Sep 29 18:19:31 2008
@@ -72,6 +72,23 @@
             ret.append(force_string(record))
         return ret
 
+    @dbus.service.method(common.DBUS_INTERFACE, in_signature='iii', out_signature='a(sis)')
+    def get_interval_totals(self, status, start, end):
+        # Return a list of categories and totals for the given month
+        ret = []
+        records = self.actions.get_interval_totals(status, start, end)
+        for record in records:
+            ret.append(record)
+        return ret
+
+    @dbus.service.method(common.DBUS_INTERFACE, in_signature='iii', out_signature='aa{ss}')
+    def get_interval_bills(self, status, start, end):
+        ret = []
+        records = self.actions.get_interval_bills(status, start, end)
+        for record in records:
+            ret.append(force_string(record))
+        return ret
+
     @dbus.service.method(common.DBUS_INTERFACE, in_signature='a{ss}', out_signature='aa{ss}')
     def get_bills(self, kwargs):
         """ Returns one or more records that meet the criteria passed """

Modified: trunk/src/gui/maindialog.py
==============================================================================
--- trunk/src/gui/maindialog.py	(original)
+++ trunk/src/gui/maindialog.py	Mon Sep 29 18:19:31 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.timeline import Timeline, Bullet
 from gui.widgets.SearchEntry import SearchEntry
 
 # Import data model modules
@@ -75,6 +76,7 @@
         </ui>'''
 
     search_text = ""
+    _bullet_cache = {}
 
     def __init__(self):
         if exists(join(USER_CFG_PATH, CFG_NAME)):
@@ -83,6 +85,8 @@
         
         self.gconf_client = gconf.client_get_default()
         self.message = Message()
+        # Connects to the database
+        self.actions = Actions()
 
         # Create a new window
         self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
@@ -130,6 +134,13 @@
         ## Pack it all up
         self.calbox.pack_start(self.calendar, expand=True, fill=True)
 
+        # Timeline
+        self.timelinebox = gtk.HBox(homogeneous=False, spacing=4)
+        self.timeline = Timeline(callback=self.on_timeline_cb)
+        self.timeline.connect("value-changed", self._on_timeline_changed)
+        ## Pack it all up
+        self.timelinebox.pack_start(self.timeline, expand=True, fill=True)
+
         ## Search Entry
 
         self.filter_hbox = gtk.HBox(homogeneous=False, spacing=4)
@@ -157,8 +168,10 @@
         # Pack it all up
         self.box.pack_start(self.toolbar,
             expand=False, fill=True, padding=0)
-        self.box.pack_start(self.calbox,
-            expand=False, fill=True, padding=4)
+        #self.box.pack_start(self.calbox,
+        #    expand=False, fill=True, padding=4)
+        self.box.pack_start(self.timelinebox,
+            expand=False, fill=True, padding=0)
         self.box.pack_start(self.listbox,
             expand=True, fill=True, padding=4)
         self.box.pack_start(self.filter_hbox,
@@ -190,8 +203,6 @@
 
         self.toggle_buttons()
 
-        # Connects to the database
-        self.actions = Actions()
         # populate treeview
         self.reloadTreeView()
         self.notify = NotifyIcon(self)
@@ -252,6 +263,9 @@
         # Reset list
         self.list.listStore.clear()
 
+        if not records:
+            return 0
+            
         # Loops through bills collection
         path = 0
         for rec in records:
@@ -263,15 +277,17 @@
     def reloadTreeView(self, *arg):
         # Update list with updated record
         status = self.gconf_client.get_int(GCONF_GUI_PATH + 'show_paid_bills')
-        month = self.calendar.currentMonth
-        year = self.calendar.currentYear
+        month = self.timeline.value.month
+        year = self.timeline.value.year
 
         path = self.list.get_cursor()[0]
         self.list.listStore.clear()
         self.currentrecord = None
 
+        first = scheduler.timestamp_from_datetime(self.timeline.start_date)
+        last = scheduler.timestamp_from_datetime(self.timeline.end_date)
         # Get list of records
-        records = self.actions.get_monthly_bills(status, month, year)
+        records = self.actions.get_interval_bills(status, first, last)
 
         # Populate treeview
         self._populateTreeView(records)
@@ -280,8 +296,8 @@
         # Update status bar
         self._update_statusbar()
         # populate chart
-        self._populate_chart(status, month, year)
-
+        self._populate_chart(status, first, last)
+        
         return len(records)
 
     def _formated_row(self, row):
@@ -324,9 +340,9 @@
             _("Not Paid"), _("Mark as not paid"), self.on_btnPaid_clicked)
         self.btnUnpaid.set_is_important(True)
 
-    def _populate_chart(self, status, month, year):
+    def _populate_chart(self, status, start, end):
         chartdata = []
-        records = self.actions.get_monthly_totals(status, month, year)
+        records = self.actions.get_interval_totals(status, start, end)
         for rec in records:
             chartdata.append([field for field in rec])
         #if chartdata:
@@ -605,6 +621,9 @@
     def _on_calendar_month_changed(self, widget, args):
         self.reloadTreeView()
 
+    def _on_timeline_changed(self, widget, args):
+        self.reloadTreeView()
+
     def _on_show_toolbar(self, action):
         # Toggle toolbar's visibility
         if action.get_active():
@@ -632,6 +651,44 @@
 
         return t
 
+    def on_timeline_cb(self, date):
+        # TODO: Improve tooltip
+        # TODO: Improve cache
+        if not date in self._bullet_cache.keys():
+            time = scheduler.timestamp_from_datetime(date)
+            self._bullet_cache[date] = self.actions.get_bills('dueDate = %s' % time)
+        
+        if self._bullet_cache[date]:
+            amount = 0
+            paid = 1
+            tooltip = ''
+            bullet = Bullet()
+            bullet.date = date
+            
+            for bill in self._bullet_cache[date]:
+                paid *= bill['paid']
+                amount += bill['amountDue']
+                if tooltip:
+                    tooltip += '\n'
+                tooltip += bill['payee'] + '\n' + str(bill['amountDue']) 
+                if bill['notes']:
+                    tooltip += '\n' + bill['notes']
+                
+            bullet.amountDue = amount
+            if paid:
+                bullet.status = bullet.PAID
+            elif date <= datetime.date.today():
+                bullet.status = bullet.OVERDUE
+            else:
+                bullet.status = bullet.TO_BE_PAID
+
+            if len(self._bullet_cache[date]) > 1:
+                bullet = True
+            bullet.tooltip = tooltip
+            return bullet
+        
+        return None
+
 def main():
     gtk.main()
 

Modified: trunk/src/gui/widgets/timeline.py
==============================================================================
--- trunk/src/gui/widgets/timeline.py	(original)
+++ trunk/src/gui/widgets/timeline.py	Mon Sep 29 18:19:31 2008
@@ -16,10 +16,10 @@
 
     debug = False
     
-    def __init__(self, date=None, amount=None, estimated=False, status=0,
+    def __init__(self, date=None, amountDue=None, estimated=False, status=0,
       overthreshold=False, multi=False, tooltip=''):
         self.date = date
-        self.amount = amount
+        self.amountDue = amountDue
         self.estimated = estimated
         self.status = status
         self.overthreshold = overthreshold
@@ -274,7 +274,7 @@
                                             self._div_width * i + \
                                             self._div_width / 2 - size_[0] / 2),
                                             self._box_rect.y + \
-                                            self._box_rect.height + 10,
+                                            self._box_rect.height + 12,
                                             self._layout)
                                             
                 line_h = 6
@@ -292,7 +292,7 @@
                                             self._div_width * i + \
                                             self._div_width / 2 - size_[0] / 2),
                                             self._box_rect.y + \
-                                            self._box_rect.height + 10,
+                                            self._box_rect.height + 12,
                                             self._layout)
                                             
                 line_h = 6
@@ -436,6 +436,7 @@
 
     def do_button_press_event(self, event):
         mx, my = self.get_pointer()
+        self.grab_focus()
         # Stop the autoscroll trigger timer
         if self._timer:
             gobject.source_remove(self._timer)
@@ -529,7 +530,7 @@
                           self._display_days
         # Set Timeline box size
         self._box_rect.x = 21
-        self._box_rect.y = 8
+        self._box_rect.y = 6
         self._box_rect.width = allocation.width - self._box_rect.x * 2
         self._box_rect.height = allocation.height - 33
         # Set Bullet radius
@@ -628,7 +629,13 @@
             self.set_position(self.position - 1, True)
         elif self.position < (self._display_days - 1) / 2:
             self.set_position(self.position + 1, True)
-        return self.position != self._display_days / 2
+            
+        if self.position == (self._display_days - 1) / 2:
+            self.value = self._dates[self.position]
+            self._dist_dates()
+            self._value_changed()
+            
+        return self.position != (self._display_days - 1) / 2
             
     def move(self, pos, update=True, redraw=True):
         position_old = self.position

Modified: trunk/src/lib/actions.py
==============================================================================
--- trunk/src/lib/actions.py	(original)
+++ trunk/src/lib/actions.py	Mon Sep 29 18:19:31 2008
@@ -60,6 +60,40 @@
 
         return records
 
+    def get_interval_totals(self, status, start, end):
+        # Return a list of categories and totals for the given month
+        # Delimeters for our search
+
+        # Determine status criteria
+        status = status < 2 and ' = %s' % status or ' in (0,1)'
+
+        stmt = 'select categoryName, ' \
+            ' sum(case when amountDue is null then 0 else amountDue end) as amount, ' \
+            ' color' \
+            ' from br_billstable, br_categoriestable where' \
+            ' paid %s' \
+            ' and dueDate >= ? and dueDate <= ?' \
+            ' and br_categoriestable.Id = br_billstable.catId' \
+            ' GROUP BY catId, color' \
+            ' ORDER BY dueDate ASC' % status
+        params = [start, end]
+        records = self.dal.executeSql(stmt, params)
+
+        return records
+
+    def get_interval_bills(self, status, start, end):
+        # Delimeters for our search
+
+        # Determine status criteria
+        status = status < 2 and ' = %s' % status or ' in (0,1)'
+
+        stmt = 'paid %s' \
+            ' and dueDate >= %s and dueDate <= %s' \
+            ' ORDER BY dueDate DESC' % (status, start, end)
+        records = self.get_bills(stmt)
+
+        return records
+
     def get_bills(self, kwargs):
         """ Returns one or more records that meet the criteria passed """
         return self.dal.get(BillsTable, kwargs)

Modified: trunk/src/lib/dbus_actions.py
==============================================================================
--- trunk/src/lib/dbus_actions.py	(original)
+++ trunk/src/lib/dbus_actions.py	Mon Sep 29 18:19:31 2008
@@ -65,16 +65,43 @@
 
 
     def get_monthly_bills(self, status, month, year):
-        try:
-            ret = []
-            records = self.dbus_interface.get_monthly_bills(status, month, year)
-            for record in records:
-                record = self._correct_type(record)
-                ret.append(record)
-            return ret
-        except dbus.DBusException:
-            if self.__init__():
-                return self.get_monthly_bills(status, month, year)
+        #try:
+        ret = []
+        records = self.dbus_interface.get_monthly_bills(status, month, year)
+        for record in records:
+            record = self._correct_type(record)
+            ret.append(record)
+        return ret
+        #except dbus.DBusException:
+        #    if self.__init__():
+        #        return self.get_monthly_bills(status, month, year)
+
+    def get_interval_totals(self, status, start, end):
+        # Return a list of categories and totals for the given month
+        #try:
+        ret = []
+        records = self.dbus_interface.get_interval_totals(status, start, end)
+        for record in records:
+            record = self._correct_type(record)
+            ret.append(record)
+        return ret
+        #except dbus.DBusException:
+        #    if self.__init__():
+        #        return self.get_interval_totals(status, start, end)
+
+
+    def get_interval_bills(self, status, start, end):
+        #try:
+        ret = []
+        records = self.dbus_interface.get_interval_bills(status, start, end)
+        for record in records:
+            record = self._correct_type(record)
+            ret.append(record)
+        return ret
+        #except dbus.DBusException:
+        #    if self.__init__():
+        #        return self.get_monthly_bills(status, start, end)
+
         
     def get_bills(self, kwargs):
         """ Returns one or more records that meet the criteria passed """

Modified: trunk/src/lib/scheduler.py
==============================================================================
--- trunk/src/lib/scheduler.py	(original)
+++ trunk/src/lib/scheduler.py	Mon Sep 29 18:19:31 2008
@@ -21,12 +21,12 @@
 
 def timestamp_from_datetime(date):
     ''' Convert a datetime object into a time object. '''
-    if isinstance(date, datetime.datetime):
+    if isinstance(date, (datetime.datetime, datetime.date)):
         ret = time.mktime(date.timetuple())
     else:
         ret = time.time()
 
-    return ret
+    return int(ret)
 
 def datetime_from_timestamp(timestamp):
     ''' Convert a time object into a datetime object. '''



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