Commit cbebbcfe authored by Og B. Maciel's avatar Og B. Maciel

Integration of timeline widget into the main dialog.

svn path=/trunk/; revision=661
parent 6e4286c0
2008-09-29 Luiz Armesto <luiz.armesto@gmail.com>
* src/gui/widgets/timeline.py: Renamed Bullet attribute amount to amountDue, and minor fixes.
* src/gui/maindialog.py: Use new timeline widget now.
* src/lib/actions.py, src/lib/dbus_actions.py, src/daemon/dbus_manager.py:
Added new methods to dbus - get_interval_totals and get_interval_bills.
2008-09-28 Og Maciel <ogmaciel@gnome.org>
* src/gui/widgets/timeline.py: More keyboard shortcuts added, such as zoom in/out.
......
......@@ -72,6 +72,23 @@ class Server(dbus.service.Object):
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 """
......
......@@ -17,6 +17,7 @@ from gui.widgets.viewbill import ViewBill as ViewBill
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 @@ class MainDialog:
</ui>'''
search_text = ""
_bullet_cache = {}
def __init__(self):
if exists(join(USER_CFG_PATH, CFG_NAME)):
......@@ -83,6 +85,8 @@ class MainDialog:
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 @@ class MainDialog:
## 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 @@ class MainDialog:
# 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 @@ class MainDialog:
self.toggle_buttons()
# Connects to the database
self.actions = Actions()
# populate treeview
self.reloadTreeView()
self.notify = NotifyIcon(self)
......@@ -252,6 +263,9 @@ class MainDialog:
# 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 @@ class MainDialog:
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 @@ class MainDialog:
# 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 @@ class MainDialog:
_("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 @@ class MainDialog:
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 @@ class MainDialog:
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()
......
......@@ -16,10 +16,10 @@ class Bullet(object):
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 @@ class Timeline(gtk.DrawingArea):
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 @@ class Timeline(gtk.DrawingArea):
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 @@ class Timeline(gtk.DrawingArea):
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 @@ class Timeline(gtk.DrawingArea):
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 @@ class Timeline(gtk.DrawingArea):
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
......
......@@ -60,6 +60,40 @@ class Actions(object):
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)
......
......@@ -65,16 +65,43 @@ class Actions(object):
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 """
......
......@@ -21,12 +21,12 @@ def time_from_calendar(calendar):
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. '''
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment