Minor fixes found while working on packaging
[doneit] / src / gtk_toolbox.py
index fdfcc44..0f29774 100644 (file)
@@ -312,32 +312,152 @@ class MessageBox2(gtk.MessageDialog):
 
 class PopupCalendar(object):
 
-       def __init__(self, parent, eventTarget = coroutines.null_sink()):
-               self._eventTarget = eventTarget
+       def __init__(self, parent, displayDate):
+               self._displayDate = displayDate
+
+               self._calendar = gtk.Calendar()
+               self._calendar.select_month(self._displayDate.month, self._displayDate.year)
+               self._calendar.select_day(self._displayDate.day)
+               self._calendar.set_display_options(
+                       gtk.CALENDAR_SHOW_HEADING |
+                       gtk.CALENDAR_SHOW_DAY_NAMES |
+                       gtk.CALENDAR_NO_MONTH_CHANGE |
+                       0
+               )
+               self._calendar.connect("day-selected", self._on_day_selected)
+
+               self._popupWindow = gtk.Window()
+               self._popupWindow.set_title("")
+               self._popupWindow.add(self._calendar)
+               self._popupWindow.set_transient_for(parent)
+               self._popupWindow.set_modal(True)
 
-               self.__calendar = gtk.Calendar()
-               self.__calendar.connect("day-selected-double-click", self._on_date_select)
+       def run(self):
+               self._popupWindow.show_all()
 
-               self.__popupWindow = gtk.Window(type = gtk.WINDOW_POPUP)
-               self.__popupWindow.set_title("")
-               self.__popupWindow.add(self.__calendar)
-               self.__popupWindow.set_transient_for(parent)
-               self.__popupWindow.set_modal(True)
+       def _on_day_selected(self, *args):
+               try:
+                       self._calendar.select_month(self._displayDate.month, self._displayDate.year)
+                       self._calendar.select_day(self._displayDate.day)
+               except StandardError, e:
+                       warnings.warn(e.message)
 
-       def get_date(self):
-               year, month, day = self.__calendar.get_date()
-               month += 1 # Seems to be 0 indexed
-               return datetime.date(year, month, day)
 
-       def run(self):
-               self.__popupWindow.show_all()
+class NotesDialog(object):
 
-       def _on_date_select(self, *args):
-               self.__popupWindow.hide()
-               self._eventTarget.send((self, self.get_date()))
+       def __init__(self, widgetTree):
+               self._dialog = widgetTree.get_widget("notesDialog")
+               self._notesBox = widgetTree.get_widget("notes-notesBox")
+               self._addButton = widgetTree.get_widget("notes-addButton")
+               self._saveButton = widgetTree.get_widget("notes-saveButton")
+               self._cancelButton = widgetTree.get_widget("notes-cancelButton")
+               self._onAddId = None
+               self._onSaveId = None
+               self._onCancelId = None
+
+               self._notes = []
+               self._notesToDelete = []
+
+       def enable(self):
+               self._dialog.set_default_size(800, 300)
+               self._onAddId = self._addButton.connect("clicked", self._on_add_clicked)
+               self._onSaveId = self._saveButton.connect("clicked", self._on_save_clicked)
+               self._onCancelId = self._cancelButton.connect("clicked", self._on_cancel_clicked)
+
+       def disable(self):
+               self._addButton.disconnect(self._onAddId)
+               self._saveButton.disconnect(self._onSaveId)
+               self._cancelButton.disconnect(self._onAddId)
+
+       def run(self, todoManager, taskId, parentWindow = None):
+               if parentWindow is not None:
+                       self._dialog.set_transient_for(parentWindow)
+
+               taskDetails = todoManager.get_task_details(taskId)
+
+               self._dialog.set_default_response(gtk.RESPONSE_OK)
+               for note in taskDetails["notes"]:
+                       noteBox, titleEntry, noteDeleteButton, noteEntry = self._append_notebox(note)
+                       noteDeleteButton.connect("clicked", self._on_delete_existing, note["id"], noteBox)
+
+               try:
+                       response = self._dialog.run()
+                       if response != gtk.RESPONSE_OK:
+                               raise RuntimeError("Edit Cancelled")
+               finally:
+                       self._dialog.hide()
+
+               for note in self._notes:
+                       noteId = note[0]
+                       noteTitle = note[2].get_text()
+                       noteBody = note[4].get_buffer().get_text()
+                       if noteId is None:
+                               print "New note:", note
+                               todoManager.add_note(taskId, noteTitle, noteBody)
+                       else:
+                               # @todo Provide way to only update on change
+                               print "Updating note:", note
+                               todoManager.update_note(noteId, noteTitle, noteBody)
+
+               for deletedNoteId in self._notesToDelete:
+                       print "Deleted note:", deletedNoteId
+                       todoManager.delete_note(noteId)
+
+       def _append_notebox(self, noteDetails = None):
+               if noteDetails is None:
+                       noteDetails = {"id": None, "title": "", "body": ""}
+
+               noteBox = gtk.VBox()
+
+               titleBox = gtk.HBox()
+               titleEntry = gtk.Entry()
+               titleEntry.set_text(noteDetails["title"])
+               titleBox.pack_start(titleEntry, True, True)
+               noteDeleteButton = gtk.Button(stock=gtk.STOCK_DELETE)
+               titleBox.pack_end(noteDeleteButton, False, False)
+               noteBox.pack_start(titleBox, False, True)
+
+               noteEntryScroll = gtk.ScrolledWindow()
+               noteEntryScroll.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+               noteEntry = gtk.TextView()
+               noteEntry.set_editable(True)
+               noteEntry.set_wrap_mode(gtk.WRAP_WORD)
+               noteEntry.get_buffer().set_text(noteDetails["body"])
+               noteEntry.set_size_request(-1, 150)
+               noteEntryScroll.add(noteEntry)
+               noteBox.pack_start(noteEntryScroll, True, True)
+
+               self._notesBox.pack_start(noteBox, True, True)
+               noteBox.show_all()
+
+               note = noteDetails["id"], noteBox, titleEntry, noteDeleteButton, noteEntry
+               self._notes.append(note)
+               return note[1:]
+
+       def _on_add_clicked(self, *args):
+               noteBox, titleEntry, noteDeleteButton, noteEntry = self._append_notebox()
+               noteDeleteButton.connect("clicked", self._on_delete_new, noteBox)
+
+       def _on_save_clicked(self, *args):
+               self._dialog.response(gtk.RESPONSE_OK)
+
+       def _on_cancel_clicked(self, *args):
+               self._dialog.response(gtk.RESPONSE_CANCEL)
+
+       def _on_delete_new(self, widget, noteBox):
+               self._notesBox.remove(noteBox)
+               self._notes = [note for note in self._notes if note[1] is not noteBox]
+
+       def _on_delete_existing(self, widget, noteId, noteBox):
+               self._notesBox.remove(noteBox)
+               self._notes = [note for note in self._notes if note[1] is not noteBox]
+               self._notesToDelete.append(noteId)
 
 
 class EditTaskDialog(object):
+       """
+       @bug The dialog doens't fit well on the maemo screen
+       """
 
        def __init__(self, widgetTree):
                self._projectsList = gtk.ListStore(gobject.TYPE_STRING)
@@ -514,4 +634,10 @@ if __name__ == "__main__":
                win.connect("destroy", lambda w: gtk.main_quit())
 
                win.show_all()
-               gtk.main()
+
+       if False:
+               cal = PopupCalendar(None, datetime.datetime.now())
+               cal._popupWindow.connect("destroy", lambda w: gtk.main_quit())
+               cal.run()
+
+       gtk.main()