Renames and making Speichern a new style object
authorepage <eopage@byu.net>
Wed, 28 Oct 2009 01:51:55 +0000 (01:51 +0000)
committerepage <eopage@byu.net>
Wed, 28 Oct 2009 01:51:55 +0000 (01:51 +0000)
git-svn-id: file:///svnroot/quicknote/trunk@60 bb7704e3-badb-4cfa-9ab3-9374dc87eaa2

15 files changed:
src/history.py [new file with mode: 0644]
src/kopfzeile.py [new file with mode: 0644]
src/libhistory.py [deleted file]
src/libkopfzeile.py [deleted file]
src/libnotizen.py [deleted file]
src/libquicknote.py [deleted file]
src/libspeichern.py [deleted file]
src/libsqldialog.py [deleted file]
src/libsync.py [deleted file]
src/notizen.py [new file with mode: 0644]
src/quicknote.py
src/quicknote_gtk.py [new file with mode: 0644]
src/speichern.py [new file with mode: 0644]
src/sqldialog.py [new file with mode: 0755]
src/sync.py [new file with mode: 0755]

diff --git a/src/history.py b/src/history.py
new file mode 100644 (file)
index 0000000..c897cd9
--- /dev/null
@@ -0,0 +1,85 @@
+#!/usr/bin/env python2.5
+# -*- coding: utf-8 -*-
+
+"""
+ Copyright (C) 2007 Christoph Würstle
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+"""
+
+
+import logging
+
+import gtk
+
+
+try:
+       _
+except NameError:
+       _ = lambda x: x
+
+
+_moduleLogger = logging.getLogger("history")
+
+
+class Dialog(gtk.Dialog):
+
+       def __init__(self, daten = None):
+               super(Dialog, self).__init__(
+                       _("History:"),
+                       None,
+                       gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
+                       (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT),
+               )
+               self.set_position(gtk.WIN_POS_CENTER)
+
+               self.noteHistory = gtk.ListStore(
+                       int, #pcdatum
+                       str, #datum
+                       str, #sql
+                       str, #param
+                       str #param schön
+               )
+
+               # create the TreeView using liststore
+               self._historyView = gtk.TreeView(self.noteHistory)
+               self._historyView.set_rules_hint(True)
+               # create a CellRenderers to render the data
+               self._timestampCell = gtk.CellRendererText()
+               self._noteCell = gtk.CellRendererText()
+
+               # create the TreeViewColumns to display the data
+               self._timestampColumn = gtk.TreeViewColumn(_('Timestamp'))
+               self._noteColumn = gtk.TreeViewColumn(_('Note'))
+               # add columns to treeview
+               self._historyView.append_column(self._timestampColumn)
+               self._historyView.append_column(self._noteColumn)
+
+               # add the cells to the columns - 2 in the first
+               self._timestampColumn.pack_start(self._timestampCell, True)
+               self._noteColumn.pack_start(self._noteCell, True)
+               self._timestampColumn.set_attributes(self._timestampCell, text = 1) #Spalten setzten hier!!!!
+               self._noteColumn.set_attributes(self._noteCell, text = 4)
+
+               self._historyView.set_reorderable(False)
+
+               scrolled_window = gtk.ScrolledWindow()
+               scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+               scrolled_window.add(self._historyView)
+               self.vbox.pack_start(scrolled_window, expand = True, fill = True, padding = 0)
+
+               self.noteHistory.clear()
+
+               if daten is not None:
+                       for data in daten:
+                               self.noteHistory.append(data)
+
+       def get_selected_row(self):
+               path = self._historyView.get_cursor()[0]
+               if path is None or path == "":
+                       return None
+
+               iter1 = self._historyView.get_model().get_iter(path)
+               return self._historyView.get_model().get(iter1, 0, 1, 2, 3, 4)
diff --git a/src/kopfzeile.py b/src/kopfzeile.py
new file mode 100644 (file)
index 0000000..d3dc00b
--- /dev/null
@@ -0,0 +1,146 @@
+#!/usr/bin/env python2.5
+# -*- coding: utf-8 -*-
+
+"""
+ Copyright (C) 2007 Christoph Würstle
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+"""
+
+
+import logging
+
+import gobject
+import gtk
+
+
+try:
+       _
+except NameError:
+       _ = lambda x: x
+
+
+_moduleLogger = logging.getLogger("kopfzeile")
+
+
+class Kopfzeile(gtk.HBox):
+       """
+       Category/Search box
+       """
+
+       __gsignals__ = {
+               'reload_notes' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
+       }
+
+       def __init__(self, db):
+               self._lastCategory = ""
+               self._db = db
+
+               gtk.HBox.__init__(self, homogeneous = False, spacing = 3)
+               _moduleLogger.info("libkopfzeile, init")
+
+               categoryHBox = gtk.HBox()
+               self.pack_start(categoryHBox, expand = False, fill = True, padding = 0)
+
+               label = gtk.Label(_("Category:  "))
+               categoryHBox.pack_start(label, expand = False, fill = True, padding = 0)
+
+               self.categoryCombo = gtk.combo_box_entry_new_text()
+               categoryHBox.pack_start(self.categoryCombo, expand = True, fill = True, padding = 0)
+               self.load_categories()
+               self.categoryCombo.connect("changed", self.category_combo_changed, None)
+
+               searchHBox = gtk.HBox()
+               self.pack_start(searchHBox, expand = True, fill = True, padding = 0)
+
+               label = gtk.Label(_("Search:  "))
+               searchHBox.pack_start(label, expand = False, fill = True, padding = 0)
+
+               self._searchEntry = gtk.Entry()
+               searchHBox.pack_start(self._searchEntry, expand = True, fill = True, padding = 0)
+               self._searchEntry.connect("changed", self.search_entry_changed, None)
+
+       def category_combo_changed(self, widget = None, data = None):
+               _moduleLogger.debug("comboCategoryChanged")
+               if self._lastCategory != self.categoryCombo.get_active():
+                       sql = "UPDATE categories SET liste = ? WHERE id = 1"
+                       self._db.speichereSQL(sql, (self.categoryCombo.get_active(), ))
+
+               self.emit("reload_notes")
+
+       def search_entry_changed(self, widget = None, data = None):
+               _moduleLogger.debug("search_entry_changed")
+               self.emit("reload_notes")
+
+       def get_category(self):
+               entry = self.categoryCombo.get_child()
+               category = entry.get_text()
+               if category == _("all"):
+                       category = "%"
+               if category == "":
+                       category = "undefined"
+                       self.categoryCombo.set_active(1)
+                       self.categoryCombo.show()
+               return category
+
+       def define_this_category(self):
+               category = self.get_category()
+
+               model = self.categoryCombo.get_model()
+               n = len(self.categoryCombo.get_model())
+               i = 0
+               active = -1
+               cats = []
+               for i, row in enumerate(model):
+                       if row[0] == category:
+                               active = i
+                       if row[0] != "%":
+                               cats.append(row[0])
+
+               if active == -1 and category != "%":
+                       self.categoryCombo.append_text(category)
+                       sql = "INSERT INTO categories  (id, liste) VALUES (0, ?)"
+                       self._db.speichereSQL(sql, (category, ))
+                       self.categoryCombo.set_active(i)
+
+       def get_search_pattern(self):
+               return self._searchEntry.get_text()
+
+       def load_categories(self):
+               sql = "CREATE TABLE categories (id TEXT , liste TEXT)"
+               self._db.speichereSQL(sql)
+
+               sql = "SELECT id, liste FROM categories WHERE id = 0 ORDER BY liste"
+               rows = self._db.ladeSQL(sql)
+               cats = []
+               if rows is not None and 0 < len(rows):
+                       for row in rows:
+                               cats.append(row[1])
+
+               sql = "SELECT * FROM categories WHERE id = 1"
+               rows = self._db.ladeSQL(sql)
+               if rows is None or len(rows) == 0:
+                       sql = "INSERT INTO categories (id, liste) VALUES (1, 1)"
+                       self._db.speichereSQL(sql)
+
+               #self.categoryCombo.clear()
+               while 0 < len(self.categoryCombo.get_model()):
+                       self.categoryCombo.remove_text(0)
+
+               self.categoryCombo.append_text(_('all'))
+               self.categoryCombo.append_text('undefined')
+
+               if cats is not None and 0 < len(cats):
+                       for cat in cats:
+                               self.categoryCombo.append_text(cat)
+
+               sql = "SELECT * FROM categories WHERE id = 1"
+               rows = self._db.ladeSQL(sql)
+               if rows is not None and 0 < len(rows):
+                       self.categoryCombo.set_active(int(rows[0][1]))
+               else:
+                       self.categoryCombo.set_active(1)
+
+               self._lastCategory = self.categoryCombo.get_active()
diff --git a/src/libhistory.py b/src/libhistory.py
deleted file mode 100644 (file)
index c897cd9..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python2.5
-# -*- coding: utf-8 -*-
-
-"""
- Copyright (C) 2007 Christoph Würstle
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License version 2 as
-published by the Free Software Foundation.
-"""
-
-
-import logging
-
-import gtk
-
-
-try:
-       _
-except NameError:
-       _ = lambda x: x
-
-
-_moduleLogger = logging.getLogger("history")
-
-
-class Dialog(gtk.Dialog):
-
-       def __init__(self, daten = None):
-               super(Dialog, self).__init__(
-                       _("History:"),
-                       None,
-                       gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
-                       (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT),
-               )
-               self.set_position(gtk.WIN_POS_CENTER)
-
-               self.noteHistory = gtk.ListStore(
-                       int, #pcdatum
-                       str, #datum
-                       str, #sql
-                       str, #param
-                       str #param schön
-               )
-
-               # create the TreeView using liststore
-               self._historyView = gtk.TreeView(self.noteHistory)
-               self._historyView.set_rules_hint(True)
-               # create a CellRenderers to render the data
-               self._timestampCell = gtk.CellRendererText()
-               self._noteCell = gtk.CellRendererText()
-
-               # create the TreeViewColumns to display the data
-               self._timestampColumn = gtk.TreeViewColumn(_('Timestamp'))
-               self._noteColumn = gtk.TreeViewColumn(_('Note'))
-               # add columns to treeview
-               self._historyView.append_column(self._timestampColumn)
-               self._historyView.append_column(self._noteColumn)
-
-               # add the cells to the columns - 2 in the first
-               self._timestampColumn.pack_start(self._timestampCell, True)
-               self._noteColumn.pack_start(self._noteCell, True)
-               self._timestampColumn.set_attributes(self._timestampCell, text = 1) #Spalten setzten hier!!!!
-               self._noteColumn.set_attributes(self._noteCell, text = 4)
-
-               self._historyView.set_reorderable(False)
-
-               scrolled_window = gtk.ScrolledWindow()
-               scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-               scrolled_window.add(self._historyView)
-               self.vbox.pack_start(scrolled_window, expand = True, fill = True, padding = 0)
-
-               self.noteHistory.clear()
-
-               if daten is not None:
-                       for data in daten:
-                               self.noteHistory.append(data)
-
-       def get_selected_row(self):
-               path = self._historyView.get_cursor()[0]
-               if path is None or path == "":
-                       return None
-
-               iter1 = self._historyView.get_model().get_iter(path)
-               return self._historyView.get_model().get(iter1, 0, 1, 2, 3, 4)
diff --git a/src/libkopfzeile.py b/src/libkopfzeile.py
deleted file mode 100644 (file)
index 017d22b..0000000
+++ /dev/null
@@ -1,143 +0,0 @@
-#!/usr/bin/env python2.5
-# -*- coding: utf-8 -*-
-
-"""
- Copyright (C) 2007 Christoph Würstle
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License version 2 as
-published by the Free Software Foundation.
-"""
-
-
-import logging
-
-import gobject
-import gtk
-
-
-try:
-       _
-except NameError:
-       _ = lambda x: x
-
-
-_moduleLogger = logging.getLogger("kopfzeile")
-
-
-class Kopfzeile(gtk.HBox):
-
-       __gsignals__ = {
-               'reload_notes' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
-       }
-
-       def __init__(self, db):
-               self._lastCategory = ""
-               self._db = db
-
-               gtk.HBox.__init__(self, homogeneous = False, spacing = 3)
-               _moduleLogger.info("libkopfzeile, init")
-
-               categoryHBox = gtk.HBox()
-               self.pack_start(categoryHBox, expand = False, fill = True, padding = 0)
-
-               label = gtk.Label(_("Category:  "))
-               categoryHBox.pack_start(label, expand = False, fill = True, padding = 0)
-
-               self.categoryCombo = gtk.combo_box_entry_new_text()
-               categoryHBox.pack_start(self.categoryCombo, expand = True, fill = True, padding = 0)
-               self.load_categories()
-               self.categoryCombo.connect("changed", self.category_combo_changed, None)
-
-               searchHBox = gtk.HBox()
-               self.pack_start(searchHBox, expand = True, fill = True, padding = 0)
-
-               label = gtk.Label(_("Search:  "))
-               searchHBox.pack_start(label, expand = False, fill = True, padding = 0)
-
-               self._searchEntry = gtk.Entry()
-               searchHBox.pack_start(self._searchEntry, expand = True, fill = True, padding = 0)
-               self._searchEntry.connect("changed", self.search_entry_changed, None)
-
-       def category_combo_changed(self, widget = None, data = None):
-               _moduleLogger.debug("comboCategoryChanged")
-               if self._lastCategory != self.categoryCombo.get_active():
-                       sql = "UPDATE categories SET liste = ? WHERE id = 1"
-                       self._db.speichereSQL(sql, (self.categoryCombo.get_active(), ))
-
-               self.emit("reload_notes")
-
-       def search_entry_changed(self, widget = None, data = None):
-               _moduleLogger.debug("search_entry_changed")
-               self.emit("reload_notes")
-
-       def get_category(self):
-               entry = self.categoryCombo.get_child()
-               category = entry.get_text()
-               if category == _("all"):
-                       category = "%"
-               if category == "":
-                       category = "undefined"
-                       self.categoryCombo.set_active(1)
-                       self.categoryCombo.show()
-               return category
-
-       def define_this_category(self):
-               category = self.get_category()
-
-               model = self.categoryCombo.get_model()
-               n = len(self.categoryCombo.get_model())
-               i = 0
-               active = -1
-               cats = []
-               for i, row in enumerate(model):
-                       if row[0] == category:
-                               active = i
-                       if row[0] != "%":
-                               cats.append(row[0])
-
-               if active == -1 and category != "%":
-                       self.categoryCombo.append_text(category)
-                       sql = "INSERT INTO categories  (id, liste) VALUES (0, ?)"
-                       self._db.speichereSQL(sql, (category, ))
-                       self.categoryCombo.set_active(i)
-
-       def get_search_pattern(self):
-               return self._searchEntry.get_text()
-
-       def load_categories(self):
-               sql = "CREATE TABLE categories (id TEXT , liste TEXT)"
-               self._db.speichereSQL(sql)
-
-               sql = "SELECT id, liste FROM categories WHERE id = 0 ORDER BY liste"
-               rows = self._db.ladeSQL(sql)
-               cats = []
-               if rows is not None and 0 < len(rows):
-                       for row in rows:
-                               cats.append(row[1])
-
-               sql = "SELECT * FROM categories WHERE id = 1"
-               rows = self._db.ladeSQL(sql)
-               if rows is None or len(rows) == 0:
-                       sql = "INSERT INTO categories (id, liste) VALUES (1, 1)"
-                       self._db.speichereSQL(sql)
-
-               #self.categoryCombo.clear()
-               while 0 < len(self.categoryCombo.get_model()):
-                       self.categoryCombo.remove_text(0)
-
-               self.categoryCombo.append_text(_('all'))
-               self.categoryCombo.append_text('undefined')
-
-               if cats is not None and 0 < len(cats):
-                       for cat in cats:
-                               self.categoryCombo.append_text(cat)
-
-               sql = "SELECT * FROM categories WHERE id = 1"
-               rows = self._db.ladeSQL(sql)
-               if rows is not None and 0 < len(rows):
-                       self.categoryCombo.set_active(int(rows[0][1]))
-               else:
-                       self.categoryCombo.set_active(1)
-
-               self._lastCategory = self.categoryCombo.get_active()
diff --git a/src/libnotizen.py b/src/libnotizen.py
deleted file mode 100644 (file)
index b18e599..0000000
+++ /dev/null
@@ -1,270 +0,0 @@
-#!/usr/bin/env python2.5
-# -*- coding: utf-8 -*-
-
-"""
- Copyright (C) 2007 Christoph Würstle
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License version 2 as
-published by the Free Software Foundation.
-"""
-
-import time
-import logging
-import uuid
-
-import gobject
-import gtk
-try:
-       import gtkspell
-except ImportError:
-       gtkspell = None
-
-import simple_list
-
-
-try:
-       _
-except NameError:
-       _ = lambda x: x
-
-
-_moduleLogger = logging.getLogger("notizen")
-
-
-class Notizen(gtk.HBox):
-
-       def __init__(self, db, topBox):
-               self._db = db
-               self._topBox = topBox
-               self.noteId = -1
-               self._pos = -1
-               self._noteBody = None #Last notetext
-               self._categoryName = ""
-
-               gtk.HBox.__init__(self, homogeneous = False, spacing = 0)
-               _moduleLogger.info("libnotizen, init")
-
-               self._noteslist = simple_list.SimpleList()
-               self._noteslist.set_eventfunction_cursor_changed(self._update_noteslist)
-
-               self._noteslist.set_size_request(250, -1)
-
-               vbox = gtk.VBox(homogeneous = False, spacing = 0)
-
-               frame = gtk.Frame(_("Titles"))
-               frame.add(self._noteslist)
-               vbox.pack_start(frame, expand = True, fill = True, padding = 3)
-
-               buttonHBox = gtk.HBox()
-               vbox.pack_start(buttonHBox, expand = False, fill = True, padding = 3)
-
-               button = gtk.Button(stock = gtk.STOCK_ADD)
-               button.connect("clicked", self._on_add_note, None)
-               buttonHBox.pack_start(button, expand = True, fill = True, padding = 3)
-
-               button = gtk.Button(stock = gtk.STOCK_DELETE)
-               button.connect("clicked", self._on_delete_note, None)
-               buttonHBox.pack_start(button, expand = True, fill = True, padding = 3)
-
-               self.pack_start(vbox, expand = False, fill = True, padding = 3)
-
-               self._noteBodyView = gtk.TextView()
-               self._noteBodyView.connect("focus-out-event", self.save_note, "focus-out-event")
-               buf = self._noteBodyView.get_buffer()
-               buf.set_text("")
-               buf.connect("changed", self._on_note_changed, None)
-               if gtkspell is not None:
-                       self._noteBodySpellChecker = gtkspell.Spell(self._noteBodyView)
-               else:
-                       self._noteBodySpellChecker = None
-
-               #self.textviewNotiz.set_size_request(-1, 50)
-               self._noteScrollWindow = gtk.ScrolledWindow()
-               self._noteScrollWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-               self._noteScrollWindow.add(self._noteBodyView)
-
-               frame = gtk.Frame(_("Note"))
-               frame.add(self._noteScrollWindow)
-
-               vbox = gtk.VBox(homogeneous = False, spacing = 0)
-               vbox.pack_start(frame, expand = True, fill = True, padding = 3)
-
-               self._historyBox = gtk.HBox(homogeneous = False, spacing = 0)
-
-               self._historyStatusLabel = gtk.Label(_("No History"))
-               self._historyStatusLabel.set_alignment(0.0, 0.5)
-               self._historyBox.pack_start(self._historyStatusLabel, expand = True, fill = True, padding = 3)
-
-               button = gtk.Button(_("History"))
-               button.connect("clicked", self._on_show_history, None)
-               self._historyBox.pack_start(button, expand = True, fill = True, padding = 3)
-
-               vbox.pack_start(self._historyBox, expand = False, fill = True, padding = 3)
-
-               self.pack_start(vbox, expand = True, fill = True, padding = 3)
-
-               self.load_notes()
-               self._topBox.connect("reload_notes", self.load_notes)
-
-       def set_wordwrap(self, enableWordWrap):
-               if enableWordWrap:
-                       self._noteScrollWindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
-                       self._noteBodyView.set_wrap_mode(gtk.WRAP_WORD)
-               else:
-                       self._noteScrollWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-                       self._noteBodyView.set_wrap_mode(gtk.WRAP_NONE)
-
-       def show_history_area(self, visible):
-               if visible:
-                       self._historyBox.show()
-               else:
-                       self._historyBox.hide()
-
-       def load_notes(self, data = None):
-               _moduleLogger.info("load_notes params: pos:"+str(self._pos)+" noteid:"+str(self.noteId))
-               self._noteslist.clear_items()
-               self._noteslist.append_item(_("New Note..."), "new")
-
-               self._categoryName = self._topBox.get_category()
-               search = self._topBox.get_search_pattern()
-               notes = self._db.searchNotes(search, self._categoryName)
-
-               if notes is not None:
-                       for note in notes:
-                               noteid, category, noteText = note
-                               title = self._get_title(noteText)
-                               self._noteslist.append_item(title, noteid)
-
-               self.noteId = -1
-               self._pos = -1
-               self._noteBodyView.get_buffer().set_text("")
-
-       def save_note(self, widget = None, data = None, data2 = None):
-               _moduleLogger.info("save_note params: pos:"+str(self._pos)+" noteid:"+str(self.noteId))
-               #print "params:", data, data2
-               buf = self._noteBodyView.get_buffer().get_text(self._noteBodyView.get_buffer().get_start_iter(), self._noteBodyView.get_buffer().get_end_iter())
-               if buf is None or len(buf) == 0:
-                       return
-
-               if buf == self._noteBody:
-                       return
-
-               _moduleLogger.info("Saving note: "+buf)
-               if self._pos == -1 or self.noteId == -1:
-                       self._pos = -1
-                       self.noteId = str(uuid.uuid4())
-                       self._db.saveNote(self.noteId, buf, self._categoryName)
-                       self._noteslist.append_item(self._get_title(buf), self.noteId)
-                       self._pos = self._noteslist.select_last_item()
-               else:
-                       self._db.saveNote(self.noteId, buf, self._categoryName)
-
-               self._topBox.define_this_category()
-
-       def _get_title(self, buf):
-               """
-               @returns the title of the current note
-               """
-               eol = buf.find("\n")
-               if -1 == eol:
-                       eol = len(buf)
-               title = buf[:eol]
-               return title
-
-       def _set_focus(self):
-               self._noteBodyView.grab_focus()
-               return False
-
-       def _update_noteslist(self, data = None, data2 = None):
-               if self._pos != -1:
-                       self.save_note()
-
-               try:
-                       (pos, key, value) = self._noteslist.get_selection_data()
-                       if (pos == -1):
-                               return
-               except StandardError:
-                       if data != "new":
-                               return
-                       key = None
-
-               if key == "new" or data == "new":
-                       #both methods supported click add note or new note (first one disabled)
-                       self.noteId = str(uuid.uuid4())
-                       self._db.saveNote(self.noteId, "", self._categoryName)
-                       self._pos = -1
-                       self._noteslist.append_item("", self.noteId)
-                       self._noteBodyView.get_buffer().set_text("")
-                       self._pos = self._noteslist.select_last_item()
-               else:
-                       self._pos = pos
-                       self.noteId, pcdatum, self._categoryName, self._noteBody = self._db.loadNote(key)
-                       self._historyStatusLabel.set_text(time.strftime(_("Last change: %d.%m.%y %H:%M"), time.localtime(pcdatum)))
-                       buf = self._noteBodyView.get_buffer()
-                       buf.set_text(self._noteBody)
-
-               gobject.timeout_add(200, self._set_focus)
-
-       def _on_note_changed(self, widget = None, data = None):
-               if self._pos == -1 or self.noteId == -1:
-                       return
-
-               buf = self._noteBodyView.get_buffer().get_text(self._noteBodyView.get_buffer().get_start_iter(), self._noteBodyView.get_buffer().get_end_iter())
-
-               title = self._get_title(buf)
-               value, key = self._noteslist.get_item(self._pos)
-
-               if value != title:
-                       self._noteslist.change_item(self._pos, title, self.noteId)
-
-       def _on_add_note(self, widget = None, data = None):
-               self._update_noteslist("new")
-
-       def _on_delete_note(self, widget = None, data = None):
-               if (self.noteId == -1):
-                       return
-               mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, _("Really delete?"))
-               response = mbox.run()
-               mbox.hide()
-               mbox.destroy()
-               if response == gtk.RESPONSE_YES:
-                       self._db.delNote(self.noteId)
-                       self.noteId = -1
-                       self._noteslist.remove_item(self._pos)
-                       self._pos = -1
-                       self._noteBodyView.get_buffer().set_text("")
-
-       def _on_show_history(self, widget = None, data = None, label = None):
-               if self.noteId == -1:
-                       mbox =  gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("No note selected."))
-                       response = mbox.run()
-                       mbox.hide()
-                       mbox.destroy()
-                       return
-
-               rows = self._db.getNoteHistory(self.noteId)
-
-               import libhistory
-               dialog = libhistory.Dialog()
-
-               lastNoteStr = ""
-               for row in rows:
-                       daten = row[4][1]
-                       if daten != "" and lastNoteStr != daten:
-                               lastNoteStr = daten
-                               dialog.noteHistory.append([row[0], row[1], row[2], row[3], daten+"\n"])
-
-               dialog.vbox.show_all()
-               dialog.set_size_request(600, 380)
-
-               if dialog.run() == gtk.RESPONSE_ACCEPT:
-                       print "saving"
-                       self.save_note()
-                       data = dialog.get_selected_row()
-                       if data is not None:
-                               self._db.speichereSQL(data[2], data[3].split(" <<Tren-ner>> "), rowid = self.noteId)
-                               _moduleLogger.info("loading History")
-                               self._update_noteslist()
-
-               dialog.destroy()
diff --git a/src/libquicknote.py b/src/libquicknote.py
deleted file mode 100644 (file)
index d44925f..0000000
+++ /dev/null
@@ -1,420 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
- Copyright (C) 2007 Christoph Würstle
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License version 2 as
-published by the Free Software Foundation.
-
-@todo Add Note Export (txt File) and Export All (json dump?)
-@todo Remove confirmation on deleting empty notes
-@todo Try to switch to more passive notifications (rather than message boxes)
-"""
-
-from __future__ import with_statement
-
-import os
-import gc
-import logging
-import warnings
-import ConfigParser
-
-import gtk
-
-try:
-       import hildon
-       IS_HILDON = True
-except ImportError:
-       import fakehildon as hildon
-       IS_HILDON = False
-
-try:
-       import osso
-except ImportError:
-       osso = None
-
-import constants
-
-import libspeichern
-import libkopfzeile
-import libnotizen
-import libsync
-
-
-try:
-       _
-except NameError:
-       _ = lambda x: x
-
-
-_moduleLogger = logging.getLogger("quick")
-
-
-class QuicknoteProgram(hildon.Program):
-
-       _user_data = os.path.join(os.path.expanduser("~"), ".%s" % constants.__app_name__)
-       _user_settings = "%s/settings.ini" % _user_data
-
-       def __init__(self):
-               super(QuicknoteProgram, self).__init__()
-               if IS_HILDON:
-                       gtk.set_application_name(constants.__pretty_app_name__)
-
-               dblog = os.path.join(self._user_data, "quicknote.log")
-
-               _moduleLogger.info('Starting quicknote')
-
-               if osso is not None:
-                       self._osso_c = osso.Context(constants.__app_name__, constants.__version__, False)
-                       self._deviceState = osso.DeviceState(self._osso_c)
-                       self._deviceState.set_device_state_callback(self._on_device_state_change, 0)
-               else:
-                       self._osso_c = None
-                       self._deviceState = None
-
-               #Get the Main Window, and connect the "destroy" event
-               self._window = hildon.Window()
-               self.add_window(self._window)
-
-               if not IS_HILDON:
-                       self._window.set_title(constants.__pretty_app_name__)
-               self._window.connect("delete_event", self._on_delete_event)
-               self._window.connect("destroy", self._on_destroy)
-               self._window.connect("key-press-event", self._on_key_press)
-               self._window.connect("window-state-event", self._on_window_state_change)
-               self._window_in_fullscreen = False #The window isn't in full screen mode initially.
-               self._isZoomEnabled = False
-
-               self._db = libspeichern.Speichern()
-               self._syncDialog = None
-               self._prepare_sync_dialog()
-
-               #Create GUI main vbox
-               vbox = gtk.VBox(homogeneous = False, spacing = 0)
-
-               #Create Menu and apply it for hildon
-               filemenu = gtk.Menu()
-
-               menu_items = gtk.MenuItem(_("Set DB file"))
-               filemenu.append(menu_items)
-               menu_items.connect("activate", self.set_db_file, None)
-
-               menu_items = gtk.MenuItem(_("SQL History"))
-               filemenu.append(menu_items)
-               menu_items.connect("activate", self._on_view_sql_history, None)
-
-               menu_items = gtk.MenuItem(_("Sync notes"))
-               filemenu.append(menu_items)
-               menu_items.connect("activate", self._on_sync_notes, None)
-
-               menu_items = gtk.MenuItem(_("Quit"))
-               filemenu.append(menu_items)
-               menu_items.connect("activate", self._on_destroy, None)
-
-               file_menu = gtk.MenuItem(_("File"))
-               file_menu.show()
-               file_menu.set_submenu(filemenu)
-
-               categorymenu = gtk.Menu()
-
-               menu_items = gtk.MenuItem(_("Delete"))
-               categorymenu.append(menu_items)
-               menu_items.connect("activate", self._on_delete_category, None)
-
-               menu_items = gtk.MenuItem(_("Move To Category"))
-               categorymenu.append(menu_items)
-               menu_items.connect("activate", self._on_move_category, None)
-
-               category_menu = gtk.MenuItem(_("Category"))
-               category_menu.show()
-               category_menu.set_submenu(categorymenu)
-
-               viewmenu = gtk.Menu()
-
-               menu_items = gtk.MenuItem(_("Word Wrap"))
-               viewmenu.append(menu_items)
-               menu_items.connect("activate", self._on_toggle_word_wrap, None)
-               self._wordWrapEnabled = False
-
-               view_menu = gtk.MenuItem(_("View"))
-               view_menu.show()
-               view_menu.set_submenu(viewmenu)
-
-               helpmenu = gtk.Menu()
-
-               menu_items = gtk.MenuItem(_("About"))
-               helpmenu.append(menu_items)
-               menu_items.connect("activate", self._on_show_about, None)
-
-               help_menu = gtk.MenuItem(_("Help"))
-               help_menu.show()
-               help_menu.set_submenu(helpmenu)
-
-               menu_bar = gtk.MenuBar()
-               menu_bar.show()
-               menu_bar.append (file_menu)
-               menu_bar.append (category_menu)
-               menu_bar.append (view_menu)
-               menu_bar.append (help_menu)
-
-               menu_bar.show()
-               if IS_HILDON:
-                       menu = gtk.Menu()
-                       for child in menu_bar.get_children():
-                               child.reparent(menu)
-                       self._window.set_menu(menu)
-                       menu_bar.destroy()
-               else:
-                       vbox.pack_start(menu_bar, False, False, 0)
-
-               #Create GUI elements
-               self._topBox = libkopfzeile.Kopfzeile(self._db)
-               vbox.pack_start(self._topBox, False, False, 0)
-
-               self._notizen = libnotizen.Notizen(self._db, self._topBox)
-               vbox.pack_start(self._notizen, True, True, 0)
-               self._window.add(vbox)
-
-               self._on_toggle_word_wrap()
-
-               try:
-                       os.makedirs(self._user_data)
-               except OSError, e:
-                       if e.errno != 17:
-                               raise
-               self._window.show_all()
-               self._load_settings()
-
-       def main(self):
-               gtk.main()
-
-       def _save_settings(self):
-               config = ConfigParser.SafeConfigParser()
-               self.save_settings(config)
-               with open(self._user_settings, "wb") as configFile:
-                       config.write(configFile)
-
-       def save_settings(self, config):
-               config.add_section(constants.__pretty_app_name__)
-               config.set(constants.__pretty_app_name__, "wordwrap", str(self._wordWrapEnabled))
-               config.set(constants.__pretty_app_name__, "zoom", str(self._isZoomEnabled))
-               config.set(constants.__pretty_app_name__, "fullscreen", str(self._window_in_fullscreen))
-
-       def _load_settings(self):
-               config = ConfigParser.SafeConfigParser()
-               config.read(self._user_settings)
-               self.load_settings(config)
-
-       def load_settings(self, config):
-               try:
-                       self._wordWrapEnabled = config.getboolean(constants.__pretty_app_name__, "wordwrap")
-                       self._isZoomEnabled = config.getboolean(constants.__pretty_app_name__, "zoom")
-                       self._window_in_fullscreen = config.getboolean(constants.__pretty_app_name__, "fullscreen")
-               except ConfigParser.NoSectionError, e:
-                       warnings.warn(
-                               "Settings file %s is missing section %s" % (
-                                       self._user_settings,
-                                       e.section,
-                               ),
-                               stacklevel=2
-                       )
-
-               self._notizen.set_wordwrap(self._wordWrapEnabled)
-
-               self.enable_zoom(self._isZoomEnabled)
-
-               if self._window_in_fullscreen:
-                       self._window.fullscreen()
-               else:
-                       self._window.unfullscreen()
-
-       def set_db_file(self, widget = None, data = None):
-               dlg = hildon.FileChooserDialog(parent=self._window, action=gtk.FILE_CHOOSER_ACTION_SAVE)
-
-               if self._db.ladeDirekt('datenbank'):
-                       dlg.set_filename(self._db.ladeDirekt('datenbank'))
-
-               dlg.set_title(_("Choose database file"))
-               if dlg.run() == gtk.RESPONSE_OK:
-                       fileName = dlg.get_filename()
-                       self._db.speichereDirekt('datenbank', fileName)
-
-                       self._db.openDB()
-                       self._topBox.load_categories()
-                       self._notizen.load_notes()
-               dlg.destroy()
-
-       def _prepare_sync_dialog(self):
-               self._syncDialog = gtk.Dialog(_("Sync"), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
-
-               self._syncDialog.set_position(gtk.WIN_POS_CENTER)
-               sync = libsync.Sync(self._db, self._window, 50504)
-               self._syncDialog.vbox.pack_start(sync, True, True, 0)
-               self._syncDialog.set_size_request(500, 350)
-               self._syncDialog.vbox.show_all()
-               sync.connect("syncFinished", self._on_sync_finished)
-
-       def enable_zoom(self, zoomEnabled):
-               self._isZoomEnabled = zoomEnabled
-               if zoomEnabled:
-                       self._topBox.hide()
-                       self._notizen.show_history_area(False)
-               else:
-                       self._topBox.show()
-                       self._notizen.show_history_area(True)
-
-       def _on_device_state_change(self, shutdown, save_unsaved_data, memory_low, system_inactivity, message, userData):
-               """
-               For system_inactivity, we have no background tasks to pause
-
-               @note Hildon specific
-               """
-               if memory_low:
-                       gc.collect()
-
-               if save_unsaved_data or shutdown:
-                       self._save_settings()
-
-       def _on_window_state_change(self, widget, event, *args):
-               if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
-                       self._window_in_fullscreen = True
-               else:
-                       self._window_in_fullscreen = False
-
-       def _on_key_press(self, widget, event, *args):
-               if event.keyval == gtk.keysyms.F6:
-                       # The "Full screen" hardware key has been pressed 
-                       if self._window_in_fullscreen:
-                               self._window.unfullscreen ()
-                       else:
-                               self._window.fullscreen ()
-               elif event.keyval == gtk.keysyms.F7:
-                       # Zoom In
-                       self.enable_zoom(True)
-               elif event.keyval == gtk.keysyms.F8:
-                       # Zoom Out
-                       self.enable_zoom(False)
-
-       def _on_view_sql_history(self, widget = None, data = None, data2 = None):
-               import libsqldialog
-               sqldiag = libsqldialog.SqlDialog(self._db)
-               res = sqldiag.run()
-               sqldiag.hide()
-               if res == sqldiag.EXPORT_RESPONSE:
-                       _moduleLogger.info("exporting sql")
-
-                       dlg = hildon.FileChooserDialog(parent=self._window, action=gtk.FILE_CHOOSER_ACTION_SAVE)
-
-                       dlg.set_title(_("Select SQL export file"))
-                       if dlg.run() == gtk.RESPONSE_OK:
-                               fileName = dlg.get_filename()
-                               sqldiag.exportSQL(fileName)
-                       dlg.destroy()
-
-               sqldiag.destroy()
-
-       def _on_move_category(self, widget = None, data = None):
-               dialog = gtk.Dialog(_("Choose category"), self._window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
-
-               dialog.set_position(gtk.WIN_POS_CENTER)
-               comboCategory = gtk.combo_box_new_text()
-
-               comboCategory.append_text('undefined')
-               sql = "SELECT id, liste FROM categories WHERE id = 0 ORDER BY liste"
-               rows = self._db.ladeSQL(sql)
-               for row in rows:
-                       comboCategory.append_text(row[1])
-
-               dialog.vbox.pack_start(comboCategory, True, True, 0)
-
-               dialog.vbox.show_all()
-               #dialog.set_size_request(400, 300)
-
-               if dialog.run() == gtk.RESPONSE_ACCEPT:
-                       n = comboCategory.get_active()
-                       if -1 < n and self._notizen.noteId != -1:
-                               model = comboCategory.get_model()
-                               active = comboCategory.get_active()
-                               if active < 0:
-                                       return None
-                               cat_id = model[active][0]
-
-                               noteid, category, note = self._db.loadNote(self._notizen.noteId)
-                               #print noteid, category, cat_id
-                               self._db.saveNote(noteid, note, cat_id, pcdatum = None)
-                               self._topBox.category_combo_changed()
-                       else:
-                               mbox = gtk.MessageDialog(self._window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("No note selected."))
-                               response = mbox.run()
-                               mbox.hide()
-                               mbox.destroy()
-
-               dialog.destroy()
-
-       def _on_delete_category(self, widget = None, data = None):
-               if self._topBox.get_category() == "%" or self._topBox.get_category() == "undefined":
-                       mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("This category can not be deleted"))
-                       response = mbox.run()
-                       mbox.hide()
-                       mbox.destroy()
-                       return
-
-               mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, _("Are you sure to delete the current category?"))
-               response = mbox.run()
-               mbox.hide()
-               mbox.destroy()
-               if response == gtk.RESPONSE_YES:
-                       sql = "UPDATE notes SET category = ? WHERE category = ?"
-                       self._db.speichereSQL(sql, ("undefined", self._topBox.get_category()))
-                       sql = "DELETE FROM categories WHERE liste = ?"
-                       self._db.speichereSQL(sql, (self._topBox.get_category(), ))
-                       model = self._topBox.categoryCombo.get_model()
-                       pos = self._topBox.categoryCombo.get_active()
-                       if (pos>1):
-                               self._topBox.categoryCombo.remove_text(pos)
-                               self._topBox.categoryCombo.set_active(0)
-
-       def _on_sync_finished(self, data = None, data2 = None):
-               self._topBox.load_categories()
-               self._notizen.load_notes()
-
-       def _on_sync_notes(self, widget = None, data = None):
-               self._syncDialog.run()
-               self._syncDialog.hide()
-
-       def _on_toggle_word_wrap(self, *args):
-               self._wordWrapEnabled = not self._wordWrapEnabled
-               self._notizen.set_wordwrap(self._wordWrapEnabled)
-
-       def _on_delete_event(self, widget, event, data = None):
-               return False
-
-       def _on_destroy(self, widget = None, data = None):
-               try:
-                       self._save_settings()
-                       self._db.close()
-                       if self._osso_c:
-                               self._osso_c.close()
-               finally:
-                       gtk.main_quit()
-
-       def _on_show_about(self, widget = None, data = None):
-               dialog = gtk.AboutDialog()
-               dialog.set_position(gtk.WIN_POS_CENTER)
-               dialog.set_name(constants.__pretty_app_name__)
-               dialog.set_version(constants.__version__)
-               dialog.set_copyright("")
-               dialog.set_website("http://axique.de/index.php?f=Quicknote")
-               comments = _("%s is a note taking program; it is optimised for quick save and search of notes") % constants.__pretty_app_name__
-               dialog.set_comments(comments)
-               dialog.set_authors(["Christoph Wurstle <n800@axique.net>", "Ed Page <edpage@byu.net> (Blame him for the most recent bugs)"])
-               dialog.run()
-               dialog.destroy()
-
-
-if __name__ == "__main__":
-       logging.basicConfig(level=logging.DEBUG)
-       app = QuicknoteProgram()
-       app.main()
diff --git a/src/libspeichern.py b/src/libspeichern.py
deleted file mode 100644 (file)
index 44d1525..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
- Copyright (C) 2007 Christoph Würstle
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License version 2 as
-published by the Free Software Foundation.
-"""
-
-
-import sys
-import os
-import time
-import sqlite3
-import shelve
-import logging
-
-
-try:
-       _
-except NameError:
-       _ = lambda x: x
-
-
-_moduleLogger = logging.getLogger("speichern")
-
-
-class Speichern():
-
-       def __init__(self):
-               home_dir = os.path.expanduser('~')
-               filename = os.path.join(home_dir, ".quicknote.dat")
-               self.d = shelve.open(filename)
-               self.openDB()
-
-       def speichereDirekt(self, schluessel, daten):
-               self.d[schluessel] = daten
-               _moduleLogger.info("speichereDirekt "+str(schluessel)+" "+str(daten)+" lesen: "+str(self.d[schluessel]))
-
-       def ladeDirekt(self, schluessel, default = ""):
-               if (self.d.has_key(schluessel) == True):
-                       data = self.d[schluessel]
-                       return data
-               else:
-                       return default
-
-       def speichereSQL(self, sql, tupel = None, commit = True, host = "self", log = True, pcdatum = None, rowid = ""):
-               try:
-                       programSQLError = True
-                       if tupel is None:
-                               self.cur.execute(sql)
-                       else:
-                               self.cur.execute(sql, tupel)
-                       programSQLError = False
-
-                       if (log == True):
-                               strtupel = []
-                               if tupel is not None:
-                                       for t in tupel:
-                                               strtupel.append(str(t))
-
-                               if pcdatum is None:
-                                       pcdatum = int(time.time())
-                               self.cur.execute("INSERT INTO logtable ( pcdatum, sql, param, host, rowid ) VALUES (?, ?, ?, ?, ?)", (pcdatum, sql, " <<Tren-ner>> ".join(strtupel), host, str(rowid) ))
-                       if commit:
-                               self.conn.commit()
-
-                       return True
-               except StandardError:
-                       s = str(sys.exc_info())
-                       if s.find(" already exists") == -1:
-                               if (programSQLError == True):
-                                       _moduleLogger.error("speichereSQL-Exception "+str(sys.exc_info())+" "+str(sql)+" "+str(tupel))
-                               else:
-                                       _moduleLogger.error("speichereSQL-Exception in Logging!!!! :"+str(sys.exc_info())+" "+str(sql)+" "+str(tupel))
-                       return False
-
-       def commitSQL(self):
-               self.conn.commit()
-
-       def ladeSQL(self, sql, tupel = None):
-               #print sql, tupel
-               try:
-                       if tupel is None:
-                               self.cur.execute(sql)
-                       else:
-                               self.cur.execute(sql, tupel)
-                       return self.cur.fetchall()
-               except StandardError:
-                       _moduleLogger.error("ladeSQL-Exception "+str(sys.exc_info())+" "+str(sql)+" "+str(tupel))
-                       return ()
-
-       def ladeHistory(self, sql_condition, param_condition):
-               sql = "SELECT * FROM logtable WHERE sql LIKE '%"+str(sql_condition)+"%' AND param LIKE '%"+str(param_condition)+"%'"
-               rows = self.ladeSQL(sql)
-               #print rows 
-               erg = []
-               for row in rows:
-                       datum = time.strftime("%d.%m.%y %H:%M:%S", (time.localtime(row[1])))
-                       erg.append([row[1], datum, row[2], row[3], row[3].split(" <<Tren-ner>> ")])
-
-               return erg
-
-       def openDB(self):
-               try:
-                       self.cur.close()
-               except StandardError:
-                       pass
-               try:
-                       self.conn.close()
-               except StandardError:
-                       pass
-
-               db = self.ladeDirekt("datenbank")
-               if db == "":
-                       home_dir = os.path.expanduser('~')
-
-                       #on hildon user not home-dir but /home/user/MyDocs
-                       if home_dir == "/home/user":
-                               if os.path.exists(home_dir+os.sep+"MyDocs/"):
-                                       home_dir = home_dir+os.sep+"MyDocs/"
-                       db = os.path.join(home_dir, "quicknote.s3db")
-
-               self.conn = sqlite3.connect(db)
-               self.cur = self.conn.cursor()
-               try:
-                       sql = "CREATE TABLE logtable (id INTEGER PRIMARY KEY AUTOINCREMENT, pcdatum INTEGER , sql TEXT, param TEXT, host TEXT, rowid TEXT)"
-                       self.cur.execute(sql)
-                       self.conn.commit()
-               except StandardError:
-                       pass
-
-               #Add rowid line (not in old versions included)
-               try:
-                       sql = "ALTER TABLE logtable ADD rowid TEXT"
-                       self.cur.execute(sql)
-                       self.conn.commit()
-               except StandardError:
-                       pass
-
-               #Create notes table
-               try:
-                       sql = "CREATE TABLE notes (noteid TEXT, pcdatum INTEGER , category TEXT, note TEXT)"
-                       self.cur.execute(sql)
-                       self.conn.commit()
-               except StandardError:
-                       pass
-
-       def saveNote(self, noteid, note, category, pcdatum = None):
-               if category == "%":
-                       category = ""
-               sql = "SELECT noteid, pcdatum, category, note FROM notes WHERE noteid = ?"
-               rows = self.ladeSQL(sql, (noteid, ))
-
-               if rows is None or len(rows) == 0:
-                       sql = "INSERT INTO notes (noteid, pcdatum, category, note) VALUES (?, ?, ?, ?)"
-                       if pcdatum is None:
-                               pcdatum = int(time.time())
-                       self.speichereSQL(sql, (noteid, pcdatum, category, note), rowid = noteid)
-               else:
-                       sql = "UPDATE notes SET category = ?, note = ?, pcdatum = ? WHERE noteid = ?"
-                       self.speichereSQL(sql, (category, note, str(int(time.time())), noteid), rowid = noteid)
-
-       def loadNote(self, noteid):
-               if noteid is None or str(noteid) == "":
-                       return (None, None, None)
-               sql = "SELECT noteid, pcdatum, category, note FROM notes WHERE noteid = ?"
-               rows = self.ladeSQL(sql, (noteid, ))
-               if rows is None or len(rows) == 0:
-                       return None
-               else:
-                       noteid, pcdatum, category, note = rows[0]
-                       return (noteid, pcdatum, category, note)
-
-       def delNote(self, noteid):
-               sql = "DELETE FROM notes WHERE noteid = ?"
-               self.speichereSQL(sql, (noteid, ), rowid = noteid)
-
-       def searchNotes(self, searchstring, category):
-               sql = "SELECT noteid, category, note FROM notes WHERE note like ? AND category like ? ORDER BY note"
-               rows = self.ladeSQL(sql, ("%"+searchstring+"%", category))
-               if rows is None or len(rows) == 0:
-                       return None
-               else:
-                       return rows
-
-       def getNoteHistory(self, noteid):
-               return self.ladeHistory("UPDATE notes ", noteid)
-
-       def close(self):
-               try:
-                       self.d.close()
-               except StandardError:
-                       pass
-               try:
-                       self.cur.close()
-               except StandardError:
-                       pass
-               try:
-                       self.conn.close()
-               except StandardError:
-                       pass
-               _moduleLogger.info("Alle Data saved")
-
-       def __del__(self):
-               self.close()
diff --git a/src/libsqldialog.py b/src/libsqldialog.py
deleted file mode 100755 (executable)
index a6cc2d6..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
- Copyright (C) 2007 Christoph Würstle
-
-This program is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License version 2 as
-published by the Free Software Foundation.
-"""
-
-
-import time
-import logging
-
-import gtk
-
-
-try:
-       _
-except NameError:
-       _ = lambda x: x
-
-
-_moduleLogger = logging.getLogger("sqldialog")
-
-
-class SqlDialog(gtk.Dialog):
-
-       EXPORT_RESPONSE = 444
-
-       def __init__(self, db):
-               self.db = db
-
-               _moduleLogger.info("sqldialog, init")
-
-               gtk.Dialog.__init__(self, _("SQL History (the past two days):"), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
-
-               self.add_button(_("Export"), self.EXPORT_RESPONSE)
-               self.add_button(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
-               self.set_position(gtk.WIN_POS_CENTER)
-
-               self.liststore = gtk.ListStore(str, str, str)
-
-               # create the TreeView using liststore
-               self.treeview = gtk.TreeView(self.liststore)
-               self.treeview.set_rules_hint(True)
-
-               # create a CellRenderers to render the data
-               self.cell1 = gtk.CellRendererText()
-               self.cell2 = gtk.CellRendererText()
-               self.cell3 = gtk.CellRendererText()
-
-               # create the TreeViewColumns to display the data
-               self.tvcolumn1 = gtk.TreeViewColumn(_('Timestamp'))
-               self.tvcolumn2 = gtk.TreeViewColumn('SQL')
-               self.tvcolumn3 = gtk.TreeViewColumn(_('Parameter'))
-
-               # add columns to treeview
-               self.treeview.append_column(self.tvcolumn1)
-               self.treeview.append_column(self.tvcolumn2)
-               self.treeview.append_column(self.tvcolumn3)
-
-
-               self.tvcolumn1.pack_start(self.cell1, True)
-               self.tvcolumn2.pack_start(self.cell2, True)
-               self.tvcolumn3.pack_start(self.cell3, True)
-
-               self.tvcolumn1.set_attributes(self.cell1, text = 0) #Spalten setzten hier!!!!
-               self.tvcolumn2.set_attributes(self.cell2, text = 1)
-               self.tvcolumn3.set_attributes(self.cell3, text = 2)
-
-               # Allow NOT drag and drop reordering of rows
-               self.treeview.set_reorderable(False)
-
-               scrolled_window = gtk.ScrolledWindow()
-               scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
-               scrolled_window.add(self.treeview)
-
-               self.vbox.pack_start(scrolled_window, True, True, 0)
-
-               self.vbox.show_all()
-
-               msgstring = ""
-               sql = "SELECT pcdatum, sql, param FROM logtable WHERE pcdatum>? ORDER BY pcdatum DESC"
-               rows = db.ladeSQL(sql, (time.time()-3*24*3600, ))
-               for row in rows:
-                       pcdatum, sql, param = row
-                       datum = str(time.strftime(_("%d.%m.%y %H:%M:%S "), (time.localtime(pcdatum))))
-                       self.liststore.append([datum, sql, param])
-
-               self.set_size_request(500, 400)
-
-       def exportSQL(self, filename):
-               f = open(filename, 'w')
-               try:
-                       msgstring = ""
-                       sql = "SELECT pcdatum, sql, param FROM logtable WHERE pcdatum>? ORDER BY pcdatum DESC"
-                       rows = self.db.ladeSQL(sql, (time.time()-2*24*3600, ))
-                       for row in rows:
-                               pcdatum, sql, param = row
-                               datum = str(time.strftime("%d.%m.%y %H:%M:%S ", (time.localtime(pcdatum))))
-                               f.write( datum +"\t" + sql + "\t\t" + param+ "\n")
-               finally:
-                       f.close()
diff --git a/src/libsync.py b/src/libsync.py
deleted file mode 100755 (executable)
index f8acdac..0000000
+++ /dev/null
@@ -1,368 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program.  If not, see <http://www.gnu.org/licenses/>.
-"""
-
-
-import sys
-import time
-import SimpleXMLRPCServer
-import xmlrpclib
-import select
-#import fcntl
-import uuid
-import logging
-import socket
-socket.setdefaulttimeout(60) # Timeout auf 60 sec. setzen
-
-import gtk
-import gobject
-
-
-try:
-       _
-except NameError:
-       _ = lambda x: x
-
-
-_moduleLogger = logging.getLogger("sync")
-
-
-class ProgressDialog(gtk.Dialog):
-
-       def __init__(self, title = _("Sync process"), parent = None):
-               gtk.Dialog.__init__(self, title, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, ())
-
-               _moduleLogger.info("ProgressDialog, init")
-
-               label = gtk.Label(_("Sync process running...please wait"))
-               self.vbox.pack_start(label, True, True, 0)
-               label = gtk.Label(_("(this can take some minutes)"))
-               self.vbox.pack_start(label, True, True, 0)
-
-               self.vbox.show_all()
-               self.show()
-
-       def pulse(self):
-               pass
-
-
-class Sync(gtk.VBox):
-
-       __gsignals__ = {
-               'syncFinished' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, )),
-               'syncBeforeStart' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, )),
-       }
-
-       def __init__(self, db, parentwindow, port):
-               gtk.VBox.__init__(self, homogeneous = False, spacing = 0)
-
-               _moduleLogger.info("Sync, init")
-               self.db = db
-               self.progress = None
-               self.server = None
-               self.port = int(port)
-               self.parentwindow = parentwindow
-               self.concernedRows = None
-
-               sql = "CREATE TABLE sync (id INTEGER PRIMARY KEY, syncpartner TEXT, uuid TEXT, pcdatum INTEGER)"
-               self.db.speichereSQL(sql, log = False)
-
-               sql = "SELECT uuid, pcdatum FROM sync WHERE syncpartner = ?"
-               rows = self.db.ladeSQL(sql, ("self", )) #Eigene Id feststellen
-
-               if (rows is None)or(len(rows)!= 1):
-                       sql = "DELETE FROM sync WHERE syncpartner = ?"
-                       self.db.speichereSQL(sql, ("self", ), log = False)
-
-                       self.sync_uuid = str(uuid.uuid4())
-                       sql = "INSERT INTO sync (syncpartner, uuid, pcdatum) VALUES (?, ?, ?)"
-                       self.db.speichereSQL(sql, ("self", str(self.sync_uuid), int(time.time())), log = False)
-               else:
-                       sync_uuid, pcdatum = rows[0]
-                       self.sync_uuid = sync_uuid
-
-               frame = gtk.Frame(_("Local SyncServer (port ")+str(self.port)+")")
-
-               self.comboIP = gtk.combo_box_entry_new_text()
-
-               self.comboIP.append_text("") #self.get_ip_address("eth0"))
-
-               frame.add(self.comboIP)
-               serverbutton = gtk.ToggleButton(_("Start/Stop SyncServer"))
-               serverbutton.connect("clicked", self.startServer, (None, ))
-               self.pack_start(frame, expand = False, fill = True, padding = 1)
-               self.pack_start(serverbutton, expand = False, fill = True, padding = 1)
-               self.syncServerStatusLabel = gtk.Label(_("SyncServer stopped"))
-               self.pack_start(self.syncServerStatusLabel, expand = False, fill = True, padding = 1)
-
-               frame = gtk.Frame(_("Remote SyncServer (port ")+str(self.port)+")")
-               self.comboRemoteIP = gtk.combo_box_entry_new_text()
-               self.comboRemoteIP.append_text("192.168.0.?")
-               self.comboRemoteIP.append_text("192.168.1.?")
-               self.comboRemoteIP.append_text("192.168.176.?")
-               frame.add(self.comboRemoteIP)
-               syncbutton = gtk.Button(_("Connect to remote SyncServer"))
-               syncbutton.connect("clicked", self.syncButton, (None, ))
-               self.pack_start(frame, expand = False, fill = True, padding = 1)
-               self.pack_start(syncbutton, expand = False, fill = True, padding = 1)
-               self.syncStatusLabel = gtk.Label(_("no sync process (at the moment)"))
-               self.pack_start(self.syncStatusLabel, expand = False, fill = True, padding = 1)
-
-               self.comboRemoteIP.get_child().set_text(self.db.ladeDirekt("syncRemoteIP"))
-               self.comboIP.get_child().set_text(self.db.ladeDirekt("syncServerIP"))
-
-               #load
-               if self.db.ladeDirekt("startSyncServer", False):
-                       serverbutton.set_active(True)
-
-       def changeSyncStatus(self, active, title):
-               self.syncStatusLabel.set_text(title)
-               if active == True:
-                       if self.progress is None:
-                               self.progress = ProgressDialog(parent = self.parentwindow)
-                               self.emit("syncBeforeStart", "syncBeforeStart")
-               else:
-                       if self.progress is not None:
-                               self.progress.hide()
-                               self.progress.destroy()
-                               self.progress = None
-                               self.emit("syncFinished", "syncFinished")
-
-       def pulse(self):
-               if self.progress is not None:
-                       self.progress.pulse()
-
-       def getUeberblickBox(self):
-               frame = gtk.Frame(_("Query"))
-               return frame
-
-       def handleRPC(self):
-               try:
-                       if self.rpcserver is None:
-                               return False
-               except StandardError:
-                       return False
-
-               while 0 < len(self.poll.poll(0)):
-                       self.rpcserver.handle_request()
-               return True
-
-       def get_ip_address(self, ifname):
-               return socket.gethostbyname(socket.gethostname())
-
-       def getLastSyncDate(self, sync_uuid):
-               sql = "SELECT syncpartner, pcdatum FROM sync WHERE uuid = ?"
-               rows = self.db.ladeSQL(sql, (sync_uuid, ))
-               if rows is not None and len(rows) == 1:
-                       syncpartner, pcdatum = rows[0]
-               else:
-                       pcdatum = -1
-               _moduleLogger.info("LastSyncDatum: "+str(pcdatum)+" Jetzt "+str(int(time.time())))
-               return pcdatum
-
-       def check4commit(self, newSQL, lastdate):
-               _moduleLogger.info("check4commit 1")
-               if self.concernedRows is None:
-                       _moduleLogger.info("check4commit Updatung concernedRows")
-                       sql = "SELECT pcdatum, rowid FROM logtable WHERE pcdatum>? ORDER BY pcdatum DESC"
-                       self.concernedRows = self.db.ladeSQL(sql, (lastdate, ))
-
-               if self.concernedRows is not None and 0 < len(self.concernedRows):
-                       id1, pcdatum, sql, param, host, rowid = newSQL
-
-                       if 0 < len(rowid):
-                               for x in self.concernedRows:
-                                       if x[1] == rowid:
-                                               if pcdatum < x[0]:
-                                                       _moduleLogger.info("newer sync entry, ignoring old one")
-                                                       return False
-                                               else:
-                                                       return True
-
-               return True
-
-       def writeSQLTupel(self, newSQLs, lastdate):
-               if newSQLs is None:
-                       return
-
-               self.concernedRows = None
-               pausenzaehler = 0
-               _moduleLogger.info("writeSQLTupel got "+str(len(newSQLs))+" sql tupels")
-               for newSQL in newSQLs:
-                       if newSQL[3] != "":
-                               param = newSQL[3].split(" <<Tren-ner>> ")
-                       else:
-                               param = None
-
-                       if 2 < len(newSQL):
-                               commitSQL = True
-
-                               if (newSQL[5]!= None)and(len(newSQL[5])>0):
-                                       commitSQL = self.check4commit(newSQL, lastdate)
-
-                               if (commitSQL == True):
-                                       self.db.speichereSQL(newSQL[2], param, commit = False, pcdatum = newSQL[1], rowid = newSQL[5])
-                       else:
-                               _moduleLogger.error("writeSQLTupel: Error")
-
-                       pausenzaehler += 1
-                       if (pausenzaehler % 10) == 0:
-                               self.pulse()
-                               while gtk.events_pending():
-                                       gtk.main_iteration()
-
-               _moduleLogger.info("Alle SQLs an sqlite geschickt, commiting now")
-               self.db.commitSQL()
-               _moduleLogger.info("Alle SQLs commited")
-
-       def doSync(self, sync_uuid, pcdatum, newSQLs, pcdatumjetzt):
-               self.changeSyncStatus(True, "sync process running")
-               self.pulse()
-
-               while gtk.events_pending():
-                       gtk.main_iteration()
-               diff = abs(time.time() - pcdatumjetzt)
-               if 30 < diff:
-                       return -1
-
-               _moduleLogger.info("doSync read sqls")
-               sql = "SELECT * FROM logtable WHERE pcdatum>?"
-               rows = self.db.ladeSQL(sql, (pcdatum, ))
-               _moduleLogger.info("doSync read sqls")
-               self.writeSQLTupel(newSQLs, pcdatum)
-               _moduleLogger.info("doSync wrote "+str(len(newSQLs))+" sqls")
-               _moduleLogger.info("doSync sending "+str(len(rows))+" sqls")
-               return rows
-
-       def getRemoteSyncUUID(self):
-               return self.sync_uuid
-
-       def startServer(self, widget, data = None):
-               #Starte RPCServer
-               self.db.speichereDirekt("syncServerIP", self.comboIP.get_child().get_text())
-
-               if widget.get_active():
-                       _moduleLogger.info("Starting Server")
-
-                       try:
-                               ip = self.comboIP.get_child().get_text()
-                               self.rpcserver = SimpleXMLRPCServer.SimpleXMLRPCServer((ip, self.port), allow_none = True)
-                               self.rpcserver.register_function(pow)
-                               self.rpcserver.register_function(self.getLastSyncDate)
-                               self.rpcserver.register_function(self.doSync)
-                               self.rpcserver.register_function(self.getRemoteSyncUUID)
-                               self.rpcserver.register_function(self.doSaveFinalTime)
-                               self.rpcserver.register_function(self.pulse)
-                               self.poll = select.poll()
-                               self.poll.register(self.rpcserver.fileno())
-                               gobject.timeout_add(1000, self.handleRPC)
-                               self.syncServerStatusLabel.set_text(_("Syncserver running..."))
-
-                               #save
-                               self.db.speichereDirekt("startSyncServer", True)
-
-                       except StandardError:
-                               s = str(sys.exc_info())
-                               _moduleLogger.error("libsync: could not start server. Error: "+s)
-                               mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Could not start SyncServer. Check IP, port settings.")) #gtk.DIALOG_MODAL
-                               mbox.set_modal(False)
-                               response = mbox.run()
-                               mbox.hide()
-                               mbox.destroy()
-                               widget.set_active(False)
-               else:
-                       _moduleLogger.info("Stopping Server")
-                       try:
-                               del self.rpcserver
-                       except StandardError:
-                               pass
-                       self.syncServerStatusLabel.set_text(_("SyncServer stopped"))
-                       #save
-                       self.db.speichereDirekt("startSyncServer", False)
-
-       def doSaveFinalTime(self, sync_uuid, pcdatum = None):
-               if pcdatum is None:
-                       pcdatum = int(time.time())
-               if pcdatum < time.time():
-                       pcdatum = int(time.time()) #größere Zeit nehmen
-
-               self.pulse()
-
-               #fime save time+uuid
-               sql = "DELETE FROM sync WHERE uuid = ?"
-               self.db.speichereSQL(sql, (sync_uuid, ), log = False)
-               sql = "INSERT INTO sync (syncpartner, uuid, pcdatum) VALUES (?, ?, ?)"
-               self.db.speichereSQL(sql, ("x", str(sync_uuid), pcdatum), log = False)
-               self.pulse()
-               self.changeSyncStatus(False, _("no sync process (at the moment)"))
-               return (self.sync_uuid, pcdatum)
-
-       def syncButton(self, widget, data = None):
-               _moduleLogger.info("Syncing")
-
-               self.changeSyncStatus(True, _("sync process running"))
-               while (gtk.events_pending()):
-                       gtk.main_iteration()
-
-               self.db.speichereDirekt("syncRemoteIP", self.comboRemoteIP.get_child().get_text())
-               try:
-                       self.server = xmlrpclib.ServerProxy("http://"+self.comboRemoteIP.get_child().get_text()+":"+str(self.port), allow_none = True)
-                       server_sync_uuid = self.server.getRemoteSyncUUID()
-                       lastDate = self.getLastSyncDate(str(server_sync_uuid))
-
-                       sql = "SELECT * FROM logtable WHERE pcdatum>?"
-                       rows = self.db.ladeSQL(sql, (lastDate, ))
-
-                       _moduleLogger.info("loaded concerned rows")
-
-                       newSQLs = self.server.doSync(self.sync_uuid, lastDate, rows, time.time())
-
-                       _moduleLogger.info("did do sync, processing sqls now")
-                       if newSQLs != -1:
-                               self.writeSQLTupel(newSQLs, lastDate)
-
-                               sync_uuid, finalpcdatum = self.server.doSaveFinalTime(self.sync_uuid)
-                               self.doSaveFinalTime(sync_uuid, finalpcdatum)
-
-                               self.changeSyncStatus(False, _("no sync process (at the moment)"))
-
-                               mbox =  gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("Synchronization successfully completed"))
-                               response = mbox.run()
-                               mbox.hide()
-                               mbox.destroy()
-                       else:
-                               _moduleLogger.warning("Zeitdiff zu groß/oder anderer db-Fehler")
-                               self.changeSyncStatus(False, _("no sync process (at the moment)"))
-                               mbox =  gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("The clocks are not synchronized between stations"))
-                               response = mbox.run()
-                               mbox.hide()
-                               mbox.destroy()
-               except StandardError:
-                       _moduleLogger.warning("Sync connect failed")
-                       self.changeSyncStatus(False, _("no sync process (at the moment)"))
-                       mbox =  gtk.MessageDialog(
-                               None,
-                               gtk.DIALOG_MODAL,
-                               gtk.MESSAGE_INFO,
-                               gtk.BUTTONS_OK,
-                               _("Sync failed, reason: ")+unicode(sys.exc_info()[1][1])
-                       )
-                       response = mbox.run()
-                       mbox.hide()
-                       mbox.destroy()
-                       self.server = None
-               self.server = None
diff --git a/src/notizen.py b/src/notizen.py
new file mode 100644 (file)
index 0000000..19bf8d1
--- /dev/null
@@ -0,0 +1,270 @@
+#!/usr/bin/env python2.5
+# -*- coding: utf-8 -*-
+
+"""
+ Copyright (C) 2007 Christoph Würstle
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+"""
+
+import time
+import logging
+import uuid
+
+import gobject
+import gtk
+try:
+       import gtkspell
+except ImportError:
+       gtkspell = None
+
+import simple_list
+
+
+try:
+       _
+except NameError:
+       _ = lambda x: x
+
+
+_moduleLogger = logging.getLogger("notizen")
+
+
+class Notizen(gtk.HBox):
+
+       def __init__(self, db, topBox):
+               self._db = db
+               self._topBox = topBox
+               self.noteId = -1
+               self._pos = -1
+               self._noteBody = None #Last notetext
+               self._categoryName = ""
+
+               gtk.HBox.__init__(self, homogeneous = False, spacing = 0)
+               _moduleLogger.info("libnotizen, init")
+
+               self._noteslist = simple_list.SimpleList()
+               self._noteslist.set_eventfunction_cursor_changed(self._update_noteslist)
+
+               self._noteslist.set_size_request(250, -1)
+
+               vbox = gtk.VBox(homogeneous = False, spacing = 0)
+
+               frame = gtk.Frame(_("Titles"))
+               frame.add(self._noteslist)
+               vbox.pack_start(frame, expand = True, fill = True, padding = 3)
+
+               buttonHBox = gtk.HBox()
+               vbox.pack_start(buttonHBox, expand = False, fill = True, padding = 3)
+
+               button = gtk.Button(stock = gtk.STOCK_ADD)
+               button.connect("clicked", self._on_add_note, None)
+               buttonHBox.pack_start(button, expand = True, fill = True, padding = 3)
+
+               button = gtk.Button(stock = gtk.STOCK_DELETE)
+               button.connect("clicked", self._on_delete_note, None)
+               buttonHBox.pack_start(button, expand = True, fill = True, padding = 3)
+
+               self.pack_start(vbox, expand = False, fill = True, padding = 3)
+
+               self._noteBodyView = gtk.TextView()
+               self._noteBodyView.connect("focus-out-event", self.save_note, "focus-out-event")
+               buf = self._noteBodyView.get_buffer()
+               buf.set_text("")
+               buf.connect("changed", self._on_note_changed, None)
+               if gtkspell is not None:
+                       self._noteBodySpellChecker = gtkspell.Spell(self._noteBodyView)
+               else:
+                       self._noteBodySpellChecker = None
+
+               #self.textviewNotiz.set_size_request(-1, 50)
+               self._noteScrollWindow = gtk.ScrolledWindow()
+               self._noteScrollWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+               self._noteScrollWindow.add(self._noteBodyView)
+
+               frame = gtk.Frame(_("Note"))
+               frame.add(self._noteScrollWindow)
+
+               vbox = gtk.VBox(homogeneous = False, spacing = 0)
+               vbox.pack_start(frame, expand = True, fill = True, padding = 3)
+
+               self._historyBox = gtk.HBox(homogeneous = False, spacing = 0)
+
+               self._historyStatusLabel = gtk.Label(_("No History"))
+               self._historyStatusLabel.set_alignment(0.0, 0.5)
+               self._historyBox.pack_start(self._historyStatusLabel, expand = True, fill = True, padding = 3)
+
+               button = gtk.Button(_("History"))
+               button.connect("clicked", self._on_show_history, None)
+               self._historyBox.pack_start(button, expand = True, fill = True, padding = 3)
+
+               vbox.pack_start(self._historyBox, expand = False, fill = True, padding = 3)
+
+               self.pack_start(vbox, expand = True, fill = True, padding = 3)
+
+               self.load_notes()
+               self._topBox.connect("reload_notes", self.load_notes)
+
+       def set_wordwrap(self, enableWordWrap):
+               if enableWordWrap:
+                       self._noteScrollWindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
+                       self._noteBodyView.set_wrap_mode(gtk.WRAP_WORD)
+               else:
+                       self._noteScrollWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+                       self._noteBodyView.set_wrap_mode(gtk.WRAP_NONE)
+
+       def show_history_area(self, visible):
+               if visible:
+                       self._historyBox.show()
+               else:
+                       self._historyBox.hide()
+
+       def load_notes(self, data = None):
+               _moduleLogger.info("load_notes params: pos:"+str(self._pos)+" noteid:"+str(self.noteId))
+               self._noteslist.clear_items()
+               self._noteslist.append_item(_("New Note..."), "new")
+
+               self._categoryName = self._topBox.get_category()
+               search = self._topBox.get_search_pattern()
+               notes = self._db.searchNotes(search, self._categoryName)
+
+               if notes is not None:
+                       for note in notes:
+                               noteid, category, noteText = note
+                               title = self._get_title(noteText)
+                               self._noteslist.append_item(title, noteid)
+
+               self.noteId = -1
+               self._pos = -1
+               self._noteBodyView.get_buffer().set_text("")
+
+       def save_note(self, widget = None, data = None, data2 = None):
+               _moduleLogger.info("save_note params: pos:"+str(self._pos)+" noteid:"+str(self.noteId))
+               #print "params:", data, data2
+               buf = self._noteBodyView.get_buffer().get_text(self._noteBodyView.get_buffer().get_start_iter(), self._noteBodyView.get_buffer().get_end_iter())
+               if buf is None or len(buf) == 0:
+                       return
+
+               if buf == self._noteBody:
+                       return
+
+               _moduleLogger.info("Saving note: "+buf)
+               if self._pos == -1 or self.noteId == -1:
+                       self._pos = -1
+                       self.noteId = str(uuid.uuid4())
+                       self._db.saveNote(self.noteId, buf, self._categoryName)
+                       self._noteslist.append_item(self._get_title(buf), self.noteId)
+                       self._pos = self._noteslist.select_last_item()
+               else:
+                       self._db.saveNote(self.noteId, buf, self._categoryName)
+
+               self._topBox.define_this_category()
+
+       def _get_title(self, buf):
+               """
+               @returns the title of the current note
+               """
+               eol = buf.find("\n")
+               if -1 == eol:
+                       eol = len(buf)
+               title = buf[:eol]
+               return title
+
+       def _set_focus(self):
+               self._noteBodyView.grab_focus()
+               return False
+
+       def _update_noteslist(self, data = None, data2 = None):
+               if self._pos != -1:
+                       self.save_note()
+
+               try:
+                       (pos, key, value) = self._noteslist.get_selection_data()
+                       if (pos == -1):
+                               return
+               except StandardError:
+                       if data != "new":
+                               return
+                       key = None
+
+               if key == "new" or data == "new":
+                       #both methods supported click add note or new note (first one disabled)
+                       self.noteId = str(uuid.uuid4())
+                       self._db.saveNote(self.noteId, "", self._categoryName)
+                       self._pos = -1
+                       self._noteslist.append_item("", self.noteId)
+                       self._noteBodyView.get_buffer().set_text("")
+                       self._pos = self._noteslist.select_last_item()
+               else:
+                       self._pos = pos
+                       self.noteId, pcdatum, self._categoryName, self._noteBody = self._db.loadNote(key)
+                       self._historyStatusLabel.set_text(time.strftime(_("Last change: %d.%m.%y %H:%M"), time.localtime(pcdatum)))
+                       buf = self._noteBodyView.get_buffer()
+                       buf.set_text(self._noteBody)
+
+               gobject.timeout_add(200, self._set_focus)
+
+       def _on_note_changed(self, widget = None, data = None):
+               if self._pos == -1 or self.noteId == -1:
+                       return
+
+               buf = self._noteBodyView.get_buffer().get_text(self._noteBodyView.get_buffer().get_start_iter(), self._noteBodyView.get_buffer().get_end_iter())
+
+               title = self._get_title(buf)
+               value, key = self._noteslist.get_item(self._pos)
+
+               if value != title:
+                       self._noteslist.change_item(self._pos, title, self.noteId)
+
+       def _on_add_note(self, widget = None, data = None):
+               self._update_noteslist("new")
+
+       def _on_delete_note(self, widget = None, data = None):
+               if (self.noteId == -1):
+                       return
+               mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, _("Really delete?"))
+               response = mbox.run()
+               mbox.hide()
+               mbox.destroy()
+               if response == gtk.RESPONSE_YES:
+                       self._db.delNote(self.noteId)
+                       self.noteId = -1
+                       self._noteslist.remove_item(self._pos)
+                       self._pos = -1
+                       self._noteBodyView.get_buffer().set_text("")
+
+       def _on_show_history(self, widget = None, data = None, label = None):
+               if self.noteId == -1:
+                       mbox =  gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("No note selected."))
+                       response = mbox.run()
+                       mbox.hide()
+                       mbox.destroy()
+                       return
+
+               rows = self._db.getNoteHistory(self.noteId)
+
+               import history
+               dialog = history.Dialog()
+
+               lastNoteStr = ""
+               for row in rows:
+                       daten = row[4][1]
+                       if daten != "" and lastNoteStr != daten:
+                               lastNoteStr = daten
+                               dialog.noteHistory.append([row[0], row[1], row[2], row[3], daten+"\n"])
+
+               dialog.vbox.show_all()
+               dialog.set_size_request(600, 380)
+
+               if dialog.run() == gtk.RESPONSE_ACCEPT:
+                       print "saving"
+                       self.save_note()
+                       data = dialog.get_selected_row()
+                       if data is not None:
+                               self._db.speichereSQL(data[2], data[3].split(" <<Tren-ner>> "), rowid = self.noteId)
+                               _moduleLogger.info("loading History")
+                               self._update_noteslist()
+
+               dialog.destroy()
index 9410944..10b6149 100755 (executable)
@@ -19,7 +19,7 @@ sys.path.append('/usr/lib/quicknote')
 
 
 import constants
