diff options
-rw-r--r-- | item.py | 11 | ||||
-rw-r--r-- | priority.py | 86 | ||||
-rw-r--r-- | storage/sqlite.py | 4 | ||||
-rw-r--r-- | ui/todolist.glade | 162 | ||||
-rw-r--r-- | ui/ui_pygtk.py | 55 |
5 files changed, 229 insertions, 89 deletions
@@ -1,5 +1,6 @@ # -*- coding: utf-8 -*- import time +from priority import Priorities class item: readOnly = ['id'] @@ -10,7 +11,7 @@ class item: if title != None: self.title = title self.created = created - self.priority = priority + self.setPriority(priority) self.description = description self.completed = completed self.removed = removed @@ -58,6 +59,14 @@ class item: def getDue(self): return self.due + def setPriority(self, id=None, name=None): + if id is not None: + self.priority = Priorities().getPriority(id = id) + elif name is not None: + self.priority = Priorities().getPriority(name = name) + else: + self.priority = None + def __setattr__(self, name, value): if name not in item.readOnly: if name not in self.__dict__ or self.__dict__[name] != value: diff --git a/priority.py b/priority.py new file mode 100644 index 0000000..d053068 --- /dev/null +++ b/priority.py @@ -0,0 +1,86 @@ +# -*- coding: utf-8 -*- +# date: 23 Mai 2009 + +class Priority: + def __init__(self, name, id, color=None): + self.name = name.__str__() + self.id = id + + if color is not None: + self.color = color + else: + self.color = id + + def getId(self): + return self.id + + def getName(self): + return self.name + + def getColor(self): + return self.color + + def __str__(self): + return self.getName() + +class Priorities: + __shared_state = {} + priorities = {} + prioritiesMap = {} + + def __init__(self): + self.__dict__ = self.__shared_state + + if len(self.priorities) == 0: + self.__add__(Priority('Low', -100)) + self.__add__(Priority('Normal', 0)) + self.__add__(Priority('High', 100)) + + def __getitem__(self, id): + return self.priorities[id] + + def __setitem__(self, id, priority): + self.priorities[id] = priority + self.prioritiesMap[priority.getName()] = priority + + def __delitem__(self, id): + priority = prioritie[key] + del(self.priorities[key]) + del(self.prioritiesMap[priority.getName()]) + + def remove(self, priority): + del(self.priorities[key]) + del(self.prioritiesMap[priority.getName()]) + + def __contians__(self, priority): + return (priority in self.priorities) + + def append(self, priority): + self.__setitem__(priority.getId(), priority) + + def __add__(self, priority): + self.__setitem__(priority.getId(), priority) + return self + + def __iter__(self): + return self.priorities.__iter__() + + def getPriority(self, id=None, name=None): + try: + if id is not None: + return self[id] + + if name is not None: + return self.prioritiesMap[name] + except(KeyError): + if name is None: + name = id + + if id is None: + id = name + + priority = Priority(id, name) + self.__add__(priority) + return priority + + return None diff --git a/storage/sqlite.py b/storage/sqlite.py index 8c97186..a7e98e9 100644 --- a/storage/sqlite.py +++ b/storage/sqlite.py @@ -93,12 +93,12 @@ class sqlite(storageBase): def notifyChange(self, sender): if sender.getId() >= 0: self.cur.execute('update todo set title=?, createdAt=?, priority=?, desc=?, completed=?, removed=?, due=? where id=?', - (sender.getTitle(), sender.getCreatedAt(), sender.getPriority(), + (sender.getTitle(), sender.getCreatedAt(), sender.getPriority().getId(), sender.getDescription(), sender.getCompleted(), sender.getRemoved(), sender.getDue(), sender.getId())) self.con.commit() else: self.cur.execute('insert into todo (title, createdAt, priority, desc, completed, removed, due) VALUES (?, ?, ?, ?, ?, ?, ?)', - (sender.getTitle(), sender.getCreatedAt(), sender.getPriority(), + (sender.getTitle(), sender.getCreatedAt(), sender.getPriority().getId(), sender.getDescription(), sender.getCompleted(), sender.getRemoved(), sender.getDue())) self.con.commit() sender.setId(self.cur.execute('select last_insert_rowid()').fetchone()[0]) diff --git a/ui/todolist.glade b/ui/todolist.glade index 0548f2c..9d08682 100644 --- a/ui/todolist.glade +++ b/ui/todolist.glade @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd"> -<!--Generated with glade3 3.4.5 on Wed May 20 13:13:43 2009 --> +<!--Generated with glade3 3.4.5 on Sun May 24 14:34:47 2009 --> <glade-interface> <widget class="GtkWindow" id="main_window"> <property name="title" translatable="yes">ToDo</property> @@ -119,7 +119,6 @@ <widget class="GtkTreeView" id="todolist"> <property name="visible">True</property> <property name="can_focus">True</property> - <property name="rules_hint">True</property> <signal name="row_activated" handler="on_treeview_row_activated"/> </widget> </child> @@ -209,69 +208,54 @@ <property name="column_spacing">7</property> <property name="row_spacing">7</property> <child> - <widget class="GtkHBox" id="hbox1"> + <widget class="GtkLabel" id="label1"> <property name="visible">True</property> - <child> - <widget class="GtkEntry" id="due_field"> - <property name="visible">True</property> - <property name="can_focus">True</property> - </widget> - </child> - <child> - <widget class="GtkButton" id="button5"> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">True</property> - <property name="label" translatable="yes">Select...</property> - <property name="response_id">0</property> - <signal name="clicked" handler="on_select_date_clicked"/> - </widget> - <packing> - <property name="expand">False</property> - <property name="fill">False</property> - <property name="position">1</property> - </packing> - </child> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="label" translatable="yes">Title:</property> </widget> <packing> - <property name="left_attach">1</property> - <property name="right_attach">2</property> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> - <property name="y_options">GTK_FILL</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> <child> - <widget class="GtkLabel" id="label4"> + <widget class="GtkLabel" id="label2"> <property name="visible">True</property> <property name="xalign">0</property> <property name="yalign">0</property> - <property name="label" translatable="yes">Due:</property> + <property name="label" translatable="yes">Priority:</property> </widget> <packing> - <property name="top_attach">2</property> - <property name="bottom_attach">3</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> <property name="x_options">GTK_FILL</property> <property name="y_options"></property> </packing> </child> <child> - <widget class="GtkComboBoxEntry" id="comboboxentry1"> + <widget class="GtkLabel" id="label3"> <property name="visible">True</property> - <property name="items" translatable="yes"></property> - <child internal-child="entry"> - <widget class="GtkEntry" id="priority_field"> - <property name="visible">True</property> - <property name="can_focus">True</property> - </widget> - </child> + <property name="xalign">0</property> + <property name="yalign">0</property> + <property name="label" translatable="yes">Description:</property> + </widget> + <packing> + <property name="top_attach">3</property> + <property name="bottom_attach">4</property> + <property name="x_options">GTK_FILL</property> + <property name="y_options">GTK_FILL</property> + </packing> + </child> + <child> + <widget class="GtkEntry" id="title_field"> + <property name="visible">True</property> + <property name="can_focus">True</property> </widget> <packing> <property name="left_attach">1</property> <property name="right_attach">2</property> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> - <property name="y_options">GTK_FILL</property> + <property name="y_options"></property> </packing> </child> <child> @@ -296,54 +280,73 @@ </packing> </child> <child> - <widget class="GtkEntry" id="title_field"> + <widget class="GtkComboBoxEntry" id="comboboxentry1"> <property name="visible">True</property> - <property name="can_focus">True</property> + <property name="items" translatable="yes">Low +Normal +High</property> + <child internal-child="entry"> + <widget class="GtkEntry" id="priority_field"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="editable">False</property> + <property name="text" translatable="yes">Normal</property> + </widget> + </child> </widget> <packing> <property name="left_attach">1</property> <property name="right_attach">2</property> - <property name="y_options"></property> - </packing> - </child> - <child> - <widget class="GtkLabel" id="label3"> - <property name="visible">True</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="label" translatable="yes">Description:</property> - </widget> - <packing> - <property name="top_attach">3</property> - <property name="bottom_attach">4</property> - <property name="x_options">GTK_FILL</property> + <property name="top_attach">1</property> + <property name="bottom_attach">2</property> <property name="y_options">GTK_FILL</property> </packing> </child> <child> - <widget class="GtkLabel" id="label2"> + <widget class="GtkLabel" id="label4"> <property name="visible">True</property> <property name="xalign">0</property> <property name="yalign">0</property> - <property name="label" translatable="yes">Priority:</property> + <property name="label" translatable="yes">Due:</property> </widget> <packing> - <property name="top_attach">1</property> - <property name="bottom_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> <property name="x_options">GTK_FILL</property> <property name="y_options"></property> </packing> </child> <child> - <widget class="GtkLabel" id="label1"> + <widget class="GtkHBox" id="hbox1"> <property name="visible">True</property> - <property name="xalign">0</property> - <property name="yalign">0</property> - <property name="label" translatable="yes">Title:</property> + <child> + <widget class="GtkEntry" id="due_field"> + <property name="visible">True</property> + <property name="can_focus">True</property> + </widget> + </child> + <child> + <widget class="GtkButton" id="button5"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="label" translatable="yes">Select...</property> + <property name="response_id">0</property> + <signal name="clicked" handler="on_select_date_clicked"/> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">1</property> + </packing> + </child> </widget> <packing> - <property name="x_options">GTK_FILL</property> - <property name="y_options"></property> + <property name="left_attach">1</property> + <property name="right_attach">2</property> + <property name="top_attach">2</property> + <property name="bottom_attach">3</property> + <property name="y_options">GTK_FILL</property> </packing> </child> </widget> @@ -402,6 +405,21 @@ <widget class="GtkVBox" id="vbox2"> <property name="visible">True</property> <child> + <widget class="GtkHButtonBox" id="hbuttonbox2"> + <property name="visible">True</property> + <child> + <widget class="GtkButton" id="button9"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="label" translatable="yes">Today</property> + <property name="response_id">0</property> + <signal name="clicked" handler="on_show_today_clicked"/> + </widget> + </child> + </widget> + </child> + <child> <widget class="GtkCalendar" id="calendar"> <property name="width_request">250</property> <property name="visible">True</property> @@ -410,6 +428,8 @@ <packing> <property name="expand">False</property> <property name="fill">False</property> + <property name="padding">4</property> + <property name="position">1</property> </packing> </child> <child> @@ -466,7 +486,7 @@ </widget> <packing> <property name="padding">4</property> - <property name="position">1</property> + <property name="position">2</property> </packing> </child> </widget> diff --git a/ui/ui_pygtk.py b/ui/ui_pygtk.py index 7f257f1..f9941ff 100644 --- a/ui/ui_pygtk.py +++ b/ui/ui_pygtk.py @@ -41,7 +41,8 @@ class ui_pygtk: "on_edit_clicked" : self.edit_clicked_callback, "on_remove_clicked" : self.remove_clicked_callback, "on_add_clicked" : self.add_clicked_callback, - "on_select_date_clicked" : self.select_date_clicked_callback + "on_select_date_clicked" : self.select_date_clicked_callback, + "on_show_today_clicked" : self.show_today_clicked_callback } glade.signal_autoconnect(dic) @@ -52,12 +53,22 @@ class ui_pygtk: self.main_window.todolist.set_model(liststore) self.main_window.todolist.append_column(self.create_column(0, 'Finished', 'getCompleted', liststore, gtk.CellRendererToggle())) + # magic column - # self.main_window.todolist.append_column(self.create_column(1, 'Todo', 'getCompleted', liststore, gtk.CellRendererText())) + cellRenderer = gtk.CellRendererText() + column = gtk.TreeViewColumn('Todo', cellRenderer) + column.set_cell_data_func(cellRenderer, (lambda column, cell, model, iter, userdata=None: cell.set_property('markup', ("<b>%s</b>\n%s" % (gobject.markup_escape_text(model.get_value(iter, 0).getTitle()), gobject.markup_escape_text(model.get_value(iter, 0).getDescription()))).strip())), None) + column.set_reorderable(True) + column.set_resizable(True) + #column.set_sort_column_id(id) + self.main_window.todolist.append_column(column) + for column in ([['Id', 'getId'], ['ToDo', 'getTitle'], ['...', 'getDescription'], ['Erstellt am', ['getCreatedAt', + (lambda x: time.strftime('%d.%m.%Y %H:%M:%S', time.localtime(x)))]], + ['Bis', ['getDue', (lambda x: time.strftime('%d.%m.%Y %H:%M:%S', time.localtime(x)))]] ]): self.main_window.todolist.append_column(self.create_column(len(self.main_window.todolist.get_columns())+1, column[0], column[1], liststore)) @@ -90,9 +101,11 @@ class ui_pygtk: def item_data_callback(self, column, cell, model, iter, userdata=None): # method to get the data from the item object for one column data='' + rowdata = model.get_value(iter, 0) + if (userdata == None): # try to convert the object to string - data = model.get_value(iter, 0) + data = rowdata.__str__() else: if type(userdata) is type([]): data = getattr(model.get_value(iter, 0), userdata[0])() @@ -105,12 +118,14 @@ class ui_pygtk: # set the data as cell content if isinstance(cell, gtk.CellRendererText) : - cell.set_property('text', data) + cell.set_property('markup', gobject.markup_escape_text(data.__str__())) + + # set backround color + if rowdata.getPriority().getColor() is not None: + cell.set_property('foreground-gdk', gtk.gdk.Color(red=rowdata.getPriority().getColor(), blue=0, green=0)) elif isinstance(cell, gtk.CellRendererToggle) : cell.set_property('active', data) - else: - return data - + def about_clicked_callback(self, widget, data=None): # show the about dialog about_window = gtk.AboutDialog() @@ -164,6 +179,14 @@ class ui_pygtk: self.main_window.todolist.get_model().row_inserted(self.main_window.todolist.get_model().get_path(iter), iter) return + def select_date(self, date): + # select the given date in the calendar control in the date select dialog + self.date_select_dialog.calendar.select_month(date[1] - 1, date[0]) + self.date_select_dialog.calendar.select_day(date[2]) + self.date_select_dialog.hour_field.set_value(date[3]) + self.date_select_dialog.minute_field.set_value(date[4]) + return + def select_date_clicked_callback(self, widget, data=None): # display the dialog to select a date after clicked on the # button in the edit dialog @@ -171,11 +194,7 @@ class ui_pygtk: date = time.strptime(self.edit_dialog.due_field.get_text(), '%d.%m.%Y %H:%M') except: date = time.localtime() - - self.date_select_dialog.calendar.select_month(date[1] - 1, date[0]) - self.date_select_dialog.calendar.select_day(date[2]) - self.date_select_dialog.hour_field.set_value(date[3]) - self.date_select_dialog.minute_field.set_value(date[4]) + self.select_date(date) if self.date_select_dialog.run(): date = self.date_select_dialog.calendar.get_date() @@ -188,7 +207,13 @@ class ui_pygtk: '%d.%m.%Y %H:%M', date)) self.date_select_dialog.hide() return - + + def show_today_clicked_callback(self, widget, data=None): + # show today in the calendar control in the date select dialog + self.select_date(time.localtime()) + return + + ######################################################### # helper methods ######################################################### @@ -212,11 +237,11 @@ class ui_pygtk: if (successfull): item.title = self.edit_dialog.title_field.get_text() - item.priority = self.edit_dialog.priority_field.get_text() + item.setPriority(name=self.edit_dialog.priority_field.get_text()) item.description = text_buffer.get_text(text_buffer.get_start_iter(), text_buffer.get_end_iter()) try: - item.due = time.strftime('%s', time.strptime(self.edit_dialog.due_field.get_text(), '%d.%m.%Y %H:%M')) + item.due = int(time.strftime('%s', time.strptime(self.edit_dialog.due_field.get_text(), '%d.%m.%Y %H:%M'))) except: item.due = -1 |