Merge tag 'upstream/0.6.0'
authorgregor herrmann <gregoa@debian.org>
Wed, 12 Jun 2013 21:06:21 +0000 (23:06 +0200)
committergregor herrmann <gregoa@debian.org>
Wed, 12 Jun 2013 21:06:21 +0000 (23:06 +0200)
Upstream version 0.6.0

89 files changed:
AUTHORS
ChangeLog
NEWS
README
TODO
confclerk.pro
confclerk.pro.user.2.3pre1 [deleted file]
data/confclerk.1
data/confclerk.png
data/confclerk.pod
src/alarm/alarm.cpp
src/alarm/alarm.h
src/alarm/alarm.pro
src/app/alarmdbus.cpp [deleted file]
src/app/alarmdbus.h [deleted file]
src/app/alarmdbusadaptor.cpp [deleted file]
src/app/alarmdbusadaptorp.h [deleted file]
src/app/app.pro
src/app/application.cpp
src/app/application.h
src/app/appsettings.cpp
src/app/appsettings.h
src/app/main.cpp
src/create_tables.sql [deleted file]
src/db.qrc
src/dbschema000.sql [new file with mode: 0644]
src/dbschema000to001.sql [new file with mode: 0644]
src/dbschema001.sql [new file with mode: 0644]
src/global.pri
src/gui/about.ui
src/gui/conferenceeditor.cpp
src/gui/conferenceeditor.h
src/gui/conflictdialogcontainer.cpp
src/gui/conflictdialogcontainer.h
src/gui/conflictsdialog.cpp
src/gui/conflictsdialog.h
src/gui/daynavigatorwidget.cpp
src/gui/daynavigatorwidget.h
src/gui/daynavigatorwidget.ui
src/gui/dayviewtabcontainer.cpp
src/gui/dayviewtabcontainer.h
src/gui/errormessage.cpp
src/gui/errormessage.h
src/gui/eventdialog.cpp
src/gui/eventdialog.h
src/gui/eventdialog.ui
src/gui/favtabcontainer.cpp
src/gui/favtabcontainer.h
src/gui/mainwindow.cpp
src/gui/mainwindow.h
src/gui/mainwindow.ui
src/gui/roomstabcontainer.cpp
src/gui/roomstabcontainer.h
src/gui/searchhead.cpp
src/gui/searchhead.h
src/gui/searchtabcontainer.cpp
src/gui/searchtabcontainer.h
src/gui/settingsdialog.cpp
src/gui/settingsdialog.h
src/gui/tabcontainer.cpp
src/gui/tabcontainer.h
src/gui/trackstabcontainer.cpp
src/gui/trackstabcontainer.h
src/gui/urlinputdialog.cpp
src/gui/urlinputdialog.h
src/mvc/conference.cpp
src/mvc/conference.h
src/mvc/conferencemodel.cpp
src/mvc/conferencemodel.h
src/mvc/delegate.cpp
src/mvc/delegate.h
src/mvc/event.cpp
src/mvc/event.h
src/mvc/eventmodel.cpp
src/mvc/eventmodel.h
src/mvc/room.cpp
src/mvc/room.h
src/mvc/track.cpp
src/mvc/track.h
src/mvc/treeview.cpp
src/mvc/treeview.h
src/orm/ormrecord.h
src/sql/schedulexmlparser.cpp
src/sql/schedulexmlparser.h
src/sql/sqlengine.cpp
src/sql/sqlengine.h
src/test/main.cpp
src/test/mvc/eventtest.cpp
src/test/mvc/eventtest.h

diff --git a/AUTHORS b/AUTHORS
index 1b8dba28d7b786a8d3f6b92cc1fe5610f37a716a..d4823fb00a6e2e701ebcbb5a84ae89e717a4cde3 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -10,5 +10,7 @@ Monika Berendova
 Pavol Korinek
 Pavol Pavelka
 Maksim Kirillov
+
 Philipp Spitzer
 gregor herrmann