-import libquicknote
+import quicknote_gtk
 
 
 if __name__ == "__main__":
@@ -33,5 +33,5 @@ if __name__ == "__main__":
        logging.basicConfig(level=logging.DEBUG, filename=userLogPath)
        _moduleLogger.info("quicknote %s-%s" % (constants.__version__, constants.__build__))
 
-       app = libquicknote.QuicknoteProgram()
+       app = quicknote_gtk.QuicknoteProgram()
        app.main()
diff --git a/src/quicknote_gtk.py b/src/quicknote_gtk.py
new file mode 100644 (file)
index 0000000..c89f704
--- /dev/null
@@ -0,0 +1,420 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ Copyright (C) 2007 Christoph Würstle
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+@todo Add Note Export (txt File) and Export All (json dump?)
+@todo Remove confirmation on deleting empty notes
+@todo Try to switch to more passive notifications (rather than message boxes)
+"""
+
+from __future__ import with_statement
+
+import os
+import gc
+import logging
+import warnings
+import ConfigParser
+
+import gtk
+
+try:
+       import hildon
+       IS_HILDON = True
+except ImportError:
+       import fakehildon as hildon
+       IS_HILDON = False
+
+try:
+       import osso
+except ImportError:
+       osso = None
+
+import constants
+
+import speichern
+import kopfzeile
+import notizen
+import sync
+
+
+try:
+       _
+except NameError:
+       _ = lambda x: x
+
+
+_moduleLogger = logging.getLogger("quick")
+
+
+class QuicknoteProgram(hildon.Program):
+
+       _user_data = os.path.join(os.path.expanduser("~"), ".%s" % constants.__app_name__)
+       _user_settings = "%s/settings.ini" % _user_data
+
+       def __init__(self):
+               super(QuicknoteProgram, self).__init__()
+               if IS_HILDON:
+                       gtk.set_application_name(constants.__pretty_app_name__)
+
+               dblog = os.path.join(self._user_data, "quicknote.log")
+
+               _moduleLogger.info('Starting quicknote')
+
+               if osso is not None:
+                       self._osso_c = osso.Context(constants.__app_name__, constants.__version__, False)
+                       self._deviceState = osso.DeviceState(self._osso_c)
+                       self._deviceState.set_device_state_callback(self._on_device_state_change, 0)
+               else:
+                       self._osso_c = None
+                       self._deviceState = None
+
+               #Get the Main Window, and connect the "destroy" event
+               self._window = hildon.Window()
+               self.add_window(self._window)
+
+               if not IS_HILDON:
+                       self._window.set_title(constants.__pretty_app_name__)
+               self._window.connect("delete_event", self._on_delete_event)
+               self._window.connect("destroy", self._on_destroy)
+               self._window.connect("key-press-event", self._on_key_press)
+               self._window.connect("window-state-event", self._on_window_state_change)
+               self._window_in_fullscreen = False #The window isn't in full screen mode initially.
+               self._isZoomEnabled = False
+
+               self._db = speichern.Speichern()
+               self._syncDialog = None
+               self._prepare_sync_dialog()
+
+               #Create GUI main vbox
+               vbox = gtk.VBox(homogeneous = False, spacing = 0)
+
+               #Create Menu and apply it for hildon
+               filemenu = gtk.Menu()
+
+               menu_items = gtk.MenuItem(_("Set DB file"))
+               filemenu.append(menu_items)
+               menu_items.connect("activate", self.set_db_file, None)
+
+               menu_items = gtk.MenuItem(_("SQL History"))
+               filemenu.append(menu_items)
+               menu_items.connect("activate", self._on_view_sql_history, None)
+
+               menu_items = gtk.MenuItem(_("Sync notes"))
+               filemenu.append(menu_items)
+               menu_items.connect("activate", self._on_sync_notes, None)
+
+               menu_items = gtk.MenuItem(_("Quit"))
+               filemenu.append(menu_items)
+               menu_items.connect("activate", self._on_destroy, None)
+
+               file_menu = gtk.MenuItem(_("File"))
+               file_menu.show()
+               file_menu.set_submenu(filemenu)
+
+               categorymenu = gtk.Menu()
+
+               menu_items = gtk.MenuItem(_("Delete"))
+               categorymenu.append(menu_items)
+               menu_items.connect("activate", self._on_delete_category, None)
+
+               menu_items = gtk.MenuItem(_("Move To Category"))
+               categorymenu.append(menu_items)
+               menu_items.connect("activate", self._on_move_category, None)
+
+               category_menu = gtk.MenuItem(_("Category"))
+               category_menu.show()
+               category_menu.set_submenu(categorymenu)
+
+               viewmenu = gtk.Menu()
+
+               menu_items = gtk.MenuItem(_("Word Wrap"))
+               viewmenu.append(menu_items)
+               menu_items.connect("activate", self._on_toggle_word_wrap, None)
+               self._wordWrapEnabled = False
+
+               view_menu = gtk.MenuItem(_("View"))
+               view_menu.show()
+               view_menu.set_submenu(viewmenu)
+
+               helpmenu = gtk.Menu()
+
+               menu_items = gtk.MenuItem(_("About"))
+               helpmenu.append(menu_items)
+               menu_items.connect("activate", self._on_show_about, None)
+
+               help_menu = gtk.MenuItem(_("Help"))
+               help_menu.show()
+               help_menu.set_submenu(helpmenu)
+
+               menu_bar = gtk.MenuBar()
+               menu_bar.show()
+               menu_bar.append (file_menu)
+               menu_bar.append (category_menu)
+               menu_bar.append (view_menu)
+               menu_bar.append (help_menu)
+
+               menu_bar.show()
+               if IS_HILDON:
+                       menu = gtk.Menu()
+                       for child in menu_bar.get_children():
+                               child.reparent(menu)
+                       self._window.set_menu(menu)
+                       menu_bar.destroy()
+               else:
+                       vbox.pack_start(menu_bar, False, False, 0)
+
+               #Create GUI elements
+               self._topBox = kopfzeile.Kopfzeile(self._db)
+               vbox.pack_start(self._topBox, False, False, 0)
+
+               self._notizen = notizen.Notizen(self._db, self._topBox)
+               vbox.pack_start(self._notizen, True, True, 0)
+               self._window.add(vbox)
+
+               self._on_toggle_word_wrap()
+
+               try:
+                       os.makedirs(self._user_data)
+               except OSError, e:
+                       if e.errno != 17:
+                               raise
+               self._window.show_all()
+               self._load_settings()
+
+       def main(self):
+               gtk.main()
+
+       def _save_settings(self):
+               config = ConfigParser.SafeConfigParser()
+               self.save_settings(config)
+               with open(self._user_settings, "wb") as configFile:
+                       config.write(configFile)
+
+       def save_settings(self, config):
+               config.add_section(constants.__pretty_app_name__)
+               config.set(constants.__pretty_app_name__, "wordwrap", str(self._wordWrapEnabled))
+               config.set(constants.__pretty_app_name__, "zoom", str(self._isZoomEnabled))
+               config.set(constants.__pretty_app_name__, "fullscreen", str(self._window_in_fullscreen))
+
+       def _load_settings(self):
+               config = ConfigParser.SafeConfigParser()
+               config.read(self._user_settings)
+               self.load_settings(config)
+
+       def load_settings(self, config):
+               try:
+                       self._wordWrapEnabled = config.getboolean(constants.__pretty_app_name__, "wordwrap")
+                       self._isZoomEnabled = config.getboolean(constants.__pretty_app_name__, "zoom")
+                       self._window_in_fullscreen = config.getboolean(constants.__pretty_app_name__, "fullscreen")
+               except ConfigParser.NoSectionError, e:
+                       warnings.warn(
+                               "Settings file %s is missing section %s" % (
+                                       self._user_settings,
+                                       e.section,
+                               ),
+                               stacklevel=2
+                       )
+
+               self._notizen.set_wordwrap(self._wordWrapEnabled)
+
+               self.enable_zoom(self._isZoomEnabled)
+
+               if self._window_in_fullscreen:
+                       self._window.fullscreen()
+               else:
+                       self._window.unfullscreen()
+
+       def set_db_file(self, widget = None, data = None):
+               dlg = hildon.FileChooserDialog(parent=self._window, action=gtk.FILE_CHOOSER_ACTION_SAVE)
+
+               if self._db.ladeDirekt('datenbank'):
+                       dlg.set_filename(self._db.ladeDirekt('datenbank'))
+
+               dlg.set_title(_("Choose database file"))
+               if dlg.run() == gtk.RESPONSE_OK:
+                       fileName = dlg.get_filename()
+                       self._db.speichereDirekt('datenbank', fileName)
+
+                       self._db.openDB()
+                       self._topBox.load_categories()
+                       self._notizen.load_notes()
+               dlg.destroy()
+
+       def _prepare_sync_dialog(self):
+               self._syncDialog = gtk.Dialog(_("Sync"), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+
+               self._syncDialog.set_position(gtk.WIN_POS_CENTER)
+               syncer = sync.Sync(self._db, self._window, 50504)
+               self._syncDialog.vbox.pack_start(syncer, True, True, 0)
+               self._syncDialog.set_size_request(500, 350)
+               self._syncDialog.vbox.show_all()
+               syncer.connect("syncFinished", self._on_sync_finished)
+
+       def enable_zoom(self, zoomEnabled):
+               self._isZoomEnabled = zoomEnabled
+               if zoomEnabled:
+                       self._topBox.hide()
+                       self._notizen.show_history_area(False)
+               else:
+                       self._topBox.show()
+                       self._notizen.show_history_area(True)
+
+       def _on_device_state_change(self, shutdown, save_unsaved_data, memory_low, system_inactivity, message, userData):
+               """
+               For system_inactivity, we have no background tasks to pause
+
+               @note Hildon specific
+               """
+               if memory_low:
+                       gc.collect()
+
+               if save_unsaved_data or shutdown:
+                       self._save_settings()
+
+       def _on_window_state_change(self, widget, event, *args):
+               if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
+                       self._window_in_fullscreen = True
+               else:
+                       self._window_in_fullscreen = False
+
+       def _on_key_press(self, widget, event, *args):
+               if event.keyval == gtk.keysyms.F6:
+                       # The "Full screen" hardware key has been pressed 
+                       if self._window_in_fullscreen:
+                               self._window.unfullscreen ()
+                       else:
+                               self._window.fullscreen ()
+               elif event.keyval == gtk.keysyms.F7:
+                       # Zoom In
+                       self.enable_zoom(True)
+               elif event.keyval == gtk.keysyms.F8:
+                       # Zoom Out
+                       self.enable_zoom(False)
+
+       def _on_view_sql_history(self, widget = None, data = None, data2 = None):
+               import sqldialog
+               sqldiag = sqldialog.SqlDialog(self._db)
+               res = sqldiag.run()
+               sqldiag.hide()
+               if res == sqldiag.EXPORT_RESPONSE:
+                       _moduleLogger.info("exporting sql")
+
+                       dlg = hildon.FileChooserDialog(parent=self._window, action=gtk.FILE_CHOOSER_ACTION_SAVE)
+
+                       dlg.set_title(_("Select SQL export file"))
+                       if dlg.run() == gtk.RESPONSE_OK:
+                               fileName = dlg.get_filename()
+                               sqldiag.exportSQL(fileName)
+                       dlg.destroy()
+
+               sqldiag.destroy()
+
+       def _on_move_category(self, widget = None, data = None):
+               dialog = gtk.Dialog(_("Choose category"), self._window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+
+               dialog.set_position(gtk.WIN_POS_CENTER)
+               comboCategory = gtk.combo_box_new_text()
+
+               comboCategory.append_text('undefined')
+               sql = "SELECT id, liste FROM categories WHERE id = 0 ORDER BY liste"
+               rows = self._db.ladeSQL(sql)
+               for row in rows:
+                       comboCategory.append_text(row[1])
+
+               dialog.vbox.pack_start(comboCategory, True, True, 0)
+
+               dialog.vbox.show_all()
+               #dialog.set_size_request(400, 300)
+
+               if dialog.run() == gtk.RESPONSE_ACCEPT:
+                       n = comboCategory.get_active()
+                       if -1 < n and self._notizen.noteId != -1:
+                               model = comboCategory.get_model()
+                               active = comboCategory.get_active()
+                               if active < 0:
+                                       return None
+                               cat_id = model[active][0]
+
+                               noteid, category, note = self._db.loadNote(self._notizen.noteId)
+                               #print noteid, category, cat_id
+                               self._db.saveNote(noteid, note, cat_id, pcdatum = None)
+                               self._topBox.category_combo_changed()
+                       else:
+                               mbox = gtk.MessageDialog(self._window, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("No note selected."))
+                               response = mbox.run()
+                               mbox.hide()
+                               mbox.destroy()
+
+               dialog.destroy()
+
+       def _on_delete_category(self, widget = None, data = None):
+               if self._topBox.get_category() == "%" or self._topBox.get_category() == "undefined":
+                       mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("This category can not be deleted"))
+                       response = mbox.run()
+                       mbox.hide()
+                       mbox.destroy()
+                       return
+
+               mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, _("Are you sure to delete the current category?"))
+               response = mbox.run()
+               mbox.hide()
+               mbox.destroy()
+               if response == gtk.RESPONSE_YES:
+                       sql = "UPDATE notes SET category = ? WHERE category = ?"
+                       self._db.speichereSQL(sql, ("undefined", self._topBox.get_category()))
+                       sql = "DELETE FROM categories WHERE liste = ?"
+                       self._db.speichereSQL(sql, (self._topBox.get_category(), ))
+                       model = self._topBox.categoryCombo.get_model()
+                       pos = self._topBox.categoryCombo.get_active()
+                       if (pos>1):
+                               self._topBox.categoryCombo.remove_text(pos)
+                               self._topBox.categoryCombo.set_active(0)
+
+       def _on_sync_finished(self, data = None, data2 = None):
+               self._topBox.load_categories()
+               self._notizen.load_notes()
+
+       def _on_sync_notes(self, widget = None, data = None):
+               self._syncDialog.run()
+               self._syncDialog.hide()
+
+       def _on_toggle_word_wrap(self, *args):
+               self._wordWrapEnabled = not self._wordWrapEnabled
+               self._notizen.set_wordwrap(self._wordWrapEnabled)
+
+       def _on_delete_event(self, widget, event, data = None):
+               return False
+
+       def _on_destroy(self, widget = None, data = None):
+               try:
+                       self._save_settings()
+                       self._db.close()
+                       if self._osso_c:
+                               self._osso_c.close()
+               finally:
+                       gtk.main_quit()
+
+       def _on_show_about(self, widget = None, data = None):
+               dialog = gtk.AboutDialog()
+               dialog.set_position(gtk.WIN_POS_CENTER)
+               dialog.set_name(constants.__pretty_app_name__)
+               dialog.set_version(constants.__version__)
+               dialog.set_copyright("")
+               dialog.set_website("http://axique.de/index.php?f=Quicknote")
+               comments = _("%s is a note taking program; it is optimised for quick save and search of notes") % constants.__pretty_app_name__
+               dialog.set_comments(comments)
+               dialog.set_authors(["Christoph Wurstle <n800@axique.net>", "Ed Page <edpage@byu.net> (Blame him for the most recent bugs)"])
+               dialog.run()
+               dialog.destroy()
+
+
+if __name__ == "__main__":
+       logging.basicConfig(level=logging.DEBUG)
+       app = QuicknoteProgram()
+       app.main()
diff --git a/src/speichern.py b/src/speichern.py
new file mode 100644 (file)
index 0000000..c66e811
--- /dev/null
@@ -0,0 +1,208 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ Copyright (C) 2007 Christoph Würstle
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+"""
+
+
+import sys
+import os
+import time
+import sqlite3
+import shelve
+import logging
+
+
+try:
+       _
+except NameError:
+       _ = lambda x: x
+
+
+_moduleLogger = logging.getLogger("speichern")
+
+
+class Speichern(object):
+
+       def __init__(self):
+               home_dir = os.path.expanduser('~')
+               filename = os.path.join(home_dir, ".quicknote.dat")
+               self.d = shelve.open(filename)
+               self.openDB()
+
+       def speichereDirekt(self, schluessel, daten):
+               self.d[schluessel] = daten
+               _moduleLogger.info("speichereDirekt "+str(schluessel)+" "+str(daten)+" lesen: "+str(self.d[schluessel]))
+
+       def ladeDirekt(self, schluessel, default = ""):
+               if (self.d.has_key(schluessel) == True):
+                       data = self.d[schluessel]
+                       return data
+               else:
+                       return default
+
+       def speichereSQL(self, sql, tupel = None, commit = True, host = "self", log = True, pcdatum = None, rowid = ""):
+               try:
+                       programSQLError = True
+                       if tupel is None:
+                               self.cur.execute(sql)
+                       else:
+                               self.cur.execute(sql, tupel)
+                       programSQLError = False
+
+                       if (log == True):
+                               strtupel = []
+                               if tupel is not None:
+                                       for t in tupel:
+                                               strtupel.append(str(t))
+
+                               if pcdatum is None:
+                                       pcdatum = int(time.time())
+                               self.cur.execute("INSERT INTO logtable ( pcdatum, sql, param, host, rowid ) VALUES (?, ?, ?, ?, ?)", (pcdatum, sql, " <<Tren-ner>> ".join(strtupel), host, str(rowid) ))
+                       if commit:
+                               self.conn.commit()
+
+                       return True
+               except StandardError:
+                       s = str(sys.exc_info())
+                       if s.find(" already exists") == -1:
+                               if (programSQLError == True):
+                                       _moduleLogger.error("speichereSQL-Exception "+str(sys.exc_info())+" "+str(sql)+" "+str(tupel))
+                               else:
+                                       _moduleLogger.error("speichereSQL-Exception in Logging!!!! :"+str(sys.exc_info())+" "+str(sql)+" "+str(tupel))
+                       return False
+
+       def commitSQL(self):
+               self.conn.commit()
+
+       def ladeSQL(self, sql, tupel = None):
+               #print sql, tupel
+               try:
+                       if tupel is None:
+                               self.cur.execute(sql)
+                       else:
+                               self.cur.execute(sql, tupel)
+                       return self.cur.fetchall()
+               except StandardError:
+                       _moduleLogger.error("ladeSQL-Exception "+str(sys.exc_info())+" "+str(sql)+" "+str(tupel))
+                       return ()
+
+       def ladeHistory(self, sql_condition, param_condition):
+               sql = "SELECT * FROM logtable WHERE sql LIKE '%"+str(sql_condition)+"%' AND param LIKE '%"+str(param_condition)+"%'"
+               rows = self.ladeSQL(sql)
+               #print rows 
+               erg = []
+               for row in rows:
+                       datum = time.strftime("%d.%m.%y %H:%M:%S", (time.localtime(row[1])))
+                       erg.append([row[1], datum, row[2], row[3], row[3].split(" <<Tren-ner>> ")])
+
+               return erg
+
+       def openDB(self):
+               try:
+                       self.cur.close()
+               except StandardError:
+                       pass
+               try:
+                       self.conn.close()
+               except StandardError:
+                       pass
+
+               db = self.ladeDirekt("datenbank")
+               if db == "":
+                       home_dir = os.path.expanduser('~')
+
+                       #on hildon user not home-dir but /home/user/MyDocs
+                       if home_dir == "/home/user":
+                               if os.path.exists(home_dir+os.sep+"MyDocs/"):
+                                       home_dir = home_dir+os.sep+"MyDocs/"
+                       db = os.path.join(home_dir, "quicknote.s3db")
+
+               self.conn = sqlite3.connect(db)
+               self.cur = self.conn.cursor()
+               try:
+                       sql = "CREATE TABLE logtable (id INTEGER PRIMARY KEY AUTOINCREMENT, pcdatum INTEGER , sql TEXT, param TEXT, host TEXT, rowid TEXT)"
+                       self.cur.execute(sql)
+                       self.conn.commit()
+               except StandardError:
+                       pass
+
+               #Add rowid line (not in old versions included)
+               try:
+                       sql = "ALTER TABLE logtable ADD rowid TEXT"
+                       self.cur.execute(sql)
+                       self.conn.commit()
+               except StandardError:
+                       pass
+
+               #Create notes table
+               try:
+                       sql = "CREATE TABLE notes (noteid TEXT, pcdatum INTEGER , category TEXT, note TEXT)"
+                       self.cur.execute(sql)
+                       self.conn.commit()
+               except StandardError:
+                       pass
+
+       def saveNote(self, noteid, note, category, pcdatum = None):
+               if category == "%":
+                       category = ""
+               sql = "SELECT noteid, pcdatum, category, note FROM notes WHERE noteid = ?"
+               rows = self.ladeSQL(sql, (noteid, ))
+
+               if rows is None or len(rows) == 0:
+                       sql = "INSERT INTO notes (noteid, pcdatum, category, note) VALUES (?, ?, ?, ?)"
+                       if pcdatum is None:
+                               pcdatum = int(time.time())
+                       self.speichereSQL(sql, (noteid, pcdatum, category, note), rowid = noteid)
+               else:
+                       sql = "UPDATE notes SET category = ?, note = ?, pcdatum = ? WHERE noteid = ?"
+                       self.speichereSQL(sql, (category, note, str(int(time.time())), noteid), rowid = noteid)
+
+       def loadNote(self, noteid):
+               if noteid is None or str(noteid) == "":
+                       return (None, None, None)
+               sql = "SELECT noteid, pcdatum, category, note FROM notes WHERE noteid = ?"
+               rows = self.ladeSQL(sql, (noteid, ))
+               if rows is None or len(rows) == 0:
+                       return None
+               else:
+                       noteid, pcdatum, category, note = rows[0]
+                       return (noteid, pcdatum, category, note)
+
+       def delNote(self, noteid):
+               sql = "DELETE FROM notes WHERE noteid = ?"
+               self.speichereSQL(sql, (noteid, ), rowid = noteid)
+
+       def searchNotes(self, searchstring, category):
+               sql = "SELECT noteid, category, note FROM notes WHERE note like ? AND category like ? ORDER BY note"
+               rows = self.ladeSQL(sql, ("%"+searchstring+"%", category))
+               if rows is None or len(rows) == 0:
+                       return None
+               else:
+                       return rows
+
+       def getNoteHistory(self, noteid):
+               return self.ladeHistory("UPDATE notes ", noteid)
+
+       def close(self):
+               try:
+                       self.d.close()
+               except StandardError:
+                       pass
+               try:
+                       self.cur.close()
+               except StandardError:
+                       pass
+               try:
+                       self.conn.close()
+               except StandardError:
+                       pass
+               _moduleLogger.info("Alle Data saved")
+
+       def __del__(self):
+               self.close()
diff --git a/src/sqldialog.py b/src/sqldialog.py
new file mode 100755 (executable)
index 0000000..a6cc2d6
--- /dev/null
@@ -0,0 +1,105 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+ Copyright (C) 2007 Christoph Würstle
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+"""
+
+
+import time
+import logging
+
+import gtk
+
+
+try:
+       _
+except NameError:
+       _ = lambda x: x
+
+
+_moduleLogger = logging.getLogger("sqldialog")
+
+
+class SqlDialog(gtk.Dialog):
+
+       EXPORT_RESPONSE = 444
+
+       def __init__(self, db):
+               self.db = db
+
+               _moduleLogger.info("sqldialog, init")
+
+               gtk.Dialog.__init__(self, _("SQL History (the past two days):"), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT)
+
+               self.add_button(_("Export"), self.EXPORT_RESPONSE)
+               self.add_button(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
+               self.set_position(gtk.WIN_POS_CENTER)
+
+               self.liststore = gtk.ListStore(str, str, str)
+
+               # create the TreeView using liststore
+               self.treeview = gtk.TreeView(self.liststore)
+               self.treeview.set_rules_hint(True)
+
+               # create a CellRenderers to render the data
+               self.cell1 = gtk.CellRendererText()
+               self.cell2 = gtk.CellRendererText()
+               self.cell3 = gtk.CellRendererText()
+
+               # create the TreeViewColumns to display the data
+               self.tvcolumn1 = gtk.TreeViewColumn(_('Timestamp'))
+               self.tvcolumn2 = gtk.TreeViewColumn('SQL')
+               self.tvcolumn3 = gtk.TreeViewColumn(_('Parameter'))
+
+               # add columns to treeview
+               self.treeview.append_column(self.tvcolumn1)
+               self.treeview.append_column(self.tvcolumn2)
+               self.treeview.append_column(self.tvcolumn3)
+
+
+               self.tvcolumn1.pack_start(self.cell1, True)
+               self.tvcolumn2.pack_start(self.cell2, True)
+               self.tvcolumn3.pack_start(self.cell3, True)
+
+               self.tvcolumn1.set_attributes(self.cell1, text = 0) #Spalten setzten hier!!!!
+               self.tvcolumn2.set_attributes(self.cell2, text = 1)
+               self.tvcolumn3.set_attributes(self.cell3, text = 2)
+
+               # Allow NOT drag and drop reordering of rows
+               self.treeview.set_reorderable(False)
+
+               scrolled_window = gtk.ScrolledWindow()
+               scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+               scrolled_window.add(self.treeview)
+
+               self.vbox.pack_start(scrolled_window, True, True, 0)
+
+               self.vbox.show_all()
+
+               msgstring = ""
+               sql = "SELECT pcdatum, sql, param FROM logtable WHERE pcdatum>? ORDER BY pcdatum DESC"
+               rows = db.ladeSQL(sql, (time.time()-3*24*3600, ))
+               for row in rows:
+                       pcdatum, sql, param = row
+                       datum = str(time.strftime(_("%d.%m.%y %H:%M:%S "), (time.localtime(pcdatum))))
+                       self.liststore.append([datum, sql, param])
+
+               self.set_size_request(500, 400)
+
+       def exportSQL(self, filename):
+               f = open(filename, 'w')
+               try:
+                       msgstring = ""
+                       sql = "SELECT pcdatum, sql, param FROM logtable WHERE pcdatum>? ORDER BY pcdatum DESC"
+                       rows = self.db.ladeSQL(sql, (time.time()-2*24*3600, ))
+                       for row in rows:
+                               pcdatum, sql, param = row
+                               datum = str(time.strftime("%d.%m.%y %H:%M:%S ", (time.localtime(pcdatum))))
+                               f.write( datum +"\t" + sql + "\t\t" + param+ "\n")
+               finally:
+                       f.close()
diff --git a/src/sync.py b/src/sync.py
new file mode 100755 (executable)
index 0000000..f8acdac
--- /dev/null
@@ -0,0 +1,368 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+"""
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+
+import sys
+import time
+import SimpleXMLRPCServer
+import xmlrpclib
+import select
+#import fcntl
+import uuid
+import logging
+import socket
+socket.setdefaulttimeout(60) # Timeout auf 60 sec. setzen
+
+import gtk
+import gobject
+
+
+try:
+       _
+except NameError:
+       _ = lambda x: x
+
+
+_moduleLogger = logging.getLogger("sync")
+
+
+class ProgressDialog(gtk.Dialog):
+
+       def __init__(self, title = _("Sync process"), parent = None):
+               gtk.Dialog.__init__(self, title, parent, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, ())
+
+               _moduleLogger.info("ProgressDialog, init")
+
+               label = gtk.Label(_("Sync process running...please wait"))
+               self.vbox.pack_start(label, True, True, 0)
+               label = gtk.Label(_("(this can take some minutes)"))
+               self.vbox.pack_start(label, True, True, 0)
+
+               self.vbox.show_all()
+               self.show()
+
+       def pulse(self):
+               pass
+
+
+class Sync(gtk.VBox):
+
+       __gsignals__ = {
+               'syncFinished' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, )),
+               'syncBeforeStart' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, (gobject.TYPE_STRING, )),
+       }
+
+       def __init__(self, db, parentwindow, port):
+               gtk.VBox.__init__(self, homogeneous = False, spacing = 0)
+
+               _moduleLogger.info("Sync, init")
+               self.db = db
+               self.progress = None
+               self.server = None
+               self.port = int(port)
+               self.parentwindow = parentwindow
+               self.concernedRows = None
+
+               sql = "CREATE TABLE sync (id INTEGER PRIMARY KEY, syncpartner TEXT, uuid TEXT, pcdatum INTEGER)"
+               self.db.speichereSQL(sql, log = False)
+
+               sql = "SELECT uuid, pcdatum FROM sync WHERE syncpartner = ?"
+               rows = self.db.ladeSQL(sql, ("self", )) #Eigene Id feststellen
+
+               if (rows is None)or(len(rows)!= 1):
+                       sql = "DELETE FROM sync WHERE syncpartner = ?"
+                       self.db.speichereSQL(sql, ("self", ), log = False)
+
+                       self.sync_uuid = str(uuid.uuid4())
+                       sql = "INSERT INTO sync (syncpartner, uuid, pcdatum) VALUES (?, ?, ?)"
+                       self.db.speichereSQL(sql, ("self", str(self.sync_uuid), int(time.time())), log = False)
+               else:
+                       sync_uuid, pcdatum = rows[0]
+                       self.sync_uuid = sync_uuid
+
+               frame = gtk.Frame(_("Local SyncServer (port ")+str(self.port)+")")
+
+               self.comboIP = gtk.combo_box_entry_new_text()
+
+               self.comboIP.append_text("") #self.get_ip_address("eth0"))
+
+               frame.add(self.comboIP)
+               serverbutton = gtk.ToggleButton(_("Start/Stop SyncServer"))
+               serverbutton.connect("clicked", self.startServer, (None, ))
+               self.pack_start(frame, expand = False, fill = True, padding = 1)
+               self.pack_start(serverbutton, expand = False, fill = True, padding = 1)
+               self.syncServerStatusLabel = gtk.Label(_("SyncServer stopped"))
+               self.pack_start(self.syncServerStatusLabel, expand = False, fill = True, padding = 1)
+
+               frame = gtk.Frame(_("Remote SyncServer (port ")+str(self.port)+")")
+               self.comboRemoteIP = gtk.combo_box_entry_new_text()
+               self.comboRemoteIP.append_text("192.168.0.?")
+               self.comboRemoteIP.append_text("192.168.1.?")
+               self.comboRemoteIP.append_text("192.168.176.?")
+               frame.add(self.comboRemoteIP)
+               syncbutton = gtk.Button(_("Connect to remote SyncServer"))
+               syncbutton.connect("clicked", self.syncButton, (None, ))
+               self.pack_start(frame, expand = False, fill = True, padding = 1)
+               self.pack_start(syncbutton, expand = False, fill = True, padding = 1)
+               self.syncStatusLabel = gtk.Label(_("no sync process (at the moment)"))
+               self.pack_start(self.syncStatusLabel, expand = False, fill = True, padding = 1)
+
+               self.comboRemoteIP.get_child().set_text(self.db.ladeDirekt("syncRemoteIP"))
+               self.comboIP.get_child().set_text(self.db.ladeDirekt("syncServerIP"))
+
+               #load
+               if self.db.ladeDirekt("startSyncServer", False):
+                       serverbutton.set_active(True)
+
+       def changeSyncStatus(self, active, title):
+               self.syncStatusLabel.set_text(title)
+               if active == True:
+                       if self.progress is None:
+                               self.progress = ProgressDialog(parent = self.parentwindow)
+                               self.emit("syncBeforeStart", "syncBeforeStart")
+               else:
+                       if self.progress is not None:
+                               self.progress.hide()
+                               self.progress.destroy()
+                               self.progress = None
+                               self.emit("syncFinished", "syncFinished")
+
+       def pulse(self):
+               if self.progress is not None:
+                       self.progress.pulse()
+
+       def getUeberblickBox(self):
+               frame = gtk.Frame(_("Query"))
+               return frame
+
+       def handleRPC(self):
+               try:
+                       if self.rpcserver is None:
+                               return False
+               except StandardError:
+                       return False
+
+               while 0 < len(self.poll.poll(0)):
+                       self.rpcserver.handle_request()
+               return True
+
+       def get_ip_address(self, ifname):
+               return socket.gethostbyname(socket.gethostname())
+
+       def getLastSyncDate(self, sync_uuid):
+               sql = "SELECT syncpartner, pcdatum FROM sync WHERE uuid = ?"
+               rows = self.db.ladeSQL(sql, (sync_uuid, ))
+               if rows is not None and len(rows) == 1:
+                       syncpartner, pcdatum = rows[0]
+               else:
+                       pcdatum = -1
+               _moduleLogger.info("LastSyncDatum: "+str(pcdatum)+" Jetzt "+str(int(time.time())))
+               return pcdatum
+
+       def check4commit(self, newSQL, lastdate):
+               _moduleLogger.info("check4commit 1")
+               if self.concernedRows is None:
+                       _moduleLogger.info("check4commit Updatung concernedRows")
+                       sql = "SELECT pcdatum, rowid FROM logtable WHERE pcdatum>? ORDER BY pcdatum DESC"
+                       self.concernedRows = self.db.ladeSQL(sql, (lastdate, ))
+
+               if self.concernedRows is not None and 0 < len(self.concernedRows):
+                       id1, pcdatum, sql, param, host, rowid = newSQL
+
+                       if 0 < len(rowid):
+                               for x in self.concernedRows:
+                                       if x[1] == rowid:
+                                               if pcdatum < x[0]:
+                                                       _moduleLogger.info("newer sync entry, ignoring old one")
+                                                       return False
+                                               else:
+                                                       return True
+
+               return True
+
+       def writeSQLTupel(self, newSQLs, lastdate):
+               if newSQLs is None:
+                       return
+
+               self.concernedRows = None
+               pausenzaehler = 0
+               _moduleLogger.info("writeSQLTupel got "+str(len(newSQLs))+" sql tupels")
+               for newSQL in newSQLs:
+                       if newSQL[3] != "":
+                               param = newSQL[3].split(" <<Tren-ner>> ")
+                       else:
+                               param = None
+
+                       if 2 < len(newSQL):
+                               commitSQL = True
+
+                               if (newSQL[5]!= None)and(len(newSQL[5])>0):
+                                       commitSQL = self.check4commit(newSQL, lastdate)
+
+                               if (commitSQL == True):
+                                       self.db.speichereSQL(newSQL[2], param, commit = False, pcdatum = newSQL[1], rowid = newSQL[5])
+                       else:
+                               _moduleLogger.error("writeSQLTupel: Error")
+
+                       pausenzaehler += 1
+                       if (pausenzaehler % 10) == 0:
+                               self.pulse()
+                               while gtk.events_pending():
+                                       gtk.main_iteration()
+
+               _moduleLogger.info("Alle SQLs an sqlite geschickt, commiting now")
+               self.db.commitSQL()
+               _moduleLogger.info("Alle SQLs commited")
+
+       def doSync(self, sync_uuid, pcdatum, newSQLs, pcdatumjetzt):
+               self.changeSyncStatus(True, "sync process running")
+               self.pulse()
+
+               while gtk.events_pending():
+                       gtk.main_iteration()
+               diff = abs(time.time() - pcdatumjetzt)
+               if 30 < diff:
+                       return -1
+
+               _moduleLogger.info("doSync read sqls")
+               sql = "SELECT * FROM logtable WHERE pcdatum>?"
+               rows = self.db.ladeSQL(sql, (pcdatum, ))
+               _moduleLogger.info("doSync read sqls")
+               self.writeSQLTupel(newSQLs, pcdatum)
+               _moduleLogger.info("doSync wrote "+str(len(newSQLs))+" sqls")
+               _moduleLogger.info("doSync sending "+str(len(rows))+" sqls")
+               return rows
+
+       def getRemoteSyncUUID(self):
+               return self.sync_uuid
+
+       def startServer(self, widget, data = None):
+               #Starte RPCServer
+               self.db.speichereDirekt("syncServerIP", self.comboIP.get_child().get_text())
+
+               if widget.get_active():
+                       _moduleLogger.info("Starting Server")
+
+                       try:
+                               ip = self.comboIP.get_child().get_text()
+                               self.rpcserver = SimpleXMLRPCServer.SimpleXMLRPCServer((ip, self.port), allow_none = True)
+                               self.rpcserver.register_function(pow)
+                               self.rpcserver.register_function(self.getLastSyncDate)
+                               self.rpcserver.register_function(self.doSync)
+                               self.rpcserver.register_function(self.getRemoteSyncUUID)
+                               self.rpcserver.register_function(self.doSaveFinalTime)
+                               self.rpcserver.register_function(self.pulse)
+                               self.poll = select.poll()
+                               self.poll.register(self.rpcserver.fileno())
+                               gobject.timeout_add(1000, self.handleRPC)
+                               self.syncServerStatusLabel.set_text(_("Syncserver running..."))
+
+                               #save
+                               self.db.speichereDirekt("startSyncServer", True)
+
+                       except StandardError:
+                               s = str(sys.exc_info())
+                               _moduleLogger.error("libsync: could not start server. Error: "+s)
+                               mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Could not start SyncServer. Check IP, port settings.")) #gtk.DIALOG_MODAL
+                               mbox.set_modal(False)
+                               response = mbox.run()
+                               mbox.hide()
+                               mbox.destroy()
+                               widget.set_active(False)
+               else:
+                       _moduleLogger.info("Stopping Server")
+                       try:
+                               del self.rpcserver
+                       except StandardError:
+                               pass
+                       self.syncServerStatusLabel.set_text(_("SyncServer stopped"))
+                       #save
+                       self.db.speichereDirekt("startSyncServer", False)
+
+       def doSaveFinalTime(self, sync_uuid, pcdatum = None):
+               if pcdatum is None:
+                       pcdatum = int(time.time())
+               if pcdatum < time.time():
+                       pcdatum = int(time.time()) #größere Zeit nehmen
+
+               self.pulse()
+
+               #fime save time+uuid
+               sql = "DELETE FROM sync WHERE uuid = ?"
+               self.db.speichereSQL(sql, (sync_uuid, ), log = False)
+               sql = "INSERT INTO sync (syncpartner, uuid, pcdatum) VALUES (?, ?, ?)"
+               self.db.speichereSQL(sql, ("x", str(sync_uuid), pcdatum), log = False)
+               self.pulse()
+               self.changeSyncStatus(False, _("no sync process (at the moment)"))
+               return (self.sync_uuid, pcdatum)
+
+       def syncButton(self, widget, data = None):
+               _moduleLogger.info("Syncing")
+
+               self.changeSyncStatus(True, _("sync process running"))
+               while (gtk.events_pending()):
+                       gtk.main_iteration()
+
+               self.db.speichereDirekt("syncRemoteIP", self.comboRemoteIP.get_child().get_text())
+               try:
+                       self.server = xmlrpclib.ServerProxy("http://"+self.comboRemoteIP.get_child().get_text()+":"+str(self.port), allow_none = True)
+                       server_sync_uuid = self.server.getRemoteSyncUUID()
+                       lastDate = self.getLastSyncDate(str(server_sync_uuid))
+
+                       sql = "SELECT * FROM logtable WHERE pcdatum>?"
+                       rows = self.db.ladeSQL(sql, (lastDate, ))
+
+                       _moduleLogger.info("loaded concerned rows")
+
+                       newSQLs = self.server.doSync(self.sync_uuid, lastDate, rows, time.time())
+
+                       _moduleLogger.info("did do sync, processing sqls now")
+                       if newSQLs != -1:
+                               self.writeSQLTupel(newSQLs, lastDate)
+
+                               sync_uuid, finalpcdatum = self.server.doSaveFinalTime(self.sync_uuid)
+                               self.doSaveFinalTime(sync_uuid, finalpcdatum)
+
+                               self.changeSyncStatus(False, _("no sync process (at the moment)"))
+
+                               mbox =  gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("Synchronization successfully completed"))
+                               response = mbox.run()
+                               mbox.hide()
+                               mbox.destroy()
+                       else:
+                               _moduleLogger.warning("Zeitdiff zu groß/oder anderer db-Fehler")
+                               self.changeSyncStatus(False, _("no sync process (at the moment)"))
+                               mbox =  gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("The clocks are not synchronized between stations"))
+                               response = mbox.run()
+                               mbox.hide()
+                               mbox.destroy()
+               except StandardError:
+                       _moduleLogger.warning("Sync connect failed")
+                       self.changeSyncStatus(False, _("no sync process (at the moment)"))
+                       mbox =  gtk.MessageDialog(
+                               None,
+                               gtk.DIALOG_MODAL,
+                               gtk.MESSAGE_INFO,
+                               gtk.BUTTONS_OK,
+                               _("Sync failed, reason: ")+unicode(sys.exc_info()[1][1])
+                       )
+                       response = mbox.run()
+                       mbox.hide()
+                       mbox.destroy()
+                       self.server = None
+               self.server = None