--- /dev/null
+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
--- /dev/null
+[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
--- /dev/null
+[D-BUS Service]
+Name=com.nokia.quicknote
+Exec=/usr/bin/quicknote
\ No newline at end of file
--- /dev/null
+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
+
--- /dev/null
+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
+
--- /dev/null
+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
--- /dev/null
+usr/bin
+usr/sbin
--- /dev/null
+README
+TODO
--- /dev/null
+#!/bin/sh -e
+gtk-update-icon-cache -f /usr/share/icons/hicolor
+exit 0
\ No newline at end of file
--- /dev/null
+#!/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
--- /dev/null
+# 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"
--- /dev/null
+# 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 "Установить соединение"
--- /dev/null
+#!/bin/sh
+
+make clean
+make
+dpkg-buildpackage -rfakeroot
+dpkg -i ../quicknote_0.7.4_all.deb
--- /dev/null
+#!/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']),
+ ]
+ )
--- /dev/null
+#!/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()
+
+
+
--- /dev/null
+#!/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)
--- /dev/null
+#!/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)
+
+
+
+
+
--- /dev/null
+#!/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)
+
+
+
+
--- /dev/null
+#/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()
+
--- /dev/null
+#!/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
--- /dev/null
+#!/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)
+
+
+
--- /dev/null
+#!/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"
--- /dev/null
+#!/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
--- /dev/null
+#!/bin/sh
+
+scp ../quicknote_0.7.3_all.deb user@192.168.0.35:/media/mmc2/
+
+#cp -R ./schulplanerclasses /home/chris/Programs/schulplaner/src/
+
+