+Stefan Strahl
index 941f3fedfef556811941e411a71c18f15e0daf88..ee8c5dc2c2cb5e04fff868a457ad1fcb20b78a79 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,275 @@
+2013-06-12  gregoa
+
+       * NEWS: Update NEWS for 0.6.0 release.
+       * src/global.pri: Set version to 0.6.0.
+
+2013-06-12  philipp
+
+       * src/gui/mainwindow.h: Removed a "TODO" comment.
+
+2013-06-12  gregoa
+
+       * README: Update example URLs in README.
+
+2013-06-12  philipp
+
+       * src/gui/mainwindow.cpp: Added some actions to the mainwindow -
+         otherwise shortcuts don't work on MAEMO (see ticket #28).
+       * src/alarm/alarm.cpp: Removed debug output.
+
+2013-05-30  gregoa
+
+       * src/gui/eventdialog.cpp: Eventdialog: make sure the same colours
+         as everywhere are used.
+         
+         Additionally adjust font size on maemo.
+         
+         This should allow to close #48.
+
+2013-05-28  philipp
+
+       * src/gui/eventdialog.cpp, src/gui/eventdialog.ui: Changed the
+         event dialog layout hoping to improve issue #48.
+
+2013-05-28  gregoa
+
+       * confclerk.pro: Move removal of generated file into new
+         releaseclean target.
+       * confclerk.pro: .pro: Add created files to QMAKE_DISTCLEAN.
+
+2013-05-28  philipp
+
+       * src/app/main.cpp, src/gui/mainwindow.cpp, src/gui/mainwindow.h:
+         Made sure the mainwindow is destroyed properly and the sql
+         database is closed.
+
+2013-05-28  gregoa
+
+       * src/gui/eventdialog.cpp, src/mvc/treeview.cpp: #include
+         appsettings.h for maemo.
+
+2013-04-30  philipp
+
+       * src/mvc/conference.h, src/mvc/event.cpp, src/mvc/eventmodel.cpp,
+         src/sql/sqlengine.cpp: Now the dayChange time is taken into
+         account. This fixes #43.
+
+2013-04-19  gregoa
+
+       * README, data/confclerk.pod, src/alarm/alarm.cpp,
+         src/alarm/alarm.h, src/app/application.cpp,
+         src/app/application.h, src/app/appsettings.cpp,
+         src/app/appsettings.h, src/app/main.cpp, src/gui/about.ui,
+         src/gui/conferenceeditor.cpp, src/gui/conferenceeditor.h,
+         src/gui/conflictdialogcontainer.cpp,
+         src/gui/conflictdialogcontainer.h, src/gui/conflictsdialog.cpp,
+         src/gui/conflictsdialog.h, src/gui/daynavigatorwidget.cpp,
+         src/gui/daynavigatorwidget.h, src/gui/dayviewtabcontainer.cpp,
+         src/gui/dayviewtabcontainer.h, src/gui/errormessage.cpp,
+         src/gui/errormessage.h, src/gui/eventdialog.cpp,
+         src/gui/eventdialog.h, src/gui/favtabcontainer.cpp,
+         src/gui/favtabcontainer.h, src/gui/mainwindow.cpp,
+         src/gui/mainwindow.h, src/gui/roomstabcontainer.cpp,
+         src/gui/roomstabcontainer.h, src/gui/searchhead.cpp,
+         src/gui/searchhead.h, src/gui/searchtabcontainer.cpp,
+         src/gui/searchtabcontainer.h, src/gui/settingsdialog.cpp,
+         src/gui/settingsdialog.h, src/gui/tabcontainer.cpp,
+         src/gui/tabcontainer.h, src/gui/trackstabcontainer.cpp,
+         src/gui/trackstabcontainer.h, src/gui/urlinputdialog.cpp,
+         src/gui/urlinputdialog.h, src/mvc/conference.cpp,
+         src/mvc/conference.h, src/mvc/conferencemodel.cpp,
+         src/mvc/conferencemodel.h, src/mvc/delegate.cpp,
+         src/mvc/delegate.h, src/mvc/event.cpp, src/mvc/event.h,
+         src/mvc/eventmodel.cpp, src/mvc/eventmodel.h, src/mvc/room.cpp,
+         src/mvc/room.h, src/mvc/track.cpp, src/mvc/track.h,
+         src/mvc/treeview.cpp, src/mvc/treeview.h, src/orm/ormrecord.h,
+         src/sql/schedulexmlparser.cpp, src/sql/schedulexmlparser.h,
+         src/sql/sqlengine.cpp, src/sql/sqlengine.h, src/test/main.cpp,
+         src/test/mvc/eventtest.cpp, src/test/mvc/eventtest.h: bump
+         copyright years
+       * AUTHORS: add Stefan to AUTHORS
+
+2013-04-16  philipp
+
+       * src/gui/mainwindow.cpp: Formatted alarm message (closes ticket
+         #46).
+       * src/alarm/alarm.h, src/app/appsettings.h,
+         src/gui/eventdialog.cpp, src/gui/mainwindow.cpp,
+         src/mvc/event.cpp, src/mvc/event.h, src/mvc/treeview.cpp: Alarms
+         are reported via QSystemTray now (see ticket #46).
+
+2013-04-04  gregoa
+
+       * src/gui/mainwindow.cpp: extend comment re systrayicon position
+
+2013-04-03  gregoa
+
+       * src/gui/mainwindow.cpp: tray icon: add (commented out) debug
+         output and ->hide
+
+2013-04-02  philipp
+
+       * src/gui/eventdialog.cpp, src/gui/mainwindow.cpp,
+         src/gui/mainwindow.h, src/mvc/delegate.cpp: Prepared to show an
+         alarm message via tray icon on non-MAEMO systems.
+
+2013-04-02  gregoa
+
+       * src/mvc/treeview.cpp: fix typo in comment
+       * src/gui/eventdialog.cpp: fix typo in comment
+       * src/mvc/event.cpp: fix typo in comment
+
+2013-03-19  philipp
+
+       * src/gui/mainwindow.ui: The day tab is now the current tab when
+         starting the program (ticket #44).
+       * src/gui/mainwindow.cpp, src/gui/mainwindow.h: Current day is used
+         now when starting the program or loading a conference (ticket
+         #44).
+       * src/gui/daynavigatorwidget.ui, src/gui/mainwindow.ui: Created
+         more shortcuts (ticket #28).
+       * src/dbschema000to001.sql, src/dbschema001.sql: Added comments to
+         the SQL statements (back in October).
+
+2012-10-17  philipp
+
+       * src/gui/searchtabcontainer.cpp: The focus is set to the search
+         input field when the search icon is clicked.
+
+2012-10-17  gregoa
+
+       * src/app/main.cpp: When ConfClerk is called with arguments
+         (alarm), check for >= 3.
+         
+         Alarmd seems to add an additional argument.
+       * src/alarm/alarm.cpp, src/alarm/alarm.pro, src/app/alarmdbus.cpp,
+         src/app/alarmdbus.h, src/app/alarmdbusadaptor.cpp,
+         src/app/alarmdbusadaptorp.h, src/app/app.pro, src/app/main.cpp:
+         Rip out unused DBUS stuff.
+
+2012-10-17  philipp
+
+       * src/alarm/alarm.cpp: Fixed bug: Arguments for calling ConfClerk
+         in an alarm event were not built correctly.
+       * src/sql/schedulexmlparser.cpp: Changed int to string converstion
+         method because the old method gave an compilation error on MAEMO.
+       * src/alarm/alarm.cpp, src/app/main.cpp, src/gui/eventdialog.cpp,
+         src/gui/eventdialog.h, src/gui/mainwindow.cpp,
+         src/gui/mainwindow.h, src/gui/tabcontainer.cpp,
+         src/mvc/conference.cpp, src/mvc/conference.h: We added the
+         conferenceId to some alarm related methods (ticket #41).
+
+2012-10-08  gregoa
+
+       * README: Update URLs in README.
+
+2012-09-25  philipp
+
+       * src/db.qrc, src/sql/sqlengine.cpp, src/sql/sqlengine.h: Schmema
+         update completed. Finally closing ticket #45.
+       * src/gui/conferenceeditor.cpp, src/gui/conferenceeditor.h,
+         src/gui/mainwindow.cpp, src/mvc/conferencemodel.cpp,
+         src/mvc/conferencemodel.h, src/sql/schedulexmlparser.cpp,
+         src/sql/schedulexmlparser.h, src/sql/sqlengine.cpp: Reloading a
+         conference works now.
+       * src/sql/sqlengine.cpp: Fixed: Forgot to call query.exec() at
+         several places.
+       * src/dbschema000to001.sql: Added sql file that updates the schema
+         from version 000 to version 001.
+       * src/dbschema001.sql: Changed table names to have small letters.
+       * src/dbschema001.sql: Changed coding style of sql file.
+
+2012-09-25  gregoa
+
+       * src/mvc/conference.cpp, src/mvc/conference.h,
+         src/sql/schedulexmlparser.cpp, src/sql/sqlengine.cpp: Remove
+         unsed (and removed from db) 'days' column fro xml parser and all
+         sql parts.
+
+2012-09-25  philipp
+
+       * src/dbschema001.sql: Suggestion for database schema version 001.
+
+2012-09-25  gregoa
+
+       * src/sql/sqlengine.cpp: Don't insert empty string into picture
+         column.
+         
+         (NOT NULL constraint removed from db schema.)
+       * src/sql/sqlengine.cpp: Remove empty-city-hack.
+         
+         (NOT NULL removed from db schema.)
+       * src/mvc/conference.h: Remove ifdef'd out members
+
+2012-09-06  gregoa
+
+       * src/sql/sqlengine.cpp: One version for creating the directory is
+         enough :)
+         
+         (Now tested on Windows, too.)
+
+2012-09-05  philipp
+
+       * src/sql/sqlengine.cpp: Added a second possibility to create the
+         directory and removed the TODO.
+
+2012-09-05  gregoa
+
+       * src/sql/sqlengine.cpp: fix .mkpath()
+         
+         Creating the "." path works. Is this idiomatic? At least it works
+         (under Windows).
+         
+         TODO left: handle errors.
+
+2012-09-04  philipp
+
+       * src/app/main.cpp, src/create_tables.sql, src/db.qrc,
+         src/dbschema000.sql, src/dbschema001.sql, src/gui/mainwindow.cpp,
+         src/gui/mainwindow.h, src/gui/searchtabcontainer.cpp,
+         src/gui/searchtabcontainer.h, src/mvc/conference.cpp,
+         src/mvc/conference.h, src/sql/schedulexmlparser.cpp,
+         src/sql/schedulexmlparser.h, src/sql/sqlengine.cpp,
+         src/sql/sqlengine.h: Restructured the SqlEngine. Not yet finished
+         (see "TODO" in the code).
+
+2012-09-04  gregoa
+
+       * src/alarm/alarm.cpp, src/alarm/alarm.h, src/app/application.cpp,
+         src/app/main.cpp, src/gui/eventdialog.h, src/gui/mainwindow.cpp,
+         src/gui/mainwindow.h, src/gui/settingsdialog.cpp,
+         src/gui/tabcontainer.cpp, src/gui/tabcontainer.h,
+         src/mvc/conference.h, src/mvc/event.h, src/mvc/room.h,
+         src/mvc/track.h, src/sql/sqlengine.cpp,
+         src/test/mvc/eventtest.cpp: fix some more header includes
+       * src/sql/sqlengine.h: fix typo in comment
+
+2012-08-27  gregoa
+
+       * src/mvc/delegate.cpp, src/mvc/eventmodel.cpp: fix #includes
+         
+         (detected by QtCreator and friends on windows)
+
+2012-08-21  philipp
+
+       * src/gui/conferenceeditor.cpp, src/gui/conferenceeditor.h,
+         src/gui/mainwindow.cpp, src/gui/mainwindow.h,
+         src/sql/schedulexmlparser.cpp, src/sql/schedulexmlparser.h,
+         src/sql/sqlengine.cpp, src/sql/sqlengine.h: On the way to fix
+         #45.
+       * src/gui/conferenceeditor.cpp: Fixed bug: Changing the conference
+         URL resulted in an error message.
+
+2012-06-13  gregoa
+
+       * ., confclerk.pro: Add .pro.user.* to svn:ignore and remove it in
+         the release target.
+       * TODO: TODO: new item about duplicate documentation.
+       * README: README: add Stefan to Contact section.
+
 2012-06-12  gregoa
 
+       * NEWS, src/global.pri: Bump version after 0.5.5 release.
        * NEWS: Add release date in NEWS.
        * TODO: remove TODO item (expand/collapse)
        * NEWS: Add more items to NEWS.
diff --git a/NEWS b/NEWS
index e4d25c58d93cc07423edf70dda58f5537e3c25fa..56138820278368d31df9afa6dd7bac4e1f92e01c 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,27 @@
 This is the NEWS file for ConfClerk. ConfClerk is the successor of
 fosdem-schedule; cf. docs/fosdem-schedule for the historic documentation.
 
+version 0.6.0, 2013-06-13
+* New DB schema 001. Datebase is converted on first start.
+  DB schema update functionality implemented.
+* Added more keybindings.
+  (Fixes: #28)
+* Rewrote event detail dialog, to avoid flicker on Maemo.
+  (Fixes: #48)
+* Events after midnight are shown on the day before (if the conference XML
+  file is correct).
+  (Fixes: #43)
+* On non-Maemo system "alarms" (notifications) are shown.
+  (Fixes: #46)
+* Try to show current day on startup and show "day" tab.
+  (Fixes: #44)
+* Use conference id (not title) for import.
+  (Fixes: #45)
+* Use conference id (not title) for alarms (maemo).
+  (Fixes: #38)
+* Use one day navigator for whole app (instead of separate ones per tab).
+  (Fixes: #11)
+
 version 0.5.5, 2012-06-12
 * UI changes:
   - button bar on the right side
diff --git a/README b/README
index 31ae446a8bd2693a90784504558c1e3c6417a997..81919aa14bef559f9e89c7740f4f4c7f27f62cc3 100644 (file)
--- a/README
+++ b/README
@@ -24,7 +24,7 @@ See the file ./INSTALL for building and installation instructions, and
 Copyright and License:
 
   Copyright (C) 2010 Ixonos Plc.
-  Copyright (C) 2011-2012, Philipp Spitzer, gregor herrmann, Stefan Strahl
+  Copyright (C) 2011-2013, Philipp Spitzer, gregor herrmann, Stefan Strahl
 
   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
@@ -116,7 +116,7 @@ Thanks guys!
 
 Contact:
 
-Philipp Spitzer, gregor herrmann
+Philipp Spitzer, gregor herrmann, Stefan Strahl
 Toastfreeware
 <toast+confclerk@toastfreeware.priv.at>
 http://www.toastfreeware.priv.at/confclerk/
@@ -124,8 +124,8 @@ http://www.toastfreeware.priv.at/confclerk/
 
 Tested pentabarf (or frab) instances:
 
-- FOSDEM (2012): http://fosdem.org/schedule/xml
-- Grazer Linuxtage (2012): http://glt12-programm.linuxtage.at/schedule.de.xml
-- DebConf (2011): http://penta.debconf.org/dc11_schedule/schedule.en.xml
-- 28C3: http://events.ccc.de/congress/2011/Fahrplan/schedule.en.xml
-- FrOSCon (2011): http://programm.froscon.org/2011/schedule.xml
+- FOSDEM: http://fosdem.org/schedule/xml
+- Grazer Linuxtage (2013): http://glt13-programm.linuxtage.at/schedule.de.xml
+- DebConf (2012): http://penta.debconf.org/dc12_schedule/schedule.en.xml
+- 29C3: http://events.ccc.de/congress/2012/Fahrplan/schedule.en.xml
+- FrOSCon (2012): http://programm.froscon.org/2012/schedule.xml
diff --git a/TODO b/TODO
index 6dd4b5e20375e4601837c90b1d0baa31f0fb2c4c..6aeeebc52f0473b6243a2bdf3323a139a2ca2d31 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,3 +1,4 @@
 - .pro: maybe add an install target
 - explore src/alarm/calendar*
 - if toolbar is turned off, it can not be turned on anymore.
+- try to de-duplicate README and data/confclerk.pod
index 662e5fb953dd8410200569e9ec73d015c838f01c..625060d328ce580acdfae5d3699734c0093a80e8 100644 (file)
@@ -12,8 +12,7 @@ SUBDIRS = src
 # The global.pri defines the VERSION of the project
 include(src/global.pri)
 
-
-QMAKE_EXTRA_TARGETS += changelog icon man release tarball
+QMAKE_EXTRA_TARGETS += changelog icon man release releaseclean tarball
 
 changelog.target = ChangeLog
 changelog.commands = \
@@ -28,14 +27,18 @@ man.target = data/$${TARGET}.1
 man.commands = pod2man --utf8 --center=\"Offlince conference scheduler\" --release=\"Version $${VERSION}\" data/$${TARGET}.pod > data/$${TARGET}.1
 man.depends = data/$${TARGET}.pod
 
-release.depends = tarball
+release.depends = releaseclean tarball
+
+releaseclean.commands = \
+ $(DEL_FILE) data/$${TARGET}.png data/$${TARGET}.1 ChangeLog
+#releaseclean.CONFIG = phony
 
 tarball.target = $${TARGET}-$${VERSION}.tar.gz
 tarball.commands = \
        $(DEL_FILE) -r $${TARGET}-$${VERSION} ; \
        $(MKDIR) $${TARGET}-$${VERSION} ; \
        $(COPY_DIR) * $${TARGET}-$${VERSION}/ ; \
-       $(DEL_FILE) $${TARGET}-$${VERSION}/*.pro.user \
+       $(DEL_FILE) $${TARGET}-$${VERSION}/*.pro.user* \
                $${TARGET}-$${VERSION}/$${TARGET}-$${VERSION}.tar.gz \
                $(DEL_FILE) -r $${TARGET}-$${VERSION}/$${TARGET}-$${VERSION} \
                $${TARGET}-$${VERSION}/Makefile ; \
diff --git a/confclerk.pro.user.2.3pre1 b/confclerk.pro.user.2.3pre1
deleted file mode 100644 (file)
index a4dd0d7..0000000
+++ /dev/null
@@ -1,207 +0,0 @@
-<!DOCTYPE QtCreatorProject>
-<qtcreator>
- <data>
-  <variable>ProjectExplorer.Project.ActiveTarget</variable>
-  <value type="int">0</value>
- </data>
- <data>
-  <variable>ProjectExplorer.Project.EditorSettings</variable>
-  <valuemap type="QVariantMap">
-   <value key="EditorConfiguration.AutoIndent" type="bool">true</value>
-   <value key="EditorConfiguration.AutoSpacesForTabs" type="bool">false</value>
-   <value key="EditorConfiguration.Codec" type="QByteArray">System</value>
-   <value key="EditorConfiguration.DoubleIndentBlocks" type="bool">false</value>
-   <value key="EditorConfiguration.IndentBraces" type="bool">false</value>
-   <value key="EditorConfiguration.IndentSize" type="int">4</value>
-   <value key="EditorConfiguration.MouseNavigation" type="bool">true</value>
-   <value key="EditorConfiguration.PaddingMode" type="int">1</value>
-   <value key="EditorConfiguration.ScrollWheelZooming" type="bool">true</value>
-   <value key="EditorConfiguration.SmartBackspace" type="bool">true</value>
-   <value key="EditorConfiguration.SpacesForTabs" type="bool">true</value>
-   <value key="EditorConfiguration.TabKeyBehavior" type="int">2</value>
-   <value key="EditorConfiguration.TabSize" type="int">4</value>
-   <value key="EditorConfiguration.UseGlobal" type="bool">true</value>
-   <value key="EditorConfiguration.Utf8BomBehavior" type="int">1</value>
-   <value key="EditorConfiguration.addFinalNewLine" type="bool">true</value>
-   <value key="EditorConfiguration.cleanIndentation" type="bool">true</value>
-   <value key="EditorConfiguration.cleanWhitespace" type="bool">true</value>
-   <value key="EditorConfiguration.inEntireDocument" type="bool">false</value>
-  </valuemap>
- </data>
- <data>
-  <variable>ProjectExplorer.Project.Target.0</variable>
-  <valuemap type="QVariantMap">
-   <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Desktop</value>
-   <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString">Desktop</value>
-   <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Target.DesktopTarget</value>
-   <value key="ProjectExplorer.Target.ActiveBuildConfiguration" type="int">1</value>
-   <value key="ProjectExplorer.Target.ActiveDeployConfiguration" type="int">0</value>
-   <value key="ProjectExplorer.Target.ActiveRunConfiguration" type="int">0</value>
-   <valuemap key="ProjectExplorer.Target.BuildConfiguration.0" type="QVariantMap">
-    <value key="ProjectExplorer.BuildCOnfiguration.ToolChain" type="QString">ProjectExplorer.ToolChain.Gcc:/usr/lib/ccache/g++.x86-linux-generic-elf-64bit.</value>
-    <valuemap key="ProjectExplorer.BuildConfiguration.BuildStepList.0" type="QVariantMap">
-     <valuemap key="ProjectExplorer.BuildStepList.Step.0" type="QVariantMap">
-      <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">qmake</value>
-      <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-      <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">QtProjectManager.QMakeBuildStep</value>
-      <value key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary" type="bool">false</value>
-      <value key="QtProjectManager.QMakeBuildStep.QMakeArguments" type="QString"></value>
-      <value key="QtProjectManager.QMakeBuildStep.QMakeForced" type="bool">false</value>
-     </valuemap>
-     <valuemap key="ProjectExplorer.BuildStepList.Step.1" type="QVariantMap">
-      <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Make</value>
-      <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-      <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.MakeStep</value>
-      <value key="Qt4ProjectManager.MakeStep.Clean" type="bool">false</value>
-      <value key="Qt4ProjectManager.MakeStep.MakeArguments" type="QString"></value>
-      <value key="Qt4ProjectManager.MakeStep.MakeCommand" type="QString"></value>
-     </valuemap>
-     <value key="ProjectExplorer.BuildStepList.StepsCount" type="int">2</value>
-     <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Build</value>
-     <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-     <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">ProjectExplorer.BuildSteps.Build</value>
-    </valuemap>
-    <valuemap key="ProjectExplorer.BuildConfiguration.BuildStepList.1" type="QVariantMap">
-     <valuemap key="ProjectExplorer.BuildStepList.Step.0" type="QVariantMap">
-      <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Make</value>
-      <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-      <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.MakeStep</value>
-      <value key="Qt4ProjectManager.MakeStep.Clean" type="bool">true</value>
-      <value key="Qt4ProjectManager.MakeStep.MakeArguments" type="QString">clean</value>
-      <value key="Qt4ProjectManager.MakeStep.MakeCommand" type="QString"></value>
-     </valuemap>
-     <value key="ProjectExplorer.BuildStepList.StepsCount" type="int">1</value>
-     <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Clean</value>
-     <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-     <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">ProjectExplorer.BuildSteps.Clean</value>
-    </valuemap>
-    <value key="ProjectExplorer.BuildConfiguration.BuildStepListCount" type="int">2</value>
-    <value key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment" type="bool">false</value>
-    <valuelist key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges" type="QVariantList"/>
-    <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Qt in PATH Release</value>
-    <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-    <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Qt4BuildConfiguration</value>
-    <value key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration" type="int">0</value>
-    <value key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory" type="QString">/home/gregoa/src/toastfreeware/confclerk</value>
-    <value key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId" type="int">2</value>
-    <value key="Qt4ProjectManager.Qt4BuildConfiguration.ToolChain" type="QString">ProjectExplorer.ToolChain.Gcc:/usr/lib/ccache/g++.x86-linux-generic-elf-64bit.</value>
-    <value key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild" type="bool">false</value>
-   </valuemap>
-   <valuemap key="ProjectExplorer.Target.BuildConfiguration.1" type="QVariantMap">
-    <value key="ProjectExplorer.BuildCOnfiguration.ToolChain" type="QString">ProjectExplorer.ToolChain.Gcc:/usr/lib/ccache/g++.x86-linux-generic-elf-64bit.</value>
-    <valuemap key="ProjectExplorer.BuildConfiguration.BuildStepList.0" type="QVariantMap">
-     <valuemap key="ProjectExplorer.BuildStepList.Step.0" type="QVariantMap">
-      <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">qmake</value>
-      <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-      <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">QtProjectManager.QMakeBuildStep</value>
-      <value key="QtProjectManager.QMakeBuildStep.LinkQmlDebuggingLibrary" type="bool">false</value>
-      <value key="QtProjectManager.QMakeBuildStep.QMakeArguments" type="QString"></value>
-      <value key="QtProjectManager.QMakeBuildStep.QMakeForced" type="bool">false</value>
-     </valuemap>
-     <valuemap key="ProjectExplorer.BuildStepList.Step.1" type="QVariantMap">
-      <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Make</value>
-      <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-      <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.MakeStep</value>
-      <value key="Qt4ProjectManager.MakeStep.Clean" type="bool">false</value>
-      <value key="Qt4ProjectManager.MakeStep.MakeArguments" type="QString"></value>
-      <value key="Qt4ProjectManager.MakeStep.MakeCommand" type="QString"></value>
-     </valuemap>
-     <value key="ProjectExplorer.BuildStepList.StepsCount" type="int">2</value>
-     <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Build</value>
-     <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-     <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">ProjectExplorer.BuildSteps.Build</value>
-    </valuemap>
-    <valuemap key="ProjectExplorer.BuildConfiguration.BuildStepList.1" type="QVariantMap">
-     <valuemap key="ProjectExplorer.BuildStepList.Step.0" type="QVariantMap">
-      <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Make</value>
-      <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-      <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.MakeStep</value>
-      <value key="Qt4ProjectManager.MakeStep.Clean" type="bool">true</value>
-      <value key="Qt4ProjectManager.MakeStep.MakeArguments" type="QString">clean</value>
-      <value key="Qt4ProjectManager.MakeStep.MakeCommand" type="QString"></value>
-     </valuemap>
-     <value key="ProjectExplorer.BuildStepList.StepsCount" type="int">1</value>
-     <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Clean</value>
-     <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-     <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">ProjectExplorer.BuildSteps.Clean</value>
-    </valuemap>
-    <value key="ProjectExplorer.BuildConfiguration.BuildStepListCount" type="int">2</value>
-    <value key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment" type="bool">false</value>
-    <valuelist key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges" type="QVariantList"/>
-    <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Qt in PATH Debug</value>
-    <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-    <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Qt4BuildConfiguration</value>
-    <value key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration" type="int">2</value>
-    <value key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory" type="QString">/home/gregoa/src/toastfreeware/confclerk</value>
-    <value key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId" type="int">2</value>
-    <value key="Qt4ProjectManager.Qt4BuildConfiguration.ToolChain" type="QString">ProjectExplorer.ToolChain.Gcc:/usr/lib/ccache/g++.x86-linux-generic-elf-64bit.</value>
-    <value key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild" type="bool">false</value>
-   </valuemap>
-   <value key="ProjectExplorer.Target.BuildConfigurationCount" type="int">2</value>
-   <valuemap key="ProjectExplorer.Target.DeployConfiguration.0" type="QVariantMap">
-    <valuemap key="ProjectExplorer.BuildConfiguration.BuildStepList.0" type="QVariantMap">
-     <value key="ProjectExplorer.BuildStepList.StepsCount" type="int">0</value>
-     <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">Deploy</value>
-     <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-     <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">ProjectExplorer.BuildSteps.Deploy</value>
-    </valuemap>
-    <value key="ProjectExplorer.BuildConfiguration.BuildStepListCount" type="int">1</value>
-    <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">No deployment</value>
-    <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-    <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">ProjectExplorer.DefaultDeployConfiguration</value>
-   </valuemap>
-   <value key="ProjectExplorer.Target.DeployConfigurationCount" type="int">1</value>
-   <valuemap key="ProjectExplorer.Target.RunConfiguration.0" type="QVariantMap">
-    <valuelist key="Analyzer.Valgrind.AddedSupressionFiles" type="QVariantList"/>
-    <value key="Analyzer.Valgrind.FilterExternalIssues" type="bool">true</value>
-    <value key="Analyzer.Valgrind.NumCallers" type="int">25</value>
-    <valuelist key="Analyzer.Valgrind.RemovedSupressionFiles" type="QVariantList"/>
-    <value key="Analyzer.Valgrind.TrackOrigins" type="bool">true</value>
-    <value key="Analyzer.Valgrind.ValgrindExecutable" type="QString">valgrind</value>
-    <valuelist key="Analyzer.Valgrind.VisibleErrorKinds" type="QVariantList">
-     <value type="int">0</value>
-     <value type="int">1</value>
-     <value type="int">2</value>
-     <value type="int">3</value>
-     <value type="int">4</value>
-     <value type="int">5</value>
-     <value type="int">6</value>
-     <value type="int">7</value>
-     <value type="int">8</value>
-     <value type="int">9</value>
-     <value type="int">10</value>
-     <value type="int">11</value>
-     <value type="int">12</value>
-     <value type="int">13</value>
-     <value type="int">14</value>
-    </valuelist>
-    <value key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName" type="QString">app</value>
-    <value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
-    <value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Qt4RunConfiguration</value>
-    <value key="Qt4ProjectManager.Qt4RunConfiguration.BaseEnvironmentBase" type="int">2</value>
-    <value key="Qt4ProjectManager.Qt4RunConfiguration.CommandLineArguments" type="QString"></value>
-    <value key="Qt4ProjectManager.Qt4RunConfiguration.ProFile" type="QString">src/app/app.pro</value>
-    <value key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix" type="bool">false</value>
-    <value key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal" type="bool">false</value>
-    <valuelist key="Qt4ProjectManager.Qt4RunConfiguration.UserEnvironmentChanges" type="QVariantList"/>
-    <value key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory" type="QString"></value>
-    <value key="RunConfiguration.QmlDebugServerPort" type="uint">3768</value>
-    <value key="RunConfiguration.UseCppDebugger" type="bool">true</value>
-    <value key="RunConfiguration.UseQmlDebugger" type="bool">false</value>
-   </valuemap>
-   <value key="ProjectExplorer.Target.RunConfigurationCount" type="int">1</value>
-  </valuemap>
- </data>
- <data>
-  <variable>ProjectExplorer.Project.TargetCount</variable>
-  <value type="int">1</value>
- </data>
- <data>
-  <variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
-  <value type="QString">{2789a944-937d-44bc-b81f-9092f03d1885}</value>
- </data>
- <data>
-  <variable>ProjectExplorer.Project.Updater.FileVersion</variable>
-  <value type="int">9</value>
- </data>
-</qtcreator>
index 13ba763ebf8c81c84f418c52534e3aa0c4c79054..74b1a8566c06e27e7d3b88b3bea36e417bd3a660 100644 (file)
@@ -62,7 +62,7 @@
 .\" ========================================================================
 .\"
 .IX Title "CONFCLERK 1"
-.TH CONFCLERK 1 "2012-06-12" "Version 0.5.5" "Offlince conference scheduler"
+.TH CONFCLERK 1 "2013-04-19" "Version 0.6.0" "Offlince conference scheduler"
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -119,9 +119,9 @@ So the configuration (see \*(L"\s-1CONFIGURATION\s0\*(R") is stored at
 .IX Subsection "Main code"
 .Vb 4
 \&    Copyright (C) 2010 Ixonos Plc.
-\&    Copyright (C) 2011\-2012, Philipp Spitzer <philipp@toastfreeware.priv.at>
-\&    Copyright (C) 2011\-2012, gregor herrmann <gregor@toastfreeware.priv.at>
-\&    Copyright (C) 2011\-2012, Stefan Strahl <stefan@toastfreeware.priv.at>
+\&    Copyright (C) 2011\-2013, Philipp Spitzer <philipp@toastfreeware.priv.at>
+\&    Copyright (C) 2011\-2013, gregor herrmann <gregor@toastfreeware.priv.at>
+\&    Copyright (C) 2011\-2013, Stefan Strahl <stefan@toastfreeware.priv.at>
 \&
 \&    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
index 995fa68f0599e90dce0e2fbd481dc97baf439ac7..74c03e4807f9b34ae6ef8448810ef5e9e42c2b2e 100644 (file)
Binary files a/data/confclerk.png and b/data/confclerk.png differ
index 4704905b4491c4f71bcb518dcfdf5a082e5c3edc..a1a2d558a2c8aa7655f5fa28a0d3695a2e67b361 100644 (file)
@@ -65,9 +65,9 @@ F<~/.local/share/data/Toastfreeware/ConfClerk/ConfClerk.sqlite>.
 =head2 Main code
 
     Copyright (C) 2010 Ixonos Plc.
-    Copyright (C) 2011-2012, Philipp Spitzer <philipp@toastfreeware.priv.at>
-    Copyright (C) 2011-2012, gregor herrmann <gregor@toastfreeware.priv.at>
-    Copyright (C) 2011-2012, Stefan Strahl <stefan@toastfreeware.priv.at>
+    Copyright (C) 2011-2013, Philipp Spitzer <philipp@toastfreeware.priv.at>
+    Copyright (C) 2011-2013, gregor herrmann <gregor@toastfreeware.priv.at>
+    Copyright (C) 2011-2013, Stefan Strahl <stefan@toastfreeware.priv.at>
 
     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
index e41984f9da85ddf343eae6f9dd1afd8ab44095e3..6f8f2f57b731eb51cc9b2ce58d774254b748e509 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -25,9 +25,6 @@
 #include <QDir>
 #include <QFileInfo>
 
-#include <QDebug>
-
-//#include <dbus-1.0/dbus/dbus-protocol.h>
 
 int Alarm::addAlarm(int conferenceId, int eventId, QString eventTitle, const QDateTime &alarmDateTime) {
     cookie_t alarmCookie = 0;
@@ -57,35 +54,13 @@ int Alarm::addAlarm(int conferenceId, int eventId, QString eventTitle, const QDa
     alarmAction = alarm_event_add_actions(alarmEvent, 1);
     alarm_action_set_label(alarmAction, "ConfClerk");
 
-    QString command = QFileInfo(*qApp->argv()).absoluteFilePath() + QString(" %1").arg(QString::number(eventId));
-    qDebug() << "Setting alarm: " << command;
+    QString command = QFileInfo(*qApp->argv()).absoluteFilePath() + QString(" %1 %2").arg(conferenceId).arg(eventId);
     alarm_action_set_exec_command(alarmAction, command.toLocal8Bit().data());
     alarmAction->flags |= ALARM_ACTION_TYPE_EXEC;
     alarmAction->flags |= ALARM_ACTION_WHEN_RESPONDED;
     alarmAction->flags |= ALARM_ACTION_EXEC_ADD_COOKIE; // adds assigned cookie at the end of command string
 
-//    // setup this action to be a "DBus command"
-//    act->flags |= ALARM_ACTION_WHEN_RESPONDED;
-//    act->flags |= ALARM_ACTION_TYPE_DBUS;
-//
-//    // DBus params for this action
-//    alarm_action_set_dbus_interface(act, "at.priv.toastfreeware.confclerk.AlarmInterface");
-//    alarm_action_set_dbus_service(act, "at.priv.toastfreeware.confclerk");
-//    alarm_action_set_dbus_path(act, "/ConfClerk");
-//    alarm_action_set_dbus_name(act, "Alarm");
-//
-//    // DBus arguments for the action
-//    alarm_action_set_dbus_args(act,  DBUS_TYPE_INT32, &aEventId, DBUS_TYPE_INVALID);
-
-    //    act->flags |= ALARM_ACTION_TYPE_EXEC;
-    //     alarm_action_set_exec_command(act, command.toLocal8Bit().data());
-    //    alarm_event_set_icon(eve, "fosdem");
-    //    alarm_event_set_title(eve, "ConfClerk");
-    // adds assigned cookie at the end of command string
-    //    act->flags |= ALARM_ACTION_EXEC_ADD_COOKIE;
-
     /* Add stop button action */
-    /* TODO: send a DBus message to remove that alarm from database */
     alarmAction = alarm_event_add_actions(alarmEvent, 1);
     alarm_action_set_label(alarmAction, "Stop");
     alarmAction->flags |= ALARM_ACTION_WHEN_RESPONDED;
index 1aa54f1c9d27d7006e60bfa3f02a6c7777a13031..25f4e6f78c352ac57ed5782efdd61da5222eaa28 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
 
 extern "C"
 {
-#include <alarmd/libalarm.h>
+#include "alarmd/libalarm.h"
 }
 
 #define APPID "confclerk-alarm"
-const int PRE_EVENT_ALARM_SEC = -15*60; // alarm goes off 15 minutes before start of event
 
 class Alarm : public QObject
 {
index b83a288e1145939664f0f633e5bb2a3ca02b9010..6a5b8960263a300b29b345f13d4839048d905869 100644 (file)
@@ -1,8 +1,8 @@
 TEMPLATE = lib
 TARGET = qalarm
 DESTDIR = ../bin
-CONFIG += static qdbus 
-QT += sql dbus
+CONFIG += static
+QT += sql
 QMAKE_CLEAN += ../bin/libqalarm.a
 
 # module dependencies
@@ -17,6 +17,3 @@ INCLUDEPATH += ../gui \
     ../mvc \ 
     ../orm \
     ../sql
-    
-
-
diff --git a/src/app/alarmdbus.cpp b/src/app/alarmdbus.cpp
deleted file mode 100644 (file)
index a924041..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
- *
- * This file is part of ConfClerk.
- *
- * ConfClerk 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 2 of the License, or (at your option)
- * any later version.
- *
- * ConfClerk 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
- * ConfClerk.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "alarmdbus.h"
-#include "eventdialog.h"
-
-
-
-
-CAlarmDBus::CAlarmDBus(QWidget * aParent)
-    : QObject(),
-    mParent(aParent)
-{
-    // constructor
-    //setAutoRelaySignals(true);
-}
-
-CAlarmDBus::~CAlarmDBus()
-{
-    // destructor
-}
-
-void CAlarmDBus::Alarm(int aEventId)
-{
-       EventDialog dialog(aEventId,mParent);
-       dialog.exec();
-
-}
diff --git a/src/app/alarmdbus.h b/src/app/alarmdbus.h
deleted file mode 100644 (file)
index 1b9127c..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
- *
- * This file is part of ConfClerk.
- *
- * ConfClerk 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 2 of the License, or (at your option)
- * any later version.
- *
- * ConfClerk 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
- * ConfClerk.  If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef ALARM_DBUS_H
-#define ALARM_DBUS_H
-
-#include <QObject>
-#include <QtDBus/QtDBus>
-
-class CAlarmDBus: public QObject
-{
-    Q_OBJECT
-    Q_CLASSINFO("D-Bus Interface", "at.priv.toastfreeware.confclerk")
-
-public:
-       CAlarmDBus(QWidget * aParent);
-    virtual ~CAlarmDBus();
-
-public: // PROPERTIES
-public Q_SLOTS: // METHODS
-    void Alarm(int aEventId);
-private:
-       QWidget * mParent;
-};
-
-
-#endif // ALARM_DBUS_H
diff --git a/src/app/alarmdbusadaptor.cpp b/src/app/alarmdbusadaptor.cpp
deleted file mode 100644 (file)
index fe1c483..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
- *
- * This file is part of ConfClerk.
- *
- * ConfClerk 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 2 of the License, or (at your option)
- * any later version.
- *
- * ConfClerk 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
- * ConfClerk.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "alarmdbusadaptorp.h"
-#include <QtCore/QMetaObject>
-#include <QtCore/QByteArray>
-#include <QtCore/QList>
-#include <QtCore/QMap>
-#include <QtCore/QString>
-#include <QtCore/QStringList>
-#include <QtCore/QVariant>
-
-
-AlarmDBusAdaptor::AlarmDBusAdaptor(QObject *parent)
-    : QDBusAbstractAdaptor(parent)
-{
-    // constructor
-    setAutoRelaySignals(true);
-}
-
-AlarmDBusAdaptor::~AlarmDBusAdaptor()
-{
-    // destructor
-}
-
-void AlarmDBusAdaptor::Alarm(int aEventId)
-{
-    QMetaObject::invokeMethod(parent(), "Alarm",Q_ARG(int, aEventId));
-}
-
-
diff --git a/src/app/alarmdbusadaptorp.h b/src/app/alarmdbusadaptorp.h
deleted file mode 100644 (file)
index c5413cd..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
- *
- * This file is part of ConfClerk.
- *
- * ConfClerk 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 2 of the License, or (at your option)
- * any later version.
- *
- * ConfClerk 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
- * ConfClerk.  If not, see <http://www.gnu.org/licenses/>.
- */
-#ifndef ALARM_DBUS_ADAPTOR_P_H
-#define ALARM_DBUS_ADAPTOR_P_H
-
-#include <QtCore/QObject>
-#include <QtDBus/QtDBus>
-
-QT_BEGIN_NAMESPACE
-class QByteArray;
-template<class T> class QList;
-template<class Key, class Value> class QMap;
-class QString;
-class QStringList;
-class QVariant;
-QT_END_NAMESPACE
-
-
-class AlarmDBusAdaptor: public QDBusAbstractAdaptor
-{
-    Q_OBJECT
-    Q_CLASSINFO("D-Bus Interface", "at.priv.toastfreeware.confclerk.AlarmInterface")
-    Q_CLASSINFO("D-Bus Introspection", ""
-"  <interface name=\"at.priv.toastfreeware.confclerk.AlarmInterface\" >\n"
-"  <method name=\"Alarm\">\n"
-"        <arg name=\"aEventId\" type=\"i\" direction=\"in\"/>\n"
-"  </method>\n"
-"  </interface>\n"
-        "")
-public:
-       AlarmDBusAdaptor(QObject *parent);
-    virtual ~AlarmDBusAdaptor();
-
-public: // PROPERTIES
-public Q_SLOTS: // METHODS
-       void Alarm(int aEventId);
-};
-
-#endif
index aa3554962ea8afafcbb9165befadd50ccf2c76f5..57cd46fc588e443378db573518f309cfdc7784e1 100644 (file)
@@ -4,7 +4,7 @@ TARGET = confclerk
 DESTDIR = ../bin
 QT += sql xml network
 CONFIG(maemo5) {
-    QT += maemo5 dbus
+    QT += maemo5
 }
 
 # module dependencies
@@ -17,10 +17,6 @@ maemo {
     INCLUDEPATH += ../alarm
     DEPENDPATH +=  ../alarm
     POST_TARGETDEPS += $$DESTDIR/libqalarm.a
-    HEADERS += alarmdbus.h \
-        alarmdbusadaptorp.h
-    SOURCES += alarmdbus.cpp \
-        alarmdbusadaptor.cpp
 }
 
 HEADERS += appsettings.h \
index d70d06a9b4e7d56f12eb018158e8987776c166da..baa86ef57d90581e2ca4a7fa8f2ef452bace720c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -20,7 +20,7 @@
 #include "application.h"
 #include "errormessage.h"
 
-#include <ormrecord.h>
+#include "ormrecord.h"
 
 // if the application uses exceptions,
 // there is always a possibility that some will leak uncached from event handler
index 84f9df2340f81ad12b4091cbc37bb55c1286a281..db337958b06616b93dc68afd0a6b1da7ca67f457 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 3d369babd57411c1214650da874e574d10ec7664..f204bb6578dbaa1602340e7997b43ebb845a376e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index a93c0aa1185719f14a504bab0272d69fb63d2064..38149c9236b82e060e6216cd532b3f12b747f3d2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -40,6 +40,7 @@ class AppSettings
         static void setProxyAddress(const QString &aAddress);
         static void setProxyPort(const quint16 aPort);
         static void setDirectConnection(bool aDirectConnection);
+        static int preEventAlarmSec() {return 60*15;} ///< seconds that alarm should ring before an event starts
 };
 
 #endif /* APPSETTINGS_H */
index c61652b3e67c67394f829ab163a3fee99c12d4e2..d7df6bc374a91374c7d02c6a017c10d203b9350c 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
  * You should have received a copy of the GNU General Public License along with
  * ConfClerk.  If not, see <http://www.gnu.org/licenses/>.
  */
-#include <mainwindow.h>
+#include "mainwindow.h"
 
-#include <sqlengine.h>
+#include "sqlengine.h"
 
 #include "eventdialog.h"
 #include "application.h"
 
-#ifdef MAEMO
-//#include <alarmdialog.h>
-#include <alarmdbus.h>
-#include <alarmdbusadaptorp.h>
-#endif /* MAEMO */
-
-
 int main(int argc, char *argv[])
 {
     Q_INIT_RESOURCE(icons);
@@ -44,44 +37,17 @@ int main(int argc, char *argv[])
     QCoreApplication::setOrganizationName("Toastfreeware");
     QCoreApplication::setApplicationName("ConfClerk");
     QCoreApplication::setApplicationVersion(VERSION);
-    SqlEngine::initialize(); // creates "SQLITE" DB connection
-
-    QWidget *window;
-
-    window = new MainWindow;
 
+    MainWindow window;
 
-#ifdef MAEMO
-    // Alarm Dbus
-    CAlarmDBus *alarmDBus = new CAlarmDBus(window);
-    new AlarmDBusAdaptor(alarmDBus);
-    QDBusConnection connection = QDBusConnection::sessionBus();
-
-    if(connection.registerObject("/ConfClerk", alarmDBus) == true)
-    {
-       if( connection.registerService("at.priv.toastfreeware.confclerk") == false)
-       {
-               if(argc>1)
-               {
-                       QDBusInterface *interface = new QDBusInterface("at.priv.toastfreeware.confclerk",
-                                                                      "/ConfClerk",
-                                                                      "at.priv.toastfreeware.confclerk.AlarmInterface",
-                                                                      connection);
-                       interface->call("Alarm",atoi(argv[1]));
-                       return 0;
-               }
-       }
-    }
-
-    if(argc > 1)
-    {
-        EventDialog dialog(atoi(argv[1]),window);
+    // If we were started with the parameters confernceid and eventid, show the corresponding event (alarm)
+    if (argc >= 3) {
+        QString conferenceIdStr = argv[1];
+        QString eventIdStr = argv[2];
+        EventDialog dialog(conferenceIdStr.toInt(), eventIdStr.toInt(), &window);
         dialog.exec();
     }
-#endif
-
-    window->show();
+    window.show();
 
     return a.exec();
 }
diff --git a/src/create_tables.sql b/src/create_tables.sql
deleted file mode 100644 (file)
index 122c1cf..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-BEGIN TRANSACTION;
-CREATE TABLE CONFERENCE ( id INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL
-    , title VARCHAR UNIQUE NOT NULL
-    , subtitle VARCHAR
-    , venue VARCHAR
-    , city VARCHAR NOT NULL
-    , start INTEGER NOT NULL
-    , end INTEGER NOT NULL
-    , days INTEGER
-    , day_change INTEGER
-    , timeslot_duration INTEGER
-    , active INTEGER DEFAULT 0
-    , url VARCHAR);
-
-CREATE TABLE TRACK ( id INTEGER  PRIMARY KEY AUTOINCREMENT  NOT NULL
-    , xid_conference INTEGER NOT NULL
-    , name VARCHAR NOT NULL
-    , UNIQUE (xid_conference, name));
-
-CREATE TABLE ROOM ( id INTEGER PRIMARY KEY AUTOINCREMENT  NOT NULL
-    , xid_conference INTEGER NOT NULL
-    , name VARCHAR NOT NULL
-    , picture VARCHAR NOT NULL
-    , UNIQUE (xid_conference, name));
-
-CREATE TABLE PERSON ( id INTEGER NOT NULL
-    , xid_conference INTEGER NOT NULL
-    , name VARCHAR NOT NULL
-    , UNIQUE (xid_conference, name)
-    , PRIMARY KEY (id, xid_conference)); 
-
-CREATE TABLE EVENT ( xid_conference INTEGER  NOT NULL
-    , id INTEGER NOT NULL
-    , start INTEGER NOT NULL
-    , duration INTEGER NOT NULL -- duration of the event in seconds
-    , xid_track INTEGER NOT NULL REFERENCES TRACK(id)
-    , type VARCHAR
-    , language VARCHAR
-    , tag VARCHAR
-    , title VARCHAR NOT NULL
-    , subtitle VARCHAR
-    , abstract VARCHAR
-    , description VARCHAR
-    , favourite INTEGER DEFAULT 0
-    , alarm INTEGER DEFAULT 0
-    , PRIMARY KEY (xid_conference ,id)
-    , FOREIGN KEY(xid_conference) REFERENCES CONFERENCE(id)
-    , FOREIGN KEY(xid_track) REFERENCES TRACK(id));
-
-CREATE TABLE EVENT_PERSON ( xid_conference INTEGER NOT NULL
-    , xid_event INTEGER NOT NULL
-    , xid_person INTEGER NOT NULL
-    , UNIQUE ( xid_conference , xid_event , xid_person ) ON CONFLICT REPLACE
-    , FOREIGN KEY(xid_conference) REFERENCES CONFERENCE(id)
-    , FOREIGN KEY(xid_conference, xid_event) REFERENCES EVENT(xid_conference, id)
-    , FOREIGN KEY(xid_conference, xid_person) REFERENCES PERSON(xid_conference, id));
-
-CREATE TABLE EVENT_ROOM ( xid_conference INTEGER NOT NULL
-    , xid_event INTEGER NOT NULL
-    , xid_room INTEGER NOT NULL
-    , UNIQUE ( xid_conference , xid_event , xid_room ) ON CONFLICT REPLACE
-    , FOREIGN KEY(xid_conference) REFERENCES CONFERENCE(id)
-    , FOREIGN KEY(xid_conference, xid_event) REFERENCES EVENT(xid_conference, id)
-    , FOREIGN KEY(xid_conference, xid_room) REFERENCES ROOM(xid_conference, id));
-
-CREATE TABLE LINK ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
-    , xid_conference INTEGER NOT NULL
-    , xid_event INTEGER NOT NULL
-    , name VARCHAR
-    , url VARCHAR NOT NULL
-    , UNIQUE ( xid_conference , xid_event , url ) ON CONFLICT REPLACE
-    , FOREIGN KEY(xid_conference) REFERENCES CONFERENCE(id)
-    , FOREIGN KEY(xid_conference, xid_event) REFERENCES EVENT(xid_conference, id));
-COMMIT;
index 03d8d30057937dd70dacfce743eeac8b880c0df6..faa1eac959bd397df6b41cd1f928bb7a9797026b 100644 (file)
@@ -1,6 +1,7 @@
 <!DOCTYPE RCC><RCC version="1.0">
 <qresource>
-    <file>create_tables.sql</file>
+    <file>dbschema001.sql</file>
+    <file>dbschema000to001.sql</file>
 </qresource>
 </RCC>
 
diff --git a/src/dbschema000.sql b/src/dbschema000.sql
new file mode 100644 (file)
index 0000000..122c1cf
--- /dev/null
@@ -0,0 +1,74 @@
+BEGIN TRANSACTION;
+CREATE TABLE CONFERENCE ( id INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL
+    , title VARCHAR UNIQUE NOT NULL
+    , subtitle VARCHAR
+    , venue VARCHAR
+    , city VARCHAR NOT NULL
+    , start INTEGER NOT NULL
+    , end INTEGER NOT NULL
+    , days INTEGER
+    , day_change INTEGER
+    , timeslot_duration INTEGER
+    , active INTEGER DEFAULT 0
+    , url VARCHAR);
+
+CREATE TABLE TRACK ( id INTEGER  PRIMARY KEY AUTOINCREMENT  NOT NULL
+    , xid_conference INTEGER NOT NULL
+    , name VARCHAR NOT NULL
+    , UNIQUE (xid_conference, name));
+
+CREATE TABLE ROOM ( id INTEGER PRIMARY KEY AUTOINCREMENT  NOT NULL
+    , xid_conference INTEGER NOT NULL
+    , name VARCHAR NOT NULL
+    , picture VARCHAR NOT NULL
+    , UNIQUE (xid_conference, name));
+
+CREATE TABLE PERSON ( id INTEGER NOT NULL
+    , xid_conference INTEGER NOT NULL
+    , name VARCHAR NOT NULL
+    , UNIQUE (xid_conference, name)
+    , PRIMARY KEY (id, xid_conference)); 
+
+CREATE TABLE EVENT ( xid_conference INTEGER  NOT NULL
+    , id INTEGER NOT NULL
+    , start INTEGER NOT NULL
+    , duration INTEGER NOT NULL -- duration of the event in seconds
+    , xid_track INTEGER NOT NULL REFERENCES TRACK(id)
+    , type VARCHAR
+    , language VARCHAR
+    , tag VARCHAR
+    , title VARCHAR NOT NULL
+    , subtitle VARCHAR
+    , abstract VARCHAR
+    , description VARCHAR
+    , favourite INTEGER DEFAULT 0
+    , alarm INTEGER DEFAULT 0
+    , PRIMARY KEY (xid_conference ,id)
+    , FOREIGN KEY(xid_conference) REFERENCES CONFERENCE(id)
+    , FOREIGN KEY(xid_track) REFERENCES TRACK(id));
+
+CREATE TABLE EVENT_PERSON ( xid_conference INTEGER NOT NULL
+    , xid_event INTEGER NOT NULL
+    , xid_person INTEGER NOT NULL
+    , UNIQUE ( xid_conference , xid_event , xid_person ) ON CONFLICT REPLACE
+    , FOREIGN KEY(xid_conference) REFERENCES CONFERENCE(id)
+    , FOREIGN KEY(xid_conference, xid_event) REFERENCES EVENT(xid_conference, id)
+    , FOREIGN KEY(xid_conference, xid_person) REFERENCES PERSON(xid_conference, id));
+
+CREATE TABLE EVENT_ROOM ( xid_conference INTEGER NOT NULL
+    , xid_event INTEGER NOT NULL
+    , xid_room INTEGER NOT NULL
+    , UNIQUE ( xid_conference , xid_event , xid_room ) ON CONFLICT REPLACE
+    , FOREIGN KEY(xid_conference) REFERENCES CONFERENCE(id)
+    , FOREIGN KEY(xid_conference, xid_event) REFERENCES EVENT(xid_conference, id)
+    , FOREIGN KEY(xid_conference, xid_room) REFERENCES ROOM(xid_conference, id));
+
+CREATE TABLE LINK ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL
+    , xid_conference INTEGER NOT NULL
+    , xid_event INTEGER NOT NULL
+    , name VARCHAR
+    , url VARCHAR NOT NULL
+    , UNIQUE ( xid_conference , xid_event , url ) ON CONFLICT REPLACE
+    , FOREIGN KEY(xid_conference) REFERENCES CONFERENCE(id)
+    , FOREIGN KEY(xid_conference, xid_event) REFERENCES EVENT(xid_conference, id));
+COMMIT;
diff --git a/src/dbschema000to001.sql b/src/dbschema000to001.sql
new file mode 100644 (file)
index 0000000..9ef3138
--- /dev/null
@@ -0,0 +1,118 @@
+BEGIN TRANSACTION;
+
+ALTER TABLE conference RENAME TO conference_old;
+ALTER TABLE track RENAME TO track_old;
+ALTER TABLE room RENAME TO room_old;
+ALTER TABLE person RENAME TO person_old;
+ALTER TABLE event RENAME TO event_old;
+ALTER TABLE event_person RENAME TO event_person_old;
+ALTER TABLE event_room RENAME TO event_room_old;
+ALTER TABLE link RENAME TO link_old;
+
+CREATE TABLE conference (
+       id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+       title VARCHAR NOT NULL,
+       subtitle VARCHAR,
+       venue VARCHAR,
+       city VARCHAR,
+       start INTEGER NOT NULL, -- timezone-less timestamp (Unix Epoch)
+       end INTEGER NOT NULL,   -- timezone-less timestamp (Unix Epoch)
+       day_change INTEGER,
+       timeslot_duration INTEGER,
+       active INTEGER DEFAULT 0,
+       url VARCHAR
+);
+
+CREATE TABLE track (
+       id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+       xid_conference INTEGER NOT NULL REFERENCES conference(id),
+       name VARCHAR NOT NULL,
+       UNIQUE (xid_conference, name)
+);
+
+CREATE TABLE room (
+       id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+       xid_conference INTEGER NOT NULL REFERENCES conference(id),
+       name VARCHAR NOT NULL,
+       picture VARCHAR,
+       UNIQUE (xid_conference, name)
+);
+
+CREATE TABLE person (
+       id INTEGER NOT NULL,
+       xid_conference INTEGER NOT NULL REFERENCES conference(id),
+       name VARCHAR NOT NULL,
+       PRIMARY KEY (id, xid_conference)
+); 
+
+CREATE TABLE event (
+       xid_conference INTEGER NOT NULL REFERENCES conference(id),
+       id INTEGER NOT NULL,
+       start INTEGER NOT NULL,
+       duration INTEGER NOT NULL, -- duration of the event in seconds
+       xid_track INTEGER NOT NULL REFERENCES track(id),
+       type VARCHAR,
+       language VARCHAR,
+       tag VARCHAR,
+       title VARCHAR NOT NULL,
+       subtitle VARCHAR,
+       abstract VARCHAR,
+       description VARCHAR,
+       favourite INTEGER DEFAULT 0,
+       alarm INTEGER DEFAULT 0,
+       PRIMARY KEY (xid_conference, id)
+);
+
+CREATE TABLE event_person (
+       xid_conference INTEGER NOT NULL,
+       xid_event INTEGER NOT NULL,
+       xid_person INTEGER NOT NULL,
+       UNIQUE (xid_conference, xid_event, xid_person ) ON CONFLICT REPLACE,
+       FOREIGN KEY(xid_conference) REFERENCES conference(id),
+       FOREIGN KEY(xid_conference, xid_event) REFERENCES event(xid_conference, id),
+       FOREIGN KEY(xid_conference, xid_person) REFERENCES person(xid_conference, id)
+);
+
+CREATE TABLE event_room (
+       xid_conference INTEGER NOT NULL,
+       xid_event INTEGER NOT NULL,
+       xid_room INTEGER NOT NULL,
+       UNIQUE (xid_conference, xid_event, xid_room) ON CONFLICT REPLACE,
+       FOREIGN KEY(xid_conference) REFERENCES conference(id),
+       FOREIGN KEY(xid_conference, xid_event) REFERENCES event(xid_conference, id),
+       FOREIGN KEY(xid_conference, xid_room) REFERENCES room(xid_conference, id)
+);
+
+CREATE TABLE link (
+       id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+       xid_conference INTEGER NOT NULL,
+       xid_event INTEGER NOT NULL,
+       name VARCHAR,
+       url VARCHAR NOT NULL,
+       UNIQUE (xid_conference, xid_event , url) ON CONFLICT REPLACE,
+       FOREIGN KEY(xid_conference) REFERENCES conference(id),
+       FOREIGN KEY(xid_conference, xid_event) REFERENCES event(xid_conference, id)
+);
+
+INSERT INTO conference SELECT id, title, subtitle, venue, city, start, end, day_change, timeslot_duration, active, url FROM conference_old;
+INSERT INTO track SELECT * FROM track_old;
+INSERT INTO room SELECT * FROM room_old;
+INSERT INTO person SELECT * FROM person_old;
+INSERT INTO event SELECT * FROM event_old;
+INSERT INTO event_person SELECT * FROM event_person_old;
+INSERT INTO event_room SELECT * FROM event_room_old;
+INSERT INTO link SELECT * FROM link_old;
+
+DROP TABLE conference_old;
+DROP TABLE track_old;
+DROP TABLE room_old;
+DROP TABLE person_old;
+DROP TABLE event_old;
+DROP TABLE event_person_old;
+DROP TABLE event_room_old;
+DROP TABLE link_old;
+
+PRAGMA user_version=1;
+
+COMMIT;
+
diff --git a/src/dbschema001.sql b/src/dbschema001.sql
new file mode 100644 (file)
index 0000000..eca2c39
--- /dev/null
@@ -0,0 +1,90 @@
+BEGIN TRANSACTION;
+
+CREATE TABLE conference (
+       id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+       title VARCHAR NOT NULL,
+       subtitle VARCHAR,
+       venue VARCHAR,
+       city VARCHAR,
+       start INTEGER NOT NULL, -- timezone-less timestamp (Unix Epoch)
+       end INTEGER NOT NULL,   -- timezone-less timestamp (Unix Epoch)
+       day_change INTEGER,
+       timeslot_duration INTEGER,
+       active INTEGER DEFAULT 0,
+       url VARCHAR
+);
+
+CREATE TABLE track (
+       id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+       xid_conference INTEGER NOT NULL REFERENCES conference(id),
+       name VARCHAR NOT NULL,
+       UNIQUE (xid_conference, name)
+);
+
+CREATE TABLE room (
+       id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+       xid_conference INTEGER NOT NULL REFERENCES conference(id),
+       name VARCHAR NOT NULL,
+       picture VARCHAR,
+       UNIQUE (xid_conference, name)
+);
+
+CREATE TABLE person (
+       id INTEGER NOT NULL,
+       xid_conference INTEGER NOT NULL REFERENCES conference(id),
+       name VARCHAR NOT NULL,
+       PRIMARY KEY (id, xid_conference)
+); 
+
+CREATE TABLE event (
+       xid_conference INTEGER NOT NULL REFERENCES conference(id),
+       id INTEGER NOT NULL,
+       start INTEGER NOT NULL,    -- timezone-less timestamp (Unix Epoch)
+       duration INTEGER NOT NULL, -- duration of the event in seconds
+       xid_track INTEGER NOT NULL REFERENCES track(id),
+       type VARCHAR,
+       language VARCHAR,
+       tag VARCHAR,
+       title VARCHAR NOT NULL,
+       subtitle VARCHAR,
+       abstract VARCHAR,
+       description VARCHAR,
+       favourite INTEGER DEFAULT 0,
+       alarm INTEGER DEFAULT 0,
+       PRIMARY KEY (xid_conference, id)
+);
+
+CREATE TABLE event_person (
+       xid_conference INTEGER NOT NULL,
+       xid_event INTEGER NOT NULL,
+       xid_person INTEGER NOT NULL,
+       UNIQUE (xid_conference, xid_event, xid_person ) ON CONFLICT REPLACE,
+       FOREIGN KEY(xid_conference) REFERENCES conference(id),
+       FOREIGN KEY(xid_conference, xid_event) REFERENCES event(xid_conference, id),
+       FOREIGN KEY(xid_conference, xid_person) REFERENCES person(xid_conference, id)
+);
+
+CREATE TABLE event_room (
+       xid_conference INTEGER NOT NULL,
+       xid_event INTEGER NOT NULL,
+       xid_room INTEGER NOT NULL,
+       UNIQUE (xid_conference, xid_event, xid_room) ON CONFLICT REPLACE,
+       FOREIGN KEY(xid_conference) REFERENCES conference(id),
+       FOREIGN KEY(xid_conference, xid_event) REFERENCES event(xid_conference, id),
+       FOREIGN KEY(xid_conference, xid_room) REFERENCES room(xid_conference, id)
+);
+
+CREATE TABLE link (
+       id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
+       xid_conference INTEGER NOT NULL,
+       xid_event INTEGER NOT NULL,
+       name VARCHAR,
+       url VARCHAR NOT NULL,
+       UNIQUE (xid_conference, xid_event , url) ON CONFLICT REPLACE,
+       FOREIGN KEY(xid_conference) REFERENCES conference(id),
+       FOREIGN KEY(xid_conference, xid_event) REFERENCES event(xid_conference, id)
+);
+
+PRAGMA user_version=1;
+
+COMMIT;
index 7d223aa7d4a80110fd66882bc757fc579bda9de6..cd4c9a142200f52bcd2d19d37c5521173e090237 100644 (file)
@@ -4,7 +4,7 @@
 # USAGE: include(./global.pri)
 
 # VERSION
-VERSION = 0.5.5
+VERSION = 0.6.0
 DEFINES += VERSION=\\\"$$VERSION\\\"
 
 # Define 'MAEMO' specific CONFIG/DEFINE
index ee39ef4103ac29ad6a8e75e3ee3d9bd38ecc731a..99fee956631bc34cf7e7bf189500ed01a0c8aa1d 100644 (file)
@@ -137,7 +137,7 @@ p, li { white-space: pre-wrap; }
 &lt;p style=&quot; margin-top:16px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:x-large; font-weight:600;&quot;&gt;Copyright and license&lt;/span&gt;&lt;/p&gt;
 &lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;ConfClerk 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 2, or (at your option) any later version.&lt;/p&gt;
 &lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;ConfClerk 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.&lt;/p&gt;
-&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Copyright (C) 2010 Ixonos Plc.&lt;br /&gt;Copyright (C) 2011-2012 Philipp Spitzer &amp;amp; gregor herrmann&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+&lt;p style=&quot; margin-top:12px; margin-bottom:12px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Copyright (C) 2010 Ixonos Plc.&lt;br /&gt;Copyright (C) 2011-2013 Philipp Spitzer &amp;amp; gregor herrmann&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
          </property>
          <property name="textFormat">
           <enum>Qt::RichText</enum>
index 718999ce62e048b167ce06ce08184c78a52e5269..b61aa486aa822f182f40b3e83bee6bc0d01b055b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -103,8 +103,8 @@ void ConferenceEditor::addClicked()
 {
     UrlInputDialog url_input(this);
     switch (url_input.exec()) {
-    case UrlInputDialog::HaveUrl: emit haveConferenceUrl(url_input.url()); break;
-    case UrlInputDialog::HaveFile: emit haveConferenceFile(url_input.url()); break;
+    case UrlInputDialog::HaveUrl: emit haveConferenceUrl(url_input.url(), 0); break;
+    case UrlInputDialog::HaveFile: emit haveConferenceFile(url_input.url(), 0); break;
     case UrlInputDialog::Cancel: return;
     }
 }
@@ -143,21 +143,21 @@ void ConferenceEditor::changeUrlClicked()
 
 void ConferenceEditor::refreshClicked()
 {
-    if (selected_id < 0) return;
+    if (selected_id <= 0) return;
     const Conference& selectedConf = Conference::getById(selected_id);
     QString url = selectedConf.url();
 
     if (url.isEmpty()) {
         static const QString format("Schedule URL for %1 is not set. Enter the schedule URL:");
         bool ok;
-        QString url = QInputDialog::getText(this, "URL Input", format.arg(selectedConf.title()), QLineEdit::Normal, QString(), &ok);
+        url = QInputDialog::getText(this, "URL Input", format.arg(selectedConf.title()), QLineEdit::Normal, QString(), &ok);
         if (!ok) return;
         // first save it, to remain if fetch fails
         emit changeUrlRequested(selected_id, url);
     }
     // fetch
     importStarted(); // just to show the progress bar
-    emit haveConferenceUrl(url);
+    emit haveConferenceUrl(url, selected_id);
 }
 
 void ConferenceEditor::importStarted()
@@ -178,8 +178,7 @@ void ConferenceEditor::showParsingProgress(int progress)
     QApplication::processEvents();
 }
 
-void ConferenceEditor::importFinished(const QString& title)
-{
+void ConferenceEditor::importFinished(int conferenceId) {
     addBtn->show();
     // removeItem should be shown later, but it takes some time,
     // and not looks good
@@ -190,14 +189,10 @@ void ConferenceEditor::importFinished(const QString& title)
 
     QApplication::processEvents();
 
-    int num = model->rowCount();
-    for (int i = 0; i < num; i++) {
-        QModelIndex item = model->index(i, 0);
-        if (model->data(item) == title) {
-            emit wantCurrent(item, QItemSelectionModel::SelectCurrent);
-            return;
-        }
-    }
-    itemSelected(QModelIndex(), QModelIndex());
+    QModelIndex item = model->indexFromId(conferenceId);
+    if (item.isValid())
+        emit wantCurrent(item, QItemSelectionModel::SelectCurrent);
+    else
+        itemSelected(QModelIndex(), QModelIndex());
 }
 
index 39af759fd62b8fa6310a661b7471e9b1cab00658..6d39b749a70354b3c7d2fa003aa3addadddaa3cb 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -47,15 +47,15 @@ signals:
     void haveConferenceSelected(int id);
     void noneConferenceSelected();
 
-    void haveConferenceUrl(const QString& url);
-    void haveConferenceFile(const QString& path);
+    void haveConferenceUrl(const QString& url, int conferenceId);
+    void haveConferenceFile(const QString& path, int conferenceId);
     void removeConferenceRequested(int id);
     void changeUrlRequested(int, const QString&);
 
     void wantCurrent(const QModelIndex&, QItemSelectionModel::SelectionFlags);
 public slots:
     void importStarted();
-    void importFinished(const QString& title);
+    void importFinished(int conferenceId);
     void conferenceRemoved();
     void showParsingProgress(int);
 private slots:
index f0f3ed571476cc03145beaa4d3cae45c08f1eb54..25ba50f980d9df89b652533df2109d6fc8a510e2 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index b7dad73045b089c881540a72d12ad1ec96c0cff3..99f1f3c40499e4907609717b0362c350e25cdeab 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 187e2a313c185e7c0713774b094308c7f6b9de62..9fcb9c2a9de7619bd807187c37950379e47867f7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index fa79c6797208655cd76902881fa995d50801e169..ae4a59565462dd9a27d42b56ad569af75aab081d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 3e6a033930d69d7ff4ebb11956bda208f6153017..50e1129a486e13cfcfc67da0df64571f01565a1b 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 889e0dbf57903c847b8d7f26c8929c08e576a922..eb11acfd53a888f1df131d27253763836aeaf216 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 4fd5b6ea607c1c7b4a34cea0288a799752010ee7..313853b84837856f208f1a4ac081fb6ffbd63599 100644 (file)
    </property>
    <item>
     <widget class="QToolButton" name="nextDayButton">
+     <property name="toolTip">
+      <string>Go to next day (Ctrl+Up)</string>
+     </property>
+     <property name="shortcut">
+      <string>Ctrl+Up</string>
+     </property>
      <property name="autoRaise">
       <bool>true</bool>
      </property>
    </item>
    <item>
     <widget class="QToolButton" name="prevDayButton">
+     <property name="toolTip">
+      <string>Go to previous day (Ctrl+Down)</string>
+     </property>
+     <property name="shortcut">
+      <string>Ctrl+Down</string>
+     </property>
      <property name="autoRaise">
       <bool>true</bool>
      </property>
index 5688053308320a821a1afea1b15779fe95278257..4a7faac79389162558e79bb47b6b4ddcb67bb0c0 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index d88d79a8f27ec34ab1ad42bf81681881911e533a..933077e1cc6e0392ead147d3532fa5d50956ac96 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 1c289136a38e224a6bb819b4613d25de6aad802c..6fa8336d11708fde5c0007b06e7d91663bc80982 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 731aa1be073e9a207c03e6b80e204d843f216ec8..c3051db1518eb37159efd2fc8140a48af6927358 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index ff3ceccb13f35e3f933faaf132f354ef17737f43..eb006ce55ce822d6c759ab67ff7663b56e25d677 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
 
 #ifdef MAEMO
 #include "alarm.h"
+#include "appsettings.h"
 #endif
 
-EventDialog::EventDialog(const int &aEventId, QWidget *aParent)
-    : QDialog(aParent)
-    , mEventId(aEventId)
-{
+EventDialog::EventDialog(int conferenceId, int eventId, QWidget *parent): QDialog(parent), mConferenceId(conferenceId), mEventId(eventId) {
     setupUi(this);
 
 #ifdef MAEMO
     showFullScreen();
-#else
-    alarmButton->hide();
 #endif
 
-    Event event = Event::getById(mEventId,Conference::activeConference());
+    Event event = Event::getById(mEventId, mConferenceId);
+
+    QString info;
+    // title
+    info.append(QString("<h1>%1</h1>\n").arg(event.title()));
+
+    // persons
+    info += QString("<h2>%1</h2>\n").arg(tr("Persons"));
+    info += QString("<p>%1</p>\n").arg(event.persons().join(", "));
+
+    // abstract
+    info += QString("<h2>%1</h2>\n").arg(tr("Abstract"));
+    info += QString("<p>%1</p>\n").arg(event.abstract());
+
+    // description
+    info += QString("<h2>%1</h2>\n").arg(tr("Description"));
+    info += QString("<p>%1</p>\n").arg(event.description());
+
+    // links
+    info += QString("<h2>%1</h2>\n<ul>\n").arg(tr("Links"));
+    QMapIterator<QString, QString> i(event.links());
+    while (i.hasNext()) {
+        i.next();
+        QString url(i.value());
+        QString name(i.key());
+        if (url.isEmpty() || url == "http://") continue;
+        if (name.isEmpty()) name = url;
+        info += QString("<li><a href=\"%1\">%2</a></li>\n").arg(url, name);
+    }
+    info += QString("</ul>\n");
+    eventInfoTextBrowser->setHtml(info);
 
-    title->setText(event.title());
-    persons->setText(event.persons().join(" and "));
-    abstract->setText(event.abstract());
-    description->setText(event.description());
-    QStringList linksText = static_cast<QStringList>(event.links().values());
-    for (QStringList::iterator linkIterator = linksText.begin(); linkIterator != linksText.end(); ++linkIterator)
-        *linkIterator = QString("<a href=\"%1\">%1</a>").arg(*linkIterator);
-    links->setText(linksText.join("<br/>"));
+    // make sure colours are the same as usual
+    eventInfoTextBrowser->setPalette(qApp->palette());
+    // reduce font size, on maemo
+#ifdef MAEMO
+    QFont font = eventInfoTextBrowser->font();
+    font.setPointSizeF(font.pointSizeF()*0.8);
+    eventInfoTextBrowser->setFont(font);
+#endif
 
     connect(favouriteButton, SIGNAL(clicked()), SLOT(favouriteClicked()));
     connect(alarmButton, SIGNAL(clicked()), SLOT(alarmClicked()));
@@ -65,9 +91,9 @@ EventDialog::EventDialog(const int &aEventId, QWidget *aParent)
 
 void EventDialog::favouriteClicked()
 {
-    Event event = Event::getById(mEventId,Conference::activeConference());
+    Event event = Event::getById(mEventId, mConferenceId);
 
-    QList<Event> conflicts = Event::conflictEvents(event.id(),Conference::activeConference());
+    QList<Event> conflicts = Event::conflictEvents(event.id(), mConferenceId);
     if(event.isFavourite())
     {
         event.setFavourite(false);
@@ -83,7 +109,7 @@ void EventDialog::favouriteClicked()
     if(event.isFavourite())
     {
         // event has became 'favourite' and so 'conflicts' list may have changed
-        conflicts = Event::conflictEvents(event.id(),Conference::activeConference());
+        conflicts = Event::conflictEvents(event.id(), mConferenceId);
     }
 
     // have to emit 'eventChanged' signal on all events in conflict
@@ -97,14 +123,14 @@ void EventDialog::favouriteClicked()
 
 void EventDialog::alarmClicked()
 {
-    Event event = Event::getById(mEventId,Conference::activeConference());
+    Event event = Event::getById(mEventId, mConferenceId);
 
     if(event.hasAlarm())
     {
         event.setHasAlarm(false); // update DB
         alarmButton->setIcon(QIcon(":/icons/alarm-off.png"));
 #ifdef MAEMO
-        // remove alarm from the 'alarmd' alrms list
+        // remove alarm from the 'alarmd' alarms list
         Alarm alarm;
         alarm.deleteAlarm(event.conferenceId(), event.id());
         // TODO: test if removing was successfull
@@ -117,7 +143,7 @@ void EventDialog::alarmClicked()
 #ifdef MAEMO
         // add alarm to the 'alarmd'
         Alarm alarm;
-        alarm.addAlarm(event.conferenceId(), event.id(), event.title(), event.start().addSecs(PRE_EVENT_ALARM_SEC));
+        alarm.addAlarm(event.conferenceId(), event.id(), event.title(), event.start().addSecs(-AppSettings::preEventAlarmSec()));
 #endif /* MAEMO */
     }
     event.update("alarm");
index bcb70cdf786d52a86721ebac978b437a4d8eef94..7640f3594b938ea720655245593cb4ead773ce31 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
 
 #include <QDialog>
 #include "ui_eventdialog.h"
-#include <event.h>
+#include "event.h"
 
 class EventDialog : public QDialog, Ui::EventDialog
 { 
     Q_OBJECT
 public:
-    EventDialog(const int &aEventId, QWidget *aParent = NULL);
+    EventDialog(int conferencdId, int eventId, QWidget *parent = 0);
     ~EventDialog() {}
 private slots:
     void favouriteClicked();
@@ -36,6 +36,7 @@ private slots:
 signals:
     void eventChanged(int aEventId, bool favouriteChanged); // emited when user changes some event details, eg. sets it Favourite
 private:
+    int mConferenceId;
     int mEventId;
 };
 
index 1ab6a55a26d0aedbd9fdcdf337ed03ae3c547d76..73e0f90320e51aa8056e1cfa1da5741de37312d8 100644 (file)
@@ -6,8 +6,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>485</width>
-    <height>368</height>
+    <width>539</width>
+    <height>404</height>
    </rect>
   </property>
   <property name="sizePolicy">
   <property name="autoFillBackground">
    <bool>false</bool>
   </property>
-  <layout class="QGridLayout" name="gridLayout">
-   <item row="0" column="0">
-    <layout class="QVBoxLayout" name="verticalLayout">
+  <layout class="QVBoxLayout" name="verticalLayout">
+   <item>
+    <widget class="QTextBrowser" name="eventInfoTextBrowser">
+     <property name="openExternalLinks">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <layout class="QHBoxLayout" name="horizontalLayout">
      <item>
-      <widget class="QLabel" name="title">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
-       </property>
-       <property name="font">
-        <font>
-         <weight>75</weight>
-         <bold>true</bold>
-         <underline>true</underline>
-        </font>
-       </property>
+      <widget class="QToolButton" name="alarmButton">
        <property name="text">
-        <string>Title goes here</string>
+        <string>...</string>
        </property>
-       <property name="alignment">
-        <set>Qt::AlignCenter</set>
+       <property name="icon">
+        <iconset resource="../icons.qrc">
+         <normaloff>:/icons/alarm-off.png</normaloff>:/icons/alarm-off.png</iconset>
        </property>
-       <property name="wordWrap">
-        <bool>true</bool>
+       <property name="iconSize">
+        <size>
+         <width>32</width>
+         <height>32</height>
+        </size>
+       </property>
+       <property name="shortcut">
+        <string>CapsLock</string>
        </property>
       </widget>
      </item>
      <item>
-      <widget class="QScrollArea" name="scrollArea">
-       <property name="sizePolicy">
-        <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
-         <horstretch>0</horstretch>
-         <verstretch>0</verstretch>
-        </sizepolicy>
+      <widget class="QToolButton" name="favouriteButton">
+       <property name="text">
+        <string>...</string>
        </property>
-       <property name="widgetResizable">
-        <bool>true</bool>
+       <property name="icon">
+        <iconset resource="../icons.qrc">
+         <normaloff>:/icons/favourite-off.png</normaloff>:/icons/favourite-off.png</iconset>
+       </property>
+       <property name="iconSize">
+        <size>
+         <width>32</width>
+         <height>32</height>
+        </size>
        </property>
-       <widget class="QWidget" name="scrollAreaWidgetContents">
-        <property name="geometry">
-         <rect>
-          <x>0</x>
-          <y>-1</y>
-          <width>446</width>
-          <height>262</height>
-         </rect>
-        </property>
-        <layout class="QGridLayout" name="gridLayout_2">
-         <item row="0" column="0">
-          <widget class="QWidget" name="content" native="true">
-           <property name="sizePolicy">
-            <sizepolicy hsizetype="Preferred" vsizetype="Expanding">
-             <horstretch>0</horstretch>
-             <verstretch>0</verstretch>
-            </sizepolicy>
-           </property>
-           <layout class="QVBoxLayout" name="verticalLayout_2">
-            <item>
-             <widget class="QGroupBox" name="personsGB">
-              <property name="sizePolicy">
-               <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
-                <horstretch>0</horstretch>
-                <verstretch>0</verstretch>
-               </sizepolicy>
-              </property>
-              <property name="font">
-               <font>
-                <weight>75</weight>
-                <bold>true</bold>
-               </font>
-              </property>
-              <property name="title">
-               <string>Persons</string>
-              </property>
-              <layout class="QVBoxLayout" name="verticalLayout_3">
-               <item>
-                <widget class="QLabel" name="persons">
-                 <property name="font">
-                  <font>
-                   <weight>50</weight>
-                   <bold>false</bold>
-                  </font>
-                 </property>
-                 <property name="text">
-                  <string>PERSONS</string>
-                 </property>
-                 <property name="wordWrap">
-                  <bool>true</bool>
-                 </property>
-                 <property name="openExternalLinks">
-                  <bool>true</bool>
-                 </property>
-                 <property name="textInteractionFlags">
-                  <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
-                 </property>
-                </widget>
-               </item>
-              </layout>
-             </widget>
-            </item>
-            <item>
-             <widget class="QGroupBox" name="abstractGB">
-              <property name="sizePolicy">
-               <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
-                <horstretch>0</horstretch>
-                <verstretch>0</verstretch>
-               </sizepolicy>
-              </property>
-              <property name="font">
-               <font>
-                <weight>75</weight>
-                <bold>true</bold>
-               </font>
-              </property>
-              <property name="title">
-               <string>Abstract</string>
-              </property>
-              <layout class="QVBoxLayout" name="verticalLayout_4">
-               <item>
-                <widget class="QLabel" name="abstract">
-                 <property name="font">
-                  <font>
-                   <weight>50</weight>
-                   <bold>false</bold>
-                  </font>
-                 </property>
-                 <property name="text">
-                  <string>ABSTRACT</string>
-                 </property>
-                 <property name="wordWrap">
-                  <bool>true</bool>
-                 </property>
-                 <property name="openExternalLinks">
-                  <bool>true</bool>
-                 </property>
-                 <property name="textInteractionFlags">
-                  <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
-                 </property>
-                </widget>
-               </item>
-              </layout>
-             </widget>
-            </item>
-            <item>
-             <widget class="QGroupBox" name="descriptionGB">
-              <property name="font">
-               <font>
-                <weight>75</weight>
-                <bold>true</bold>
-               </font>
-              </property>
-              <property name="title">
-               <string>Description</string>
-              </property>
-              <layout class="QVBoxLayout" name="verticalLayout_5">
-               <item>
-                <widget class="QLabel" name="description">
-                 <property name="sizePolicy">
-                  <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
-                   <horstretch>0</horstretch>
-                   <verstretch>0</verstretch>
-                  </sizepolicy>
-                 </property>
-                 <property name="font">
-                  <font>
-                   <weight>50</weight>
-                   <bold>false</bold>
-                  </font>
-                 </property>
-                 <property name="text">
-                  <string>DESCRIPTION</string>
-                 </property>
-                 <property name="wordWrap">
-                  <bool>true</bool>
-                 </property>
-                 <property name="openExternalLinks">
-                  <bool>true</bool>
-                 </property>
-                 <property name="textInteractionFlags">
-                  <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
-                 </property>
-                </widget>
-               </item>
-              </layout>
-             </widget>
-            </item>
-            <item>
-             <widget class="QGroupBox" name="linksGB">
-              <property name="font">
-               <font>
-                <weight>75</weight>
-                <bold>true</bold>
-               </font>
-              </property>
-              <property name="title">
-               <string>Links</string>
-              </property>
-              <layout class="QVBoxLayout" name="verticalLayout_6">
-               <item>
-                <widget class="QLabel" name="links">
-                 <property name="sizePolicy">
-                  <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
-                   <horstretch>0</horstretch>
-                   <verstretch>0</verstretch>
-                  </sizepolicy>
-                 </property>
-                 <property name="font">
-                  <font>
-                   <weight>50</weight>
-                   <bold>false</bold>
-                  </font>
-                 </property>
-                 <property name="text">
-                  <string>LINKS</string>
-                 </property>
-                 <property name="textFormat">
-                  <enum>Qt::RichText</enum>
-                 </property>
-                 <property name="wordWrap">
-                  <bool>true</bool>
-                 </property>
-                 <property name="openExternalLinks">
-                  <bool>true</bool>
-                 </property>
-                 <property name="textInteractionFlags">
-                  <set>Qt::LinksAccessibleByKeyboard|Qt::LinksAccessibleByMouse|Qt::TextBrowserInteraction|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
-                 </property>
-                </widget>
-               </item>
-              </layout>
-             </widget>
-            </item>
-           </layout>
-          </widget>
-         </item>
-        </layout>
-       </widget>
       </widget>
      </item>
      <item>
-      <spacer name="verticalSpacer_2">
+      <spacer name="horizontalSpacer">
        <property name="orientation">
-        <enum>Qt::Vertical</enum>
-       </property>
-       <property name="sizeType">
-        <enum>QSizePolicy::Minimum</enum>
+        <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
-         <width>20</width>
-         <height>10</height>
+         <width>40</width>
+         <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item>
-      <layout class="QHBoxLayout" name="horizontalLayout">
-       <item>
-        <widget class="QToolButton" name="alarmButton">
-         <property name="text">
-          <string>...</string>
-         </property>
-         <property name="icon">
-          <iconset resource="../icons.qrc">
-           <normaloff>:/icons/alarm-off.png</normaloff>:/icons/alarm-off.png</iconset>
-         </property>
-         <property name="iconSize">
-          <size>
-           <width>32</width>
-           <height>32</height>
-          </size>
-         </property>
-         <property name="shortcut">
-          <string>CapsLock</string>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <widget class="QToolButton" name="favouriteButton">
-         <property name="text">
-          <string>...</string>
-         </property>
-         <property name="icon">
-          <iconset resource="../icons.qrc">
-           <normaloff>:/icons/favourite-off.png</normaloff>:/icons/favourite-off.png</iconset>
-         </property>
-         <property name="iconSize">
-          <size>
-           <width>32</width>
-           <height>32</height>
-          </size>
-         </property>
-        </widget>
-       </item>
-       <item>
-        <spacer name="horizontalSpacer">
-         <property name="orientation">
-          <enum>Qt::Horizontal</enum>
-         </property>
-         <property name="sizeHint" stdset="0">
-          <size>
-           <width>40</width>
-           <height>20</height>
-          </size>
-         </property>
-        </spacer>
-       </item>
-       <item>
-        <widget class="QPushButton" name="okButton">
-         <property name="text">
-          <string>OK</string>
-         </property>
-        </widget>
-       </item>
-      </layout>
+      <widget class="QPushButton" name="okButton">
+       <property name="text">
+        <string>OK</string>
+       </property>
+      </widget>
      </item>
     </layout>
    </item>
index 1d13e408e811752c6e6754e859b37ea819661c02..034af37d86506d2bde5f7c2f5e580d427207fbfa 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 1622027b472ab4b8bb36883f1f6248103ad4dd67..dd264ce30d283080f0876826c1d57b4a6ca8122a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 67cf5bd168ed8894edcfff3910490909611dd579..7f4608be73ba5660c2ade9b8e8336d5d2bd4d736 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
 #include <QNetworkAccessManager>
 #include <QNetworkReply>
 
-#include <sqlengine.h>
+#include "sqlengine.h"
 
-#include <track.h>
-#include <eventmodel.h>
-#include <delegate.h>
+#include "track.h"
+#include "eventmodel.h"
+#include "delegate.h"
+#include "room.h"
 
-#include <conference.h>
+#include "conference.h"
 
 #include <QDialog>
 #include <QMessageBox>
 
 #include "ui_about.h"
-#include <eventdialog.h>
+#include "eventdialog.h"
 #include "daynavigatorwidget.h"
 #include "settingsdialog.h"
 #include "conferenceeditor.h"
 #include "schedulexmlparser.h"
 #include "errormessage.h"
 
-#include <tabcontainer.h>
-#include <appsettings.h>
+#include "tabcontainer.h"
+#include "appsettings.h"
 
 const QString PROXY_USERNAME;
 const QString PROXY_PASSWD;
 
-MainWindow::MainWindow(int aEventId, QWidget *aParent)
-    : QMainWindow(aParent)
-    , conferenceModel(new ConferenceModel(this))
-    , mXmlParser(new ScheduleXmlParser(this))
-    , mNetworkAccessManager(new QNetworkAccessManager(this))
-{
+MainWindow::MainWindow(QWidget* parent): QMainWindow(parent) {
     setupUi(this);
 
+    // Open database
+    sqlEngine = new SqlEngine(this);
+    searchTabContainer->setSqlEngine(sqlEngine);
+    connect(sqlEngine, SIGNAL(dbError(QString)), this, SLOT(showError(QString)));
+    sqlEngine->open();
+    sqlEngine->createOrUpdateDbSchema();
+
+    conferenceModel = new ConferenceModel(this);
+    mXmlParser = new ScheduleXmlParser(sqlEngine, this);
+    mNetworkAccessManager = new QNetworkAccessManager(this);
+    systemTrayIcon = new QSystemTrayIcon(qApp->windowIcon(), this);
+    alarmTimer = new QTimer(this);
+
+    alarmTimer->setInterval(60000);
+    alarmTimer->start();
     saved_title = windowTitle();
 
 #ifdef N810
@@ -69,12 +80,6 @@ MainWindow::MainWindow(int aEventId, QWidget *aParent)
     if(!AppSettings::contains("proxyIsDirectConnection"))
         AppSettings::setDirectConnection(true);
 
-    /*
-    if(AppSettings::isDirectConnection())
-    {
-        qDebug() << "Setting-up proxy: " << AppSettings::proxyAddress() << ":" << AppSettings::proxyPort();
-    }
-    */
     QNetworkProxy proxy(
             AppSettings::isDirectConnection() ? QNetworkProxy::NoProxy : QNetworkProxy::HttpProxy,
             AppSettings::proxyAddress(),
@@ -100,7 +105,19 @@ MainWindow::MainWindow(int aEventId, QWidget *aParent)
     // search result has changed
     connect(searchTabContainer, SIGNAL(searchResultChanged()), SLOT(onSearchResultChanged()));
 
+    // systm tray icon
+    connect(systemTrayIcon, SIGNAL(messageClicked()), SLOT(onSystemTrayMessageClicked()));
+    connect(systemTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), SLOT(onSystemTrayMessageClicked()));
+
+    // timer
+    connect(alarmTimer, SIGNAL(timeout()), SLOT(onAlarmTimerTimeout()));
+
+    // add the actions from the main menu to the window, otherwise the shortcuts don't work on MAEMO
+    addAction(conferencesAction);
+    addAction(settingsAction);
+    addAction(quitAction);
 
+    // open conference
     useConference(Conference::activeConference());
     // optimization, see useConference() code
     try {
@@ -110,25 +127,17 @@ MainWindow::MainWindow(int aEventId, QWidget *aParent)
         clearTabs();
     }
 
-    // open dialog for given Event ID
-    // this is used in case Alarm Dialog request application to start
-    if(aEventId)
-    {
-        try
-        {
-            EventDialog dialog(aEventId,this);
-            dialog.exec();
-        }
-        catch(OrmNoObjectException&) {} // just start application
-        catch(...) {} // just start application
-    }
-
     connect(mNetworkAccessManager, SIGNAL(finished(QNetworkReply*)), SLOT(networkQueryFinished(QNetworkReply*)));
-
     connect(mXmlParser, SIGNAL(parsingScheduleBegin()), conferenceModel, SLOT(newConferenceBegin()));
-    connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), conferenceModel, SLOT(newConferenceEnd(const QString&)));
+    connect(mXmlParser, SIGNAL(parsingScheduleEnd(int)), conferenceModel, SLOT(newConferenceEnd(int)));
 }
 
+
+MainWindow::~MainWindow() {
+    sqlEngine->close();
+}
+
+
 void MainWindow::on_aboutAction_triggered()
 {
     QDialog dialog(this);
@@ -147,7 +156,7 @@ void MainWindow::on_reloadAction_triggered() {
     if (confId== -1) return;
     Conference active = Conference::getById(confId);
     if (active.url().isEmpty()) return;
-    importFromNetwork(active.url());
+    importFromNetwork(active.url(), confId);
     setEnabled(false);
 }
 
@@ -220,20 +229,67 @@ void MainWindow::onSearchResultChanged() {
 }
 
 
-void MainWindow::useConference(int id)
+void MainWindow::onSystemTrayMessageClicked() {
+    systemTrayIcon->hide();
+}
+
+
+void MainWindow::onAlarmTimerTimeout() {
+    // determine if an alarm is set on an event that's starting soon
+    QList<Event> events = Event::getImminentAlarmEvents(AppSettings::preEventAlarmSec(), Conference::activeConference());
+    if (events.empty()) return;
+
+    // build a message string
+    Event event;
+    QString title;
+    QString message;
+    if (events.size() == 1) {
+        event = events.first();
+        title = tr("Next event at %1").arg(event.start().toString("HH:mm"));
+        message = tr("\"%1\"\n(%2)").arg(event.title()).arg(event.room()->name());
+    } else {
+        title = tr("%1 upcoming events").arg(events.size());
+        QStringList messages;
+        foreach (event, events) {
+            messages += tr("%1: \"%2\" (%3)").arg(event.start().toString("HH:mm")).arg(event.title()).arg(event.room()->name());
+        }
+        message = messages.join("\n");
+    }
+
+    // and delete the corresponding alarm
+    foreach (event, events) {
+        event.setHasAlarm(false);
+        event.update("alarm");
+        onEventChanged(event.id(), false);
+    }
+
+    // show message
+    systemTrayIcon->show();
+    // The next two lines are to prevent a very strange position of the message box the first time at X11/aweseome (not Win32/XP)
+    systemTrayIcon->showMessage("ConfClerk", "Your upcoming events", QSystemTrayIcon::Information);
+    qApp->processEvents();
+    systemTrayIcon->showMessage(title, message, QSystemTrayIcon::Information, 60*60*24*1000);
+    QApplication::alert(this);
+    QApplication::beep();
+}
+
+
+void MainWindow::useConference(int conferenceId)
 {
-    if (id == -1)  // in case no conference is active
+    if (conferenceId == -1)  // in case no conference is active
     {
         unsetConference();
         return;
     }
     try {
-        Conference::getById(Conference::activeConference()).update("active",0);
-        Conference new_active = Conference::getById(id);
-        new_active.update("active",1);
+        int oldActiveConferenceId = Conference::activeConference();
+        bool switchActiveConference = conferenceId != oldActiveConferenceId;
+        if (switchActiveConference) Conference::getById(oldActiveConferenceId).update("active", 0);
+        Conference activeConference = Conference::getById(conferenceId);
+        if (switchActiveConference) activeConference.update("active",1);
 
         // looks like it does not work at n900
-        setWindowTitle(new_active.title());
+        setWindowTitle(activeConference.title());
 
         // optimization.
         // dont run initTabs() here
@@ -268,6 +324,7 @@ void MainWindow::initTabs()
 
         // 'dayNavigator' emits signal 'dateChanged' after setting valid START:END dates
         dayNavigator->setDates(startDate, endDate);
+        nowAction->trigger();
     }
 }
 
@@ -287,6 +344,12 @@ void MainWindow::unsetConference()
     setWindowTitle(saved_title);
 }
 
+
+void MainWindow::showError(const QString& message) {
+    error_message(message);
+}
+
+
 void MainWindow::on_settingsAction_triggered()
 {
     SettingsDialog dialog;
@@ -317,8 +380,8 @@ void MainWindow::on_conferencesAction_triggered()
 {
     ConferenceEditor dialog(conferenceModel, this);
 
-    connect(&dialog, SIGNAL(haveConferenceUrl(const QString&)), SLOT(importFromNetwork(const QString&)));
-    connect(&dialog, SIGNAL(haveConferenceFile(const QString&)), SLOT(importFromFile(const QString&)));
+    connect(&dialog, SIGNAL(haveConferenceUrl(const QString&, int)), SLOT(importFromNetwork(const QString&, int)));
+    connect(&dialog, SIGNAL(haveConferenceFile(const QString&, int)), SLOT(importFromFile(const QString&, int)));
     connect(&dialog, SIGNAL(removeConferenceRequested(int)), SLOT(removeConference(int)));
     connect(&dialog, SIGNAL(changeUrlRequested(int, const QString&)),
                     SLOT(changeConferenceUrl(int, const QString&)));
@@ -328,7 +391,7 @@ void MainWindow::on_conferencesAction_triggered()
 
     connect(mXmlParser, SIGNAL(parsingScheduleBegin()), &dialog, SLOT(importStarted()));
     connect(mXmlParser, SIGNAL(progressStatus(int)), &dialog, SLOT(showParsingProgress(int)));
-    connect(mXmlParser, SIGNAL(parsingScheduleEnd(const QString&)), &dialog, SLOT(importFinished(const QString&)));
+    connect(mXmlParser, SIGNAL(parsingScheduleEnd(int)), &dialog, SLOT(importFinished(int)));
 
     connect(this, SIGNAL(conferenceRemoved()), &dialog, SLOT(conferenceRemoved()));
 
@@ -349,33 +412,34 @@ void MainWindow::networkQueryFinished(QNetworkReply *aReply) {
         QUrl redirectUrl = aReply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
         if (!redirectUrl.isEmpty()) {
             if (redirectUrl != aReply->request().url()) {
-                importFromNetwork(redirectUrl.toString());
+                importFromNetwork(redirectUrl.toString(), aReply->request().attribute(QNetworkRequest::User).toInt());
                 return; // don't enable controls
             } else {
                 error_message(QString("Error: Cyclic redirection from %1 to itself.").arg(redirectUrl.toString()));
             }
         } else {
-            importData(aReply->readAll(), aReply->url().toEncoded());
+            importData(aReply->readAll(), aReply->url().toEncoded(), aReply->request().attribute(QNetworkRequest::User).toInt());
         }
     }
     setEnabled(true);
 }
 
-void MainWindow::importData(const QByteArray &aData, const QString& url)
+void MainWindow::importData(const QByteArray &aData, const QString& url, int conferenceId)
 {
-    mXmlParser->parseData(aData, url);
+    mXmlParser->parseData(aData, url, conferenceId);
 }
 
-void MainWindow::importFromNetwork(const QString& url)
+void MainWindow::importFromNetwork(const QString& url, int conferenceId)
 {
     QNetworkRequest request;
     request.setUrl(QUrl(url));
+    request.setAttribute(QNetworkRequest::User, conferenceId);
 
     mNetworkAccessManager->setProxy(QNetworkProxy::applicationProxy());
     mNetworkAccessManager->get(request);
 }
 
-void MainWindow::importFromFile(const QString& filename)
+void MainWindow::importFromFile(const QString& filename, int conferenceId)
 {
     QFile file(filename);
     if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {    
@@ -383,19 +447,18 @@ void MainWindow::importFromFile(const QString& filename)
         error_message(format.arg(filename, QString::number(file.error())));
     }
 
-    importData(file.readAll(), "");
+    importData(file.readAll(), "", conferenceId);
 }
 
-void MainWindow::removeConference(int id)
-{
-    Conference::deleteConference(id);
-    conferenceModel->conferenceRemoved();
 
+void MainWindow::removeConference(int id) {
+    sqlEngine->deleteConference(id);
+    conferenceModel->conferenceRemoved();
     emit conferenceRemoved();
 }
 
-void MainWindow::changeConferenceUrl(int id, const QString& url)
-{
+
+void MainWindow::changeConferenceUrl(int id, const QString& url) {
     Conference::getById(id).setUrl(url);
 }
 
index fd9a0d100787f2b47428d75c87466e10fe281813..488dede57c18d993638d1793dc03eae65c78beed 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -22,7 +22,7 @@
 
 #include <QtGui/QMainWindow>
 
-#include <ui_mainwindow.h>
+#include "ui_mainwindow.h"
 
 #include "conferencemodel.h"
 
@@ -34,10 +34,8 @@ class MainWindow : public QMainWindow, private Ui::MainWindow
 {
     Q_OBJECT
 public:
-    // aEventId is used to inform widget to automatically open
-    // Event dialog for given Event ID
-    MainWindow(int aEventId = 0, QWidget *aParent = NULL);
-    ~MainWindow() {}
+    MainWindow(QWidget *parent = 0);
+    ~MainWindow();
 signals:
     void conferenceRemoved();
 private slots:
@@ -52,25 +50,32 @@ private slots:
 
     void onEventChanged(int aEventId, bool favouriteChanged);
     void onSearchResultChanged();
-    // TODO: remove
+
     void networkQueryFinished(QNetworkReply*);
-    void importFromNetwork(const QString&);
-    void importFromFile(const QString&);
+    void importFromNetwork(const QString&, int conferenceId);
+    void importFromFile(const QString&, int conferenceId);
     void removeConference(int);
     void changeConferenceUrl(int, const QString&);
+    void onSystemTrayMessageClicked();
+    void onAlarmTimerTimeout();
 
-    void useConference(int id);
+    void useConference(int conferenceId);
     void unsetConference();
+
+    void showError(const QString& message);
 private:
     void fillAndShowConferenceHeader();
-    void initTabs();
+    void initTabs(); ///< called on startup and on change of a conference
     void clearTabs();
-    void importData(const QByteArray &aData, const QString& url);
+    void importData(const QByteArray &aData, const QString& url, int conferenceId);
 
     QString saved_title;
+    SqlEngine* sqlEngine;
     ConferenceModel* conferenceModel;
     ScheduleXmlParser *mXmlParser;
     QNetworkAccessManager *mNetworkAccessManager;
+    QSystemTrayIcon* systemTrayIcon; ///< to be able to show notifications
+    QTimer* alarmTimer; ///< timer that triggers every minute to be able to show alarms
 };
 
 #endif /* MAINWINDOW_H */
index 395850c3ce879841a70977e036127c53d8b1b407..17ce90aa04b7a41f739ee23a78639b28166b1d5d 100644 (file)
@@ -38,7 +38,7 @@
     <item>
      <widget class="QTabWidget" name="tabWidget">
       <property name="currentIndex">
-       <number>0</number>
+       <number>1</number>
       </property>
       <property name="elideMode">
        <enum>Qt::ElideRight</enum>
@@ -55,7 +55,7 @@
       </widget>
       <widget class="QWidget" name="dayViewTab">
        <attribute name="title">
-        <string>&amp;Days</string>
+        <string>&amp;Day</string>
        </attribute>
        <layout class="QGridLayout" name="gridLayout">
         <item row="0" column="0">
    <property name="text">
     <string>C&amp;onferences</string>
    </property>
+   <property name="toolTip">
+    <string>Manage Conferences (Ctrl+O)</string>
+   </property>
    <property name="shortcut">
     <string>Ctrl+O</string>
    </property>
    <property name="text">
     <string>&amp;Quit</string>
    </property>
+   <property name="toolTip">
+    <string>Quit (Ctrl+Q)</string>
+   </property>
    <property name="shortcut">
     <string>Ctrl+Q</string>
    </property>
     <string>Reload Conference</string>
    </property>
    <property name="toolTip">
-    <string>Reload Conference</string>
+    <string>Reload Conference (Ctrl+R)</string>
    </property>
    <property name="shortcut">
     <string>Ctrl+R</string>
    <property name="text">
     <string>Jump to now</string>
    </property>
+   <property name="toolTip">
+    <string>Jump to now (Ctrl+N)</string>
+   </property>
    <property name="shortcut">
     <string>Ctrl+N</string>
    </property>
    <property name="text">
     <string>&amp;Search</string>
    </property>
+   <property name="toolTip">
+    <string>Search (Ctrl+F)</string>
+   </property>
    <property name="shortcut">
     <string>Ctrl+F</string>
    </property>
    <property name="text">
     <string>Expand all</string>
    </property>
+   <property name="toolTip">
+    <string>Expand all (Ctrl++)</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl++</string>
+   </property>
   </action>
   <action name="collapseAllAction">
    <property name="icon">
    <property name="text">
     <string>Collapse all</string>
    </property>
+   <property name="toolTip">
+    <string>Collapse all (Ctrl+-)</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+-</string>
+   </property>
   </action>
  </widget>
  <customwidgets>
index 9a53cfe69f91abba43ef6201053824edef862eee..6d23c7be0afb7367307759a79ce3f908e5576621 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 6e05d2eb5dbb8aa83fe04ae7e70800813c99639f..9cb179080c3c02349160e2d32c27697597c1c031 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 6864c051a85a6adb8140167752e4ba9ba360ceef..4f53c44de3311de4a250fc3bf9606563ef945253 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 2f284dd3854bf4ae7e41c089c1524d9668345425..5afacbfe59ed44b67cce369489bb9faac0973642 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 23cbdf6d288776607c82c2eb0415c68fec6ddeac..7cebadd1bd80c90592874b56c85eae2d7aeb733e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -22,8 +22,7 @@
 #include "searchhead.h"
 #include <QMessageBox>
 
-SearchTabContainer::SearchTabContainer(QWidget *aParent) : TabContainer( aParent )
-{
+SearchTabContainer::SearchTabContainer(QWidget *aParent): TabContainer(aParent), sqlEngine(0) {
     header = new SearchHead(this);
     header->setObjectName(QString::fromUtf8("header"));
     QSizePolicy sizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);
@@ -54,10 +53,13 @@ int SearchTabContainer::searchResultCount(const QDate& date) const {
 void SearchTabContainer::showSearchDialog(bool show) {
     header->setVisible(show);
     treeView->setVisible(!show);
+    if (show) header->searchEdit->setFocus(Qt::OtherFocusReason);
 }
 
 
 void SearchTabContainer::searchButtonClicked() {
+    if (!sqlEngine) return;
+
     QHash<QString,QString> columns;
 
     SearchHead *searchHeader = static_cast<SearchHead*>(header);
@@ -78,7 +80,7 @@ void SearchTabContainer::searchButtonClicked() {
     if (confId == -1) return;
     Conference conf = Conference::getById(confId);
 
-    SqlEngine::searchEvent( confId, columns, keyword );
+    sqlEngine->searchEvent( confId, columns, keyword );
 
     int nrofFounds = 0;
     for (QDate d = conf.start(); d <= conf.end(); d = d.addDays(1))
index 6144073602ab0237979b2ef8789745a0a7fce07b..f6e4809118bdb6a765cc4f593bb462ca16e7064d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
 
 #include "tabcontainer.h"
 #include "searchhead.h"
+#include "sqlengine.h"
 
 class SearchTabContainer: public TabContainer {
     Q_OBJECT
+private:
+    SqlEngine* sqlEngine;
 public:
     SearchTabContainer(QWidget *aParent);
     virtual ~SearchTabContainer() {}
+    void setSqlEngine(SqlEngine* sqlEngine) {this->sqlEngine = sqlEngine;}
     bool searchDialogIsVisible() const;
     int searchResultCount(const QDate& date) const; ///< returns the number of events found on that specific date
 
index 1d57797af661337bf9424f828587e516e24b2f63..7ed770c2c415aca3fcb8834dfd5f2d4b8d6308f1 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -19,7 +19,7 @@
  */
 #include "settingsdialog.h"
 
-#include <appsettings.h>
+#include "appsettings.h"
 #include <QDebug>
 
 SettingsDialog::SettingsDialog(QWidget *aParent)
index 59dcf0c076af83fbe059a9de96dc5774ce4ecbf3..0b6d22b4d9b8cb1fb578300cd0c326ace1bdeec9 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 522860e668e50ad9cfff51f4501c2118e685a788..7ceb718438412e60fb5081f5de57625328f1c8fe 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -23,8 +23,8 @@
 #include <QMessageBox>
 #include <QTimer>
 
-#include <treeview.h>
-#include <delegate.h>
+#include "treeview.h"
+#include "delegate.h"
 
 #include "eventdialog.h"
 #include "room.h"
@@ -65,7 +65,7 @@ void TabContainer::itemClicked(const QModelIndex &aIndex)
     if(!aIndex.parent().isValid()) // time-group
         return;
 
-    EventDialog dialog(static_cast<Event*>(aIndex.internalPointer())->id(),this);
+    EventDialog dialog(Conference::activeConference(), static_cast<Event*>(aIndex.internalPointer())->id(),this);
 #ifdef N810
     dialog.setFixedWidth(static_cast<QWidget*>(parent())->width());
 #endif
index fe03b5436ec895ec537f743a322776ca7122de73..d8277c030d62aeef7124b48c59f707702c58b6f7 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
 #include <QWidget>
 #include "ui_tabcontainer.h"
 
-#include <conference.h>
-#include <sqlengine.h>
-#include <conference.h>
-#include <eventmodel.h>
+#include "conference.h"
+#include "sqlengine.h"
+#include "conference.h"
+#include "eventmodel.h"
 
 class TabContainer : public QWidget, public Ui::TabContainer
 {
index 52d3cab2c04c4a67643b3f4688cfbb1bfd4233f2..45288c6e7f767d6456f8afa37760f6785de0ade0 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index abaab097144e6229d97bf4271916fcaf178e6fe2..09498f221ec43d1e6c3624f6e4f1c2b2292e4928 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index b7cc5fc5d1f9e843a8aaea9292588dd3ada3febc..d5a5cf22a88f827364ee3620d4e1df40de2dcae8 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 14e71f25dfae1715858e8f6d78d2d0a724a680a0..199922e68f19e3a4e13f0ef7135a3085f909c6fa 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index b53255e0a59c3585f69ff2147cabc2b9fb3638e4..7e7558d9f8b36758e9899203e7206d2f66f67d46 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -28,7 +28,6 @@ QSqlRecord const Conference::sColumns = Conference::toRecord(QList<QSqlField>()
     << QSqlField("city", QVariant::String)
     << QSqlField("start", QVariant::DateTime)
     << QSqlField("end", QVariant::DateTime)
-    << QSqlField("days", QVariant::Int)
     << QSqlField("day_change", QVariant::Int)
     << QSqlField("timeslot_duration", QVariant::Int)
     << QSqlField("active", QVariant::Bool)
@@ -52,29 +51,10 @@ QList<Conference> Conference::getAll()
     return load(query);
 }
 
-int Conference::activeConference()
-{
-    {
-        QSqlQuery query("SELECT id FROM conference WHERE active = 1");
-        query.exec();
-
-        // TODO: change it so that it will select somw existing ID
-
-        if (query.next()) {
-            return query.record().value("id").toInt();
-        }
-    }
-
-    QSqlQuery query2("SELECT id FROM conference ORDER BY id");
-    if (query2.next()) {
-        return query2.record().value("id").toInt();
-    }
-
-    return -1;
+int Conference::activeConference() {
+    QSqlQuery query("SELECT id FROM conference ORDER BY active DESC, id LIMIT 1");
+    if (!query.exec() || !query.first()) return -1;
+    return query.record().value("id").toInt();
 }
 
-void Conference::deleteConference(int id)
-{
-    SqlEngine::deleteConference(id);
-}
 
index adf8ff9bcf894f2e3a41c4a35887bcbf39e8362b..51dee99896705e161e889ed35c996aab43d047ef 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -24,7 +24,7 @@
 #include <QVector>
 #include <QStringList>
 
-#include <ormrecord.h>
+#include "ormrecord.h"
 
 class Conference : public OrmRecord<Conference>
 {
@@ -35,8 +35,10 @@ public:
 public:
     static Conference getById(int id);
     static QList<Conference> getAll();
-    static int activeConference(); ///< returns -1 if no conference is active
-    static void deleteConference(int id);
+
+    /// Returns the active conference. If no active conference can be found, it returns the conference with the lowest id.
+    /// If no conference exists or database errors occur, it returns -1.
+    static int activeConference();
 
 public:
     int id() const { return value("id").toInt(); }
@@ -46,25 +48,12 @@ public:
     QString city() const { return value("city").toString(); }
     QDate start() const { return value("start").toDate(); }
     QDate end() const { return value("end").toDate(); }
-    int days() const { return value("days").toInt(); }
     int dayChange() const { return value("day_change").toInt(); } // in seconds from 00:00
+    QTime dayChangeTime() const {QTime dayChangeTime(0, 0); return dayChangeTime.addSecs(dayChange());}
     int timeslotDuration() const { return value("timeslot_duration").toInt(); } // in seconds
     bool isActive() const { return value("active").toBool(); }
     QString url() const { return stringFromNullable(value("url")); }
 
-    #if 0
-    void setId(int id) { setValue("id", id); }
-    void setTitle(const QString& title) { setValue("title", title); }
-    void setSubtitle(const QString& subtitle) { setValue("subtitle", subtitle); }
-    void setVenue(const QString& venue) { setValue("venue", venue); }
-    void setCity(const QString& city) { setValue("city", city); }
-    void setStart(const QDate& start) { setValue("start", start); }
-    void setEnd(const QDate& end) { setValue("end", end); }
-    void setDays(int days) { setValue("days", days); }
-    void setDayChange(int dayChange) { setValue("day_change", dayChange); }
-    void setTimeslotDuration(int timeslotDuration) { setValue("timeslot_duration", timeslotDuration); }
-    void setActive(bool active) { setValue("active", (int)((active))); }
-    #endif
     void setUrl(const QString& url)
     {
         setValue("url", url.isNull() ? QVariant() : url);
index 16d76a567bbdb6f13ed398afc88212a07ae31e2d..f8688c10824f8ff5a4a74cc7e63f43fe4b205235 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -77,9 +77,8 @@ void ConferenceModel::newConferenceBegin()
 {
 }
 
-void ConferenceModel::newConferenceEnd(const QString& title)
-{
-    Q_UNUSED(title);
+void ConferenceModel::newConferenceEnd(int conferenceId) {
+    Q_UNUSED(conferenceId);
     reinit();
 }
 
index cd1c4fdd55227140e5be503e70d2ccb81123ea70..fe0f242214416c7267cd5721012f584a34768a4d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -46,7 +46,7 @@ public:
     QModelIndex indexFromId(int id) const;
 public slots:
     void newConferenceBegin();
-    void newConferenceEnd(const QString& title);
+    void newConferenceEnd(int conferenceId);
     void conferenceRemoved();
 private:
     // reinitialize list from database
index 7e4724c274240badae9945c6f2ae6437ab571846..5551be3e2b4c1395ffcf5114d0b9ebb0772a3b84 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -19,7 +19,7 @@
  */
 #include "delegate.h"
 #include "eventmodel.h"
-#include <track.h>
+#include "track.h"
 
 #include <QDebug>
 #include <QPainter>
@@ -109,12 +109,12 @@ void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, cons
             mControls[FavouriteControlOn]->paint(painter, option.rect);
         else
             mControls[FavouriteControlOff]->paint(painter, option.rect);
-#ifdef MAEMO
+
         if(event->hasAlarm())
             mControls[AlarmControlOn]->paint(painter, option.rect);
         else
             mControls[AlarmControlOff]->paint(painter, option.rect);
-#endif
+
         if(event->hasTimeConflict())
             mControls[WarningControl]->paint(painter, option.rect);
 
@@ -163,9 +163,7 @@ void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, cons
     else // doesn't have parent - time-groups' elements (top items)
     {
         int numFav = numberOfFavourities(index);
-#ifdef MAEMO
         int numAlarm = numberOfAlarms(index);
-#endif
 
         QStyleOptionButton styleOptionButton;
         styleOptionButton.rect = option.rect;
@@ -199,13 +197,13 @@ void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, cons
         painter->drawImage(drawPoint,*image);
         painter->drawText(drawPoint+QPoint(image->width()+2, image->height() - 2),
                 QString::number(numFav));
-#ifdef MAEMO
+
         drawPoint.setX(drawPoint.x() - spacer - image->width());
         image = mControls[numAlarm ? AlarmControlOn : AlarmControlOff]->image();
         painter->drawImage(drawPoint,*image);
         painter->drawText(drawPoint+QPoint(image->width()+2, image->height() - 2),
                 QString::number(numAlarm));
-#endif
+
         // draw texts
         QString numEvents = QString::number(index.model()->rowCount(index)).append("/");
         drawPoint.setX(drawPoint.x() - spacer - fmSmall.boundingRect(numEvents).width());
@@ -313,7 +311,6 @@ void Delegate::defineControls()
     // off
     mControls.insert(FavouriteControlOff, new Control(FavouriteControlOff, QString(":icons/favourite-off.png"), NULL));
 
-#ifdef MAEMO
     // ALARM ICONs
     // on
     mControls.insert(AlarmControlOn,
@@ -324,13 +321,7 @@ void Delegate::defineControls()
     // WARNING ICON
     mControls.insert(WarningControl,
                     new Control(WarningControl, QString(":icons/dialog-warning.png"), mControls[AlarmControlOff]));
-#else
-    // WARNING ICON
-    mControls.insert(WarningControl,
-                    new Control(WarningControl, QString(":icons/dialog-warning.png"), mControls[FavouriteControlOn]));
-#endif
-
-}
+        }
 
 bool Delegate::isPointFromRect(const QPoint &aPoint, const QRect &aRect) const
 {
index 0859b563fd3c828b3cf2b8d8eb98d757e5058940..e4f254989ea5a88fcec019aaa3b91a2e4a4c4d69 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 58c217ad5597e82f47b2c00262cd6c7d6ad3fa55..c8cc349c99dcac1332f1e51cbea728039747698d 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -17,6 +17,7 @@
  * You should have received a copy of the GNU General Public License along with
  * ConfClerk.  If not, see <http://www.gnu.org/licenses/>.
  */
+#include "conference.h"
 #include "event.h"
 #include "room.h"
 
@@ -53,24 +54,30 @@ Event Event::getById(int id, int conferenceId) {
 
 
 QList<Event> Event::getByDate(const QDate& date, int conferenceId, QString orderBy) {
+    Q_ASSERT(conferenceId > 0);
+    Conference conference = Conference::getById(conferenceId);
+    QDateTime dayStart(date, conference.dayChangeTime(), Qt::UTC);
     QSqlQuery query;
     query.prepare(selectQuery() + QString("WHERE xid_conference = :conf AND start >= :start AND start < :end ORDER BY %1").arg(orderBy));
     query.bindValue(":conf", conferenceId);
-    query.bindValue(":start", convertToDb(date, QVariant::DateTime));
-    query.bindValue(":end", convertToDb(date.addDays(1), QVariant::DateTime));
+    query.bindValue(":start", dayStart.toTime_t());
+    query.bindValue(":end", dayStart.addDays(1).toTime_t());
     return load(query);
 }
 
-QList<Event> Event::getByDateAndRoom(const QDate& date, int conferenceId)
-{
+
+QList<Event> Event::getByDateAndRoom(const QDate& date, int conferenceId) {
+    Q_ASSERT(conferenceId > 0);
+    Conference conference = Conference::getById(conferenceId);
+    QDateTime dayStart(date, conference.dayChangeTime(), Qt::UTC);
     QSqlQuery query;
     QString aliasEvent("E");
     QString aliasEventRoom("R");
     query.prepare(QString("SELECT %1 FROM %2 %3, %4 %5 WHERE %3.xid_conference = :conf AND %3.start >= :start AND %3.start < :end AND %3.id = R.xid_event ORDER BY %5.xid_room, %3.start, %3.duration").arg(
                     columnsForSelect(aliasEvent), Event::sTableName, aliasEvent, "EVENT_ROOM", aliasEventRoom));
     query.bindValue(":conf", conferenceId);
-    query.bindValue(":start", convertToDb(date, QVariant::DateTime));
-    query.bindValue(":end", convertToDb(date.addDays(1), QVariant::DateTime));
+    query.bindValue(":start", dayStart.toTime_t());
+    query.bindValue(":end", dayStart.addDays(1).toTime_t());
 
     return load(query);
 }
@@ -94,13 +101,24 @@ QList<Event> Event::conflictEvents(int aEventId, int conferenceId) {
 }
 
 
-QList<Event> Event::getFavByDate(const QDate& date, int conferenceId)
-{
+QList<Event> Event::getImminentAlarmEvents(int maxSecToAlarm, int conferenceId) {
+    QSqlQuery query;
+    query.prepare(selectQuery() + "WHERE xid_conference = :conf AND (start < :start AND alarm = 1) ORDER BY start, duration");
+    query.bindValue(":conf", conferenceId);
+    query.bindValue(":start", convertToDb(QDateTime::currentDateTime().addSecs(maxSecToAlarm), QVariant::DateTime));
+    return load(query);
+}
+
+
+QList<Event> Event::getFavByDate(const QDate& date, int conferenceId) {
+    Q_ASSERT(conferenceId > 0);
+    Conference conference = Conference::getById(conferenceId);
+    QDateTime dayStart(date, conference.dayChangeTime(), Qt::UTC);
     QSqlQuery query;
     query.prepare(selectQuery() + QString("WHERE xid_conference = :conf AND start >= :start AND start < :end AND favourite = 1 ORDER BY start, duration"));
     query.bindValue(":conf", conferenceId);
-    query.bindValue(":start", convertToDb(date, QVariant::DateTime));
-    query.bindValue(":end", convertToDb(date.addDays(1), QVariant::DateTime));
+    query.bindValue(":start", dayStart.toTime_t());
+    query.bindValue(":end", dayStart.addDays(1).toTime_t());
 
     return load(query);
 }
@@ -164,7 +182,7 @@ QMap<QString,QString> Event::links()
         query.bindValue(":id", id());
         query.bindValue(":conf", conferenceId());
         query.exec();
-        // TODO: handle qeury error
+        // TODO: handle query error
         //qDebug() << query.lastError();
 
         while(query.next())
@@ -227,9 +245,13 @@ QList<Event> Event::getSearchResultByDate(const QDate& date, int conferenceId, Q
             throw OrmSqlException( query.lastError().text() );
         }
 
+        Q_ASSERT(conferenceId > 0);
+        Conference conference = Conference::getById(conferenceId);
+        QDateTime dayStart(date, conference.dayChangeTime(), Qt::UTC);
+
         query.bindValue(":conf", conferenceId);
-        query.bindValue(":start", convertToDb(date, QVariant::DateTime));
-        query.bindValue(":end", convertToDb(date.addDays(1), QVariant::DateTime));
+        query.bindValue(":start", dayStart.toTime_t());
+        query.bindValue(":end", dayStart.addDays(1).toTime_t());
 
         list = load(query);
     }
index 3dc6b8fd71aef4c6820c135b172a99f0424b282f..101e8f64fb36a69b6c70649d1cc95780bc531215 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -24,7 +24,7 @@
 #include <QVector>
 #include <QStringList>
 
-#include <ormrecord.h>
+#include "ormrecord.h"
 
 class Room;
 
@@ -49,6 +49,7 @@ public:
     static QList<Event> getByTrack(int id);
     static QList<Event> getByDateAndRoom(const QDate& date, int conferenceId);
     static QList<Event> conflictEvents(int aEventId, int conferenceId);
+    static QList<Event> getImminentAlarmEvents(int maxSecToAlarm, int conferenceId);
 public:
     int id() const { return value("id").toInt(); }
     int conferenceId() const { return value("xid_conference").toInt(); }
index 79b36710ca5c8f2688b5b420bd6bba0734493a30..139d3301e1642d3fdbce0991325fbe164dcd8c1e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -18,9 +18,9 @@
  * ConfClerk.  If not, see <http://www.gnu.org/licenses/>.
  */
 #include "eventmodel.h"
-#include <conference.h>
-#include <track.h>
-#include <room.h>
+#include "conference.h"
+#include "track.h"
+#include "room.h"
 
 const QString EventModel::COMMA_SEPARATOR = ", ";
 
@@ -29,10 +29,10 @@ EventModel::EventModel()
 
 
 void EventModel::Group::setTitle(const QList<Event>& mEvents) {
-    QTime startTime = mEvents.at(mFirstEventIndex).start().time();
-    QTime endTime(0, 0);
+    QDateTime startTime = mEvents.at(mFirstEventIndex).start();
+    QDateTime endTime(startTime);
     for (int i = mFirstEventIndex; i != mFirstEventIndex + mChildCount; ++i) {
-        endTime = qMax(mEvents.at(i).start().time().addSecs(mEvents.at(i).duration()), endTime);
+        endTime = qMax(mEvents.at(i).start().addSecs(mEvents.at(i).duration()), endTime);
     }
     mTitle = QString("%1 - %2").arg(startTime.toString("HH:mm")).arg(endTime.toString("HH:mm"));
 }
@@ -235,44 +235,31 @@ void EventModel::clearModel()
     reset();
 }
 
-void EventModel::loadEvents(const QDate &aDate, int aConferenceId)
-{
+
+void EventModel::loadEvents(const QDate &aDate, int aConferenceId) {
     clearModel();
-    // check for existence of the conference in the DB
-    if(Conference::getAll().count())
-    {
-        mEvents = Event::getByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId, "start, duration");
-    }
+    mEvents = Event::getByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId, "start, duration");
     createTimeGroups();
 }
 
-void EventModel::loadFavEvents(const QDate &aDate, int aConferenceId)
-{
+
+void EventModel::loadFavEvents(const QDate &aDate, int aConferenceId) {
     clearModel();
-    // check for existence of the conference in the DB
-    if(Conference::getAll().count())
-    {
-        mEvents = Event::getFavByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId);
-    }
+    mEvents = Event::getFavByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId);
     createTimeGroups();
 }
 
-int EventModel::loadSearchResultEvents(const QDate &aDate, int aConferenceId)
-{
-    clearModel();
-    // check for existence of the conference in the DB
-    if(Conference::getAll().count())
-    {
-        try{
-            mEvents = Event::getSearchResultByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId, "start, duration");
-        }
-        catch( OrmException &e  ){
-            qDebug() << "Event::getSearchResultByDate failed: " << e.text();
-        }
-        catch(...){
-            qDebug() << "Event::getSearchResultByDate failed";
-        }
 
+int EventModel::loadSearchResultEvents(const QDate &aDate, int aConferenceId) {
+    clearModel();
+    try {
+        mEvents = Event::getSearchResultByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId, "start, duration");
+    }
+    catch( OrmException &e  ){
+        qDebug() << "Event::getSearchResultByDate failed: " << e.text();
+    }
+    catch(...){
+        qDebug() << "Event::getSearchResultByDate failed";
     }
 
     createTimeGroups();
@@ -280,37 +267,28 @@ int EventModel::loadSearchResultEvents(const QDate &aDate, int aConferenceId)
     return mEvents.count();
 }
 
-void EventModel::loadEventsByTrack(const QDate &aDate, int aConferenceId)
-{
+
+void EventModel::loadEventsByTrack(const QDate &aDate, int aConferenceId) {
     clearModel();
-    if (Conference::getAll().count())
-    {
-        mEvents = Event::getByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId, "xid_track, start, duration");
-    }
+    mEvents = Event::getByDate(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId, "xid_track, start, duration");
     createTrackGroups();
 }
 
-void EventModel::loadEventsByRoom(const QDate &aDate, int aConferenceId)
-{
+
+void EventModel::loadEventsByRoom(const QDate &aDate, int aConferenceId) {
     clearModel();
-    if (Conference::getAll().count())
-    {
-        mEvents = Event::getByDateAndRoom(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId);
-    }
+    mEvents = Event::getByDateAndRoom(QDate(aDate.year(), aDate.month(), aDate.day()), aConferenceId);
     createRoomGroups();
 }
 
 
 void EventModel::loadConflictEvents(int aEventId, int aConferenceId) {
     clearModel();
-    // check for existence of the conference in the DB
-    if(Conference::getAll().count())
-    {
-        mEvents = Event::conflictEvents(aEventId, aConferenceId);
-    }
+    mEvents = Event::conflictEvents(aEventId, aConferenceId);
     createTimeGroups();
 }
 
+
 void EventModel::updateModel(int aEventId)
 {
     for(int i=0; i<mEvents.count(); i++)
index 039b8779e7df52566568b66e418a6cb4b1e5e4bd..4d8992533477093b5aed111ee4bab3a1fc7582cb 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 1b2c203496f4b8f9bf9d4ca1432243cc9233de61..5a894c437ef0344784f895480ae117af3bf1f84e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 542a722b3f498618a163a8b5c9814122e6d9e5dc..613a5146b74459f9495059c75e2a0ee824f498a5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -21,7 +21,7 @@
 #ifndef ROOM_H_
 #define ROOM_H_
 
-#include <ormrecord.h>
+#include "ormrecord.h"
 
 class Room : public OrmRecord<Room>
 {
index bb0bf3969a785e8557c2873ee7b155ae681ba61a..ae77d199762140819695bd2b78c9b722cb053589 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index d654cc5f8deef50cd4a4fc32b49741971aacf4ed..384f4bd0caa0a6944ac86e3f4adaa6065e06ab46 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -21,7 +21,7 @@
 #ifndef TRACK_H_
 #define TRACK_H_
 
-#include <ormrecord.h>
+#include "ormrecord.h"
 
 class Track : public OrmRecord<Track>
 {
index 6b427e184234527132514cb108ff436813cc26bc..74ee1195fc59fdeb9b3b97c996998d6ccc5433b5 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -27,6 +27,7 @@
 
 #ifdef MAEMO
 #include "alarm.h"
+#include "appsettings.h"
 #endif
 
 #include <QDebug>
@@ -99,7 +100,7 @@ bool TreeView::testForControlClicked(const QModelIndex &aIndex, const QPoint &aP
                 {
                     event.setHasAlarm(false); // update DB
 #ifdef MAEMO
-                    // remove alarm from the 'alarmd' alrms list
+                    // remove alarm from the 'alarmd' alarms list
                     Alarm alarm;
                     alarm.deleteAlarm(event.conferenceId(), event.id());
 #endif /* MAEMO */
@@ -110,7 +111,7 @@ bool TreeView::testForControlClicked(const QModelIndex &aIndex, const QPoint &aP
 #ifdef MAEMO
                     // add alarm to the 'alarmd'
                     Alarm alarm;
-                    alarm.addAlarm(event.conferenceId(), event.id(), event.title(),event.start().addSecs(PRE_EVENT_ALARM_SEC));
+                    alarm.addAlarm(event.conferenceId(), event.id(), event.title(),event.start().addSecs(-AppSettings::preEventAlarmSec()));
 #endif /* MAEMO */
                 }
                 event.update("alarm");
index fde2728f9cd266b0d113a1f299faf326631ef7e2..6d27f81c8b4bef196b397aaa0cf1aef96a980b9e 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index e5e6cfa1488f2c9c76b0ce15aafeafa7b9368da2..8357b6bfc2fabe5f4ad055e8c3444036bcfaddb6 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 6e361abbe57b70adb24c74febcdd7290fbad9874..80531f880788e0ee47f024809e0d309fb608da8a 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
 
 #include <QDebug>
 
-ScheduleXmlParser::ScheduleXmlParser(QObject *aParent)
-    : QObject(aParent)
-{
+ScheduleXmlParser::ScheduleXmlParser(SqlEngine* sqlEngine, QObject *aParent): QObject(aParent),sqlEngine(sqlEngine) {
 }
 
-void ScheduleXmlParser::parseData(const QByteArray &aData, const QString& url)
+
+void ScheduleXmlParser::parseData(const QByteArray &aData, const QString& url, int conferenceId)
 {
     QDomDocument document;
     QString xml_error;
@@ -45,9 +44,8 @@ void ScheduleXmlParser::parseData(const QByteArray &aData, const QString& url)
 
     QDomElement scheduleElement = document.firstChildElement("schedule");
 
-    SqlEngine::beginTransaction();
+    sqlEngine->beginTransaction();
 
-    int confId = 0;
     QString conference_title;
     if (!scheduleElement.isNull())
     {
@@ -56,19 +54,18 @@ void ScheduleXmlParser::parseData(const QByteArray &aData, const QString& url)
         {
             emit(parsingScheduleBegin());
             QHash<QString,QString> conference;
-            conference["id"] = QString::number(0); // conference ID is assigned automatically, or obtained from the DB
+            conference["id"] = QString::number(conferenceId); // conference ID is assigned automatically if 0
             conference["title"] = conferenceElement.firstChildElement("title").text();
             conference["subtitle"] = conferenceElement.firstChildElement("subtitle").text();
             conference["venue"] = conferenceElement.firstChildElement("venue").text();
             conference["city"] = conferenceElement.firstChildElement("city").text();
             conference["start"] = conferenceElement.firstChildElement("start").text(); // date
             conference["end"] = conferenceElement.firstChildElement("end").text(); // date
-            conference["days"] = conferenceElement.firstChildElement("days").text(); // int
             conference["day_change"] = conferenceElement.firstChildElement("day_change").text(); // time
             conference["timeslot_duration"] = conferenceElement.firstChildElement("timeslot_duration").text(); // time
             conference["url"] = url;
-            SqlEngine::addConferenceToDB(conference);
-            confId = conference["id"].toInt();
+            sqlEngine->addConferenceToDB(conference, conferenceId);
+            conferenceId = conference["id"].toInt();
             conference_title = conference["title"];
         }
 
@@ -104,13 +101,13 @@ void ScheduleXmlParser::parseData(const QByteArray &aData, const QString& url)
                         QHash<QString,QString> room;
                         room["name"] = roomElement.attribute("name");
                         room["event_id"] = eventElement.attribute("id");
-                        room["conference_id"] = QString::number(confId,10);
-                        SqlEngine::addRoomToDB(room);
+                        room["conference_id"] = QString::number(conferenceId,10);
+                        sqlEngine->addRoomToDB(room);
 
                         // process event's nodes
                         QHash<QString,QString> event;
                         event["id"] = eventElement.attribute("id");;
-                        event["conference_id"] = QString::number(confId, 10);
+                        event["conference_id"] = QString::number(conferenceId, 10);
                         event["start"] = eventElement.firstChildElement("start").text(); // time eg. 10:00
                         event["date"] = dayElement.attribute("date"); // date eg. 2009-02-07
                         event["duration"] = eventElement.firstChildElement("duration").text(); // time eg. 00:30
@@ -123,9 +120,8 @@ void ScheduleXmlParser::parseData(const QByteArray &aData, const QString& url)
                         event["language"] = eventElement.firstChildElement("language").text(); // language eg. "English"
                         event["abstract"] = eventElement.firstChildElement("abstract").text(); // string
                         event["description"] = eventElement.firstChildElement("description").text(); // string
-                        SqlEngine::addEventToDB(event);
+                        sqlEngine->addEventToDB(event);
                         // process persons' nodes
-                        QList<QString> persons;
                         QDomElement personsElement = eventElement.firstChildElement("persons");
                         QDomNodeList personList = personsElement.elementsByTagName("person");
                         for(int i = 0;i < personList.count();i++){
@@ -133,9 +129,8 @@ void ScheduleXmlParser::parseData(const QByteArray &aData, const QString& url)
                             person["id"] = personList.at(i).toElement().attribute("id");
                             person["name"] = personList.at(i).toElement().text();
                             person["event_id"] = eventElement.attribute("id");
-                            person["conference_id"] = QString::number(confId, 10);
-                            //qDebug() << "adding Person: " << person["name"];
-                            SqlEngine::addPersonToDB(person);
+                            person["conference_id"] = QString::number(conferenceId, 10);
+                            sqlEngine->addPersonToDB(person);
                         }
                         // process links' nodes
                         QDomElement linksElement = eventElement.firstChildElement("links");
@@ -145,8 +140,8 @@ void ScheduleXmlParser::parseData(const QByteArray &aData, const QString& url)
                             link["name"] = linkList.at(i).toElement().text();
                             link["url"] = linkList.at(i).toElement().attribute("href");
                             link["event_id"] = eventElement.attribute("id");
-                            link["conference_id"] = QString::number(confId, 10);
-                            SqlEngine::addLinkToDB(link);
+                            link["conference_id"] = QString::number(conferenceId, 10);
+                            sqlEngine->addLinkToDB(link);
                         }
                         // emit signal to inform the user about the current status (how many events are parsed so far - expressed in %)
                         int status = currentEvent * 100 / totalEventsCount;
@@ -156,9 +151,9 @@ void ScheduleXmlParser::parseData(const QByteArray &aData, const QString& url)
             } // parsing room elements
         } // parsing day elements
     } // schedule element
-    SqlEngine::commitTransaction();
+    sqlEngine->commitTransaction();
     if (!conference_title.isNull()) {
-        emit parsingScheduleEnd(conference_title);
+        emit parsingScheduleEnd(conferenceId);
     } else {
         error_message("Could not parse schedule");
     }
index cf3f0010ed8fdf39e049f9dbcc6eecb5649aed80..fd1a1ad4b8cf10ea3b1f397eefda1fd15b7cd435 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
 #define SCHEDULEXMLPARSER_H_
 
 #include <QObject>
+#include "sqlengine.h"
 
 class ScheduleXmlParser : public QObject
 {
     Q_OBJECT
+    private:
+        SqlEngine* sqlEngine;
     public:
-        ScheduleXmlParser (QObject *aParent = NULL);
+        ScheduleXmlParser(SqlEngine* sqlEngine, QObject *aParent = NULL);
 
     public slots:
-        void parseData(const QByteArray &aData, const QString& url);
+        void parseData(const QByteArray &aData, const QString& url, int conferenceId);
 
     signals:
         void progressStatus(int aStatus);
         void parsingScheduleBegin();
-        void parsingScheduleEnd(const QString& title);
+        void parsingScheduleEnd(int conferenceId);
 };
 
 #endif /* SCHEDULEXMLPARSER_H_ */
index 4212e02b8904c5891915916922dba4b1b399b1dd..823a2b63c96511e9c176dc577273e9390a0bc1dd 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
 #include <QDir>
 #include <QDesktopServices>
 #include "sqlengine.h"
-#include <track.h>
-#include <conference.h>
+#include "track.h"
+#include "conference.h"
 
 #include <QDebug>
 
 const QString DATE_FORMAT ("yyyy-MM-dd");
 const QString TIME_FORMAT ("hh:mm");
 
-SqlEngine::SqlEngine(QObject *aParent)
-    : QObject(aParent)
-{
+SqlEngine::SqlEngine(QObject *aParent): QObject(aParent) {
+    QDir dbPath(QDesktopServices::storageLocation(QDesktopServices::DataLocation));
+    dbFilename = dbPath.absoluteFilePath("ConfClerk.sqlite");
 }
 
-SqlEngine::~SqlEngine()
-{
+
+SqlEngine::~SqlEngine() {
 }
 
-QString SqlEngine::login(const QString &aDatabaseType, const QString &aDatabaseName)
-{
-    QSqlDatabase database = QSqlDatabase::addDatabase(aDatabaseType);
-    database.setDatabaseName(aDatabaseName);
 
-    bool result = false;
-    if(!QFile::exists(aDatabaseName)) // the DB (tables) doesn't exists, and so we have to create one
-    {
-        // create Db
-        if (!database.open()) qDebug() << "Could not open database" << database.lastError();
-        QFile file(":/create_tables.sql");
-        file.open(QIODevice::ReadOnly | QIODevice::Text);
-        QString allSqlStatements = file.readAll();
-        foreach(QString sql, allSqlStatements.split(";")) {
-            if (sql.trimmed().length() == 0)     // do not execute empty queries like the last character from create_tables.sql
-                continue;
-            QSqlQuery query(database);
-            if (!query.exec(sql)) qDebug() << "Could not execute query '" << sql << "' error:" << query.lastError();
-        }
+void SqlEngine::open() {
+    // we may have to create the directory of the database
+    QFileInfo dbFilenameInfo(dbFilename);
+    QDir cwd;
+    cwd.mkpath(dbFilenameInfo.absolutePath());
+    // We don't have to handle errors because in worst case, opening the database will fail
+    // and db.isOpen() returns false.
+    db = QSqlDatabase::addDatabase("QSQLITE");
+    db.setDatabaseName(dbFilename);
+    db.open();
+}
+
+
+int SqlEngine::dbSchemaVersion() {
+    QSqlQuery query(db);
+    if (!query.exec("PRAGMA user_version")) {
+        emitSqlQueryError(query);
+        return -2;
     }
-    else
-    {
-        database.open();
+    query.first();
+    int version = query.value(0).toInt();
+    if (version == 0) {
+        // check whether the tables are existing
+        if (!query.exec("select count(*) from sqlite_master where name='CONFERENCE'")) {
+            emitSqlQueryError(query);
+            return -2;
+        }
+        query.first();
+        if (query.value(0).toInt() == 1) return 0; // tables are existing
+        return -1; // database seems to be empty (or has other tables)
     }
+    return version;
+}
 
-    //LOG_INFO(QString("Opening '%1' database '%2'").arg(aDatabaseType).arg(aDatabaseName));
 
-    return result ? QString() : database.lastError().text();
+bool SqlEngine::updateDbSchemaVersion000To001() {
+    return applySqlFile(":/dbschema000to001.sql");
 }
 
-void SqlEngine::initialize()
-{
-    QString databaseName;
-    QString dataDirName;
-    dataDirName = QDesktopServices::storageLocation(QDesktopServices::DataLocation);
-    QDir dataDir = QDir(dataDirName).absolutePath();
-    if(!dataDir.exists())
-        dataDir.mkpath(dataDirName);
-    databaseName = dataDirName + "/ConfClerk.sqlite";
-    login("QSQLITE",databaseName);
+
+bool SqlEngine::createCurrentDbSchema() {
+    return applySqlFile(":/dbschema001.sql");
 }
 
-void SqlEngine::addConferenceToDB(QHash<QString,QString> &aConference)
-{
-    QSqlDatabase db = QSqlDatabase::database();
 
-    if (db.isValid() && db.isOpen())
-    {
-        int confId = 0;
-        QList<Conference> confsList = Conference::getAll();
-        if(confsList.count())
-        {
-            QListIterator<Conference> i(confsList);
-            while (i.hasNext())
-            {
-                Conference conf = i.next();
-                if( aConference["title"] == conf.title() )
-                {
-                    confId = conf.id();
-                    aConference["id"] = QString::number(confId);
-                    break;
-                }
-            }
-        }
+bool SqlEngine::createOrUpdateDbSchema() {
+    int version = dbSchemaVersion();
+    switch (version) {
+    case -2:
+        // the error has already been emitted by the previous function
+        return false;
+    case -1:
+        // empty database
+        return createCurrentDbSchema();
+    case 0:
+        // db schema version 0
+        return updateDbSchemaVersion000To001();
+    case 1:
+        // current schema
+        return true;
+    default:
+        // unsupported schema
+        emit dbError(tr("Unsupported database schema version %1.").arg(version));
+    }
+    return false;
+}
 
-        if(!confId) // conference 'aConference' isn't in the table => insert
-        {
-            // HACK
-            // When city is empty, assign a dummy value. We probably want to find a way to change the database scheme ...
-            // cf. #32
-            if (aConference["city"].isEmpty()) aConference["city"] = "n/a";
-
-            QSqlQuery query(db);
-            query.prepare("INSERT INTO CONFERENCE (title,url,subtitle,venue,city,start,end,days,"
-                                                    "day_change,timeslot_duration,active) "
-                            " VALUES (:title,:url,:subtitle,:venue,:city,:start,:end,:days,"
-                                                    ":day_change,:timeslot_duration,:active)");
-            foreach (QString prop_name, (QList<QString>() << "title" << "url" << "subtitle" << "venue" << "city" << "days")) {
-                query.bindValue(QString(":") + prop_name, aConference[prop_name]);
-            }
-            query.bindValue(":start", QDateTime(QDate::fromString(aConference["start"],DATE_FORMAT),QTime(0,0),Qt::UTC).toTime_t());
-            query.bindValue(":end", QDateTime(QDate::fromString(aConference["end"],DATE_FORMAT),QTime(0,0),Qt::UTC).toTime_t());
-            query.bindValue(":day_change", -QTime::fromString(aConference["day_change"],TIME_FORMAT).secsTo(QTime(0,0)));
-            query.bindValue(":day_change", -QTime::fromString(aConference["timeslot_duration"],TIME_FORMAT).secsTo(QTime(0,0)));
-            query.bindValue(":active", confsList.count() > 0 ? 0 : 1);
-            if (!query.exec()) qDebug() << "Could not execute query to insert a conference:" << query.lastError();
-            aConference["id"] = query.lastInsertId().toString(); // 'id' is assigned automatically
+
+bool SqlEngine::applySqlFile(const QString sqlFile) {
+    QFile file(sqlFile);
+    file.open(QIODevice::ReadOnly | QIODevice::Text);
+    QString allSqlStatements = file.readAll();
+    QSqlQuery query(db);
+    foreach(QString sql, allSqlStatements.split(";")) {
+        if (sql.trimmed().isEmpty())  // do not execute empty queries like the last character from create_tables.sql
+            continue;
+        if (!query.exec(sql)) {
+            emitSqlQueryError(query);
+            return false;
         }
     }
+    return true;
 }
 
-void SqlEngine::addEventToDB(QHash<QString,QString> &aEvent)
-{
-    QSqlDatabase db = QSqlDatabase::database();
 
-    if (db.isValid() && db.isOpen())
+void SqlEngine::addConferenceToDB(QHash<QString,QString> &aConference, int conferenceId) {
+    QSqlQuery query(db);
+    if (conferenceId <= 0) // insert conference
     {
-        //insert event track to table and get track id
-        int conference = aEvent["conference_id"].toInt();
-        QString name = aEvent["track"];
-        Track track;
-        int trackId;
-        try
-        {
-            track = Track::retrieveByName(conference, name);
-            trackId = track.id();
-        }
-        catch (OrmNoObjectException &e) {
-            track.setConference(conference);
-            track.setName(name);
-            trackId = track.insert();
-        }
-        QDateTime startDateTime;
-        startDateTime.setTimeSpec(Qt::UTC);
-        startDateTime = QDateTime(QDate::fromString(aEvent["date"],DATE_FORMAT),QTime::fromString(aEvent["start"],TIME_FORMAT),Qt::UTC);
-
-        bool event_exists = false;
-        {
-            QSqlQuery check_event_query;
-            check_event_query.prepare("SELECT * FROM EVENT WHERE xid_conference = :xid_conference AND id = :id");
-            check_event_query.bindValue(":xid_conference", aEvent["conference_id"]);
-            check_event_query.bindValue(":id", aEvent["id"]);
-            if (!check_event_query.exec()) {
-                qWarning() << "check event failed, conference id:" << aEvent["xid_conference"]
-                        << "event id:" << aEvent["id"]
-                        << "error:" << check_event_query.lastError()
-                        ;
-                return;
-            }
-            if (check_event_query.isActive() and check_event_query.isSelect() and check_event_query.next()) {
-                event_exists = true;
-            }
-        }
-
-        QSqlQuery result;
-        if (event_exists) {
-            result.prepare("UPDATE EVENT SET"
-                            " start = :start"
-                            ", duration = :duration"
-                            ", xid_track = :xid_track"
-                            ", type = :type"
-                            ", language = :language"
-                            ", tag = :tag"
-                            ", title = :title"
-                            ", subtitle = :subtitle"
-                            ", abstract = :abstract"
-                            ", description = :description"
-                                " WHERE id = :id AND xid_conference = :xid_conference");
-        } else {
-            result.prepare("INSERT INTO EVENT "
-                            " (xid_conference, id, start, duration, xid_track, type, "
-                                " language, tag, title, subtitle, abstract, description) "
-                            " VALUES (:xid_conference, :id, :start, :duration, :xid_track, :type, "
-                                ":language, :tag, :title, :subtitle, :abstract, :description)");
+        query.prepare("INSERT INTO CONFERENCE (title,url,subtitle,venue,city,start,end,"
+                                                "day_change,timeslot_duration,active) "
+                        " VALUES (:title,:url,:subtitle,:venue,:city,:start,:end,"
+                                                ":day_change,:timeslot_duration,:active)");
+        foreach (QString prop_name, (QList<QString>() << "title" << "url" << "subtitle" << "venue" << "city")) {
+            query.bindValue(QString(":") + prop_name, aConference[prop_name]);
         }
-        result.bindValue(":xid_conference", aEvent["conference_id"]);
-        result.bindValue(":start", QString::number(startDateTime.toTime_t()));
-        result.bindValue(":duration", -QTime::fromString(aEvent["duration"],TIME_FORMAT).secsTo(QTime(0,0)));
-        result.bindValue(":xid_track", trackId);
-        static const QList<QString> props = QList<QString>()
-            << "id" << "type" << "language" << "tag" << "title" << "subtitle" << "abstract" << "description";
-        foreach (QString prop_name, props) {
-            result.bindValue(QString(":") + prop_name, aEvent[prop_name]);
-        }
-        if (!result.exec()) {
-            qWarning() << "event insert/update failed:" << result.lastError();
+        query.bindValue(":start", QDateTime(QDate::fromString(aConference["start"],DATE_FORMAT),QTime(0,0),Qt::UTC).toTime_t());
+        query.bindValue(":end", QDateTime(QDate::fromString(aConference["end"],DATE_FORMAT),QTime(0,0),Qt::UTC).toTime_t());
+        query.bindValue(":day_change", -QTime::fromString(aConference["day_change"],TIME_FORMAT).secsTo(QTime(0,0)));
+        query.bindValue(":timeslot_duration", -QTime::fromString(aConference["timeslot_duration"],TIME_FORMAT).secsTo(QTime(0,0)));
+        query.bindValue(":active", 1);
+        query.exec();
+        emitSqlQueryError(query);
+        aConference["id"] = query.lastInsertId().toString(); // 'id' is assigned automatically
+    }
+    else // update conference
+    {
+        query.prepare("UPDATE CONFERENCE set title=:title, url=:url, subtitle=:subtitle, venue=:venue, city=:city, start=:start, end=:end,"
+                                            "day_change=:day_change, timeslot_duration=:timeslot_duration, active=:active "
+                      "WHERE id=:id");
+        foreach (QString prop_name, (QList<QString>() << "title" << "url" << "subtitle" << "venue" << "city")) {
+            query.bindValue(QString(":") + prop_name, aConference[prop_name]);
         }
+        query.bindValue(":start", QDateTime(QDate::fromString(aConference["start"],DATE_FORMAT),QTime(0,0),Qt::UTC).toTime_t());
+        query.bindValue(":end", QDateTime(QDate::fromString(aConference["end"],DATE_FORMAT),QTime(0,0),Qt::UTC).toTime_t());
+        query.bindValue(":day_change", -QTime::fromString(aConference["day_change"],TIME_FORMAT).secsTo(QTime(0,0)));
+        query.bindValue(":timeslot_duration", -QTime::fromString(aConference["timeslot_duration"],TIME_FORMAT).secsTo(QTime(0,0)));
+        query.bindValue(":active", 1);
+        query.bindValue(":id", conferenceId);
+        query.exec();
+        emitSqlQueryError(query);
+        aConference["id"] = QVariant(conferenceId).toString();
     }
 }
 
-void SqlEngine::addPersonToDB(QHash<QString,QString> &aPerson)
-{
-    QSqlDatabase db = QSqlDatabase::database();
 
-    if (db.isValid() && db.isOpen())
+void SqlEngine::addEventToDB(QHash<QString,QString> &aEvent) {
+    int conferenceId = aEvent["conference_id"].toInt();
+    Conference conference = Conference::getById(conferenceId);
+
+    // insert event track to table and get track id
+    Track track;
+    int trackId;
+    QString trackName = aEvent["track"];
+    try
     {
-        QSqlQuery query(db);
-        query.prepare("INSERT INTO PERSON (xid_conference,id,name) VALUES (:xid_conference, :id, :name)");
-        query.bindValue(":xid_conference", aPerson["conference_id"]);
-        query.bindValue(":id", aPerson["id"]);
-        query.bindValue(":name", aPerson["name"]);
-        query.exec(); // some queries fail due to the unique key constraint
-        // if (!query.exec()) qDebug() << "SQL query 'insert into person' failed: " << query.lastError();
+        track = Track::retrieveByName(conferenceId, trackName);
+        trackId = track.id();
+    }
+    catch (OrmNoObjectException &e) {
+        track.setConference(conferenceId);
+        track.setName(trackName);
+        trackId = track.insert();
+    }
+    QDate startDate = QDate::fromString(aEvent["date"], DATE_FORMAT);
+    QTime startTime = QTime::fromString(aEvent["start"], TIME_FORMAT);
+    // consider day_change (note that if day_change is e.g. at 04:00 AM, an event starting at 02:00 AM has the previous date in the XML file)
+    if (startTime < conference.dayChangeTime()) startDate = startDate.addDays(1);
+    QDateTime startDateTime;
+    startDateTime.setTimeSpec(Qt::UTC);
+    startDateTime = QDateTime(startDate, startTime, Qt::UTC);
+
+    bool event_exists = false;
+    {
+        QSqlQuery check_event_query;
+        check_event_query.prepare("SELECT * FROM EVENT WHERE xid_conference = :xid_conference AND id = :id");
+        check_event_query.bindValue(":xid_conference", aEvent["conference_id"]);
+        check_event_query.bindValue(":id", aEvent["id"]);
+        if (!check_event_query.exec()) {
+            qWarning() << "check event failed, conference id:" << aEvent["xid_conference"]
+                    << "event id:" << aEvent["id"]
+                    << "error:" << check_event_query.lastError()
+                    ;
+            return;
+        }
+        if (check_event_query.isActive() and check_event_query.isSelect() and check_event_query.next()) {
+            event_exists = true;
+        }
+    }
 
-        query = QSqlQuery(db);
-        query.prepare("INSERT INTO EVENT_PERSON (xid_conference,xid_event,xid_person) VALUES (:xid_conference, :xid_event, :xid_person)");
-        query.bindValue(":xid_conference", aPerson["conference_id"]);
-        query.bindValue(":xid_event", aPerson["event_id"]);
-        query.bindValue(":xid_person", aPerson["id"]);
-        query.exec(); // some queries fail due to the unique key constraint
-        // if (!query.exec()) qDebug() << "SQL query 'insert into event_person' failed: " << query.lastError();
+    QSqlQuery result;
+    if (event_exists) {
+        result.prepare("UPDATE EVENT SET"
+                        " start = :start"
+                        ", duration = :duration"
+                        ", xid_track = :xid_track"
+                        ", type = :type"
+                        ", language = :language"
+                        ", tag = :tag"
+                        ", title = :title"
+                        ", subtitle = :subtitle"
+                        ", abstract = :abstract"
+                        ", description = :description"
+                            " WHERE id = :id AND xid_conference = :xid_conference");
+    } else {
+        result.prepare("INSERT INTO EVENT "
+                        " (xid_conference, id, start, duration, xid_track, type, "
+                            " language, tag, title, subtitle, abstract, description) "
+                        " VALUES (:xid_conference, :id, :start, :duration, :xid_track, :type, "
+                            ":language, :tag, :title, :subtitle, :abstract, :description)");
+    }
+    result.bindValue(":xid_conference", aEvent["conference_id"]);
+    result.bindValue(":start", QString::number(startDateTime.toTime_t()));
+    result.bindValue(":duration", -QTime::fromString(aEvent["duration"],TIME_FORMAT).secsTo(QTime(0,0)));
+    result.bindValue(":xid_track", trackId);
+    static const QList<QString> props = QList<QString>()
+        << "id" << "type" << "language" << "tag" << "title" << "subtitle" << "abstract" << "description";
+    foreach (QString prop_name, props) {
+        result.bindValue(QString(":") + prop_name, aEvent[prop_name]);
+    }
+    if (!result.exec()) {
+        qWarning() << "event insert/update failed:" << result.lastError();
     }
 }
 
-void SqlEngine::addRoomToDB(QHash<QString,QString> &aRoom)
-{
-    QSqlDatabase db = QSqlDatabase::database();
 
-    if (db.isValid() && db.isOpen())
+void SqlEngine::addPersonToDB(QHash<QString,QString> &aPerson) {
+    QSqlQuery query(db);
+    query.prepare("INSERT INTO PERSON (xid_conference,id,name) VALUES (:xid_conference, :id, :name)");
+    query.bindValue(":xid_conference", aPerson["conference_id"]);
+    query.bindValue(":id", aPerson["id"]);
+    query.bindValue(":name", aPerson["name"]);
+    query.exec(); // TODO some queries fail due to the unique key constraint
+    // if (!query.exec()) qDebug() << "SQL query 'insert into person' failed: " << query.lastError();
+
+    query = QSqlQuery(db);
+    query.prepare("INSERT INTO EVENT_PERSON (xid_conference,xid_event,xid_person) VALUES (:xid_conference, :xid_event, :xid_person)");
+    query.bindValue(":xid_conference", aPerson["conference_id"]);
+    query.bindValue(":xid_event", aPerson["event_id"]);
+    query.bindValue(":xid_person", aPerson["id"]);
+    query.exec(); // TODO some queries fail due to the unique key constraint
+    // if (!query.exec()) qDebug() << "SQL query 'insert into event_person' failed: " << query.lastError();
+}
+
+
+void SqlEngine::addRoomToDB(QHash<QString,QString> &aRoom) {
+    QSqlQuery query(db);
+    query.prepare("SELECT id FROM ROOM WHERE xid_conference=:conference_id and name=:name");
+    query.bindValue(":conference_id", aRoom["conference_id"]);
+    query.bindValue(":name", aRoom["name"]);
+    query.exec();
+    emitSqlQueryError(query);
+    // now we have to check whether ROOM record with 'name' exists or not,
+    // - if it doesn't exist yet, then we have to add that record to 'ROOM' table
+    //   and assign autoincremented 'id' to aRoom
+    // - if it exists, then we need to get its 'id' and assign it to aRoom
+    aRoom["id"] = "";
+    if(query.next()) // ROOM record with 'name' already exists: we need to get its 'id'
+    {
+        aRoom["id"] = query.value(0).toString();
+    }
+    else // ROOM record doesn't exist yet, need to create it
     {
-        QSqlQuery query(db);
-        query.prepare("SELECT id FROM ROOM WHERE xid_conference=:conference_id and name=:name");
-        query.bindValue(":conference_id", aRoom["conference_id"]);
-        query.bindValue(":name", aRoom["name"]);
-        if (!query.exec()) qDebug() << "Could not execute select room query: " << query.lastError();
-        // now we have to check whether ROOM record with 'name' exists or not,
-        // - if it doesn't exist yet, then we have to add that record to 'ROOM' table
-        //   and assign autoincremented 'id' to aRoom
-        // - if it exists, then we need to get its 'id' and assign it to aRoom
-        aRoom["id"] = "";
-        if(query.next()) // ROOM record with 'name' already exists: we need to get its 'id'
-        {
-            aRoom["id"] = query.value(0).toString();
-        }
-        else // ROOM record doesn't exist yet, need to create it
-        {
-            query = QSqlQuery(db);
-            query.prepare("INSERT INTO ROOM (xid_conference,name,picture) VALUES (:xid_conference, :name, '')");
-            query.bindValue(":xid_conference", aRoom["conference_id"]);
-            query.bindValue(":xid_name", aRoom["name"]);
-            if (!query.exec()) qDebug() << "Could not execute 'insert into room ...' query." << query.lastError();
-            aRoom["id"]= query.lastInsertId().toString(); // 'id' is assigned automatically
-            //LOG_AUTOTEST(query);
-        }
-        
-        // remove previous conference/room records; room names might have changed
-        query = QSqlQuery(db);
-        query.prepare("DELETE FROM EVENT_ROOM WHERE xid_conference=:conference_id AND xid_event=:event_id");
-        query.bindValue(":conference_id", aRoom["conference_id"]);
-        query.bindValue(":event_id", aRoom["event_id"]);
-        if (!query.exec()) qDebug() << "Could not execute SELECT * FROM EVENT_ROOM' query:" << query.lastError();
-        // and insert new ones
         query = QSqlQuery(db);
-        query.prepare("INSERT INTO EVENT_ROOM (xid_conference,xid_event,xid_room) VALUES (:conference_id, :event_id, :room_id)");
-        query.bindValue(":conference_id", aRoom["conference_id"]);
-        query.bindValue(":event_id", aRoom["event_id"]);
-        query.bindValue(":room_id", aRoom["id"]);
-        if (!query.exec()) qDebug() << "Could not 'execute insert into event_room' query:" << query.lastError();
+        query.prepare("INSERT INTO ROOM (xid_conference,name) VALUES (:xid_conference, :name)");
+        query.bindValue(":xid_conference", aRoom["conference_id"]);
+        query.bindValue(":xid_name", aRoom["name"]);
+        query.exec();
+        emitSqlQueryError(query);
+        aRoom["id"]= query.lastInsertId().toString(); // 'id' is assigned automatically
+        //LOG_AUTOTEST(query);
     }
+
+    // remove previous conference/room records; room names might have changed
+    query = QSqlQuery(db);
+    query.prepare("DELETE FROM EVENT_ROOM WHERE xid_conference=:conference_id AND xid_event=:event_id");
+    query.bindValue(":conference_id", aRoom["conference_id"]);
+    query.bindValue(":event_id", aRoom["event_id"]);
+    query.exec();
+    emitSqlQueryError(query);
+    // and insert new ones
+    query = QSqlQuery(db);
+    query.prepare("INSERT INTO EVENT_ROOM (xid_conference,xid_event,xid_room) VALUES (:conference_id, :event_id, :room_id)");
+    query.bindValue(":conference_id", aRoom["conference_id"]);
+    query.bindValue(":event_id", aRoom["event_id"]);
+    query.bindValue(":room_id", aRoom["id"]);
+    query.exec();
+    emitSqlQueryError(query);
 }
 
-void SqlEngine::addLinkToDB(QHash<QString,QString> &aLink)
-{
-    QSqlDatabase db = QSqlDatabase::database();
 
+void SqlEngine::addLinkToDB(QHash<QString,QString> &aLink) {
     //TODO: check if the link doesn't exist before inserting
-    if (db.isValid() && db.isOpen())
-    {
-        QSqlQuery query(db);
-        query.prepare("INSERT INTO LINK (xid_event, xid_conference, name, url) VALUES (:xid_event, :xid_conference, :name, :url)");
-        query.bindValue(":xid_event", aLink["event_id"]);
-        query.bindValue(":xid_conference", aLink["conference_id"]);
-        query.bindValue(":name", aLink["name"]);
-        query.bindValue(":url", aLink["url"]);
-        if (!query.exec()) qDebug() << "Error executing 'insert into link' query: " << query.lastError();
-    }
+    QSqlQuery query(db);
+    query.prepare("INSERT INTO LINK (xid_event, xid_conference, name, url) VALUES (:xid_event, :xid_conference, :name, :url)");
+    query.bindValue(":xid_event", aLink["event_id"]);
+    query.bindValue(":xid_conference", aLink["conference_id"]);
+    query.bindValue(":name", aLink["name"]);
+    query.bindValue(":url", aLink["url"]);
+    query.exec();
+    emitSqlQueryError(query);
 }
 
-int SqlEngine::searchEvent(int aConferenceId, const QHash<QString,QString> &aColumns, const QString &aKeyword)
-{
-    QSqlDatabase db = QSqlDatabase::database();
 
-    if ( !db.isValid() || !db.isOpen())
-        return -1;
-
-    if (aColumns.empty()) return -1;
+bool SqlEngine::searchEvent(int aConferenceId, const QHash<QString,QString> &aColumns, const QString &aKeyword) {
+    if (aColumns.empty()) return false;
 
     // DROP
-    execQuery( db, "DROP TABLE IF EXISTS SEARCH_EVENT");
+    QSqlQuery query(db);
+    query.exec("DROP TABLE IF EXISTS SEARCH_EVENT");
+    emitSqlQueryError(query);
+
     // CREATE
-    execQuery( db, "CREATE TEMP TABLE SEARCH_EVENT ( xid_conference INTEGER  NOT NULL, id INTEGER NOT NULL )");
+    query.exec("CREATE TEMP TABLE SEARCH_EVENT ( xid_conference INTEGER  NOT NULL, id INTEGER NOT NULL )");
+    emitSqlQueryError(query);
+
     // INSERT
     QString sql = QString("INSERT INTO SEARCH_EVENT ( xid_conference, id ) "
                 "SELECT DISTINCT EVENT.xid_conference, EVENT.id FROM EVENT ");
@@ -342,7 +368,6 @@ int SqlEngine::searchEvent(int aConferenceId, const QHash<QString,QString> &aCol
     sql += whereAnd.join(") AND (");
     sql += QString(")");
 
-    QSqlQuery query(db);
     query.prepare(sql);
     for (int i = 0; i != searchKeywords.size(); ++i) {
         QString keyword = searchKeywords[i];
@@ -353,72 +378,60 @@ int SqlEngine::searchEvent(int aConferenceId, const QHash<QString,QString> &aCol
         }
     }
 
-    if( !query.exec() ){
-       qDebug() << "Could not execute search query: " << query.lastError().text();
-       return -1;
-    }
-
-    return 1;
+    bool success = query.exec();
+    emitSqlQueryError(query);
+    return success;
 }
 
-bool SqlEngine::beginTransaction()
-{
-    QSqlDatabase db = QSqlDatabase::database();
 
-    return execQuery(db, "BEGIN IMMEDIATE TRANSACTION");
+bool SqlEngine::beginTransaction() {
+    QSqlQuery query(db);
+    bool success = query.exec("BEGIN IMMEDIATE TRANSACTION");
+    emitSqlQueryError(query);
+    return success;
 }
 
-bool SqlEngine::commitTransaction()
-{
-    QSqlDatabase db = QSqlDatabase::database();
 
-    return execQuery(db, "COMMIT");
+bool SqlEngine::commitTransaction() {
+    QSqlQuery query(db);
+    bool success = query.exec("COMMIT");
+    emitSqlQueryError(query);
+    return success;
 }
 
-void SqlEngine::deleteConference(int id)
-{
-    QSqlDatabase db = QSqlDatabase::database();
 
-    if ( !db.isValid() || !db.isOpen()) {
-        return;
+bool SqlEngine::deleteConference(int id) {
+    QSqlQuery query(db);
+    bool success = query.exec("BEGIN IMMEDIATE TRANSACTION");
+    emitSqlQueryError(query);
+
+    QStringList sqlList;
+    sqlList << "DELETE FROM LINK WHERE xid_conference = ?"
+            << "DELETE FROM EVENT_ROOM WHERE xid_conference = ?"
+            << "DELETE FROM EVENT_PERSON WHERE xid_conference = ?"
+            << "DELETE FROM EVENT WHERE xid_conference = ?"
+            << "DELETE FROM ROOM WHERE xid_conference = ?"
+            << "DELETE FROM PERSON WHERE xid_conference = ?"
+            << "DELETE FROM TRACK WHERE xid_conference = ?"
+            << "DELETE FROM CONFERENCE WHERE id = ?";
+
+    foreach (const QString& sql, sqlList) {
+        query.prepare(sql);
+        query.bindValue(0, id);
+        success &= query.exec();
+        emitSqlQueryError(query);
     }
 
-    beginTransaction();
-
-    QHash<QString, QVariant> params;
-    params["xid_conference"] = id;
-    execQueryWithParameter(db, "DELETE FROM LINK WHERE xid_conference = :xid_conference", params);
-    execQueryWithParameter(db, "DELETE FROM EVENT_ROOM WHERE xid_conference = :xid_conference", params);
-    execQueryWithParameter(db, "DELETE FROM EVENT_PERSON WHERE xid_conference = :xid_conference", params);
-    execQueryWithParameter(db, "DELETE FROM EVENT WHERE xid_conference = :xid_conference", params);
-    execQueryWithParameter(db, "DELETE FROM ROOM WHERE xid_conference = :xid_conference", params);
-    execQueryWithParameter(db, "DELETE FROM PERSON WHERE xid_conference = :xid_conference", params);
-    execQueryWithParameter(db, "DELETE FROM TRACK WHERE xid_conference = :xid_conference", params);
-    execQueryWithParameter(db, "DELETE FROM CONFERENCE WHERE id = :xid_conference", params);
+    success &= query.exec("COMMIT");
+    emitSqlQueryError(query);
 
-    commitTransaction();
+    return success;
 }
 
-bool SqlEngine::execQuery(QSqlDatabase &aDatabase, const QString &aQuery)
-{
-    QSqlQuery sqlQuery(aDatabase);
-    if( !sqlQuery.exec(aQuery) ){
-       qDebug() << "SQL ERR: " << sqlQuery.lastError().number() << ", " << sqlQuery.lastError().text();
-       return false;
-    }
-    return true;
-}
 
-bool SqlEngine::execQueryWithParameter(QSqlDatabase &aDatabase, const QString &aQuery, const QHash<QString, QVariant>& params)
-{
-    QSqlQuery sqlQuery(aDatabase);
-    sqlQuery.prepare(aQuery);
-    foreach (QString param_key, params.keys()) {
-        sqlQuery.bindValue(param_key, params[param_key]);
-    }
-    if( !sqlQuery.exec() ){
-       qDebug() << "SQL ERR: " << sqlQuery.lastError().number() << ", " << sqlQuery.lastError().text();
-       return false;
-    }
-    return true;
+void SqlEngine::emitSqlQueryError(const QSqlQuery &query) {
+    QSqlError error = query.lastError();
+    if (error.type() == QSqlError::NoError) return;
+    emit dbError(error.text());
 }
+
index 2781f3fb16d4e719844972a50136be7f10ed9635..7348ec8a1e6b05166f6376eb3b1afb7ee9e2c944 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
 
 #include <QObject>
 #include <QHash>
+#include <QSqlDatabase>
 
-class QSqlDatabase;
 
-class SqlEngine : public QObject
-{
+class SqlEngine : public QObject {
     Q_OBJECT
     public:
+        QString dbFilename; ///< database filename including path
+        QSqlDatabase db; ///< this may be private one day...
+
         SqlEngine(QObject *aParent = NULL);
         ~SqlEngine();
-        static void initialize();
-        static void addConferenceToDB(QHash<QString,QString> &aConference);
-        static void addEventToDB(QHash<QString,QString> &aEvent);
-        static void addPersonToDB(QHash<QString,QString> &aPerson);
-        static void addLinkToDB(QHash<QString,QString> &aLink);
-        static void addRoomToDB(QHash<QString,QString> &aRoom);
-        static void deleteConference(int id);
-
-        static bool beginTransaction();
-        static bool commitTransaction();
-
-        // search Events for ....
-        static int searchEvent(int conferenceId, const QHash<QString,QString> &columns, const QString &keyword);
+
+        // Open/Close
+        void open(); ///< emits a database error if failed.
+        bool isOpen() const {return db.isOpen();}
+        void close() {db.close();}
+
+        // Schema version
+        /// returns the "user_version" of the database schema
+        /// we return -1 for an empty database
+        /// the database has to be open
+        /// returns -2 if an error occurs and emits the error message
+        int dbSchemaVersion();
+        /// called by createOrUpdateDbSchema. Do not use directly. true for success.
+        bool updateDbSchemaVersion000To001();
+        /// called by createOrUpdateDbSchma. Do not use directly. true for success.
+        bool createCurrentDbSchema();
+        /// creates the current database schema if an empty database is found,
+        /// otherwise updates the schema if an old one is found. true for success.
+        bool createOrUpdateDbSchema();
+        /// Applies an SQL file
+        bool applySqlFile(const QString sqlFile);
+
+        // if a conferneceId != 0 is given, the confernce is updated instead of inserted.
+        void addConferenceToDB(QHash<QString,QString> &aConference, int conferenceId);
+        void addEventToDB(QHash<QString,QString> &aEvent);
+        void addPersonToDB(QHash<QString,QString> &aPerson);
+        void addLinkToDB(QHash<QString,QString> &aLink);
+        void addRoomToDB(QHash<QString,QString> &aRoom);
+        bool deleteConference(int id);
+
+        bool beginTransaction();
+        bool commitTransaction();
+
+        /// search Events for .... returns true if success
+        bool searchEvent(int conferenceId, const QHash<QString,QString> &columns, const QString &keyword);
     private:
         static QString login(const QString &aDatabaseType, const QString &aDatabaseName);
-        static bool execQuery(QSqlDatabase &aDatabase, const QString &aQuery);
-        static bool execQueryWithParameter(QSqlDatabase &aDatabase, const QString &aQuery, const QHash<QString, QVariant>& params);
+        /// emits a possible error message as signal. Does nothing if there was not last error
+        void emitSqlQueryError(const QSqlQuery& query);
+
+    signals:
+        /// emitted when a database errors occur
+        void dbError(const QString& message);
 };
 
 #endif /* SQLENGINE_H */
index 05be3b30758b68557bfcd077c956fd44ea49041d..ce9b559dce8d37176a18bb9974c2ab390a81d015 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
index 5184b876d635b2bc74800053dca4d8e163e4efb1..2f3c8fe1c2570b0ce645bbe18c1a3618aad5cc34 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *
@@ -24,7 +24,7 @@
 
 #include <QDebug>
 
-#include <event.h>
+#include "event.h"
 
 void EventTest::initTestCase()
 {
index 098df804f65d1b2f5f200d2c7cf05ca3360615fc..656024c7452f0d3b1b7aa17a693dee4365410bcf 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2010 Ixonos Plc.
- * Copyright (C) 2011-2012 Philipp Spitzer, gregor herrmann, Stefan Stahl
+ * Copyright (C) 2011-2013 Philipp Spitzer, gregor herrmann, Stefan Stahl
  *
  * This file is part of ConfClerk.
  *