Tagging the pre-epage code svn/tags/0.7.5
authorepage <eopage@byu.net>
Sat, 16 May 2009 13:00:14 +0000 (13:00 +0000)
committerepage <eopage@byu.net>
Sat, 16 May 2009 13:00:14 +0000 (13:00 +0000)
git-svn-id: file:///svnroot/quicknote/tags/0.7.5@34 bb7704e3-badb-4cfa-9ab3-9374dc87eaa2

31 files changed:
Makefile [new file with mode: 0644]
data/40/quicknote.png [new file with mode: 0644]
data/48/quicknote.png [new file with mode: 0644]
data/low/quicknote.png [new file with mode: 0644]
data/quicknote.desktop [new file with mode: 0644]
data/quicknote.png [new file with mode: 0644]
data/quicknote.service [new file with mode: 0644]
data/scale/quicknote.png [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/copyright [new file with mode: 0644]
debian/dirs [new file with mode: 0644]
debian/docs [new file with mode: 0644]
debian/postinst [new file with mode: 0644]
debian/rules [new file with mode: 0755]
po/de.po [new file with mode: 0644]
po/ru.po [new file with mode: 0644]
remake [new file with mode: 0755]
setup.py [new file with mode: 0644]
src/quicknote [new file with mode: 0755]
src/quicknoteclasses/__init__.py [new file with mode: 0755]
src/quicknoteclasses/libhistory.py [new file with mode: 0644]
src/quicknoteclasses/libkopfzeile.py [new file with mode: 0644]
src/quicknoteclasses/libnotizen.py [new file with mode: 0644]
src/quicknoteclasses/libquicknote.py [new file with mode: 0644]
src/quicknoteclasses/libspeichern.py [new file with mode: 0644]
src/quicknoteclasses/libsqldialog.py [new file with mode: 0755]
src/quicknoteclasses/libsync.py [new file with mode: 0755]
src/quicknoteclasses/simple_list.py [new file with mode: 0644]
upload.sh [new file with mode: 0755]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..98a81ee
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,26 @@
+all: build_mo
+       python2.5 setup.py build  
+clean: 
+       rm -rf ./locale
+       python2.5 setup.py clean --all
+install: build_mo
+       python2.5 setup.py install --root $(DESTDIR) 
+
+TEXT_DOMAIN=quicknote
+POTFILES=$(wildcard src/quicknoteclasses/*.py)
+
+update_po: po/templates.pot
+       @for lang in $(basename $(notdir $(wildcard po/*.po))); do \
+               msgmerge -U --strict --no-wrap po/$$lang.po po/templates.pot; \
+       done
+
+po/templates.pot: $(POTFILES)
+       xgettext --language=Python --strict --no-wrap --output=$@ $(POTFILES)
+
+build_mo:
+       @for lang in $(basename $(notdir $(wildcard po/*.po))); do \
+               mkdir -p locale/$$lang/LC_MESSAGES; \
+               msgfmt --statistics -c -o locale/$$lang/LC_MESSAGES/$(TEXT_DOMAIN).mo po/$$lang.po; \
+       done
+
+.PHONES: update_po build_mo
diff --git a/data/40/quicknote.png b/data/40/quicknote.png
new file mode 100644 (file)
index 0000000..d6aa8d9
Binary files /dev/null and b/data/40/quicknote.png differ
diff --git a/data/48/quicknote.png b/data/48/quicknote.png
new file mode 100644 (file)
index 0000000..7c9f7af
Binary files /dev/null and b/data/48/quicknote.png differ
diff --git a/data/low/quicknote.png b/data/low/quicknote.png
new file mode 100644 (file)
index 0000000..f7fc618
Binary files /dev/null and b/data/low/quicknote.png differ
diff --git a/data/quicknote.desktop b/data/quicknote.desktop
new file mode 100644 (file)
index 0000000..8719f73
--- /dev/null
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Name=Quicknote
+Comment=Quicknote
+Type=Application
+Exec=/usr/bin/quicknote
+Icon=quicknote
+X-Window-Icon=quicknote
+X-Window-Icon-Dimmed=quicknote
+#X-Osso-Service=quicknote
+X-Osso-Type=application/x-executable
\ No newline at end of file
diff --git a/data/quicknote.png b/data/quicknote.png
new file mode 100644 (file)
index 0000000..46c8c02
Binary files /dev/null and b/data/quicknote.png differ
diff --git a/data/quicknote.service b/data/quicknote.service
new file mode 100644 (file)
index 0000000..177db0a
--- /dev/null
@@ -0,0 +1,3 @@
+[D-BUS Service] 
+Name=com.nokia.quicknote
+Exec=/usr/bin/quicknote
\ No newline at end of file
diff --git a/data/scale/quicknote.png b/data/scale/quicknote.png
new file mode 100644 (file)
index 0000000..da2d5f5
Binary files /dev/null and b/data/scale/quicknote.png differ
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..624ba89
--- /dev/null
@@ -0,0 +1,35 @@
+quicknote (0.7.4) unstable; urgency=low
+
+  * fixed small bugs
+  * move category
+
+ -- unknown <n800@axique.de>  Thu,  22 May 2008 08:12:53 +0100
+
+
+quicknote (0.7.3) unstable; urgency=low
+
+  * fixed small bugs
+  * move category
+
+ -- unknown <n800@axique.de>  Wed,  28 Jan 2008 08:12:53 +0100
+
+quicknote (0.7.2) unstable; urgency=low
+
+  * improved sync, fixed a small bug
+
+ -- unknown <n800@axique.de>  Wed,  26 Nov 2007 08:12:53 +0100
+
+quicknote (0.7.1) unstable; urgency=low
+
+  * improved sync
+
+ -- unknown <n800@axique.de>  Wed,  7 Nov 2007 08:12:53 +0100
+
+
+
+quicknote (0.7.0) unstable; urgency=low
+
+  * Initial Release.
+
+ -- unknown <n800@axique.de>  Mon,  6 Nov 2007 08:12:53 +0100
+
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..b8626c4
--- /dev/null
@@ -0,0 +1 @@
+4
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..3929d54
--- /dev/null
@@ -0,0 +1,21 @@
+Source: quicknote
+Section: user/other
+Priority: optional
+Maintainer: Christoph Würstle <n800 at axique de>
+Build-Depends: debhelper (>= 4.0.0), python2.5-dev
+Standards-Version: 3.6.1
+
+Package: quicknote
+Architecture: all
+Depends: python2.5-hildon, python2.5-gtk2, python2.5-osso, python2.5-runtime
+Description: Quicknote
+XB-Maemo-Icon-26:
+ iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A
+ /wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9cLAwkANf/o52QAAAAddEVYdENv
+ bW1lbnQAQ3JlYXRlZCB3aXRoIFRoZSBHSU1Q72QlbgAAARNJREFUSMfNlsENhCAQRT9oPFiDmFCN
+ iRW7DViBnj1gEXog7AkXERUQk/0nCMpzZr4DRCkFAGjbVg3DgLIs8VRSSlBK0XUd4ZwDAHK9OI4j
+ +r5HKtV1jWVZtjnVgxSR2KKUHkFv6xLEGANj7F2QDyDkQ/IriBDiFqqfiQLZL/tuFl2jUDWsigfZ
+ aYs1SO67uRDiUDvfaE5Brs1ckIZV+Ih5m5vjKDPcGcIGvm6GIJDvj+pbm9PUmUV3pc1c+4jZG0Sv
+ amR3hivXRdnbhpn/jg25M8Et6G9aUGiHyEOOCbNmLtM8PibOIghJaZLOEFQjKWXybqCvcruIsixL
+ dj/QIoT8xpo6TZNa13W3+FScc1IUBQDgC9noggh/sT9oAAAAAElFTkSuQmCC
+
diff --git a/debian/copyright b/debian/copyright
new file mode 100644 (file)
index 0000000..3c80733
--- /dev/null
@@ -0,0 +1,12 @@
+This package was debianized by Christoph Würstle <n800 !at! axique .dotx de> on
+Mon, 22 Jan 2007 22:44:33 +0200.
+
+It was downloaded from <fill in ftp site>
+
+Copyright:
+
+Upstream Author(s): <put author(s) name and email here>
+
+License:
+
+Special drop a mail
diff --git a/debian/dirs b/debian/dirs
new file mode 100644 (file)
index 0000000..ca882bb
--- /dev/null
@@ -0,0 +1,2 @@
+usr/bin
+usr/sbin
diff --git a/debian/docs b/debian/docs
new file mode 100644 (file)
index 0000000..724e084
--- /dev/null
@@ -0,0 +1,2 @@
+README
+TODO
diff --git a/debian/postinst b/debian/postinst
new file mode 100644 (file)
index 0000000..1df47d1
--- /dev/null
@@ -0,0 +1,3 @@
+#!/bin/sh -e
+gtk-update-icon-cache -f /usr/share/icons/hicolor
+exit 0
\ No newline at end of file
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..273008d
--- /dev/null
@@ -0,0 +1,93 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+       INSTALL_PROGRAM += -s
+endif
+
+configure: configure-stamp
+configure-stamp:
+       dh_testdir
+       # Add here commands to configure the package.
+
+       touch configure-stamp
+
+
+build: build-stamp
+
+build-stamp: configure-stamp 
+       dh_testdir
+
+       # Add here commands to compile the package.
+       $(MAKE)
+
+       touch build-stamp
+
+clean:
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp configure-stamp
+
+       # Add here commands to clean up after the build process.
+       -$(MAKE) clean
+
+       dh_clean
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k
+       dh_installdirs
+
+       # Add here commands to install the package into debian/quicknote
+       $(MAKE) install DESTDIR=$(CURDIR)/debian/quicknote
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+       dh_installchangelogs
+#      dh_installdocs
+       dh_installexamples
+#      dh_install
+#      dh_installmenu
+#      dh_installdebconf       
+#      dh_installlogrotate
+#      dh_installemacsen
+#      dh_installpam
+#      dh_installmime
+#      dh_installinit
+#      dh_installcron
+#      dh_installinfo
+       dh_installman
+       dh_link
+       dh_strip
+       dh_compress
+       dh_fixperms
+#      dh_perl
+#      dh_python
+#      dh_makeshlibs
+       dh_installdeb
+       dh_shlibdeps
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/po/de.po b/po/de.po
new file mode 100644 (file)
index 0000000..a83382f
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,228 @@
+# German translations for quicknote package
+# German messages for quicknote.
+# Copyright (C) 2008 THE quicknote'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the quicknote package.
+# Christoph Würstle <chris@axique.de>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: quicknote\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-06-03 16:25+0400\n"
+"PO-Revision-Date: 2008-06-03 16:07+0400\n"
+"Last-Translator: Christoph Würstle <chris@axique.de>\n"
+"Language-Team: German\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+#
+# File: src/quicknoteclasses/libhistory.py, line: 30
+msgid "History:"
+msgstr "Historie:"
+#
+# File: src/quicknoteclasses/libhistory.py, line: 43
+# File: src/quicknoteclasses/libsqldialog.py, line: 65
+msgid "Timestamp"
+msgstr "Zeitstempel"
+#
+# File: src/quicknoteclasses/libhistory.py, line: 44
+# File: src/quicknoteclasses/libnotizen.py, line: 234
+msgid "Note"
+msgstr "Notiz"
+#
+# File: src/quicknoteclasses/libkopfzeile.py, line: 48
+# File: src/quicknoteclasses/libkopfzeile.py, line: 106
+msgid "all"
+msgstr "alle"
+#
+# File: src/quicknoteclasses/libkopfzeile.py, line: 131
+msgid "Search:  "
+msgstr "Suche:"
+#
+# File: src/quicknoteclasses/libkopfzeile.py, line: 141
+msgid "Category:  "
+msgstr "Kategorie"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 105
+msgid "Last change: %d.%m.%y %H:%M"
+msgstr "Letzte Änderung: %d.%m.%y %H:%M"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 116
+msgid "Really delete?"
+msgstr "Wirklich löschen?"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 131
+msgid "new Note"
+msgstr "neue Notiz"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 150
+# File: src/quicknoteclasses/libquicknote.py, line: 183
+msgid "No note selected."
+msgstr "Keine Notiz markiert"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 209
+msgid "Titles"
+msgstr "Titel"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 213
+msgid "add note"
+msgstr "Notiz hinzufügen"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 217
+msgid "del note"
+msgstr "Notiz löschen"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 247
+msgid "History"
+msgstr "Historie"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 78
+msgid "Choose database file"
+msgstr "Datenbankdatei auswählen"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 95
+#, python-format
+msgid "%s is a note taking program; it is optimised for quick save and search of notes"
+msgstr "%s ist ein Programm um Notizen zu verwaltn; es ist für schnelles speichern und finden optimiert"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 117
+msgid "Select SQL export file"
+msgstr "Wähle SQL-Export-Datei"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 130
+msgid "This category can not be deleted"
+msgstr "Diese Kategorie kann nicht gelöscht werden"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 136
+msgid "Are you sure to delete the current category?"
+msgstr "Wirklich aktuell gewählte Kategorie löschen?"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 152
+msgid "Choose category"
+msgstr "Wähle Kategorie"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 196
+msgid "Sync"
+msgstr "Syncronisation"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 269
+msgid "Set DB file"
+msgstr "Setzte Datenbaknkdatei"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 273
+msgid "SQL History"
+msgstr "SQL Historie"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 277
+msgid "Sync notes"
+msgstr "Syncronisiere Notizen"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 281
+msgid "Quit"
+msgstr "Beenden"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 285
+msgid "File"
+msgstr "Datei"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 296
+msgid "delete"
+msgstr "löschen"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 300
+msgid "move to category"
+msgstr "verschiebe zu Kategorie"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 304
+msgid "Category"
+msgstr "Kategorie"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 310
+msgid "About"
+msgstr "Über"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 314
+msgid "Help"
+msgstr "Hilfe"
+#
+# File: src/quicknoteclasses/libsqldialog.py, line: 46
+msgid "SQL History (the past two days):"
+msgstr "SQL Historie (der letzten 2 Tage):"
+#
+# File: src/quicknoteclasses/libsqldialog.py, line: 67
+msgid "Parameter"
+msgstr "Parameter"
+#
+# File: src/quicknoteclasses/libsqldialog.py, line: 105
+msgid "%d.%m.%y %H:%M:%S "
+msgstr "%d.%m.%y %H:%M:%S "
+#
+# File: src/quicknoteclasses/libsync.py, line: 43
+msgid "Sync process"
+msgstr "Syncronisationsprozess"
+#
+# File: src/quicknoteclasses/libsync.py, line: 48
+msgid "Sync process running...please wait"
+msgstr "Syncronisationsprozess läuft...bitte warten"
+#
+# File: src/quicknoteclasses/libsync.py, line: 50
+msgid "(this can take some minutes)"
+msgstr "(dies kann einige Minuten dauern)"
+#
+# File: src/quicknoteclasses/libsync.py, line: 90
+msgid "Query"
+msgstr "Anfrage"
+#
+# File: src/quicknoteclasses/libsync.py, line: 242
+msgid "Syncserver running..."
+msgstr "Syncronisationsprozess läuft..."
+#
+# File: src/quicknoteclasses/libsync.py, line: 250
+msgid "Could not start SyncServer. Check IP, port settings."
+msgstr "Konnte Syncronisationsserver nicht starten. Bitte IP und Port-Einstellungen überprüfen."
+#
+# File: src/quicknoteclasses/libsync.py, line: 263
+# File: src/quicknoteclasses/libsync.py, line: 409
+msgid "SyncServer stopped"
+msgstr "Syncronisationsprozess gestoppt."
+#
+# File: src/quicknoteclasses/libsync.py, line: 280
+# File: src/quicknoteclasses/libsync.py, line: 316
+# File: src/quicknoteclasses/libsync.py, line: 324
+# File: src/quicknoteclasses/libsync.py, line: 331
+# File: src/quicknoteclasses/libsync.py, line: 422
+msgid "no sync process (at the moment)"
+msgstr "Kein Syncronisationsprozess (im Moment)"
+#
+# File: src/quicknoteclasses/libsync.py, line: 289
+msgid "sync process running"
+msgstr "Syncronisationsprozess läuft"
+#
+# File: src/quicknoteclasses/libsync.py, line: 318
+msgid "Synchronization successfully completed"
+msgstr "Synchronisation erfolgreich beendet"
+#
+# File: src/quicknoteclasses/libsync.py, line: 325
+msgid "The clocks are not synchronized between stations"
+msgstr "Zeit differiert zu viel zwischen den Systemen"
+#
+# File: src/quicknoteclasses/libsync.py, line: 332
+msgid "Sync failed, reason: "
+msgstr "Sync gescheitert. Fehler:"
+#
+# File: src/quicknoteclasses/libsync.py, line: 387
+msgid "Local SyncServer (port "
+msgstr "LokalerSync-Server (Port "
+#
+# File: src/quicknoteclasses/libsync.py, line: 405
+msgid "Start/Stop SyncServer"
+msgstr "SyncServer starten/stoppen"
+#
+# File: src/quicknoteclasses/libsync.py, line: 412
+msgid "Remote SyncServer (port "
+msgstr "RemoteSync-Server (Port "
+#
+# File: src/quicknoteclasses/libsync.py, line: 418
+msgid "Connect to remote SyncServer"
+msgstr "Verbinde zu Remote-SyncServer"
diff --git a/po/ru.po b/po/ru.po
new file mode 100644 (file)
index 0000000..398d498
--- /dev/null
+++ b/po/ru.po
@@ -0,0 +1,226 @@
+# Russian translations for quicknote package
+# Copyright (C) 2008 THE quicknote'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the quicknote package.
+# Nikolay Logvinov <NLogvinov@gmail.com>, 2008.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: quicknote\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2008-06-03 16:25+0400\n"
+"PO-Revision-Date: 2008-06-03 15:38+0400\n"
+"Last-Translator: Nikolay Logvinov <NLogvinov@gmail.com>\n"
+"Language-Team: Russian\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+#
+# File: src/quicknoteclasses/libhistory.py, line: 30
+msgid "History:"
+msgstr "История изменений"
+#
+# File: src/quicknoteclasses/libhistory.py, line: 43
+# File: src/quicknoteclasses/libsqldialog.py, line: 65
+msgid "Timestamp"
+msgstr "Время"
+#
+# File: src/quicknoteclasses/libhistory.py, line: 44
+# File: src/quicknoteclasses/libnotizen.py, line: 234
+msgid "Note"
+msgstr "Заметка"
+#
+# File: src/quicknoteclasses/libkopfzeile.py, line: 48
+# File: src/quicknoteclasses/libkopfzeile.py, line: 106
+msgid "all"
+msgstr "все"
+#
+# File: src/quicknoteclasses/libkopfzeile.py, line: 131
+msgid "Search:  "
+msgstr "Поиск:  "
+#
+# File: src/quicknoteclasses/libkopfzeile.py, line: 141
+msgid "Category:  "
+msgstr "Категория:  "
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 105
+msgid "Last change: %d.%m.%y %H:%M"
+msgstr "Редактировалась %d.%m.%y в %H:%M"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 116
+msgid "Really delete?"
+msgstr "Всё-таки удалять?"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 131
+msgid "new Note"
+msgstr "__ новая __"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 150
+# File: src/quicknoteclasses/libquicknote.py, line: 183
+msgid "No note selected."
+msgstr "Выберите сначала заметку"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 209
+msgid "Titles"
+msgstr "Заголовки"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 213
+msgid "add note"
+msgstr "добавить Заметку"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 217
+msgid "del note"
+msgstr "удалить Заметку"
+#
+# File: src/quicknoteclasses/libnotizen.py, line: 247
+msgid "History"
+msgstr "История изменений"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 78
+msgid "Choose database file"
+msgstr "Выберите файл для хранения заметок"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 95
+msgid "%s is a note taking program; it is optimised for quick save and search of notes"
+msgstr "%s - приложение для создания, хранения и быстрого поиска заметок"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 117
+msgid "Select SQL export file"
+msgstr "Выберите файл для экспорта запросов SQL"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 130
+msgid "This category can not be deleted"
+msgstr "Эту категорию нельзя удалять"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 136
+msgid "Are you sure to delete the current category?"
+msgstr "Вы уверены в удалении текущей категории?"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 152
+msgid "Choose category"
+msgstr "Категория:"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 196
+msgid "Sync"
+msgstr "Синхронизация"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 269
+msgid "Set DB file"
+msgstr "Хранилище"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 273
+msgid "SQL History"
+msgstr "SQL запросы"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 277
+msgid "Sync notes"
+msgstr "Синхронизация"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 281
+msgid "Quit"
+msgstr "Выход"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 285
+msgid "File"
+msgstr "Файл"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 296
+msgid "delete"
+msgstr "убрать"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 300
+msgid "move to category"
+msgstr "назначить"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 304
+msgid "Category"
+msgstr "Категория"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 310
+msgid "About"
+msgstr "О программе"
+#
+# File: src/quicknoteclasses/libquicknote.py, line: 314
+msgid "Help"
+msgstr "Справка"
+#
+# File: src/quicknoteclasses/libsqldialog.py, line: 46
+msgid "SQL History (the past two days):"
+msgstr "SQL запросы (за 2 последних дня)"
+#
+# File: src/quicknoteclasses/libsqldialog.py, line: 67
+msgid "Parameter"
+msgstr "Параметры"
+#
+# File: src/quicknoteclasses/libsqldialog.py, line: 105
+msgid "%d.%m.%y %H:%M:%S "
+msgstr "%d.%m.%y %H:%M:%S "
+#
+# File: src/quicknoteclasses/libsync.py, line: 43
+msgid "Sync process"
+msgstr "Синхронизация"
+#
+# File: src/quicknoteclasses/libsync.py, line: 48
+msgid "Sync process running...please wait"
+msgstr "Синхронизируются заметки, подождите ..."
+#
+# File: src/quicknoteclasses/libsync.py, line: 50
+msgid "(this can take some minutes)"
+msgstr "(некоторое время)"
+#
+# File: src/quicknoteclasses/libsync.py, line: 90
+msgid "Query"
+msgstr "Запрос"
+#
+# File: src/quicknoteclasses/libsync.py, line: 242
+msgid "Syncserver running..."
+msgstr "Сервер синхронизации работает ..."
+#
+# File: src/quicknoteclasses/libsync.py, line: 250
+msgid "Could not start SyncServer. Check IP, port settings."
+msgstr "Не удаётся стартовать Сервер синхронизации. Проверьте IP-адрес и порт."
+#
+# File: src/quicknoteclasses/libsync.py, line: 263
+# File: src/quicknoteclasses/libsync.py, line: 409
+msgid "SyncServer stopped"
+msgstr "Сервер синхронизации остановлен"
+#
+# File: src/quicknoteclasses/libsync.py, line: 280
+# File: src/quicknoteclasses/libsync.py, line: 316
+# File: src/quicknoteclasses/libsync.py, line: 324
+# File: src/quicknoteclasses/libsync.py, line: 331
+# File: src/quicknoteclasses/libsync.py, line: 422
+msgid "no sync process (at the moment)"
+msgstr "сейчас синхронизация не выполняется"
+#
+# File: src/quicknoteclasses/libsync.py, line: 289
+msgid "sync process running"
+msgstr "идёт синхронизация"
+#
+# File: src/quicknoteclasses/libsync.py, line: 318
+msgid "Synchronization successfully completed"
+msgstr "Синхронизация успешно завершенa"
+#
+# File: src/quicknoteclasses/libsync.py, line: 325
+msgid "The clocks are not synchronized between stations"
+msgstr "Согласуйте время между системами"
+#
+# File: src/quicknoteclasses/libsync.py, line: 332
+msgid "Sync failed, reason: "
+msgstr "Синхронизовать заметки не удалось по причине: "
+#
+# File: src/quicknoteclasses/libsync.py, line: 387
+msgid "Local SyncServer (port "
+msgstr "Местный сервер синхронизации (порт "
+#
+# File: src/quicknoteclasses/libsync.py, line: 405
+msgid "Start/Stop SyncServer"
+msgstr "Запуск/Остановка сервера синхронизации"
+#
+# File: src/quicknoteclasses/libsync.py, line: 412
+msgid "Remote SyncServer (port "
+msgstr "Удалённый сервер синхронизации (порт "
+#
+# File: src/quicknoteclasses/libsync.py, line: 418
+msgid "Connect to remote SyncServer"
+msgstr "Установить соединение"
diff --git a/remake b/remake
new file mode 100755 (executable)
index 0000000..9b571c2
--- /dev/null
+++ b/remake
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+make clean
+make 
+dpkg-buildpackage -rfakeroot 
+dpkg -i ../quicknote_0.7.4_all.deb
diff --git a/setup.py b/setup.py
new file mode 100644 (file)
index 0000000..c8a8429
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python2.5
+# -*- coding: utf-8 -*-
+#
+#
+
+from distutils.core import setup  
+
+setup(name='quicknote',
+       version='1.0',
+       scripts=['src/quicknote'],
+       packages=['quicknoteclasses'],
+       package_dir={'quicknoteclasses': 'src/quicknoteclasses'},
+       data_files = [
+                    ('share/icons/hicolor/26x26/hildon', ['data/low/quicknote.png']),
+                   ('share/icons/hicolor/40x40/hildon', ['data/40/quicknote.png']),
+                   #('share/icons/hicolor/48x48/apps', ['data/48/quicknote.png']),
+                   ('share/icons/hicolor/scalable/hildon', ['data/scale/quicknote.png']),
+                    ('share/applications/hildon', ['data/quicknote.desktop']),
+                    ('share/dbus-1/services',     ['data/quicknote.service']),
+                    # I18N
+                    ('share/locale/de/LC_MESSAGES', ['locale/de/LC_MESSAGES/quicknote.mo']),
+                    ('share/locale/ru/LC_MESSAGES', ['locale/ru/LC_MESSAGES/quicknote.mo']),
+                    ]
+      ) 
diff --git a/src/quicknote b/src/quicknote
new file mode 100755 (executable)
index 0000000..8687a4e
--- /dev/null
@@ -0,0 +1,38 @@
+#!/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 os
+import sys
+sys.path.append('/usr/lib/')
+
+##
+## I18N
+##
+import locale
+import gettext
+gettext.install('quicknote', unicode=1)
+
+#print "x2!"
+
+#f = open('/home/user/start0.txt', 'a')
+#f.write('0123456789abcdef')
+#f.close()
+
+if __name__ == "__main__":
+               from quicknoteclasses import libquicknote
+               app = libquicknote.quicknoteclass() 
+               app.main() 
+
+               
+       
diff --git a/src/quicknoteclasses/__init__.py b/src/quicknoteclasses/__init__.py
new file mode 100755 (executable)
index 0000000..8d1c8b6
--- /dev/null
@@ -0,0 +1 @@
diff --git a/src/quicknoteclasses/libhistory.py b/src/quicknoteclasses/libhistory.py
new file mode 100644 (file)
index 0000000..34a1e67
--- /dev/null
@@ -0,0 +1,66 @@
+#!/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 gobject
+import time
+import logging
+import gtk 
+
+class Dialog(gtk.Dialog):
+               
+       def get_selected_row(self):
+               path=self.treeview.get_cursor()[0]
+               if (path==None)or(path==""):
+                       return None
+               iter1=self.treeview.get_model().get_iter(path)
+               return self.treeview.get_model().get(iter1,0,1,2,3,4)
+
+       def __init__(self,daten=None):
+               gtk.Dialog.__init__(self,_("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.liststore = gtk.ListStore(int, str, str, str, str)
+                                       #pcdatum, datum, sql, param # param schön
+
+               # create the TreeView using liststore
+               self.treeview = gtk.TreeView(self.liststore)
+               # create a CellRenderers to render the data
+               self.cell1 = gtk.CellRendererText()
+               self.cell2 = gtk.CellRendererText()
+               
+               # create the TreeViewColumns to display the data
+               self.tvcolumn1 = gtk.TreeViewColumn(_('Timestamp'))
+               self.tvcolumn2 = gtk.TreeViewColumn(_('Note'))
+               # add columns to treeview
+               self.treeview.append_column(self.tvcolumn1)
+               self.treeview.append_column(self.tvcolumn2)
+               
+               # add the cells to the columns - 2 in the first
+               self.tvcolumn1.pack_start(self.cell1, True)
+               self.tvcolumn2.pack_start(self.cell2, True)
+               self.tvcolumn1.set_attributes(self.cell1, text=1) #Spalten setzten hier!!!!
+               self.tvcolumn2.set_attributes(self.cell2, text=4)
+               
+               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, expand=True, fill=True, padding=0)
+               
+               self.liststore.clear()
+               
+               if (daten!=None):
+                       for data in daten:
+                               self.liststore.append(data)
diff --git a/src/quicknoteclasses/libkopfzeile.py b/src/quicknoteclasses/libkopfzeile.py
new file mode 100644 (file)
index 0000000..2238364
--- /dev/null
@@ -0,0 +1,155 @@
+#!/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 gobject
+import time
+import random
+import logging
+
+import gtk
+
+import libspeichern
+import string
+
+
+class Kopfzeile(gtk.HBox):
+       
+       __gsignals__ = {
+               'reload_notes' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE,()),
+       }
+
+       def comboCategoryChanged(self, widget=None, data=None):
+               logging.debug("comboCategoryChanged")
+               if (self.lastCategory!=self.comboCategory.get_active()):
+                       sql="UPDATE categories SET liste=? WHERE id=1"
+                       self.db.speichereSQL(sql,(self.comboCategory.get_active(),))
+                       
+               self.emit("reload_notes")
+       
+       def searchEntryChanged(self, widget=None, data=None):
+               logging.debug("searchEntryChanged")
+               self.emit("reload_notes")
+               
+
+       def getCategory(self):
+               entry = self.comboCategory.get_child()
+               category=entry.get_text()
+               if (category==_("all")):
+                       category="%"
+               if (category==""):
+                       category="undefined"
+                       self.comboCategory.set_active(1)
+                       self.comboCategory.show()
+               return category
+       
+       def defineThisCategory(self):
+               category=self.getCategory()
+               
+               model = self.comboCategory.get_model()
+               n=len(self.comboCategory.get_model())
+               i=0
+               active=-1
+               cats=[]
+               while i<n:
+                       
+                       if (model[i][0]==category): 
+                               #self.comboCategory.set_active(i)
+                               active=i
+                       if (model[i][0]!="%"):
+                               cats.append(model[i][0])
+                       i+=1
+               
+               if (active==-1)and(category!="%"):
+                       self.comboCategory.append_text(category)
+                       sql="INSERT INTO categories  (id,liste) VALUES (0,?)"
+                       self.db.speichereSQL(sql,(category,))
+                       self.comboCategory.set_active(i)
+                       
+       def getSearchPattern(self):
+               return self.searchEntry.get_text()
+
+
+       def loadCategories(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)
+               self.cats=[]
+               if (rows!=None)and(len(rows)>0):
+                       for row in rows:
+                               self.cats.append(row[1])
+                               
+                       
+               sql="SELECT * FROM categories WHERE id=1"
+               rows=self.db.ladeSQL(sql)
+               cats=None
+               if (rows==None)or(len(rows)==0):
+                       sql="INSERT INTO categories (id, liste) VALUES (1,1)"
+                       self.db.speichereSQL(sql)
+                       
+               #self.comboCategory.clear()
+               while len(self.comboCategory.get_model())>0:
+                       self.comboCategory.remove_text(0)
+                       
+               self.comboCategory.append_text(_('all'))
+               self.comboCategory.append_text('undefined')
+               
+               if (self.cats!=None)and(len(self.cats)>0):
+                       for cat in self.cats:
+                               #print cat
+                               self.comboCategory.append_text(cat)
+                               
+               sql="SELECT * FROM categories WHERE id=1"
+               rows=self.db.ladeSQL(sql)
+               if (rows!=None)and(len(rows)>0):
+                       self.comboCategory.set_active(int(rows[0][1]))
+               else:   
+                       self.comboCategory.set_active(1)
+                       
+               self.lastCategory=self.comboCategory.get_active()
+
+
+       def __init__(self,db):
+               
+               self.db=db
+
+               gtk.HBox.__init__(self,homogeneous=False, spacing=3)
+               logging.info("libkopfzeile, init")
+               
+               label=gtk.Label(_("Search:  "))
+               self.pack_start(label, expand=False, fill=True, padding=0)
+               
+               self.searchEntry=gtk.Entry()
+               self.pack_start(self.searchEntry, expand=True, fill=True, padding=0)
+               self.searchEntry.connect("changed", self.searchEntryChanged, None)
+               
+               label=gtk.Label("   ")
+               self.pack_start(label, expand=True, fill=True, padding=0)
+               
+               label=gtk.Label(_("Category:  "))
+               self.pack_start(label, expand=False, fill=True, padding=0)
+               
+               self.comboCategory = gtk.combo_box_entry_new_text()
+
+               self.pack_start(self.comboCategory, expand=True, fill=True, padding=0)
+               
+               self.loadCategories()
+               
+               self.comboCategory.connect("changed", self.comboCategoryChanged, None)
+               
+               
+
+
+
diff --git a/src/quicknoteclasses/libnotizen.py b/src/quicknoteclasses/libnotizen.py
new file mode 100644 (file)
index 0000000..8519009
--- /dev/null
@@ -0,0 +1,264 @@
+#!/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 gobject
+import time
+import random
+import logging
+
+import gtk
+
+import libspeichern
+import simple_list
+import uuid
+import string
+
+
+
+class Notizen(gtk.HBox):
+
+       def getTitle(self,buf):
+               eol=buf.find("\n")
+               if (eol>-1):
+                       title=buf[:eol]
+               else:
+                       title=buf
+               return title    
+               
+
+       def noteChanged(self, widget=None, data=None):
+               if (self.pos==-1)or(self.noteid==-1):
+                       return
+               buf=self.textviewNote.get_buffer().get_text(self.textviewNote.get_buffer().get_start_iter(),self.textviewNote.get_buffer().get_end_iter())
+               
+               title=self.getTitle(buf)
+               value, key = self.noteslist.get_item(self.pos)
+               
+               if (value!=title):
+                       self.noteslist.change_item(self.pos,title,self.noteid)
+               
+
+
+       def saveNote(self,widget=None,data=None,data2=None):
+               logging.info("saveNote params: pos:"+str(self.pos)+" noteid:"+str(self.noteid))
+               #print "params:",data,data2
+               buf=self.textviewNote.get_buffer().get_text(self.textviewNote.get_buffer().get_start_iter(),self.textviewNote.get_buffer().get_end_iter())
+               if (buf==None)or(len(buf)==0): 
+                       return
+               
+               if (buf==self.note):
+                       return
+               
+               logging.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.category)
+                       self.noteslist.append_item(self.getTitle(buf), self.noteid)
+                       self.pos=self.noteslist.select_last_item()
+               else:
+                       self.db.saveNote(self.noteid,buf,self.category)
+                       
+               self.topBox.defineThisCategory()
+               
+               
+       def setFocus(self):
+               self.textviewNote.grab_focus()
+               return False
+       
+       def noteslist_changed(self,data=None,data2=None):
+               if (self.pos!=-1):
+                       self.saveNote()
+               
+               try:
+                       (pos, key, value) = self.noteslist.get_selection_data()
+                       if (pos==-1):
+                               return
+                       #print "(pos, key, value) =", self.noteslist.get_selection_data()
+               except:
+                       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.category)
+                       self.pos=-1
+                       self.noteslist.append_item("", self.noteid)
+                       self.textviewNote.get_buffer().set_text("")
+                       self.pos=self.noteslist.select_last_item()
+               else:
+                       self.pos=pos
+                       self.noteid,pcdatum,self.category,self.note = self.db.loadNote(key)
+                        self.statuslabel.set_text(time.strftime(_("Last change: %d.%m.%y %H:%M"), time.localtime(pcdatum)))
+                       buf=self.textviewNote.get_buffer()
+                       buf.set_text(self.note)
+
+               gobject.timeout_add(200, self.setFocus)
+               
+       def add_note(self,widget=None,data=None):
+               self.noteslist_changed("new")
+               
+       def del_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.textviewNote.get_buffer().set_text("")
+                       
+               
+       def loadNotes(self,data=None):
+               logging.info("loadNotes params: pos:"+str(self.pos)+" noteid:"+str(self.noteid))
+               self.noteslist.clear_items()
+               self.noteslist.append_item(_("new Note"), "new")
+               
+               self.category=self.topBox.getCategory()
+               search=self.topBox.getSearchPattern()
+               notes=self.db.searchNotes(search,self.category)
+               
+               if (notes!=None):
+                       for note in notes:
+                               noteid,category,noteText = note
+                               title=self.getTitle(noteText)
+                               self.noteslist.append_item(title, noteid)
+                       
+               self.noteid=-1
+               self.pos=-1
+               self.textviewNote.get_buffer().set_text("")
+
+
+       def 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:
+                       #for x in row:
+                       #       print x
+                       daten=row[4][1]
+                       if (daten!="")and(lastNoteStr!=daten):
+                               lastNoteStr=daten
+                               dialog.liststore.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.saveNote()
+                       data=dialog.get_selected_row()
+                       if data!=None:
+                               self.db.speichereSQL(data[2],data[3].split(" <<Tren-ner>> "),rowid=self.noteid)
+                               logging.info("loading History")
+                               self.noteslist_changed()
+               
+               dialog.destroy()
+
+       def __init__(self,db,topBox):
+               
+               self.db=db
+               self.topBox=topBox
+               self.noteid=-1
+               self.pos=-1
+               self.note=None #Last notetext
+               
+               gtk.HBox.__init__(self,homogeneous=False, spacing=0)
+               logging.info("libnotizen, init")
+               
+               self.noteslist = simple_list.SimpleList()
+               self.noteslist.set_eventfunction__cursor_changed(self.noteslist_changed)
+
+               self.noteslist.set_size_request(250,-1)
+               
+               vbox = gtk.VBox(homogeneous=False, spacing=0)
+               
+               #button=gtk.Button("add note")
+               #button.connect("clicked", self.add_note, None)
+               #vbox.pack_start(button, expand=False, fill=True, padding=3)
+               
+               frame=gtk.Frame(_("Titles"))
+               frame.add(self.noteslist)
+               vbox.pack_start(frame, expand=True, fill=True, padding=3)
+               
+               button=gtk.Button(_("add note"))
+               button.connect("clicked", self.add_note, None)
+               vbox.pack_start(button, expand=False, fill=True, padding=3)
+               
+               button=gtk.Button(_("del note"))
+               button.connect("clicked", self.del_note, None)
+               vbox.pack_start(button, expand=False, fill=True, padding=3)
+               
+               self.pack_start(vbox, expand=False, fill=True, padding=3)
+               
+               self.textviewNote=gtk.TextView()
+               self.textviewNote.connect("focus-out-event",self.saveNote,"focus-out-event")
+               buf=self.textviewNote.get_buffer()
+               buf.set_text("")
+               buf.connect("changed", self.noteChanged, None)
+               
+               #self.textviewNotiz.set_size_request(-1,50)
+               scrolled_window = gtk.ScrolledWindow()
+               scrolled_window.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
+               scrolled_window.add(self.textviewNote)
+               
+               frame=gtk.Frame(_("Note"))
+               frame.add(scrolled_window)
+               
+               
+               vbox = gtk.VBox(homogeneous=False, spacing=0)
+               vbox.pack_start(frame, expand=True, fill=True, padding=3)
+               
+               hbox = gtk.VBox(homogeneous=False, spacing=0)
+               
+               self.statuslabel=gtk.Label("Test")
+               self.statuslabel.set_alignment(0.0,0.5)
+               hbox.pack_start(self.statuslabel, expand=False, fill=True, padding=3)
+               
+               button=gtk.Button(_("History"))
+               button.connect("clicked", self.show_history, None)
+               hbox.pack_start(button, expand=False, fill=True, padding=3)
+               
+               
+               vbox.pack_start(hbox, expand=False, fill=True, padding=3)
+               
+               
+               self.pack_start(vbox, expand=True, fill=True, padding=3)
+
+               
+               
+               self.loadNotes()
+               self.topBox.connect("reload_notes",self.loadNotes)
+               
+
+
+
diff --git a/src/quicknoteclasses/libquicknote.py b/src/quicknoteclasses/libquicknote.py
new file mode 100644 (file)
index 0000000..4b26335
--- /dev/null
@@ -0,0 +1,375 @@
+#/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 os
+import sys
+import logging
+import libsync
+
+try:
+        import gtk
+        #import gtk.glade
+except:
+       print "gtk import failed"
+        sys.exit(1)
+       
+try:
+       import hildon
+       #import osso
+       isHildon=True
+       
+       #f = open('/home/user/start.txt', 'a')
+       #f.write('0123456789abcdef')
+       #f.close()
+       import osso
+       osso_c = osso.Context("quicknote", "0.7.4", False)
+       #f = open('/home/user/stop.txt', 'a')
+       #f.write('0123456789abcdef')
+       #f.close()
+       
+except:
+       isHildon=False
+       class hildon():
+               def __init__(self):
+                       print "PseudoClass hildon"
+               class Program():
+                       def __init__(self):
+                               print "PseudoClass hildon.Program"
+
+import libspeichern
+import libkopfzeile
+import libnotizen
+import uuid
+
+version = "0.7.2"
+settings_file_name = ".quicknote"
+app_name = "Quicknote"
+
+               
+       
+
+class quicknoteclass(hildon.Program):
+       
+       
+       def set_db_file(self,widget=None,data=None):
+               if (isHildon==False):
+                       dlg = gtk.FileChooserDialog(parent = self.window, action = gtk.FILE_CHOOSER_ACTION_SAVE)
+                       dlg.add_button( gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+                       dlg.add_button( gtk.STOCK_OK, gtk.RESPONSE_OK)
+               else:
+                       #dlg = hildon.FileChooserDialog(parent = self.window, action = gtk.FILE_CHOOSER_ACTION_SAVE)
+                       dlg=hildon.FileChooserDialog(self.window, 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.loadCategories()
+                       self.notizen.loadNotes()
+               dlg.destroy()
+               
+       def show_about(self, widget=None,data=None):
+               dialog = gtk.AboutDialog()
+               dialog.set_position(gtk.WIN_POS_CENTER)
+               dialog.set_name(app_name)
+               dialog.set_version(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") % app_name
+               dialog.set_comments(comments)        
+               dialog.run()     
+               dialog.destroy()
+               
+               
+       def view_sql_history(self,widget=None,data=None,data2=None):
+               import libsqldialog
+               sqldiag=libsqldialog.sqlDialog(self.db)
+               res=sqldiag.run()
+               sqldiag.hide()
+               if res==444:
+                       logging.info("exporting sql")
+                       
+                       if (isHildon==False):
+                               dlg = gtk.FileChooserDialog(parent = self.window, action = gtk.FILE_CHOOSER_ACTION_SAVE)
+                               dlg.add_button( gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
+                               dlg.add_button( gtk.STOCK_OK, gtk.RESPONSE_OK)
+                       else:
+                               #dlg = hildon.FileChooserDialog(parent = self.window, action = gtk.FILE_CHOOSER_ACTION_SAVE)
+                               dlg=hildon.FileChooserDialog(self.window, gtk.FILE_CHOOSER_ACTION_SAVE)
+                       
+                       dlg.set_title(_("Select SQL export file"))
+                       if dlg.run() == gtk.RESPONSE_OK:
+                               fileName = dlg.get_filename()
+                               dlg.destroy()
+                               sqldiag.exportSQL(fileName)
+                       else:
+                               dlg.destroy()
+                               
+               sqldiag.destroy()
+
+               
+       def delete_Category(self,widget=None,data=None):
+               if (self.topBox.getCategory()=="%")or(self.topBox.getCategory()=="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.getCategory()))
+                       sql="DELETE FROM categories WHERE liste=?"
+                       self.db.speichereSQL(sql,(self.topBox.getCategory(),))
+                       model=self.topBox.comboCategory.get_model()
+                       pos=self.topBox.comboCategory.get_active()
+                       if (pos>1):
+                               self.topBox.comboCategory.remove_text(pos)
+                               self.topBox.comboCategory.set_active(0)
+                       
+       def 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 (n>-1)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.comboCategoryChanged()
+                       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 sync_finished(self,data=None,data2=None):
+               self.topBox.loadCategories()
+               self.notizen.loadNotes()                
+       
+       def prepare_sync_dialog(self):
+               self.sync_dialog = gtk.Dialog(_("Sync"),None,gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+               
+               self.sync_dialog.set_position(gtk.WIN_POS_CENTER)
+               sync=libsync.Sync(self.db,self.window,50504)
+               self.sync_dialog.vbox.pack_start(sync, True, True, 0)
+               self.sync_dialog.set_size_request(500,350)
+               self.sync_dialog.vbox.show_all()
+               sync.connect("syncFinished",self.sync_finished)
+       
+       def sync_notes(self,widget=None,data=None):
+               self.sync_dialog.run()
+               self.sync_dialog.hide()
+       
+       def __init__(self):
+               
+               #
+               home_dir = os.path.expanduser('~')
+               dblog=os.path.join(home_dir, "quicknote.log") 
+               #logging.basicConfig(level=logging.DEBUG,format='%(asctime)s %(levelname)-8s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename=dblog,filemode='a')
+               #logging.getLogger('').addHandler(console)
+               
+               # define a Handler which writes INFO messages or higher to the sys.stderr
+               console = logging.StreamHandler()
+               console.setLevel(logging.DEBUG)
+               # set a format which is simpler for console use
+               formatter = logging.Formatter('%(asctime)s  %(levelname)-8s %(message)s')
+               # tell the handler to use this format
+               console.setFormatter(formatter)
+               # add the handler to the root logger
+               logging.getLogger('').addHandler(console)
+               
+               logging.info('Starting quicknote')
+               
+               if (isHildon==True): 
+                       logging.info('Hildon erkannt, rufe Hildon constructor auf')
+                       hildon.Program.__init__(self)
+                       
+
+                               
+                #Get the Main Window, and connect the "destroy" event
+               if (isHildon==False):
+                       self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
+                       self.window.set_default_size(700,500)
+               else:
+                       self.window = hildon.Window()
+                       self.add_window(self.window)
+                       #self.osso_c = osso.Context(app_name, version, False)
+                       
+                       
+                       
+               #print "1b: ",time.clock() 
+               
+                if (self.window):
+                       self.window.connect("delete_event", self.delete_event)
+                       self.window.connect("destroy", self.destroy)
+                       self.window.set_title("Quicknote")
+                       
+                       #Enable fullscreen
+                       if (isHildon==True): 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.db=libspeichern.Speichern()
+               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.view_sql_history, None)
+               
+               menu_items = gtk.MenuItem(_("Sync notes"))
+               filemenu.append(menu_items)
+               menu_items.connect("activate", self.sync_notes, None)
+               
+               menu_items = gtk.MenuItem(_("Quit"))
+               filemenu.append(menu_items)
+               menu_items.connect("activate", self.destroy, None)
+               
+               file_menu = gtk.MenuItem(_("File"))
+               file_menu.show()
+               file_menu.set_submenu(filemenu)
+               
+               
+               categorymenu = gtk.Menu()
+               
+               #menu_items = gtk.MenuItem("rename")
+               #categorymenu.append(menu_items)
+               #menu_items.connect("activate", self.rename_category, None)
+               
+               menu_items = gtk.MenuItem(_("delete"))
+               categorymenu.append(menu_items)
+               menu_items.connect("activate", self.delete_Category, None)
+               
+               menu_items = gtk.MenuItem(_("move to category"))
+               categorymenu.append(menu_items)
+               menu_items.connect("activate", self.move_Category, None)
+               
+               category_menu = gtk.MenuItem(_("Category"))
+               category_menu.show()
+               category_menu.set_submenu(categorymenu)
+               
+               helpmenu = gtk.Menu()
+               
+               menu_items = gtk.MenuItem(_("About"))
+               helpmenu.append(menu_items)
+               menu_items.connect("activate", self.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 (help_menu)
+                               
+               menu_bar.show()
+               if (isHildon==True):
+                       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.window.show_all()
+               
+               
+       def delete_event(self, widget, event, data=None):
+               #print "delete event occurred"
+               #if (isHildon==True): self.osso_c.close()
+               return False
+
+       def destroy(self, widget=None, data=None):
+               self.db.close()
+               #if (isHildon==True): self.osso_c.close()
+               gtk.main_quit()
+
+       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):
+               #Hildon Fullscreen Modus
+               if (isHildon==False): return
+               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 () 
+
+
+       def main(self):
+               gtk.main()
+               #if (isHildon==True): self.osso_c.close()
diff --git a/src/quicknoteclasses/libspeichern.py b/src/quicknoteclasses/libspeichern.py
new file mode 100644 (file)
index 0000000..802c26b
--- /dev/null
@@ -0,0 +1,234 @@
+#!/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 gobject
+import time
+import sqlite3
+import shelve
+import sys
+import pickle
+import string
+import shutil
+import os
+import logging
+
+class Speichern():
+       def speichereDirekt(self,schluessel,daten):
+               self.d[schluessel]=daten
+               logging.info("speichereDirekt "+str(schluessel)+" "+str(daten)+" lesen: "+str(self.d[schluessel]))
+
+       
+       def ladeDirekt(self,schluessel,default=""):
+               #print "ladeDirekt",schluessel, "Schluessel vorhanden",self.d.has_key(schluessel)
+               if (self.d.has_key(schluessel)==True):
+                       data=self.d[schluessel]
+                       #print data
+                       return data
+               else:
+                       return default
+                               
+                               
+       def speichereSQL(self,sql,tupel=None,commit=True,host="self",log=True,pcdatum=None,rowid=""):
+               #print "speichereSQL:",sql,tupel
+               try:
+                       programSQLError=True
+                       if (tupel==None):
+                               self.cur.execute(sql)
+                       else:
+                               self.cur.execute(sql,tupel)
+                       programSQLError=False   
+                       
+                       #print int(time.time()), sql, pickle.dumps(tupel), host
+                       if (log==True):
+                               strtupel=[]
+                               if (tupel!=None):
+                                       for t in tupel:
+                                               strtupel.append(str(t))
+
+
+                               if pcdatum==None: pcdatum=int(time.time())
+                               self.cur.execute("INSERT INTO logtable ( pcdatum,sql,param,host,rowid ) VALUES (?,?,?,?,?)",(pcdatum, sql, string.join(strtupel," <<Tren-ner>> "), host,str(rowid) ))
+                       if (commit==True): self.conn.commit()
+                       
+                       return True
+               except:
+                       s=str(sys.exc_info())
+                       if (s.find(" already exists")==-1):
+                               if (programSQLError==True):
+                                       logging.error("speichereSQL-Exception "+str(sys.exc_info())+" "+str(sql)+" "+str(tupel))
+                               else:
+                                       logging.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==None):
+                               self.cur.execute(sql)
+                       else:
+                               self.cur.execute(sql,tupel)
+                       return self.cur.fetchall()
+               except:
+                       logging.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 
+               i=0
+               erg=[]
+               while i<len(rows):
+                       datum=time.strftime("%d.%m.%y %H:%M:%S", (time.localtime(rows[i][1])))
+                       erg.append([rows[i][1],datum,rows[i][2],rows[i][3],rows[i][3].split(" <<Tren-ner>> ")])
+                                       #pcdatum #datum #sql # Param_org #param 
+                       
+                       i+=1
+                       
+               return erg
+               
+               
+       def openDB(self):
+               try:
+                       self.cur.close()
+               except:
+                       pass
+               try:
+                       self.conn.close()
+               except:
+                       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") 
+                       
+               
+               #datum=time.strftime("%Y-%m-%d--", (time.localtime(time.time())))+str(int(time.time()))+"--"
+               #if (os.path.exists(db))and(os.path.exists(os.path.dirname(db)+os.sep+"backup/")):
+               #       try:
+               #               shutil.copyfile(db,str(os.path.dirname(db))+os.sep+"backup"+os.sep+datum+os.path.basename(db))
+               #               #logging.debug(str(os.path.dirname(db))+os.sep+"backup"+os.sep+datum+os.path.basename(db))
+               #       except:
+               #               logging.info("Achtung Backup-Datei NICHT (!!!) angelegt!")
+               #               #print db,str(os.path.dirname(db))+os.sep+"backup"+os.sep+datum+os.path.basename(db)
+               
+               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:
+                       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:
+                       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:
+                       pass    
+               
+               #print "optimizing begin"
+               #sql="VACUUM"
+               #self.cur.execute(sql)
+               #self.conn.commit()
+
+               #print "optimizing end"
+               
+       def __init__(self):
+               home_dir = os.path.expanduser('~')
+               filename=os.path.join(home_dir, ".quicknote.dat") 
+               self.d = shelve.open(filename)
+               self.openDB()
+
+       
+       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==None)or(len(rows)==0):
+                       sql="INSERT INTO notes (noteid,pcdatum,category,note) VALUES (?,?,?,?)"
+                       if (pcdatum==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==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==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==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:
+                       pass
+               try:
+                       self.cur.close()
+               except:
+                       pass
+               try:
+                       self.conn.close()
+               except:
+                       pass
+               logging.info("Alle Data saved")
+               
+       def __del__(self):
+               self.close()
\ No newline at end of file
diff --git a/src/quicknoteclasses/libsqldialog.py b/src/quicknoteclasses/libsqldialog.py
new file mode 100755 (executable)
index 0000000..3a8d9ae
--- /dev/null
@@ -0,0 +1,111 @@
+#!/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 gobject
+import time
+import string
+import gtk
+import sys
+import logging
+
+import libspeichern 
+class sqlDialog(gtk.Dialog):
+       
+       def exportSQL(self,filename):
+               f = open(filename, 'w')
+               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")
+                       
+                       
+               f.close()
+               
+       
+       def __init__(self,db):
+               self.db=db
+               
+               logging.info("sqldialog, init")
+               
+               gtk.Dialog.__init__(self,_("SQL History (the past two days):"),None,gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
+               
+               
+               self.add_button("Export", 444)
+               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)
+               
+               # create a CellRenderers to render the data
+               self.cell1 = gtk.CellRendererText()
+               self.cell2 = gtk.CellRendererText()
+               self.cell3 = gtk.CellRendererText()
+               #self.cell1.set_property('markup', 1)
+               
+               # 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)
+
+               # make treeview searchable
+               #self.treeview.set_search_column(0)
+               #self.tvcolumn.set_sort_column_id(0)
+               
+               # 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.pack_start(scrolled_window, expand=True, fill=True, padding=0)
+               
+               
+               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)
+               
+               
+               
diff --git a/src/quicknoteclasses/libsync.py b/src/quicknoteclasses/libsync.py
new file mode 100755 (executable)
index 0000000..45a019a
--- /dev/null
@@ -0,0 +1,434 @@
+#!/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 gobject
+import time
+import string
+from SimpleXMLRPCServer import SimpleXMLRPCServer 
+import random
+import socket 
+socket.setdefaulttimeout(60) # Timeout auf 60 sec. setzen 
+import xmlrpclib 
+import select
+#import fcntl
+import struct
+import gtk
+import uuid
+import sys
+import logging
+
+import libspeichern 
+class ProgressDialog(gtk.Dialog):
+       
+       def pulse(self):
+               #self.progressbar.pulse()
+               pass
+       
+       def __init__(self,title=_("Sync process"), parent=None):
+               gtk.Dialog.__init__(self,title,parent,gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,())
+               
+               logging.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.progressbar=gtk.ProgressBar()
+               #self.vbox.pack_start(self.progressbar, True, True, 0)
+               
+               #self.set_keep_above(True)
+               self.vbox.show_all()
+               self.show()
+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 changeSyncStatus(self,active,title):
+               self.syncStatusLabel.set_text(title)
+               if active==True:
+                       if self.progress==None:
+                               self.progress=ProgressDialog(parent=self.parentwindow)
+                               self.emit("syncBeforeStart","syncBeforeStart")
+                               
+                               
+               else:
+                       if self.progress!=None:
+                               self.progress.hide()            
+                               self.progress.destroy()
+                               self.progress=None
+                               self.emit("syncFinished","syncFinished")
+       
+       def pulse(self):
+               if self.progress!=None:
+                       self.progress.pulse()
+               #if self.server!=None:
+               #       self.server.pulse()
+               
+       
+       def getUeberblickBox(self):
+               frame=gtk.Frame(_("Query"))
+               return frame
+                       
+       def handleRPC(self):
+               try:
+                       if (self.rpcserver==None): return False
+               except:
+                       return False
+                       
+               while (len(self.poll.poll(0))>0):
+                       self.rpcserver.handle_request()
+               return True
+
+       def get_ip_address(self,ifname):
+               return socket.gethostbyname(socket.gethostname())
+               #try:
+               #       s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+               #       ip=socket.inet_ntoa(fcntl.ioctl(s.fileno(),0x8915,struct.pack('256s', ifname[:15]))[20:24])
+               #       s.close()
+               #except:
+               #       ip=socket.gethostbyname(socket.gethostname())
+               #       s.close()
+               
+               #return ip FixME
+               
+       def getLastSyncDate(self,sync_uuid):
+               sql="SELECT syncpartner,pcdatum FROM sync WHERE uuid=?"
+               rows=self.db.ladeSQL(sql,(sync_uuid,))
+               if (rows!=None)and(len(rows)==1): 
+                       syncpartner,pcdatum = rows[0]
+               else:
+                       pcdatum=-1
+               logging.info("LastSyncDatum: "+str(pcdatum)+" Jetzt "+str(int(time.time())))
+               return pcdatum
+               
+               
+       def check4commit(self,newSQL,lastdate):
+               logging.info("check4commit 1")
+               if self.concernedRows==None:
+                       logging.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!=None)and(len(self.concernedRows)>0):
+                       #logging.info("check4commit 2")
+                       id1, pcdatum,sql, param, host, rowid = newSQL
+                       
+                       if len(rowid)>0:
+                               for x in self.concernedRows:
+                                       #logging.info("check4commit 3")
+                                       if (x[1]==rowid):
+                                               if (x[0]>pcdatum):
+                                                       logging.info("newer sync entry, ignoring old one")
+                                                       #logging.info("check4commit 9.1")
+                                                       return False
+                                               else:
+                                                       #logging.info("check4commit 9.2")
+                                                       return True
+                                                       
+               #logging.info("check4commit 9.3")
+               return True
+       
+       def writeSQLTupel(self,newSQLs,lastdate):
+               if (newSQLs==None):
+                        return
+               
+               self.concernedRows=None
+               pausenzaehler=0
+               logging.info("writeSQLTupel got "+str(len(newSQLs))+" sql tupels")
+               for newSQL in newSQLs:
+                       #print ""
+                       #print "SQL1: ",newSQL[1]
+                       #print "SQL2: ",newSQL[2]
+                       #print "SQL3: ",newSQL[3]
+                       #print "Param:",string.split(newSQL[3]," <<Tren-ner>> ")
+                       #print ""
+                       if (newSQL[3]!=""):
+                               param=string.split(newSQL[3]," <<Tren-ner>> ")
+                       else:
+                               param=None
+               
+                       if (len(newSQL)>2):
+                               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: 
+                               logging.error("writeSQLTupel: Error")
+                               
+                       pausenzaehler+=1
+                       if (pausenzaehler % 10)==0:
+                               self.pulse()
+                               while (gtk.events_pending()):
+                                       gtk.main_iteration();
+                               
+               logging.info("Alle SQLs an sqlite geschickt, commiting now")
+               self.db.commitSQL()
+               logging.info("Alle SQLs commited")
+               
+       
+       def doSync(self,sync_uuid,pcdatum,newSQLs,pcdatumjetzt):
+               #print uuid,pcdatum,newSQLs
+               #logging.info("doSync 0")
+               self.changeSyncStatus(True,"sync process running")
+               self.pulse()
+               #logging.info("doSync 1")
+               
+               while (gtk.events_pending()):
+                       gtk.main_iteration();
+               diff=time.time()-pcdatumjetzt
+               if diff<0:
+                       diff=diff*(-1)
+               if diff>30:
+                       return -1
+               
+               logging.info("doSync read sqls")
+               sql="SELECT * FROM logtable WHERE pcdatum>?"
+               rows=self.db.ladeSQL(sql,(pcdatum,))
+               logging.info("doSync read sqls")
+               self.writeSQLTupel(newSQLs,pcdatum)
+               logging.info("doSync wrote "+str(len(newSQLs))+" sqls")
+               logging.info("doSync sending "+str(len(rows))+" sqls")
+               i=0
+               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()==True):
+                       logging.info("Starting Server")
+                       
+                       try:
+                               ip=self.comboIP.get_child().get_text()
+                               self.rpcserver = 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:
+                               s=str(sys.exc_info())
+                               logging.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:
+                       logging.info("Stopping Server")
+                       try:
+                               del self.rpcserver      
+                       except:
+                               pass
+                       self.syncServerStatusLabel.set_text(_("SyncServer stopped"))
+                       #save
+                       self.db.speichereDirekt("startSyncServer",False)
+               
+       def doSaveFinalTime(self,sync_uuid,pcdatum=None):
+               if (pcdatum==None): pcdatum=int(time.time())
+               if (time.time()>pcdatum):
+                       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):
+               logging.info("Syncing")
+               #sql="DELETE FROM logtable WHERE sql LIKE externeStundenplanung"
+               #self.db.speichereSQL(sql)
+               
+               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) 
+                       #lastDate=server.getLastSyncDate(str(self.sync_uuid))
+                       server_sync_uuid=self.server.getRemoteSyncUUID()
+                       lastDate=self.getLastSyncDate(str(server_sync_uuid))
+                       
+                       #print ("LastSyncDate: "+str(lastDate)+" Now: "+str(int(time.time())))
+               
+                       sql="SELECT * FROM logtable WHERE pcdatum>?"
+                       rows=self.db.ladeSQL(sql,(lastDate,))
+                       
+                       logging.info("loaded concerned rows")
+               
+                       newSQLs=self.server.doSync(self.sync_uuid,lastDate,rows,time.time())
+               
+                       logging.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:
+                               logging.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:
+                               logging.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
+                               
+
+                       
+       
+       def __init__(self,db,parentwindow,port):
+               gtk.VBox.__init__(self,homogeneous=False, spacing=0)
+               
+               logging.info("Sync, init")
+               self.db=db
+               self.progress=None
+               self.server=None
+               self.port=int(port)
+               self.parentwindow=parentwindow
+               self.concernedRows=None
+               
+               #print "Sync, 2"
+               #sql = "DROP TABLE sync"
+               #self.db.speichereSQL(sql,log=False)
+               
+               sql = "CREATE TABLE sync (id INTEGER PRIMARY KEY, syncpartner TEXT, uuid TEXT, pcdatum INTEGER)"
+               self.db.speichereSQL(sql,log=False)
+               
+               #print "Sync, 3"
+               
+               sql="SELECT uuid,pcdatum FROM sync WHERE syncpartner=?"
+               rows=self.db.ladeSQL(sql,("self",)) #Eigene Id feststellen
+               
+               #print "Sync, 3a"
+               if (rows==None)or(len(rows)!=1):
+                       sql="DELETE FROM sync WHERE syncpartner=?"
+                       self.db.speichereSQL(sql,("self",),log=False)
+                       #uuid1=uuid()
+                       #print "Sync, 3b"
+                       
+                       #print "Sync, 3bb"
+                       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)
+                       #print "Sync, 3c"
+               else:
+                       sync_uuid,pcdatum = rows[0]
+                       self.sync_uuid=sync_uuid
+               #print "x1"
+               
+               
+               
+               #print "Sync, 4"
+
+               
+               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"))
+               #self.comboIP.append_text(self.get_ip_address("eth1")) #fixme
+               #self.comboIP.append_text(self.get_ip_address("eth2"))
+               #self.comboIP.append_text(self.get_ip_address("eth3"))
+               #print "Sync, 4d"
+               #self.comboIP.append_text(self.get_ip_address("wlan0"))
+               #self.comboIP.append_text(self.get_ip_address("wlan1"))
+               
+               #print "Sync, 4e"
+               
+               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.set_text_column("Test")
+               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)==True):
+                       serverbutton.set_active(True)
+                       
+               #print "Sync, 9"
diff --git a/src/quicknoteclasses/simple_list.py b/src/quicknoteclasses/simple_list.py
new file mode 100644 (file)
index 0000000..794e5dc
--- /dev/null
@@ -0,0 +1,162 @@
+#!/usr/bin/env python2.5\r
+# -*- coding: utf-8 -*-\r
+\r
+"""\r
+ *\r
+ *  Copyright (C) 2007 Christoph Würstle and in big parts by Gerold Penz\r
+ *\r
+ * This program is free software; you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License version 2 as\r
+ * published by the Free Software Foundation.\r
+ *\r
+ *\r
+"""\r
+\r
+import pygtk\r
+pygtk.require("2.0")\r
+import gtk\r
+\r
+\r
+#----------------------------------------------------------------------\r
+class SimpleList(gtk.ScrolledWindow):\r
+       """\r
+       Stellt eine einfache Liste mit Laufbalken dar. Das wird mit\r
+       den Objekten ScrolledWindow und TreeView erreicht.\r
+       """\r
+\r
+       #----------------------------------------------------------------------\r
+       def append_item(self, value, key = ""):\r
+               """\r
+               F�gt der Liste Werte und wenn gew�nscht, Schl�ssel hinzu.\r
+               """\r
+\r
+               self.list_store.append([key, value])\r
+\r
+\r
+       def select_last_item(self):\r
+               path=str(len(self.list_store)-1)\r
+               self.tree_view.set_cursor(path,self.value_column)\r
+               return len(self.list_store)-1\r
+\r
+       #----------------------------------------------------------------------\r
+       def change_item(self, pos, value, key = ""):\r
+               self.list_store[pos]=[key, value]\r
+\r
+       def remove_item(self, pos):\r
+               model=self.tree_view.get_model()\r
+               self.list_store.remove(model.get_iter(str(pos)))\r
+\r
+       def get_item(self, pos):\r
+               return self.list_store[pos]\r
+       \r
+       def clear_items(self):\r
+               self.list_store.clear()\r
+\r
+\r
+\r
+       #----------------------------------------------------------------------\r
+       def _on_row_activated(self, treeview, path, view_column, data = None):\r
+               """\r
+               Setzt den Wert von self.selected_items. Dieser Wert kann\r
+               mit der Methode "get_selection_data" abgerufen werden.\r
+               """\r
+\r
+               iter = self.list_store.get_iter(path)\r
+        \r
+               if iter:\r
+                       self.selected_item = (\r
+                       path[0], # Position\r
+                       self.list_store.get_value(iter, 0), # Key\r
+                       self.list_store.get_value(iter, 1) # Value\r
+               )\r
+\r
+\r
+       #----------------------------------------------------------------------\r
+       def _on_cursor_changed(self, widget, data1 = None, data2 = None):\r
+               """\r
+               Setzt den Wert von self.selected_items. Dieser Wert kann\r
+               mit der Methode "get_selection_data" abgerufen werden.\r
+               """\r
+\r
+               selection = widget.get_selection()\r
+               (model, iter) = selection.get_selected()\r
+\r
+               if iter:\r
+                       self.selected_item = (\r
+                       int(selection.get_selected_rows()[1][0][0]), # Position\r
+                       str(model.get_value(iter, 0)), # Key\r
+                       str(model.get_value(iter, 1)) # Value\r
+                       )\r
+\r
+\r
+       #----------------------------------------------------------------------\r
+       def get_selection_data(self):\r
+               """\r
+               Gibt die Variable self.selected_item zur�ck.\r
+               Diese enth�lt ein Tupel. (<Position>, <Key>, <Value>)\r
+               """\r
+        \r
+               return self.selected_item  # (<Position>, <Key>, <Value>)\r
+    \r
+\r
+       #----------------------------------------------------------------------\r
+       def set_eventfunction__cursor_changed(self, function):\r
+               """\r
+               Verbindet die �bergebene Funktion mit dem \r
+               Signal "cursor-changed".\r
+               """\r
+        \r
+               self.tree_view.connect("cursor-changed", function)\r
+\r
+\r
+    #----------------------------------------------------------------------\r
+       def __init__(self):\r
+               """\r
+               Initialisieren\r
+               """\r
+        \r
+               gtk.ScrolledWindow.__init__(self)\r
+               self.selected_item = None # (<Position>, <Key>, <Value>)\r
+        \r
+               # Liste\r
+               self.list_store = gtk.ListStore(str, str)\r
+        \r
+               # ScrolledWindow\r
+               self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)\r
+               #self.set_border_width(6)\r
+               self.set_shadow_type(gtk.SHADOW_IN)\r
+        \r
+               # Treeview\r
+               self.tree_view = gtk.TreeView(self.list_store)\r
+               self.tree_view.set_headers_visible(False)\r
+               self.tree_view.get_selection().set_mode(gtk.SELECTION_BROWSE)\r
+               self.tree_view.connect("cursor-changed", self._on_cursor_changed)\r
+               self.tree_view.connect("row-activated", self._on_row_activated)\r
+               self.tree_view.show()\r
+        \r
+               # Key-Spalte hinzuf�gen\r
+               self.key_cell = gtk.CellRendererText()\r
+               self.key_column = gtk.TreeViewColumn("Key")\r
+               self.key_column.pack_start(self.key_cell, True)\r
+               self.key_column.add_attribute(self.key_cell, "text", 0)\r
+               self.key_column.set_visible(False)\r
+               self.tree_view.append_column(self.key_column)\r
+        \r
+               # Value-Spalte hinzufügen\r
+               self.value_cell = gtk.CellRendererText()\r
+               self.value_column = gtk.TreeViewColumn("Caption")\r
+               self.value_column.pack_start(self.value_cell, True)\r
+               self.value_column.add_attribute(self.value_cell, "text", 1)\r
+               self.tree_view.append_column(self.value_column)\r
+\r
+               # Suchspalte setzen\r
+               # Leider funktioniert die Suche im Moment nicht so \r
+               # wie ich das möchte. Deshalb habe ich die Suche abgeschaltet.\r
+               self.tree_view.set_enable_search(False)\r
+               #self.tree_view.set_search_column(1)\r
+       \r
+               # Anzeigen\r
+               self.add(self.tree_view)\r
+               self.show()\r
+\r
+\r
diff --git a/upload.sh b/upload.sh
new file mode 100755 (executable)
index 0000000..9e09cdc
--- /dev/null
+++ b/upload.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+scp ../quicknote_0.7.3_all.deb user@192.168.0.35:/media/mmc2/
+
+#cp -R ./schulplanerclasses /home/chris/Programs/schulplaner/src/
+
+