import gtk import gobject from datetime import * class Window: def __init__(self, ds): self.ds = ds self.shown_projects = [] now = datetime.now() self.monday = now.date() - timedelta(now.weekday()) # Top-level Window creation self.window = gtk.Window(gtk.WINDOW_TOPLEVEL) self.window.set_geometry_hints(); self.window.connect("delete_event", self.delete_event) self.window.connect("destroy", self.destroy_event) self.window.connect("key-press-event", self.window_key_press_event) # Menu Bar self.menubar = gtk.MenuBar() mi = gtk.MenuItem('_File') self.menubar.append(mi) mi = gtk.MenuItem('_Report') self.menubar.append(mi) mi = gtk.MenuItem('_Help') self.menubar.append(mi) # Projects Table self.projects_present = False self.projects_container = gtk.VBox() self.updateProjects() # Bottom Control Bar self.mark_label = gtk.Label() adjust_button = gtk.Button('Adjust') in_button = gtk.Button('In') out_button = gtk.Button('Out') hbox = gtk.HBox() hbox.pack_start(self.mark_label) hbox.pack_start(adjust_button) hbox.pack_start(in_button) hbox.pack_start(out_button) vbox = gtk.VBox() vbox.pack_start(self.menubar) vbox.pack_start(self.projects_container) vbox.pack_start(gtk.HSeparator()) vbox.pack_start(hbox) self.window.add(vbox) def updateProjects(self): if self.projects_present: self.projects_container.remove(self.projects_table) self.projects = self.ds.getProjects() self.project_hour_labels = {} projects_to_show = {} for p in self.shown_projects: projects_to_show[p] = 1 # Header row col_headers = ('Project', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun', 'Tot') rows = 3 + len(projects_to_show) self.projects_table = gtk.Table(rows = rows, columns = len(col_headers)) for i in range(len(col_headers)): l = gtk.Label() l.set_markup('%s' % col_headers[i]) l.set_size_request(35 if i > 0 else 200, -1) self.projects_table.attach(l, i, i + 1, 0, 1) row = 1 pnames_to_show = map(lambda x: self.projects[x], projects_to_show) pnames_to_show.sort() for pname in pnames_to_show: pnum = self.getProjectNum(pname) self.projects_table.attach(gtk.Label(pname), 0, 1, row, row + 1) self.project_hour_labels[pnum] = {} for i in range(7): l = gtk.Label() self.projects_table.attach(l, i + 1, i + 2, row, row + 1) self.project_hour_labels[pnum][i] = l row += 1 # Totals row l = gtk.Label() l.set_markup('Total') self.projects_table.attach(l, 0, 1, rows - 2, rows - 1) # Add project row self.new_project_combobox = gtk.combo_box_entry_new_text() self.new_project_combobox.connect("key-release-event", self.project_key_press_event) project_names = self.projects.values() project_names.sort() for project in project_names: self.new_project_combobox.append_text(project) self.add_project_button = gtk.Button('Add') self.add_project_button.connect('clicked', self.add_project_event) self.projects_table.attach(self.new_project_combobox, 0, 1, rows - 1, rows) hbox = gtk.HBox() hbox.pack_start(self.add_project_button, expand = False) self.projects_table.attach(hbox, 1, 9, rows - 1, rows) self.projects_table.set_row_spacings(3) self.projects_container.pack_start(self.projects_table) self.projects_present = True self.projects_table.show_all() self.updateProjectHours() def updateProjectHours(self): for day in range(7): dt = str(self.monday + timedelta(day)) day_hours = self.ds.getProjectDailyHours(dt) for p in day_hours: if p in self.project_hour_labels: hrs = self.hoursFromSeconds(day_hours[p]) self.project_hour_labels[p][day].set_text(hrs) def hoursFromSeconds(self, secs): if secs < 0.6 * 60 * 60: secs = 0.6 * 60 * 60; return "%.1f" % (secs / 60.0 / 60.0) def main(self): self.window.show_all() gtk.main() def getProjectNum(self, pname): for p in self.projects: if self.projects[p] == pname: return p return 0 def add_project_event(self, button, data=None): pname = self.new_project_combobox.get_active_text() if pname in self.projects.values(): pnum = self.getProjectNum(pname) else: pnum = self.ds.createProject(pname) self.shown_projects.append(pnum) self.updateProjects() def project_key_press_event(self, widget, event, data=None): if event.keyval == gtk.gdk.keyval_from_name("Return"): self.add_project_event(1) return True return False def delete_event(self, widget, event, data=None): return False def destroy_event(self, widget, data=None): gtk.main_quit() def window_key_press_event(self, widget, event, data=None): if event.keyval == gtk.gdk.keyval_from_name("Escape"): gtk.main_quit()