summaryrefslogtreecommitdiff
path: root/libopie
authorzecke <zecke>2003-02-21 23:31:52 (UTC)
committer zecke <zecke>2003-02-21 23:31:52 (UTC)
commit46f47c0a1e542a8b4222f3ced8f3304534c7509d (patch) (unidiff)
tree82dc97a07bae77387987711c0c21697691955937 /libopie
parenta7448ec87d97a0128618e83ad7526bd884ef8853 (diff)
downloadopie-46f47c0a1e542a8b4222f3ced8f3304534c7509d.zip
opie-46f47c0a1e542a8b4222f3ced8f3304534c7509d.tar.gz
opie-46f47c0a1e542a8b4222f3ced8f3304534c7509d.tar.bz2
Add XML datebookresource
-clean up todoaccessxml header -implement some more stuff in the oeven tester -extend DefaultFactory to not crash and to use datebook -reading of OEvents is working nicely.. saving will be added tomorrow -fix spelling in ODateBookAcces
Diffstat (limited to 'libopie') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie/libopie.pro2
-rw-r--r--libopie/pim/obackendfactory.h41
-rw-r--r--libopie/pim/odatebookaccess.cpp5
-rw-r--r--libopie/pim/odatebookaccess.h4
-rw-r--r--libopie/pim/odatebookaccessbackend_xml.cpp395
-rw-r--r--libopie/pim/odatebookaccessbackend_xml.h48
-rw-r--r--libopie/pim/oevent.cpp5
-rw-r--r--libopie/pim/opimnotify.h2
-rw-r--r--libopie/pim/otodoaccessxml.cpp2
-rw-r--r--libopie/pim/test/oevent_test.cpp27
10 files changed, 512 insertions, 19 deletions
diff --git a/libopie/libopie.pro b/libopie/libopie.pro
index 70399ea..391f30e 100644
--- a/libopie/libopie.pro
+++ b/libopie/libopie.pro
@@ -1,116 +1,118 @@
1TEMPLATE = lib 1TEMPLATE = lib
2CONFIG += qte warn_on release 2CONFIG += qte warn_on release
3HEADERS = ofontmenu.h \ 3HEADERS = ofontmenu.h \
4 ocolorbutton.h \ 4 ocolorbutton.h \
5 ofiledialog.h ofileselector.h \ 5 ofiledialog.h ofileselector.h \
6 ocheckitem.h \ 6 ocheckitem.h \
7 xmltree.h \ 7 xmltree.h \
8 colordialog.h colorpopupmenu.h \ 8 colordialog.h colorpopupmenu.h \
9 oclickablelabel.h oprocctrl.h \ 9 oclickablelabel.h oprocctrl.h \
10 oprocess.h odevice.h odevicebutton.h \ 10 oprocess.h odevice.h odevicebutton.h \
11 otimepicker.h otabwidget.h \ 11 otimepicker.h otabwidget.h \
12 otabbar.h otabinfo.h \ 12 otabbar.h otabinfo.h \
13 ofontselector.h \ 13 ofontselector.h \
14 pim/opimrecord.h \ 14 pim/opimrecord.h \
15 pim/otodo.h \ 15 pim/otodo.h \
16 pim/orecordlist.h \ 16 pim/orecordlist.h \
17 pim/opimaccesstemplate.h \ 17 pim/opimaccesstemplate.h \
18 pim/opimaccessbackend.h \ 18 pim/opimaccessbackend.h \
19 pim/otodoaccess.h \ 19 pim/otodoaccess.h \
20 pim/otodoaccessbackend.h \ 20 pim/otodoaccessbackend.h \
21 pim/ocontact.h \ 21 pim/ocontact.h \
22 pim/ocontactaccess.h \ 22 pim/ocontactaccess.h \
23 pim/ocontactaccessbackend.h \ 23 pim/ocontactaccessbackend.h \
24 pim/ocontactaccessbackend_xml.h \ 24 pim/ocontactaccessbackend_xml.h \
25 pim/ocontactaccessbackend_vcard.h \ 25 pim/ocontactaccessbackend_vcard.h \
26 pim/obackendfactory.h \ 26 pim/obackendfactory.h \
27 pim/opimcache.h \ 27 pim/opimcache.h \
28 pim/otodoaccessvcal.h \ 28 pim/otodoaccessvcal.h \
29 pim/orecur.h \ 29 pim/orecur.h \
30 pim/opimstate.h \ 30 pim/opimstate.h \
31 pim/opimxrefpartner.h \ 31 pim/opimxrefpartner.h \
32 pim/opimxref.h \ 32 pim/opimxref.h \
33 pim/opimxrefmanager.h \ 33 pim/opimxrefmanager.h \
34 pim/opimmaintainer.h \ 34 pim/opimmaintainer.h \
35 pim/opimnotify.h \ 35 pim/opimnotify.h \
36 pim/opimnotifymanager.h \ 36 pim/opimnotifymanager.h \
37 pim/opimmainwindow.h \ 37 pim/opimmainwindow.h \
38 pim/opimresolver.h \ 38 pim/opimresolver.h \
39 pim/oevent.h \ 39 pim/oevent.h \
40 pim/otimezone.h \ 40 pim/otimezone.h \
41 pim/odatebookaccess.h \ 41 pim/odatebookaccess.h \
42 pim/odatebookaccessbackend.h \ 42 pim/odatebookaccessbackend.h \
43 pim/odatebookaccessbackend_xml.h \
43 orecurrancewidget.h \ 44 orecurrancewidget.h \
44 oticker.h 45 oticker.h
45# pim/otodoaccesssql.h \ 46# pim/otodoaccesssql.h \
46 47
47SOURCES = ofontmenu.cc \ 48SOURCES = ofontmenu.cc \
48 ocolorbutton.cpp \ 49 ocolorbutton.cpp \
49 sharp_compat.cpp \ 50 sharp_compat.cpp \
50 xmltree.cc \ 51 xmltree.cc \
51 ofiledialog.cc ofileselector.cc \ 52 ofiledialog.cc ofileselector.cc \
52 ocheckitem.cpp \ 53 ocheckitem.cpp \
53 colordialog.cpp \ 54 colordialog.cpp \
54 colorpopupmenu.cpp oclickablelabel.cpp \ 55 colorpopupmenu.cpp oclickablelabel.cpp \
55 oprocctrl.cpp oprocess.cpp \ 56 oprocctrl.cpp oprocess.cpp \
56 odevice.cpp odevicebutton.cpp otimepicker.cpp \ 57 odevice.cpp odevicebutton.cpp otimepicker.cpp \
57 otabwidget.cpp otabbar.cpp \ 58 otabwidget.cpp otabbar.cpp \
58 ofontselector.cpp \ 59 ofontselector.cpp \
59 pim/otodo.cpp \ 60 pim/otodo.cpp \
60 pim/opimrecord.cpp \ 61 pim/opimrecord.cpp \
61 pim/otodoaccess.cpp \ 62 pim/otodoaccess.cpp \
62 pim/otodoaccessbackend.cpp \ 63 pim/otodoaccessbackend.cpp \
63 pim/otodoaccessxml.cpp \ 64 pim/otodoaccessxml.cpp \
64 pim/ocontact.cpp \ 65 pim/ocontact.cpp \
65 pim/ocontactaccess.cpp \ 66 pim/ocontactaccess.cpp \
66 pim/ocontactaccessbackend_vcard.cpp \ 67 pim/ocontactaccessbackend_vcard.cpp \
67 pim/otodoaccessvcal.cpp \ 68 pim/otodoaccessvcal.cpp \
68 pim/orecur.cpp \ 69 pim/orecur.cpp \
69 pim/opimstate.cpp \ 70 pim/opimstate.cpp \
70 pim/opimxrefpartner.cpp \ 71 pim/opimxrefpartner.cpp \
71 pim/opimxref.cpp \ 72 pim/opimxref.cpp \
72 pim/opimxrefmanager.cpp \ 73 pim/opimxrefmanager.cpp \
73 pim/opimmaintainer.cpp \ 74 pim/opimmaintainer.cpp \
74 pim/opimnotify.cpp \ 75 pim/opimnotify.cpp \
75 pim/opimnotifymanager.cpp \ 76 pim/opimnotifymanager.cpp \
76 pim/opimmainwindow.cpp \ 77 pim/opimmainwindow.cpp \
77 pim/opimresolver.cpp \ 78 pim/opimresolver.cpp \
78 pim/oevent.cpp \ 79 pim/oevent.cpp \
79 pim/otimezone.cpp \ 80 pim/otimezone.cpp \
80 pim/odatebookaccess.cpp \ 81 pim/odatebookaccess.cpp \
81 pim/odatebookaccessbackend.cpp \ 82 pim/odatebookaccessbackend.cpp \
83 pim/odatebookaccessbackend_xml.cpp \
82 orecurrancewidget.cpp \ 84 orecurrancewidget.cpp \
83 oticker.cpp 85 oticker.cpp
84# pim/otodoaccesssql.cpp \ 86# pim/otodoaccesssql.cpp \
85 87
86TARGET = opie 88TARGET = opie
87INCLUDEPATH += $(OPIEDIR)/include 89INCLUDEPATH += $(OPIEDIR)/include
88DESTDIR = $(OPIEDIR)/lib$(PROJMAK) 90DESTDIR = $(OPIEDIR)/lib$(PROJMAK)
89#VERSION = 1.0.0 91#VERSION = 1.0.0
90 92
91LIBS += -lqpe 93LIBS += -lqpe
92 94
93# LIBS += -lopiesql 95# LIBS += -lopiesql
94 96
95INTERFACES = otimepickerbase.ui orecurrancebase.ui 97INTERFACES = otimepickerbase.ui orecurrancebase.ui
96 98
97TRANSLATIONS = ../i18n/de/libopie.ts \ 99TRANSLATIONS = ../i18n/de/libopie.ts \
98 ../i18n/xx/libopie.ts \ 100 ../i18n/xx/libopie.ts \
99 ../i18n/en/libopie.ts \ 101 ../i18n/en/libopie.ts \
100 ../i18n/es/libopie.ts \ 102 ../i18n/es/libopie.ts \
101 ../i18n/fr/libopie.ts \ 103 ../i18n/fr/libopie.ts \
102 ../i18n/hu/libopie.ts \ 104 ../i18n/hu/libopie.ts \
103 ../i18n/ja/libopie.ts \ 105 ../i18n/ja/libopie.ts \
104 ../i18n/ko/libopie.ts \ 106 ../i18n/ko/libopie.ts \
105 ../i18n/no/libopie.ts \ 107 ../i18n/no/libopie.ts \
106 ../i18n/pl/libopie.ts \ 108 ../i18n/pl/libopie.ts \
107 ../i18n/pt/libopie.ts \ 109 ../i18n/pt/libopie.ts \
108 ../i18n/pt_BR/libopie.ts \ 110 ../i18n/pt_BR/libopie.ts \
109 ../i18n/sl/libopie.ts \ 111 ../i18n/sl/libopie.ts \
110 ../i18n/zh_CN/libopie.ts \ 112 ../i18n/zh_CN/libopie.ts \
111 ../i18n/zh_TW/libopie.ts \ 113 ../i18n/zh_TW/libopie.ts \
112 ../i18n/da/libopie.ts 114 ../i18n/da/libopie.ts
113 115
114 116
115 117
116include ( $(OPIEDIR)/include.pro ) 118include ( $(OPIEDIR)/include.pro )
diff --git a/libopie/pim/obackendfactory.h b/libopie/pim/obackendfactory.h
index b796fb8..3a73210 100644
--- a/libopie/pim/obackendfactory.h
+++ b/libopie/pim/obackendfactory.h
@@ -1,113 +1,130 @@
1/* 1/*
2 * Class to manage Backends. 2 * Class to manage Backends.
3 * 3 *
4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de) 4 * Copyright (c) 2002 by Stefan Eilers (Eilers.Stefan@epost.de)
5 * 5 *
6 * ===================================================================== 6 * =====================================================================
7 *This program is free software; you can redistribute it and/or 7 *This program is free software; you can redistribute it and/or
8 *modify it under the terms of the GNU Library General Public 8 *modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; 9 * License as published by the Free Software Foundation;
10 * either version 2 of the License, or (at your option) any later 10 * either version 2 of the License, or (at your option) any later
11 * version. 11 * version.
12 * ===================================================================== 12 * =====================================================================
13 * ToDo: Use plugins 13 * ToDo: Use plugins
14 * ===================================================================== 14 * =====================================================================
15 * Version: $Id$ 15 * Version: $Id$
16 * ===================================================================== 16 * =====================================================================
17 * History: 17 * History:
18 * $Log$ 18 * $Log$
19 * Revision 1.5 2003/02/21 23:31:52 zecke
20 * Add XML datebookresource
21 * -clean up todoaccessxml header
22 * -implement some more stuff in the oeven tester
23 * -extend DefaultFactory to not crash and to use datebook
24 *
25 * -reading of OEvents is working nicely.. saving will be added
26 * tomorrow
27 * -fix spelling in ODateBookAcces
28 *
19 * Revision 1.4 2002/10/14 15:55:18 eilers 29 * Revision 1.4 2002/10/14 15:55:18 eilers
20 * Redeactivate SQL.. ;) 30 * Redeactivate SQL.. ;)
21 * 31 *
22 * Revision 1.3 2002/10/10 17:08:58 zecke 32 * Revision 1.3 2002/10/10 17:08:58 zecke
23 * The Cache is finally in place 33 * The Cache is finally in place
24 * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;) 34 * I tested it with my todolist and it 'works' for 10.000 todos the hits are awesome ;)
25 * The read ahead functionality does not make sense for XMLs backends because most of the stuff is already in memory. While using readahead on SQL makes things a lot faster.... 35 * The read ahead functionality does not make sense for XMLs backends because most of the stuff is already in memory. While using readahead on SQL makes things a lot faster....
26 * I still have to fully implement read ahead 36 * I still have to fully implement read ahead
27 * This change is bic but sc 37 * This change is bic but sc
28 * 38 *
29 * Revision 1.2 2002/10/08 09:27:36 eilers 39 * Revision 1.2 2002/10/08 09:27:36 eilers
30 * Fixed libopie.pro to include the new pim-API. 40 * Fixed libopie.pro to include the new pim-API.
31 * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to 41 * The SQL-Stuff is currently deactivated. Otherwise everyone who wants to
32 * compile itself would need to install libsqlite, libopiesql... 42 * compile itself would need to install libsqlite, libopiesql...
33 * Therefore, the backend currently uses XML only.. 43 * Therefore, the backend currently uses XML only..
34 * 44 *
35 * Revision 1.1 2002/10/07 17:35:01 eilers 45 * Revision 1.1 2002/10/07 17:35:01 eilers
36 * added OBackendFactory for advanced backend access 46 * added OBackendFactory for advanced backend access
37 * 47 *
38 * 48 *
39 * ===================================================================== 49 * =====================================================================
40 */ 50 */
41#ifndef OPIE_BACKENDFACTORY_H_ 51#ifndef OPIE_BACKENDFACTORY_H_
42#define OPIE_BACKENDFACTORY_H_ 52#define OPIE_BACKENDFACTORY_H_
43 53
44#include <qstring.h> 54#include <qstring.h>
45#include <qasciidict.h> 55#include <qasciidict.h>
46#include <qpe/config.h> 56#include <qpe/config.h>
47 57
48#include "otodoaccessxml.h" 58#include "otodoaccessxml.h"
49#include "ocontactaccessbackend_xml.h" 59#include "ocontactaccessbackend_xml.h"
60#include "odatebookaccessbackend_xml.h"
50 61
51#ifdef __USE_SQL 62#ifdef __USE_SQL
52#include "otodoaccesssql.h" 63#include "otodoaccesssql.h"
53#endif 64#endif
54 65
55 66
56template<class T> 67template<class T>
57class OBackendFactory 68class OBackendFactory
58{ 69{
59 public: 70 public:
60 OBackendFactory() {}; 71 OBackendFactory() {};
61 72
62 enum BACKENDS { 73 enum BACKENDS {
63 TODO, 74 TODO,
64 CONTACT, 75 CONTACT,
65 DATE 76 DATE
66 }; 77 };
67 78
68 static T* Default( const QString backendName, const QString& appName ){ 79 static T* Default( const QString backendName, const QString& appName ){
69 80
70 // __asm__("int3"); 81 // __asm__("int3");
71 82
72 Config config( "pimaccess" ); 83 Config config( "pimaccess" );
73 config.setGroup ( backendName ); 84 config.setGroup ( backendName );
74 QString backend = config.readEntry( "usebackend" ); 85 QString backend = config.readEntry( "usebackend" );
75 86
76 QAsciiDict<int> dict ( 3 ); 87 QAsciiDict<int> dict ( 3 );
77 dict.setAutoDelete ( TRUE ); 88 dict.setAutoDelete ( TRUE );
78 89
79 dict.insert( "todo", new int (TODO) ); 90 dict.insert( "todo", new int (TODO) );
80 dict.insert( "contact", new int (CONTACT) ); 91 dict.insert( "contact", new int (CONTACT) );
92 dict.insert( "datebook", new int(DATE) );
81 93
82 qWarning ("TODO is: %d", TODO); 94 qWarning ("TODO is: %d", TODO);
83 qWarning ("CONTACT is: %d", CONTACT); 95 qWarning ("CONTACT is: %d", CONTACT);
84 96
85 switch ( *dict.take( backendName ) ){ 97 int *find = dict[ backendName ];
98 if (!find ) return 0;
99
100 switch ( *find ){
86 case TODO: 101 case TODO:
87#ifdef __USE_SQL 102#ifdef __USE_SQL
88 if ( backend == "sql" ) 103 if ( backend == "sql" )
89 return (T*) new OTodoAccessBackendSQL(""); 104 return (T*) new OTodoAccessBackendSQL("");
90#else 105#else
91 if ( backend == "sql" ) 106 if ( backend == "sql" )
92 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); 107 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
93#endif 108#endif
94 109
95 return (T*) new OTodoAccessXML( appName ); 110 return (T*) new OTodoAccessXML( appName );
96 case CONTACT: 111 case CONTACT:
97 if ( backend == "sql" ) 112 if ( backend == "sql" )
98 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!"); 113 qWarning ("OBackendFactory:: sql Backend not implemented! Using XML instead!");
99 114
100 return (T*) new OContactAccessBackend_XML( appName ); 115 return (T*) new OContactAccessBackend_XML( appName );
101 case DATE: 116 case DATE:
102 qWarning ("OBackendFactory:: DATE-Backend not implemented!"); 117 if ( backend == "sql" )
103 return NULL; 118 qWarning("OBackendFactory:: sql Backend not implemented! Using XML instead!");
119
120 return (T*) new ODateBookAccessBackend_XML( appName );
104 default: 121 default:
105 return NULL; 122 return NULL;
106 } 123 }
107 124
108 125
109 } 126 }
110}; 127};
111 128
112 129
113#endif 130#endif
diff --git a/libopie/pim/odatebookaccess.cpp b/libopie/pim/odatebookaccess.cpp
index 5f97e7c..08e61ff 100644
--- a/libopie/pim/odatebookaccess.cpp
+++ b/libopie/pim/odatebookaccess.cpp
@@ -1,37 +1,38 @@
1#include "obackendfactory.h" 1#include "obackendfactory.h"
2#include "odatebookaccess.h" 2#include "odatebookaccess.h"
3 3
4ODateBookAccess::ODateBookAccess( ODateBookAccessBackend* back, enum Access ac ) 4ODateBookAccess::ODateBookAccess( ODateBookAccessBackend* back, enum Access ac )
5 : OPimAccessTemplate<OEvent>( back ) 5 : OPimAccessTemplate<OEvent>( back )
6{ 6{
7 if (!back ) 7 if (!back )
8 back = OBackendFactory<ODateBookAccessBackend>::Default("datebook", QString::null ); 8 back = OBackendFactory<ODateBookAccessBackend>::Default("datebook", QString::null );
9 9
10 m_backEnd = back; 10 m_backEnd = back;
11 setBackEnd( m_backEnd );
11} 12}
12ODateBookAccess::~ODateBookAccess() { 13ODateBookAccess::~ODateBookAccess() {
13} 14}
14ODateBookAccess::List ODateBookAccess::rawEvents()const { 15ODateBookAccess::List ODateBookAccess::rawEvents()const {
15 QArray<int> ints = m_backEnd->rawEvents(); 16 QArray<int> ints = m_backEnd->rawEvents();
16 17
17 List lis( ints, this ); 18 List lis( ints, this );
18 return lis; 19 return lis;
19} 20}
20ODateBookAccess::List ODateBookAccess::rawRepeats()const { 21ODateBookAccess::List ODateBookAccess::rawRepeats()const {
21 QArray<int> ints = m_backEnd->rawRepeats(); 22 QArray<int> ints = m_backEnd->rawRepeats();
22 23
23 List lis( ints, this ); 24 List lis( ints, this );
24 return lis; 25 return lis;
25} 26}
26ODateBookAccess::List ODateBookAccess::nonRepeats()const { 27ODateBookAccess::List ODateBookAccess::nonRepeats()const {
27 QArray<int> ints = m_backEnd->nonRepeats(); 28 QArray<int> ints = m_backEnd->nonRepeats();
28 29
29 List lis( ints, this ); 30 List lis( ints, this );
30 return lis; 31 return lis;
31} 32}
32OEffectiveEvent::ValueList ODateBookAccess::effecticeEvents( const QDate& from, const QDate& to ) { 33OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDate& from, const QDate& to ) {
33 return m_backEnd->effecticeEvents( from, to ); 34 return m_backEnd->effecticeEvents( from, to );
34} 35}
35OEffectiveEvent::ValueList ODateBookAccess::effecticeEvents( const QDateTime& start ) { 36OEffectiveEvent::ValueList ODateBookAccess::effectiveEvents( const QDateTime& start ) {
36 return m_backEnd->effecticeEvents( start ); 37 return m_backEnd->effecticeEvents( start );
37} 38}
diff --git a/libopie/pim/odatebookaccess.h b/libopie/pim/odatebookaccess.h
index 3f2c728..7047039 100644
--- a/libopie/pim/odatebookaccess.h
+++ b/libopie/pim/odatebookaccess.h
@@ -1,32 +1,32 @@
1#ifndef OPIE_DATE_BOOK_ACCESS_H 1#ifndef OPIE_DATE_BOOK_ACCESS_H
2#define OPIE_DATE_BOOK_ACCESS_H 2#define OPIE_DATE_BOOK_ACCESS_H
3 3
4#include "odatebookaccessbackend.h" 4#include "odatebookaccessbackend.h"
5#include "opimaccesstemplate.h" 5#include "opimaccesstemplate.h"
6 6
7#include "oevent.h" 7#include "oevent.h"
8 8
9class ODateBookAccess : public OPimAccessTemplate<OEvent> { 9class ODateBookAccess : public OPimAccessTemplate<OEvent> {
10public: 10public:
11 ODateBookAccess( ODateBookAccessBackend* = 0l, enum Access acc = Random ); 11 ODateBookAccess( ODateBookAccessBackend* = 0l, enum Access acc = Random );
12 ~ODateBookAccess(); 12 ~ODateBookAccess();
13 13
14 /** return all events */ 14 /** return all events */
15 List rawEvents()const; 15 List rawEvents()const;
16 16
17 /** return repeating events */ 17 /** return repeating events */
18 List rawRepeats()const; 18 List rawRepeats()const;
19 19
20 /** return non repeating events */ 20 /** return non repeating events */
21 List nonRepeats()const; 21 List nonRepeats()const;
22 22
23 OEffectiveEvent::ValueList effecticeEvents( const QDate& from, const QDate& to ); 23 OEffectiveEvent::ValueList effectiveEvents( const QDate& from, const QDate& to );
24 OEffectiveEvent::ValueList effecticeEvents( const QDateTime& start ); 24 OEffectiveEvent::ValueList effectiveEvents( const QDateTime& start );
25 25
26private: 26private:
27 ODateBookAccessBackend* m_backEnd; 27 ODateBookAccessBackend* m_backEnd;
28 class Private; 28 class Private;
29 Private* d; 29 Private* d;
30}; 30};
31 31
32#endif 32#endif
diff --git a/libopie/pim/odatebookaccessbackend_xml.cpp b/libopie/pim/odatebookaccessbackend_xml.cpp
new file mode 100644
index 0000000..a4c514b
--- a/dev/null
+++ b/libopie/pim/odatebookaccessbackend_xml.cpp
@@ -0,0 +1,395 @@
1#include <errno.h>
2#include <fcntl.h>
3
4#include <sys/types.h>
5#include <sys/mman.h>
6#include <sys/stat.h>
7
8#include <unistd.h>
9
10#include <qasciidict.h>
11#include <qfile.h>
12
13#include <qtopia/global.h>
14#include <qtopia/stringutil.h>
15
16#include "opimnotifymanager.h"
17#include "orecur.h"
18#include "otimezone.h"
19#include "odatebookaccessbackend_xml.h"
20
21namespace {
22 time_t start, end, created, rp_end;
23 ORecur* rec;
24 ORecur* recur() {
25 if (!rec)
26 rec = new ORecur;
27
28 return rec;
29 }
30 int alarmTime;
31 int snd;
32 enum Attribute{
33 FDescription = 0,
34 FLocation,
35 FCategories,
36 FUid,
37 FType,
38 FAlarm,
39 FSound,
40 FRType,
41 FRWeekdays,
42 FRPosition,
43 FRFreq,
44 FRHasEndDate,
45 FREndDate,
46 FRStart,
47 FREnd,
48 FNote,
49 FCreated
50 };
51}
52
53ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& ,
54 const QString& fileName )
55 : ODateBookAccessBackend() {
56 m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName;
57 m_changed = false;
58}
59ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() {
60}
61bool ODateBookAccessBackend_XML::load() {
62 return loadFile();
63}
64bool ODateBookAccessBackend_XML::reload() {
65 clear();
66 return load();
67}
68bool ODateBookAccessBackend_XML::save() {
69 if (!m_changed) return true;
70 m_changed = false;
71
72 return true;
73}
74QArray<int> ODateBookAccessBackend_XML::allRecords()const {
75 QArray<int> ints( m_raw.count()+ m_rep.count() );
76 uint i = 0;
77 QMap<int, OEvent>::ConstIterator it;
78
79 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
80 ints[i] = it.key();
81 i++;
82 }
83 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
84 ints[i] = it.key();
85 i++;
86 }
87
88 return ints;
89}
90QArray<int> ODateBookAccessBackend_XML::queryByExample(const OEvent&, int ) {
91 return QArray<int>();
92}
93void ODateBookAccessBackend_XML::clear() {
94 m_raw.clear();
95 m_rep.clear();
96}
97OEvent ODateBookAccessBackend_XML::find( int uid ) const{
98 if ( m_raw.contains( uid ) )
99 return m_raw[uid];
100 else
101 return m_rep[uid];
102}
103bool ODateBookAccessBackend_XML::add( const OEvent& ev ) {
104 m_changed = true;
105 if (ev.hasRecurrence() )
106 m_rep.insert( ev.uid(), ev );
107 else
108 m_raw.insert( ev.uid(), ev );
109
110 return true;
111}
112bool ODateBookAccessBackend_XML::remove( int uid ) {
113 m_changed = true;
114 m_rep.remove( uid );
115 m_rep.remove( uid );
116
117 return true;
118}
119bool ODateBookAccessBackend_XML::replace( const OEvent& ev ) {
120 replace( ev.uid() );
121 return add( ev );
122}
123QArray<int> ODateBookAccessBackend_XML::rawEvents()const {
124 return allRecords();
125}
126QArray<int> ODateBookAccessBackend_XML::rawRepeats()const {
127 QArray<int> ints( m_rep.count() );
128 uint i = 0;
129 QMap<int, OEvent>::ConstIterator it;
130
131 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
132 ints[i] = it.key();
133 i++;
134 }
135
136 return ints;
137}
138QArray<int> ODateBookAccessBackend_XML::nonRepeats()const {
139 QArray<int> ints( m_raw.count() );
140 uint i = 0;
141 QMap<int, OEvent>::ConstIterator it;
142
143 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
144 ints[i] = it.key();
145 i++;
146 }
147
148 return ints;
149}
150OEvent::ValueList ODateBookAccessBackend_XML::directNonRepeats() {
151 OEvent::ValueList list;
152 QMap<int, OEvent>::ConstIterator it;
153 for (it = m_raw.begin(); it != m_raw.end(); ++it )
154 list.append( it.data() );
155
156 return list;
157}
158OEvent::ValueList ODateBookAccessBackend_XML::directRawRepeats() {
159 OEvent::ValueList list;
160 QMap<int, OEvent>::ConstIterator it;
161 for (it = m_rep.begin(); it != m_rep.end(); ++it )
162 list.append( it.data() );
163
164 return list;
165}
166bool ODateBookAccessBackend_XML::loadFile() {
167 m_changed = false;
168
169 int fd = ::open( QFile::encodeName(m_name).data(), O_RDONLY );
170 if ( fd < 0 ) return false;
171
172 struct stat attribute;
173 if ( ::fstat(fd, &attribute ) == -1 ) {
174 ::close( fd );
175 return false;
176 }
177 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 );
178 if ( map_addr == ( (caddr_t)-1) ) {
179 ::close( fd );
180 return false;
181 }
182
183 ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL );
184 ::close( fd );
185
186 QAsciiDict<int> dict(FCreated+1);
187 dict.setAutoDelete( true );
188 dict.insert( "description", new int(FDescription) );
189 dict.insert( "location", new int(FLocation) );
190 dict.insert( "categories", new int(FCategories) );
191 dict.insert( "uid", new int(FUid) );
192 dict.insert( "type", new int(FType) );
193 dict.insert( "alarm", new int(FAlarm) );
194 dict.insert( "sound", new int(FSound) );
195 dict.insert( "rtype", new int(FRType) );
196 dict.insert( "rweekdays", new int(FRWeekdays) );
197 dict.insert( "rposition", new int(FRPosition) );
198 dict.insert( "rfreq", new int(FRFreq) );
199 dict.insert( "rhasenddate", new int(FRHasEndDate) );
200 dict.insert( "enddt", new int(FREndDate) );
201 dict.insert( "start", new int(FRStart) );
202 dict.insert( "end", new int(FREnd) );
203 dict.insert( "note", new int(FNote) );
204 dict.insert( "created", new int(FCreated) );
205
206 char* dt = (char*)map_addr;
207 int len = attribute.st_size;
208 int i = 0;
209 char* point;
210 const char* collectionString = "<event ";
211 int strLen = ::strlen(collectionString);
212 int *find;
213 while ( dt + 1 != 0 && (( point = ::strstr( dt+i, collectionString ) ) != 0 ) ) {
214 i = point -dt;
215 i+= strLen;
216
217 alarmTime = -1;
218 snd = 0; // silent
219
220 OEvent ev;
221 rec = 0;
222
223 while ( TRUE ) {
224 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
225 ++i;
226 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
227 break;
228
229
230 // we have another attribute, read it.
231 int j = i;
232 while ( j < len && dt[j] != '=' )
233 ++j;
234 QCString attr( dt+i, j-i+1);
235
236 i = ++j; // skip =
237
238 // find the start of quotes
239 while ( i < len && dt[i] != '"' )
240 ++i;
241 j = ++i;
242
243 bool haveUtf = FALSE;
244 bool haveEnt = FALSE;
245 while ( j < len && dt[j] != '"' ) {
246 if ( ((unsigned char)dt[j]) > 0x7f )
247 haveUtf = TRUE;
248 if ( dt[j] == '&' )
249 haveEnt = TRUE;
250 ++j;
251 }
252 if ( i == j ) {
253 // empty value
254 i = j + 1;
255 continue;
256 }
257
258 QCString value( dt+i, j-i+1 );
259 i = j + 1;
260
261 QString str = (haveUtf ? QString::fromUtf8( value )
262 : QString::fromLatin1( value ) );
263 if ( haveEnt )
264 str = Qtopia::plainString( str );
265
266 /*
267 * add key + value
268 */
269 find = dict[attr.data()];
270 if (!find)
271 ev.setCustomField( attr, value );
272 else {
273 setField( ev, *find, value );
274 }
275 }
276 /* time to finalize */
277 finalizeRecord( ev );
278 add( ev );
279 delete rec;
280 }
281 ::munmap(map_addr, attribute.st_size );
282 m_changed = false; // changed during add
283
284 return true;
285}
286void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) {
287 /* AllDay is alway in UTC */
288 if ( ev.isAllDay() ) {
289 OTimeZone utc = OTimeZone::utc();
290 ev.setStartDateTime( utc.fromUTCDateTime( start ) );
291 ev.setEndDateTime ( utc.fromUTCDateTime( end ) );
292 }else {
293 OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() );
294 ev.setStartDateTime( zone.toDateTime( start ) );
295 ev.setEndDateTime ( zone.toDateTime( end ) );
296 }
297 if ( rec && rec->doesRecur() ) {
298 OTimeZone utc = OTimeZone::utc();
299 ORecur recu( *rec ); // call copy c'tor;
300 recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() );
301 recu.setCreatedDateTime( utc.fromUTCDateTime( created ) );
302 recu.setStart( ev.startDateTime().date() );
303 ev.setRecurrence( recu );
304 }
305
306 if (alarmTime != -1 ) {
307 QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 );
308 OPimAlarm al( snd , dt );
309 ev.notifiers().add( al );
310 }
311 if ( m_raw.contains( ev.uid() ) || m_rep.contains( ev.uid() ) ) {
312 ev.setUid( 1 );
313 }
314 if ( ev.hasRecurrence() )
315 m_rep.insert( ev.uid(), ev );
316 else
317 m_raw.insert( ev.uid(), ev );
318
319}
320void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& value) {
321// qWarning(" setting %s", value.latin1() );
322 switch( id ) {
323 case FDescription:
324 e.setDescription( value );
325 break;
326 case FLocation:
327 e.setLocation( value );
328 break;
329 case FCategories:
330 e.setCategories( e.idsFromString( value ) );
331 break;
332 case FUid:
333 e.setUid( value.toInt() );
334 break;
335 case FType:
336 if ( value == "AllDay" ) {
337 e.setAllDay( true );
338 e.setTimeZone( "UTC" );
339 }
340 break;
341 case FAlarm:
342 alarmTime = value.toInt();
343 break;
344 case FSound:
345 snd = value == "loud" ? OPimAlarm::Loud : OPimAlarm::Silent;
346 break;
347 // recurrence stuff
348 case FRType:
349 if ( value == "Daily" )
350 recur()->setType( ORecur::Daily );
351 else if ( value == "Weekly" )
352 recur()->setType( ORecur::Weekly);
353 else if ( value == "MonthlyDay" )
354 recur()->setType( ORecur::MonthlyDay );
355 else if ( value == "MonthlyDate" )
356 recur()->setType( ORecur::MonthlyDate );
357 else if ( value == "Yearly" )
358 recur()->setType( ORecur::Yearly );
359 else
360 recur()->setType( ORecur::NoRepeat );
361 break;
362 case FRWeekdays:
363 recur()->setDays( value.toInt() );
364 break;
365 case FRPosition:
366 recur()->setPosition( value.toInt() );
367 break;
368 case FRFreq:
369 recur()->setFrequency( value.toInt() );
370 break;
371 case FRHasEndDate:
372 recur()->setHasEndDate( value.toInt() );
373 break;
374 case FREndDate: {
375 rp_end = (time_t) value.toLong();
376 break;
377 }
378 case FRStart: {
379 start = (time_t) value.toLong();
380 break;
381 }
382 case FREnd: {
383 end = ( (time_t) value.toLong() );
384 break;
385 }
386 case FNote:
387 e.setNote( value );
388 break;
389 case FCreated:
390 created = value.toInt();
391 break;
392 default:
393 break;
394 }
395}
diff --git a/libopie/pim/odatebookaccessbackend_xml.h b/libopie/pim/odatebookaccessbackend_xml.h
new file mode 100644
index 0000000..40f69d8
--- a/dev/null
+++ b/libopie/pim/odatebookaccessbackend_xml.h
@@ -0,0 +1,48 @@
1#ifndef OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H
2#define OPIE_DATE_BOOK_ACCESS_BACKEND_XML__H
3
4#include <qmap.h>
5
6#include "odatebookaccessbackend.h"
7
8class ODateBookAccessBackend_XML : public ODateBookAccessBackend {
9public:
10 ODateBookAccessBackend_XML( const QString& appName,
11 const QString& fileName = QString::null);
12 ~ODateBookAccessBackend_XML();
13
14 bool load();
15 bool reload();
16 bool save();
17
18 QArray<int> allRecords()const;
19 QArray<int> queryByExample( const OEvent&, int );
20 OEvent find( int uid )const;
21 void clear();
22 bool add( const OEvent& ev );
23 bool remove( int uid );
24 bool replace( const OEvent& ev );
25
26 QArray<UID> rawEvents()const;
27 QArray<UID> rawRepeats()const;
28 QArray<UID> nonRepeats()const;
29
30 OEvent::ValueList directNonRepeats();
31 OEvent::ValueList directRawRepeats();
32
33private:
34 bool m_changed :1 ;
35 bool loadFile();
36 inline void finalizeRecord( OEvent& ev );
37 inline void setField( OEvent&, int field, const QString& val );
38 QString m_name;
39 QMap<int, OEvent> m_raw;
40 QMap<int, OEvent> m_rep;
41
42 struct Data;
43 Data* data;
44 class Private;
45 Private *d;
46};
47
48#endif
diff --git a/libopie/pim/oevent.cpp b/libopie/pim/oevent.cpp
index aaae3b2..ada596c 100644
--- a/libopie/pim/oevent.cpp
+++ b/libopie/pim/oevent.cpp
@@ -1,426 +1,431 @@
1#include <qshared.h> 1#include <qshared.h>
2 2
3#include <qpe/palmtopuidgen.h> 3#include <qpe/palmtopuidgen.h>
4#include <qpe/categories.h> 4#include <qpe/categories.h>
5 5
6#include "orecur.h" 6#include "orecur.h"
7#include "opimresolver.h" 7#include "opimresolver.h"
8#include "opimnotifymanager.h" 8#include "opimnotifymanager.h"
9 9
10#include "oevent.h" 10#include "oevent.h"
11 11
12int OCalendarHelper::week( const QDate& date) { 12int OCalendarHelper::week( const QDate& date) {
13 // Calculates the week this date is in within that 13 // Calculates the week this date is in within that
14 // month. Equals the "row" is is in in the month view 14 // month. Equals the "row" is is in in the month view
15 int week = 1; 15 int week = 1;
16 QDate tmp( date.year(), date.month(), 1 ); 16 QDate tmp( date.year(), date.month(), 1 );
17 if ( date.dayOfWeek() < tmp.dayOfWeek() ) 17 if ( date.dayOfWeek() < tmp.dayOfWeek() )
18 ++week; 18 ++week;
19 19
20 week += ( date.day() - 1 ) / 7; 20 week += ( date.day() - 1 ) / 7;
21 21
22 return week; 22 return week;
23} 23}
24int OCalendarHelper::ocurrence( const QDate& date) { 24int OCalendarHelper::ocurrence( const QDate& date) {
25 // calculates the number of occurrances of this day of the 25 // calculates the number of occurrances of this day of the
26 // week till the given date (e.g 3rd Wednesday of the month) 26 // week till the given date (e.g 3rd Wednesday of the month)
27 return ( date.day() - 1 ) / 7 + 1; 27 return ( date.day() - 1 ) / 7 + 1;
28} 28}
29int OCalendarHelper::dayOfWeek( char day ) { 29int OCalendarHelper::dayOfWeek( char day ) {
30 int dayOfWeek = 1; 30 int dayOfWeek = 1;
31 char i = ORecur::MON; 31 char i = ORecur::MON;
32 while ( !( i & day ) && i <= ORecur::SUN ) { 32 while ( !( i & day ) && i <= ORecur::SUN ) {
33 i <<= 1; 33 i <<= 1;
34 ++dayOfWeek; 34 ++dayOfWeek;
35 } 35 }
36 return dayOfWeek; 36 return dayOfWeek;
37} 37}
38int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { 38int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) {
39 return ( second.year() - first.year() ) * 12 + 39 return ( second.year() - first.year() ) * 12 +
40 second.month() - first.month(); 40 second.month() - first.month();
41} 41}
42 42
43struct OEvent::Data : public QShared { 43struct OEvent::Data : public QShared {
44 Data() : QShared() { 44 Data() : QShared() {
45 recur = 0; 45 recur = 0;
46 manager = 0; 46 manager = 0;
47 isAllDay = false; 47 isAllDay = false;
48 } 48 }
49 ~Data() { 49 ~Data() {
50 delete manager; 50 delete manager;
51 delete recur; 51 delete recur;
52 } 52 }
53 QString description; 53 QString description;
54 QString location; 54 QString location;
55 OPimNotifyManager* manager; 55 OPimNotifyManager* manager;
56 ORecur* recur; 56 ORecur* recur;
57 QString note; 57 QString note;
58 QDateTime created; 58 QDateTime created;
59 QDateTime start; 59 QDateTime start;
60 QDateTime end; 60 QDateTime end;
61 bool isAllDay : 1; 61 bool isAllDay : 1;
62 QString timezone; 62 QString timezone;
63}; 63};
64 64
65OEvent::OEvent( int uid ) 65OEvent::OEvent( int uid )
66 : OPimRecord( uid ) { 66 : OPimRecord( uid ) {
67 data = new Data; 67 data = new Data;
68} 68}
69OEvent::OEvent( const OEvent& ev) 69OEvent::OEvent( const OEvent& ev)
70 : OPimRecord( ev ), data( ev.data ) 70 : OPimRecord( ev ), data( ev.data )
71{ 71{
72 data->ref(); 72 data->ref();
73} 73}
74OEvent::~OEvent() { 74OEvent::~OEvent() {
75 if ( data->deref() ) { 75 if ( data->deref() ) {
76 delete data; 76 delete data;
77 data = 0; 77 data = 0;
78 } 78 }
79} 79}
80OEvent& OEvent::operator=( const OEvent& ev) { 80OEvent& OEvent::operator=( const OEvent& ev) {
81 if ( *this == ev ) return *this; 81 if ( *this == ev ) return *this;
82 82
83 OPimRecord::operator=( ev ); 83 OPimRecord::operator=( ev );
84 ev.data->ref(); 84 ev.data->ref();
85 deref(); 85 deref();
86 data = ev.data; 86 data = ev.data;
87 87
88 88
89 return *this; 89 return *this;
90} 90}
91QString OEvent::description()const { 91QString OEvent::description()const {
92 return data->description; 92 return data->description;
93} 93}
94void OEvent::setDescription( const QString& description ) { 94void OEvent::setDescription( const QString& description ) {
95 changeOrModify(); 95 changeOrModify();
96 data->description = description; 96 data->description = description;
97} 97}
98void OEvent::setLocation( const QString& loc ) { 98void OEvent::setLocation( const QString& loc ) {
99 changeOrModify(); 99 changeOrModify();
100 data->location = loc; 100 data->location = loc;
101} 101}
102QString OEvent::location()const { 102QString OEvent::location()const {
103 return data->location; 103 return data->location;
104} 104}
105OPimNotifyManager &OEvent::notifiers() { 105OPimNotifyManager &OEvent::notifiers() {
106 // I hope we can skip the changeOrModify here 106 // I hope we can skip the changeOrModify here
107 // the notifier should take care of it 107 // the notifier should take care of it
108 // and OPimNotify is shared too 108 // and OPimNotify is shared too
109 if (!data->manager ) 109 if (!data->manager )
110 data->manager = new OPimNotifyManager; 110 data->manager = new OPimNotifyManager;
111 111
112 return *data->manager; 112 return *data->manager;
113} 113}
114bool OEvent::hasNotifiers()const { 114bool OEvent::hasNotifiers()const {
115 return ( data->manager); 115 return ( data->manager);
116} 116}
117ORecur OEvent::recurrence()const { 117ORecur OEvent::recurrence()const {
118 if (!data->recur) 118 if (!data->recur)
119 data->recur = new ORecur; 119 data->recur = new ORecur;
120 120
121 return *data->recur; 121 return *data->recur;
122} 122}
123void OEvent::setRecurrence( const ORecur& rec) { 123void OEvent::setRecurrence( const ORecur& rec) {
124 changeOrModify(); 124 changeOrModify();
125 if (data->recur ) 125 if (data->recur )
126 (*data->recur) = rec; 126 (*data->recur) = rec;
127 else 127 else
128 data->recur = new ORecur( rec ); 128 data->recur = new ORecur( rec );
129} 129}
130bool OEvent::hasRecurrence()const { 130bool OEvent::hasRecurrence()const {
131 if (!data->recur ) return false; 131 if (!data->recur ) return false;
132 return data->recur->doesRecur(); 132 return data->recur->doesRecur();
133} 133}
134QString OEvent::note()const { 134QString OEvent::note()const {
135 return data->note; 135 return data->note;
136} 136}
137void OEvent::setNote( const QString& note ) { 137void OEvent::setNote( const QString& note ) {
138 changeOrModify(); 138 changeOrModify();
139 data->note = note; 139 data->note = note;
140} 140}
141QDateTime OEvent::createdDateTime()const { 141QDateTime OEvent::createdDateTime()const {
142 return data->created; 142 return data->created;
143} 143}
144void OEvent::setCreatedDateTime( const QDateTime& time ) { 144void OEvent::setCreatedDateTime( const QDateTime& time ) {
145 changeOrModify(); 145 changeOrModify();
146 data->created = time; 146 data->created = time;
147} 147}
148QDateTime OEvent::startDateTime()const { 148QDateTime OEvent::startDateTime()const {
149 if ( data->isAllDay ) 149 if ( data->isAllDay )
150 return QDateTime( data->start.date(), QTime(0, 0, 0 ) ); 150 return QDateTime( data->start.date(), QTime(0, 0, 0 ) );
151 return data->start; 151 return data->start;
152} 152}
153QDateTime OEvent::startDateTimeInZone()const { 153QDateTime OEvent::startDateTimeInZone()const {
154 /* if no timezone, or all day event or if the current and this timeZone match... */ 154 /* if no timezone, or all day event or if the current and this timeZone match... */
155 if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime(); 155 if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return startDateTime();
156 156
157 OTimeZone zone(data->timezone ); 157 OTimeZone zone(data->timezone );
158 return zone.toDateTime( data->start, OTimeZone::current() ); 158 return zone.toDateTime( data->start, OTimeZone::current() );
159} 159}
160void OEvent::setStartDateTime( const QDateTime& dt ) { 160void OEvent::setStartDateTime( const QDateTime& dt ) {
161 changeOrModify(); 161 changeOrModify();
162 data->start = dt; 162 data->start = dt;
163} 163}
164QDateTime OEvent::endDateTime()const { 164QDateTime OEvent::endDateTime()const {
165 /* 165 /*
166 * if all Day event the end time needs 166 * if all Day event the end time needs
167 * to be on the same day as the start 167 * to be on the same day as the start
168 */ 168 */
169 if ( data->isAllDay ) 169 if ( data->isAllDay )
170 return QDateTime( data->start.date(), QTime(23, 59, 59 ) ); 170 return QDateTime( data->start.date(), QTime(23, 59, 59 ) );
171 return data->end; 171 return data->end;
172} 172}
173QDateTime OEvent::endDateTimeInZone()const { 173QDateTime OEvent::endDateTimeInZone()const {
174 /* if no timezone, or all day event or if the current and this timeZone match... */ 174 /* if no timezone, or all day event or if the current and this timeZone match... */
175 if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime(); 175 if (data->timezone.isEmpty() || data->isAllDay || data->timezone == OTimeZone::current().timeZone() ) return endDateTime();
176 176
177 OTimeZone zone(data->timezone ); 177 OTimeZone zone(data->timezone );
178 return zone.toDateTime( data->end, OTimeZone::current() ); 178 return zone.toDateTime( data->end, OTimeZone::current() );
179} 179}
180void OEvent::setEndDateTime( const QDateTime& dt ) { 180void OEvent::setEndDateTime( const QDateTime& dt ) {
181 changeOrModify(); 181 changeOrModify();
182 data->end = dt; 182 data->end = dt;
183} 183}
184bool OEvent::isMultipleDay()const { 184bool OEvent::isMultipleDay()const {
185 return data->end.date().day() - data->start.date().day(); 185 return data->end.date().day() - data->start.date().day();
186} 186}
187bool OEvent::isAllDay()const { 187bool OEvent::isAllDay()const {
188 return data->isAllDay; 188 return data->isAllDay;
189} 189}
190void OEvent::setAllDay( bool allDay ) {
191 changeOrModify();
192 data->isAllDay = allDay;
193 if (allDay ) data->timezone = "UTC";
194}
190void OEvent::setTimeZone( const QString& tz ) { 195void OEvent::setTimeZone( const QString& tz ) {
191 changeOrModify(); 196 changeOrModify();
192 data->timezone = tz; 197 data->timezone = tz;
193} 198}
194QString OEvent::timeZone()const { 199QString OEvent::timeZone()const {
195 return data->timezone; 200 return data->timezone;
196} 201}
197bool OEvent::match( const QRegExp& )const { 202bool OEvent::match( const QRegExp& )const {
198 // FIXME 203 // FIXME
199 return false; 204 return false;
200} 205}
201QString OEvent::toRichText()const { 206QString OEvent::toRichText()const {
202 // FIXME 207 // FIXME
203 return "OEvent test"; 208 return "OEvent test";
204} 209}
205QString OEvent::toShortText()const { 210QString OEvent::toShortText()const {
206 return "OEvent shotText"; 211 return "OEvent shotText";
207} 212}
208QString OEvent::type()const { 213QString OEvent::type()const {
209 return QString::fromLatin1("OEvent"); 214 return QString::fromLatin1("OEvent");
210} 215}
211QString OEvent::recordField( int /*id */ )const { 216QString OEvent::recordField( int /*id */ )const {
212 return QString::null; 217 return QString::null;
213} 218}
214int OEvent::rtti() { 219int OEvent::rtti() {
215 return OPimResolver::DateBook; 220 return OPimResolver::DateBook;
216} 221}
217bool OEvent::loadFromStream( QDataStream& ) { 222bool OEvent::loadFromStream( QDataStream& ) {
218 return true; 223 return true;
219} 224}
220bool OEvent::saveToStream( QDataStream& )const { 225bool OEvent::saveToStream( QDataStream& )const {
221 return true; 226 return true;
222} 227}
223void OEvent::changeOrModify() { 228void OEvent::changeOrModify() {
224 if ( data->count != 1 ) { 229 if ( data->count != 1 ) {
225 data->deref(); 230 data->deref();
226 Data* d2 = new Data; 231 Data* d2 = new Data;
227 d2->description = data->description; 232 d2->description = data->description;
228 d2->location = data->location; 233 d2->location = data->location;
229 d2->manager = data->manager; 234 d2->manager = data->manager;
230 d2->recur = data->recur; 235 d2->recur = data->recur;
231 d2->note = data->note; 236 d2->note = data->note;
232 d2->created = data->created; 237 d2->created = data->created;
233 d2->start = data->start; 238 d2->start = data->start;
234 d2->end = data->end; 239 d2->end = data->end;
235 d2->isAllDay = data->isAllDay; 240 d2->isAllDay = data->isAllDay;
236 d2->timezone = data->timezone; 241 d2->timezone = data->timezone;
237 242
238 data = d2; 243 data = d2;
239 } 244 }
240} 245}
241void OEvent::deref() { 246void OEvent::deref() {
242 if ( data->deref() ) { 247 if ( data->deref() ) {
243 delete data; 248 delete data;
244 data = 0; 249 data = 0;
245 } 250 }
246} 251}
247// FIXME 252// FIXME
248QMap<int, QString> OEvent::toMap()const { 253QMap<int, QString> OEvent::toMap()const {
249 return QMap<int, QString>(); 254 return QMap<int, QString>();
250} 255}
251QMap<QString, QString> OEvent::toExtraMap()const { 256QMap<QString, QString> OEvent::toExtraMap()const {
252 return QMap<QString, QString>(); 257 return QMap<QString, QString>();
253} 258}
254 259
255 260
256struct OEffectiveEvent::Data : public QShared { 261struct OEffectiveEvent::Data : public QShared {
257 Data() : QShared() { 262 Data() : QShared() {
258 } 263 }
259 OEvent event; 264 OEvent event;
260 QDate date; 265 QDate date;
261 QTime start, end; 266 QTime start, end;
262 QDate startDate, endDate; 267 QDate startDate, endDate;
263 bool dates : 1; 268 bool dates : 1;
264}; 269};
265 270
266OEffectiveEvent::OEffectiveEvent() { 271OEffectiveEvent::OEffectiveEvent() {
267 data = new Data; 272 data = new Data;
268 data->date = QDate::currentDate(); 273 data->date = QDate::currentDate();
269 data->start = data->end = QTime::currentTime(); 274 data->start = data->end = QTime::currentTime();
270 data->dates = false; 275 data->dates = false;
271} 276}
272OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate, 277OEffectiveEvent::OEffectiveEvent( const OEvent& ev, const QDate& startDate,
273 Position pos ) { 278 Position pos ) {
274 data = new Data; 279 data = new Data;
275 data->event = ev; 280 data->event = ev;
276 data->date = startDate; 281 data->date = startDate;
277 if ( pos & Start ) 282 if ( pos & Start )
278 data->start = ev.startDateTime().time(); 283 data->start = ev.startDateTime().time();
279 else 284 else
280 data->start = QTime( 0, 0, 0 ); 285 data->start = QTime( 0, 0, 0 );
281 286
282 if ( pos & End ) 287 if ( pos & End )
283 data->end = ev.endDateTime().time(); 288 data->end = ev.endDateTime().time();
284 else 289 else
285 data->end = QTime( 23, 59, 59 ); 290 data->end = QTime( 23, 59, 59 );
286 291
287 data->dates = false; 292 data->dates = false;
288} 293}
289OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) { 294OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev) {
290 data = ev.data; 295 data = ev.data;
291 data->ref(); 296 data->ref();
292} 297}
293OEffectiveEvent::~OEffectiveEvent() { 298OEffectiveEvent::~OEffectiveEvent() {
294 if ( data->deref() ) { 299 if ( data->deref() ) {
295 delete data; 300 delete data;
296 data = 0; 301 data = 0;
297 } 302 }
298} 303}
299OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) { 304OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) {
300 if ( *this == ev ) return *this; 305 if ( *this == ev ) return *this;
301 306
302 ev.data->ref(); 307 ev.data->ref();
303 deref(); 308 deref();
304 data = ev.data; 309 data = ev.data;
305 310
306 return *this; 311 return *this;
307} 312}
308 313
309void OEffectiveEvent::setStartTime( const QTime& ti) { 314void OEffectiveEvent::setStartTime( const QTime& ti) {
310 changeOrModify(); 315 changeOrModify();
311 data->start = ti; 316 data->start = ti;
312} 317}
313void OEffectiveEvent::setEndTime( const QTime& en) { 318void OEffectiveEvent::setEndTime( const QTime& en) {
314 changeOrModify(); 319 changeOrModify();
315 data->end = en; 320 data->end = en;
316} 321}
317void OEffectiveEvent::setEvent( const OEvent& ev) { 322void OEffectiveEvent::setEvent( const OEvent& ev) {
318 changeOrModify(); 323 changeOrModify();
319 data->event = ev; 324 data->event = ev;
320} 325}
321void OEffectiveEvent::setDate( const QDate& da) { 326void OEffectiveEvent::setDate( const QDate& da) {
322 changeOrModify(); 327 changeOrModify();
323 data->date = da; 328 data->date = da;
324} 329}
325void OEffectiveEvent::setEffectiveDates( const QDate& from, 330void OEffectiveEvent::setEffectiveDates( const QDate& from,
326 const QDate& to ) { 331 const QDate& to ) {
327 if (!from.isValid() ) { 332 if (!from.isValid() ) {
328 data->dates = false; 333 data->dates = false;
329 return; 334 return;
330 } 335 }
331 336
332 data->startDate = from; 337 data->startDate = from;
333 data->endDate = to; 338 data->endDate = to;
334} 339}
335QString OEffectiveEvent::description()const { 340QString OEffectiveEvent::description()const {
336 return data->event.description(); 341 return data->event.description();
337} 342}
338QString OEffectiveEvent::location()const { 343QString OEffectiveEvent::location()const {
339 return data->event.location(); 344 return data->event.location();
340} 345}
341QString OEffectiveEvent::note()const { 346QString OEffectiveEvent::note()const {
342 return data->event.note(); 347 return data->event.note();
343} 348}
344OEvent OEffectiveEvent::event()const { 349OEvent OEffectiveEvent::event()const {
345 return data->event; 350 return data->event;
346} 351}
347QTime OEffectiveEvent::startTime()const { 352QTime OEffectiveEvent::startTime()const {
348 return data->start; 353 return data->start;
349} 354}
350QTime OEffectiveEvent::endTime()const { 355QTime OEffectiveEvent::endTime()const {
351 return data->end; 356 return data->end;
352} 357}
353QDate OEffectiveEvent::date()const { 358QDate OEffectiveEvent::date()const {
354 return data->date; 359 return data->date;
355} 360}
356int OEffectiveEvent::length()const { 361int OEffectiveEvent::length()const {
357 return (data->end.hour() * 60 - data->start.hour() * 60) 362 return (data->end.hour() * 60 - data->start.hour() * 60)
358 + QABS(data->start.minute() - data->end.minute() ); 363 + QABS(data->start.minute() - data->end.minute() );
359} 364}
360int OEffectiveEvent::size()const { 365int OEffectiveEvent::size()const {
361 return ( data->end.hour() - data->start.hour() ) * 3600 366 return ( data->end.hour() - data->start.hour() ) * 3600
362 + (data->end.minute() - data->start.minute() * 60 367 + (data->end.minute() - data->start.minute() * 60
363 + data->end.second() - data->start.second() ); 368 + data->end.second() - data->start.second() );
364} 369}
365QDate OEffectiveEvent::startDate()const { 370QDate OEffectiveEvent::startDate()const {
366 if ( data->dates ) 371 if ( data->dates )
367 return data->startDate; 372 return data->startDate;
368 else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer 373 else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer
369 return data->date; 374 return data->date;
370 else 375 else
371 return data->event.startDateTime().date(); 376 return data->event.startDateTime().date();
372} 377}
373QDate OEffectiveEvent::endDate()const { 378QDate OEffectiveEvent::endDate()const {
374 if ( data->dates ) 379 if ( data->dates )
375 return data->endDate; 380 return data->endDate;
376 else if ( data->event.hasRecurrence() ) 381 else if ( data->event.hasRecurrence() )
377 return data->date; 382 return data->date;
378 else 383 else
379 return data->event.endDateTime().date(); 384 return data->event.endDateTime().date();
380} 385}
381void OEffectiveEvent::deref() { 386void OEffectiveEvent::deref() {
382 if ( data->deref() ) { 387 if ( data->deref() ) {
383 delete data; 388 delete data;
384 data = 0; 389 data = 0;
385 } 390 }
386} 391}
387void OEffectiveEvent::changeOrModify() { 392void OEffectiveEvent::changeOrModify() {
388 if ( data->count != 1 ) { 393 if ( data->count != 1 ) {
389 data->deref(); 394 data->deref();
390 Data* d2 = new Data; 395 Data* d2 = new Data;
391 d2->event = data->event; 396 d2->event = data->event;
392 d2->date = data->date; 397 d2->date = data->date;
393 d2->start = data->start; 398 d2->start = data->start;
394 d2->end = data->end; 399 d2->end = data->end;
395 d2->startDate = data->startDate; 400 d2->startDate = data->startDate;
396 d2->endDate = data->endDate; 401 d2->endDate = data->endDate;
397 d2->dates = data->dates; 402 d2->dates = data->dates;
398 data = d2; 403 data = d2;
399 } 404 }
400} 405}
401bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{ 406bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const{
402 if ( data->date < e.date() ) 407 if ( data->date < e.date() )
403 return TRUE; 408 return TRUE;
404 if ( data->date == e.date() ) 409 if ( data->date == e.date() )
405 return ( startTime() < e.startTime() ); 410 return ( startTime() < e.startTime() );
406 else 411 else
407 return FALSE; 412 return FALSE;
408} 413}
409bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const{ 414bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const{
410 return (data->date <= e.date() ); 415 return (data->date <= e.date() );
411} 416}
412bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const { 417bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const {
413 return ( date() == e.date() 418 return ( date() == e.date()
414 && startTime() == e.startTime() 419 && startTime() == e.startTime()
415 && endTime()== e.endTime() 420 && endTime()== e.endTime()
416 && event() == e.event() ); 421 && event() == e.event() );
417} 422}
418bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const { 423bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const {
419 return !(*this == e ); 424 return !(*this == e );
420} 425}
421bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const { 426bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const {
422 return !(*this <= e ); 427 return !(*this <= e );
423} 428}
424bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const { 429bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const {
425 return !(*this < e); 430 return !(*this < e);
426} 431}
diff --git a/libopie/pim/opimnotify.h b/libopie/pim/opimnotify.h
index 3501948..b0de000 100644
--- a/libopie/pim/opimnotify.h
+++ b/libopie/pim/opimnotify.h
@@ -1,142 +1,142 @@
1#ifndef OPIE_PIM_NOTIFY_H 1#ifndef OPIE_PIM_NOTIFY_H
2#define OPIE_PIM_NOTIFY_H 2#define OPIE_PIM_NOTIFY_H
3 3
4#include <qdatetime.h> 4#include <qdatetime.h>
5#include <qvaluelist.h> 5#include <qvaluelist.h>
6 6
7/** 7/**
8 * This is the base class of Notifiers. Possible 8 * This is the base class of Notifiers. Possible
9 * notifiers would be Alarms, Reminders 9 * notifiers would be Alarms, Reminders
10 * What they share is that they have 10 * What they share is that they have
11 * A DateTime, Type, Duration 11 * A DateTime, Type, Duration
12 * This is what this base class takes care of 12 * This is what this base class takes care of
13 * on top of that it's shared 13 * on top of that it's shared
14 */ 14 */
15/* 15/*
16 * TALK to eilers: have a class OPimDuration which sets the Duration 16 * TALK to eilers: have a class OPimDuration which sets the Duration
17 * given on the Due/Start Date? -zecke 17 * given on the Due/Start Date? -zecke
18 * discuss: do we need a uid for the notify? -zecke 18 * discuss: do we need a uid for the notify? -zecke
19 */ 19 */
20class OPimNotify { 20class OPimNotify {
21public: 21public:
22 typedef QValueList<OPimNotify> ValueList; 22 typedef QValueList<OPimNotify> ValueList;
23 OPimNotify( const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 ); 23 OPimNotify( const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 );
24 OPimNotify( const OPimNotify& ); 24 OPimNotify( const OPimNotify& );
25 virtual ~OPimNotify(); 25 virtual ~OPimNotify();
26 26
27 OPimNotify &operator=(const OPimNotify& ); 27 OPimNotify &operator=(const OPimNotify& );
28 bool operator==( const OPimNotify& ); 28 bool operator==( const OPimNotify& );
29 29
30 virtual QString type()const = 0; 30 virtual QString type()const = 0;
31 31
32 /** start date */ 32 /** start date */
33 QDateTime dateTime()const; 33 QDateTime dateTime()const;
34 QString service()const; 34 QString service()const;
35 35
36 /** 36 /**
37 * RETURN the parent uid 37 * RETURN the parent uid
38 */ 38 */
39 int parent()const; 39 int parent()const;
40 40
41 /** 41 /**
42 * in Seconds 42 * in Seconds
43 */ 43 */
44 int duration()const; 44 int duration()const;
45 45
46 /** 46 /**
47 * Start Time + Duration 47 * Start Time + Duration
48 */ 48 */
49 QDateTime endTime()const; 49 QDateTime endTime()const;
50 50
51 void setDateTime( const QDateTime& ); 51 void setDateTime( const QDateTime& );
52 void setDuration( int dur ); 52 void setDuration( int dur );
53 void setParent(int uid ); 53 void setParent(int uid );
54 void setService( const QString& ); 54 void setService( const QString& );
55 55
56 56
57private: 57private:
58 inline void copyIntern(); 58 inline void copyIntern();
59 void deref(); 59 void deref();
60 struct Data; 60 struct Data;
61 Data* data; 61 Data* data;
62 62
63 /* d-pointer */ 63 /* d-pointer */
64 class NotifyPrivate; 64 class NotifyPrivate;
65 NotifyPrivate* d; 65 NotifyPrivate* d;
66 66
67}; 67};
68/** 68/**
69 * An alarm is a sound/mail/buzzer played/send 69 * An alarm is a sound/mail/buzzer played/send
70 * at a given time to inform about 70 * at a given time to inform about
71 * an Event 71 * an Event
72 */ 72 */
73class OPimAlarm : public OPimNotify { 73class OPimAlarm : public OPimNotify {
74public: 74public:
75 enum Sound{Loud=0, Silent, Custom }; 75 enum Sound{Loud=1, Silent=0, Custom=2 };
76 OPimAlarm( int sound = Silent, const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 ); 76 OPimAlarm( int sound = Silent, const QDateTime& start = QDateTime(), int duration = 0, int parent = 0 );
77 OPimAlarm( const OPimAlarm& ); 77 OPimAlarm( const OPimAlarm& );
78 ~OPimAlarm(); 78 ~OPimAlarm();
79 79
80 OPimAlarm &operator=( const OPimAlarm& ); 80 OPimAlarm &operator=( const OPimAlarm& );
81 bool operator==( const OPimAlarm& ); 81 bool operator==( const OPimAlarm& );
82 QString type()const; 82 QString type()const;
83 83
84 int sound()const; 84 int sound()const;
85 QString file()const; 85 QString file()const;
86 86
87 void setSound( int ); 87 void setSound( int );
88 /* only when sound is custom... */ 88 /* only when sound is custom... */
89 void setFile( const QString& sound ); 89 void setFile( const QString& sound );
90 90
91private: 91private:
92 void deref(); 92 void deref();
93 void copyIntern(); 93 void copyIntern();
94 struct Data; 94 struct Data;
95 Data * data; 95 Data * data;
96 96
97 class Private; 97 class Private;
98 Private* d; 98 Private* d;
99 99
100}; 100};
101 101
102/** 102/**
103 * A Reminder will be put into the 103 * A Reminder will be put into the
104 * datebook 104 * datebook
105 */ 105 */
106class OPimReminder : public OPimNotify { 106class OPimReminder : public OPimNotify {
107public: 107public:
108 108
109 /** 109 /**
110 * c'tor of a reminder 110 * c'tor of a reminder
111 * @param uid The uid of the Record inside the Datebook 111 * @param uid The uid of the Record inside the Datebook
112 * @param start the StartDate invalid for all day... 112 * @param start the StartDate invalid for all day...
113 * @param duration The duration of the event ( -1 for all day ) 113 * @param duration The duration of the event ( -1 for all day )
114 * @param parent The 'parent' record of this reminder 114 * @param parent The 'parent' record of this reminder
115 */ 115 */
116 OPimReminder( int uid = 0, const QDateTime& start = QDateTime(), 116 OPimReminder( int uid = 0, const QDateTime& start = QDateTime(),
117 int duration = 0, int parent = 0 ); 117 int duration = 0, int parent = 0 );
118 OPimReminder( const OPimReminder& ); 118 OPimReminder( const OPimReminder& );
119 OPimReminder &operator=(const OPimReminder& ); 119 OPimReminder &operator=(const OPimReminder& );
120 120
121 QString type()const; 121 QString type()const;
122 122
123 bool operator==( const OPimReminder& ); 123 bool operator==( const OPimReminder& );
124 124
125 /** 125 /**
126 * the uid of the alarm 126 * the uid of the alarm
127 * inside the 'datebook' application 127 * inside the 'datebook' application
128 */ 128 */
129 int recordUid()const; 129 int recordUid()const;
130 void setRecordUid( int uid ); 130 void setRecordUid( int uid );
131 131
132private: 132private:
133 void deref(); 133 void deref();
134 void copyIntern(); 134 void copyIntern();
135 135
136 struct Data; 136 struct Data;
137 Data* data; 137 Data* data;
138 class Private; 138 class Private;
139 Private *d; 139 Private *d;
140}; 140};
141 141
142#endif 142#endif
diff --git a/libopie/pim/otodoaccessxml.cpp b/libopie/pim/otodoaccessxml.cpp
index c3416cb..22b2469 100644
--- a/libopie/pim/otodoaccessxml.cpp
+++ b/libopie/pim/otodoaccessxml.cpp
@@ -1,649 +1,647 @@
1#include <errno.h> 1#include <errno.h>
2#include <fcntl.h> 2#include <fcntl.h>
3 3
4#include <sys/mman.h> 4#include <sys/mman.h>
5#include <sys/stat.h> 5#include <sys/stat.h>
6#include <sys/types.h> 6#include <sys/types.h>
7 7
8#include <unistd.h> 8#include <unistd.h>
9 9
10 10
11#include <qfile.h> 11#include <qfile.h>
12#include <qvector.h> 12#include <qvector.h>
13 13
14#include <qpe/global.h> 14#include <qpe/global.h>
15#include <qpe/stringutil.h> 15#include <qpe/stringutil.h>
16#include <qpe/timeconversion.h> 16#include <qpe/timeconversion.h>
17 17
18#include <opie/xmltree.h>
19
20#include "otodoaccessxml.h" 18#include "otodoaccessxml.h"
21 19
22OTodoAccessXML::OTodoAccessXML( const QString& appName, 20OTodoAccessXML::OTodoAccessXML( const QString& appName,
23 const QString& fileName ) 21 const QString& fileName )
24 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false ) 22 : OTodoAccessBackend(), m_app( appName ), m_opened( false ), m_changed( false )
25{ 23{
26 if (!fileName.isEmpty() ) 24 if (!fileName.isEmpty() )
27 m_file = fileName; 25 m_file = fileName;
28 else 26 else
29 m_file = Global::applicationFileName( "todolist", "todolist.xml" ); 27 m_file = Global::applicationFileName( "todolist", "todolist.xml" );
30} 28}
31OTodoAccessXML::~OTodoAccessXML() { 29OTodoAccessXML::~OTodoAccessXML() {
32 30
33} 31}
34bool OTodoAccessXML::load() { 32bool OTodoAccessXML::load() {
35 m_opened = true; 33 m_opened = true;
36 m_changed = false; 34 m_changed = false;
37 /* initialize dict */ 35 /* initialize dict */
38 /* 36 /*
39 * UPDATE dict if you change anything!!! 37 * UPDATE dict if you change anything!!!
40 */ 38 */
41 QAsciiDict<int> dict(21); 39 QAsciiDict<int> dict(21);
42 dict.setAutoDelete( TRUE ); 40 dict.setAutoDelete( TRUE );
43 dict.insert("Categories" , new int(OTodo::Category) ); 41 dict.insert("Categories" , new int(OTodo::Category) );
44 dict.insert("Uid" , new int(OTodo::Uid) ); 42 dict.insert("Uid" , new int(OTodo::Uid) );
45 dict.insert("HasDate" , new int(OTodo::HasDate) ); 43 dict.insert("HasDate" , new int(OTodo::HasDate) );
46 dict.insert("Completed" , new int(OTodo::Completed) ); 44 dict.insert("Completed" , new int(OTodo::Completed) );
47 dict.insert("Description" , new int(OTodo::Description) ); 45 dict.insert("Description" , new int(OTodo::Description) );
48 dict.insert("Summary" , new int(OTodo::Summary) ); 46 dict.insert("Summary" , new int(OTodo::Summary) );
49 dict.insert("Priority" , new int(OTodo::Priority) ); 47 dict.insert("Priority" , new int(OTodo::Priority) );
50 dict.insert("DateDay" , new int(OTodo::DateDay) ); 48 dict.insert("DateDay" , new int(OTodo::DateDay) );
51 dict.insert("DateMonth" , new int(OTodo::DateMonth) ); 49 dict.insert("DateMonth" , new int(OTodo::DateMonth) );
52 dict.insert("DateYear" , new int(OTodo::DateYear) ); 50 dict.insert("DateYear" , new int(OTodo::DateYear) );
53 dict.insert("Progress" , new int(OTodo::Progress) ); 51 dict.insert("Progress" , new int(OTodo::Progress) );
54 dict.insert("Completed", new int(OTodo::Completed) ); 52 dict.insert("Completed", new int(OTodo::Completed) );
55 dict.insert("CrossReference", new int(OTodo::CrossReference) ); 53 dict.insert("CrossReference", new int(OTodo::CrossReference) );
56 dict.insert("State", new int(OTodo::State) ); 54 dict.insert("State", new int(OTodo::State) );
57 dict.insert("Recurrence", new int(OTodo::Recurrence) ); 55 dict.insert("Recurrence", new int(OTodo::Recurrence) );
58 dict.insert("Alarms", new int(OTodo::Alarms) ); 56 dict.insert("Alarms", new int(OTodo::Alarms) );
59 dict.insert("Reminders", new int(OTodo::Reminders) ); 57 dict.insert("Reminders", new int(OTodo::Reminders) );
60 dict.insert("Notifiers", new int(OTodo::Notifiers) ); 58 dict.insert("Notifiers", new int(OTodo::Notifiers) );
61 dict.insert("Maintainer", new int(OTodo::Maintainer) ); 59 dict.insert("Maintainer", new int(OTodo::Maintainer) );
62 60
63 // here the custom XML parser from TT it's GPL 61 // here the custom XML parser from TT it's GPL
64 // but we want to push OpiePIM... to TT..... 62 // but we want to push OpiePIM... to TT.....
65 // mmap part from zecke :) 63 // mmap part from zecke :)
66 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY ); 64 int fd = ::open( QFile::encodeName(m_file).data(), O_RDONLY );
67 struct stat attribut; 65 struct stat attribut;
68 if ( fd < 0 ) return false; 66 if ( fd < 0 ) return false;
69 67
70 if ( fstat(fd, &attribut ) == -1 ) { 68 if ( fstat(fd, &attribut ) == -1 ) {
71 ::close( fd ); 69 ::close( fd );
72 return false; 70 return false;
73 } 71 }
74 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 72 void* map_addr = ::mmap(NULL, attribut.st_size, PROT_READ, MAP_SHARED, fd, 0 );
75 if ( map_addr == ( (caddr_t)-1) ) { 73 if ( map_addr == ( (caddr_t)-1) ) {
76 ::close(fd ); 74 ::close(fd );
77 return false; 75 return false;
78 } 76 }
79 /* advise the kernel who we want to read it */ 77 /* advise the kernel who we want to read it */
80 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL ); 78 ::madvise( map_addr, attribut.st_size, MADV_SEQUENTIAL );
81 /* we do not the file any more */ 79 /* we do not the file any more */
82 ::close( fd ); 80 ::close( fd );
83 81
84 char* dt = (char*)map_addr; 82 char* dt = (char*)map_addr;
85 int len = attribut.st_size; 83 int len = attribut.st_size;
86 int i = 0; 84 int i = 0;
87 char *point; 85 char *point;
88 const char* collectionString = "<Task "; 86 const char* collectionString = "<Task ";
89 int strLen = strlen(collectionString); 87 int strLen = strlen(collectionString);
90 while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) { 88 while ( dt+i != 0 && ( point = strstr( dt+i, collectionString ) ) != 0l ) {
91 i = point -dt; 89 i = point -dt;
92 i+= strLen; 90 i+= strLen;
93 qWarning("Found a start at %d %d", i, (point-dt) ); 91 qWarning("Found a start at %d %d", i, (point-dt) );
94 92
95 OTodo ev; 93 OTodo ev;
96 m_year = m_month = m_day = 0; 94 m_year = m_month = m_day = 0;
97 95
98 while ( TRUE ) { 96 while ( TRUE ) {
99 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') ) 97 while ( i < len && (dt[i] == ' ' || dt[i] == '\n' || dt[i] == '\r') )
100 ++i; 98 ++i;
101 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') ) 99 if ( i >= len-2 || (dt[i] == '/' && dt[i+1] == '>') )
102 break; 100 break;
103 101
104 // we have another attribute, read it. 102 // we have another attribute, read it.
105 int j = i; 103 int j = i;
106 while ( j < len && dt[j] != '=' ) 104 while ( j < len && dt[j] != '=' )
107 ++j; 105 ++j;
108 QCString attr( dt+i, j-i+1); 106 QCString attr( dt+i, j-i+1);
109 107
110 i = ++j; // skip = 108 i = ++j; // skip =
111 109
112 // find the start of quotes 110 // find the start of quotes
113 while ( i < len && dt[i] != '"' ) 111 while ( i < len && dt[i] != '"' )
114 ++i; 112 ++i;
115 j = ++i; 113 j = ++i;
116 114
117 bool haveUtf = FALSE; 115 bool haveUtf = FALSE;
118 bool haveEnt = FALSE; 116 bool haveEnt = FALSE;
119 while ( j < len && dt[j] != '"' ) { 117 while ( j < len && dt[j] != '"' ) {
120 if ( ((unsigned char)dt[j]) > 0x7f ) 118 if ( ((unsigned char)dt[j]) > 0x7f )
121 haveUtf = TRUE; 119 haveUtf = TRUE;
122 if ( dt[j] == '&' ) 120 if ( dt[j] == '&' )
123 haveEnt = TRUE; 121 haveEnt = TRUE;
124 ++j; 122 ++j;
125 } 123 }
126 if ( i == j ) { 124 if ( i == j ) {
127 // empty value 125 // empty value
128 i = j + 1; 126 i = j + 1;
129 continue; 127 continue;
130 } 128 }
131 129
132 QCString value( dt+i, j-i+1 ); 130 QCString value( dt+i, j-i+1 );
133 i = j + 1; 131 i = j + 1;
134 132
135 QString str = (haveUtf ? QString::fromUtf8( value ) 133 QString str = (haveUtf ? QString::fromUtf8( value )
136 : QString::fromLatin1( value ) ); 134 : QString::fromLatin1( value ) );
137 if ( haveEnt ) 135 if ( haveEnt )
138 str = Qtopia::plainString( str ); 136 str = Qtopia::plainString( str );
139 137
140 /* 138 /*
141 * add key + value 139 * add key + value
142 */ 140 */
143 todo( &dict, ev, attr, str ); 141 todo( &dict, ev, attr, str );
144 142
145 } 143 }
146 /* 144 /*
147 * now add it 145 * now add it
148 */ 146 */
149 qWarning("End at %d", i ); 147 qWarning("End at %d", i );
150 if (m_events.contains( ev.uid() ) || ev.uid() == 0) { 148 if (m_events.contains( ev.uid() ) || ev.uid() == 0) {
151 ev.setUid( 1 ); 149 ev.setUid( 1 );
152 m_changed = true; 150 m_changed = true;
153 } 151 }
154 if ( ev.hasDueDate() ) { 152 if ( ev.hasDueDate() ) {
155 ev.setDueDate( QDate(m_year, m_month, m_day) ); 153 ev.setDueDate( QDate(m_year, m_month, m_day) );
156 } 154 }
157 m_events.insert(ev.uid(), ev ); 155 m_events.insert(ev.uid(), ev );
158 m_year = m_month = m_day = -1; 156 m_year = m_month = m_day = -1;
159 } 157 }
160 158
161 munmap(map_addr, attribut.st_size ); 159 munmap(map_addr, attribut.st_size );
162 160
163 qWarning("counts %d records loaded!", m_events.count() ); 161 qWarning("counts %d records loaded!", m_events.count() );
164 return true; 162 return true;
165} 163}
166bool OTodoAccessXML::reload() { 164bool OTodoAccessXML::reload() {
167 m_events.clear(); 165 m_events.clear();
168 return load(); 166 return load();
169} 167}
170bool OTodoAccessXML::save() { 168bool OTodoAccessXML::save() {
171// qWarning("saving"); 169// qWarning("saving");
172 if (!m_opened || !m_changed ) { 170 if (!m_opened || !m_changed ) {
173// qWarning("not saving"); 171// qWarning("not saving");
174 return true; 172 return true;
175 } 173 }
176 QString strNewFile = m_file + ".new"; 174 QString strNewFile = m_file + ".new";
177 QFile f( strNewFile ); 175 QFile f( strNewFile );
178 if (!f.open( IO_WriteOnly|IO_Raw ) ) 176 if (!f.open( IO_WriteOnly|IO_Raw ) )
179 return false; 177 return false;
180 178
181 int written; 179 int written;
182 QString out; 180 QString out;
183 out = "<!DOCTYPE Tasks>\n<Tasks>\n"; 181 out = "<!DOCTYPE Tasks>\n<Tasks>\n";
184 182
185 // for all todos 183 // for all todos
186 QMap<int, OTodo>::Iterator it; 184 QMap<int, OTodo>::Iterator it;
187 for (it = m_events.begin(); it != m_events.end(); ++it ) { 185 for (it = m_events.begin(); it != m_events.end(); ++it ) {
188 out+= "<Task " + toString( (*it) ) + " />\n"; 186 out+= "<Task " + toString( (*it) ) + " />\n";
189 QCString cstr = out.utf8(); 187 QCString cstr = out.utf8();
190 written = f.writeBlock( cstr.data(), cstr.length() ); 188 written = f.writeBlock( cstr.data(), cstr.length() );
191 189
192 /* less written then we wanted */ 190 /* less written then we wanted */
193 if ( written != (int)cstr.length() ) { 191 if ( written != (int)cstr.length() ) {
194 f.close(); 192 f.close();
195 QFile::remove( strNewFile ); 193 QFile::remove( strNewFile );
196 return false; 194 return false;
197 } 195 }
198 out = QString::null; 196 out = QString::null;
199 } 197 }
200 198
201 out += "</Tasks>"; 199 out += "</Tasks>";
202 QCString cstr = out.utf8(); 200 QCString cstr = out.utf8();
203 written = f.writeBlock( cstr.data(), cstr.length() ); 201 written = f.writeBlock( cstr.data(), cstr.length() );
204 202
205 if ( written != (int)cstr.length() ) { 203 if ( written != (int)cstr.length() ) {
206 f.close(); 204 f.close();
207 QFile::remove( strNewFile ); 205 QFile::remove( strNewFile );
208 return false; 206 return false;
209 } 207 }
210 /* flush before renaming */ 208 /* flush before renaming */
211 f.close(); 209 f.close();
212 210
213 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) { 211 if( ::rename( strNewFile.latin1(), m_file.latin1() ) < 0 ) {
214// qWarning("error renaming"); 212// qWarning("error renaming");
215 QFile::remove( strNewFile ); 213 QFile::remove( strNewFile );
216 } 214 }
217 215
218 m_changed = false; 216 m_changed = false;
219 return true; 217 return true;
220} 218}
221QArray<int> OTodoAccessXML::allRecords()const { 219QArray<int> OTodoAccessXML::allRecords()const {
222 QArray<int> ids( m_events.count() ); 220 QArray<int> ids( m_events.count() );
223 QMap<int, OTodo>::ConstIterator it; 221 QMap<int, OTodo>::ConstIterator it;
224 int i = 0; 222 int i = 0;
225 223
226 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 224 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
227 ids[i] = it.key(); 225 ids[i] = it.key();
228 i++; 226 i++;
229 } 227 }
230 return ids; 228 return ids;
231} 229}
232QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int ) { 230QArray<int> OTodoAccessXML::queryByExample( const OTodo&, int ) {
233 QArray<int> ids(0); 231 QArray<int> ids(0);
234 return ids; 232 return ids;
235} 233}
236OTodo OTodoAccessXML::find( int uid )const { 234OTodo OTodoAccessXML::find( int uid )const {
237 OTodo todo; 235 OTodo todo;
238 todo.setUid( 0 ); // isEmpty() 236 todo.setUid( 0 ); // isEmpty()
239 QMap<int, OTodo>::ConstIterator it = m_events.find( uid ); 237 QMap<int, OTodo>::ConstIterator it = m_events.find( uid );
240 if ( it != m_events.end() ) 238 if ( it != m_events.end() )
241 todo = it.data(); 239 todo = it.data();
242 240
243 return todo; 241 return todo;
244} 242}
245void OTodoAccessXML::clear() { 243void OTodoAccessXML::clear() {
246 if (m_opened ) 244 if (m_opened )
247 m_changed = true; 245 m_changed = true;
248 246
249 m_events.clear(); 247 m_events.clear();
250} 248}
251bool OTodoAccessXML::add( const OTodo& todo ) { 249bool OTodoAccessXML::add( const OTodo& todo ) {
252// qWarning("add"); 250// qWarning("add");
253 m_changed = true; 251 m_changed = true;
254 m_events.insert( todo.uid(), todo ); 252 m_events.insert( todo.uid(), todo );
255 253
256 return true; 254 return true;
257} 255}
258bool OTodoAccessXML::remove( int uid ) { 256bool OTodoAccessXML::remove( int uid ) {
259 m_changed = true; 257 m_changed = true;
260 m_events.remove( uid ); 258 m_events.remove( uid );
261 259
262 return true; 260 return true;
263} 261}
264bool OTodoAccessXML::replace( const OTodo& todo) { 262bool OTodoAccessXML::replace( const OTodo& todo) {
265 m_changed = true; 263 m_changed = true;
266 m_events.replace( todo.uid(), todo ); 264 m_events.replace( todo.uid(), todo );
267 265
268 return true; 266 return true;
269} 267}
270QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start, 268QArray<int> OTodoAccessXML::effectiveToDos( const QDate& start,
271 const QDate& end, 269 const QDate& end,
272 bool includeNoDates ) { 270 bool includeNoDates ) {
273 QArray<int> ids( m_events.count() ); 271 QArray<int> ids( m_events.count() );
274 QMap<int, OTodo>::Iterator it; 272 QMap<int, OTodo>::Iterator it;
275 273
276 int i = 0; 274 int i = 0;
277 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 275 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
278 if ( !it.data().hasDueDate() ) { 276 if ( !it.data().hasDueDate() ) {
279 if ( includeNoDates ) { 277 if ( includeNoDates ) {
280 ids[i] = it.key(); 278 ids[i] = it.key();
281 i++; 279 i++;
282 } 280 }
283 }else if ( it.data().dueDate() >= start && 281 }else if ( it.data().dueDate() >= start &&
284 it.data().dueDate() <= end ) { 282 it.data().dueDate() <= end ) {
285 ids[i] = it.key(); 283 ids[i] = it.key();
286 i++; 284 i++;
287 } 285 }
288 } 286 }
289 ids.resize( i ); 287 ids.resize( i );
290 return ids; 288 return ids;
291} 289}
292QArray<int> OTodoAccessXML::overDue() { 290QArray<int> OTodoAccessXML::overDue() {
293 QArray<int> ids( m_events.count() ); 291 QArray<int> ids( m_events.count() );
294 int i = 0; 292 int i = 0;
295 293
296 QMap<int, OTodo>::Iterator it; 294 QMap<int, OTodo>::Iterator it;
297 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 295 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
298 if ( it.data().isOverdue() ) { 296 if ( it.data().isOverdue() ) {
299 ids[i] = it.key(); 297 ids[i] = it.key();
300 i++; 298 i++;
301 } 299 }
302 } 300 }
303 ids.resize( i ); 301 ids.resize( i );
304 return ids; 302 return ids;
305} 303}
306 304
307 305
308/* private */ 306/* private */
309void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev, 307void OTodoAccessXML::todo( QAsciiDict<int>* dict, OTodo& ev,
310 const QCString& attr, const QString& val) { 308 const QCString& attr, const QString& val) {
311// qWarning("parse to do from XMLElement" ); 309// qWarning("parse to do from XMLElement" );
312 310
313 int *find=0; 311 int *find=0;
314 312
315 find = (*dict)[ attr.data() ]; 313 find = (*dict)[ attr.data() ];
316 if (!find ) { 314 if (!find ) {
317// qWarning("Unknown option" + it.key() ); 315// qWarning("Unknown option" + it.key() );
318 ev.setCustomField( attr, val ); 316 ev.setCustomField( attr, val );
319 return; 317 return;
320 } 318 }
321 319
322 switch( *find ) { 320 switch( *find ) {
323 case OTodo::Uid: 321 case OTodo::Uid:
324 ev.setUid( val.toInt() ); 322 ev.setUid( val.toInt() );
325 break; 323 break;
326 case OTodo::Category: 324 case OTodo::Category:
327 ev.setCategories( ev.idsFromString( val ) ); 325 ev.setCategories( ev.idsFromString( val ) );
328 break; 326 break;
329 case OTodo::HasDate: 327 case OTodo::HasDate:
330 ev.setHasDueDate( val.toInt() ); 328 ev.setHasDueDate( val.toInt() );
331 break; 329 break;
332 case OTodo::Completed: 330 case OTodo::Completed:
333 ev.setCompleted( val.toInt() ); 331 ev.setCompleted( val.toInt() );
334 break; 332 break;
335 case OTodo::Description: 333 case OTodo::Description:
336 ev.setDescription( val ); 334 ev.setDescription( val );
337 break; 335 break;
338 case OTodo::Summary: 336 case OTodo::Summary:
339 ev.setSummary( val ); 337 ev.setSummary( val );
340 break; 338 break;
341 case OTodo::Priority: 339 case OTodo::Priority:
342 ev.setPriority( val.toInt() ); 340 ev.setPriority( val.toInt() );
343 break; 341 break;
344 case OTodo::DateDay: 342 case OTodo::DateDay:
345 m_day = val.toInt(); 343 m_day = val.toInt();
346 break; 344 break;
347 case OTodo::DateMonth: 345 case OTodo::DateMonth:
348 m_month = val.toInt(); 346 m_month = val.toInt();
349 break; 347 break;
350 case OTodo::DateYear: 348 case OTodo::DateYear:
351 m_year = val.toInt(); 349 m_year = val.toInt();
352 break; 350 break;
353 case OTodo::Progress: 351 case OTodo::Progress:
354 ev.setProgress( val.toInt() ); 352 ev.setProgress( val.toInt() );
355 break; 353 break;
356 case OTodo::CrossReference: 354 case OTodo::CrossReference:
357 { 355 {
358 /* 356 /*
359 * A cross refernce looks like 357 * A cross refernce looks like
360 * appname,id;appname,id 358 * appname,id;appname,id
361 * we need to split it up 359 * we need to split it up
362 */ 360 */
363 QStringList refs = QStringList::split(';', val ); 361 QStringList refs = QStringList::split(';', val );
364 QStringList::Iterator strIt; 362 QStringList::Iterator strIt;
365 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) { 363 for (strIt = refs.begin(); strIt != refs.end(); ++strIt ) {
366 int pos = (*strIt).find(','); 364 int pos = (*strIt).find(',');
367 if ( pos > -1 ) 365 if ( pos > -1 )
368 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() ); 366 ; // ev.addRelation( (*strIt).left(pos), (*strIt).mid(pos+1).toInt() );
369 367
370 } 368 }
371 break; 369 break;
372 } 370 }
373 default: 371 default:
374 break; 372 break;
375 } 373 }
376} 374}
377QString OTodoAccessXML::toString( const OTodo& ev )const { 375QString OTodoAccessXML::toString( const OTodo& ev )const {
378 QString str; 376 QString str;
379 377
380 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" "; 378 str += "Completed=\"" + QString::number( ev.isCompleted() ) + "\" ";
381 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" "; 379 str += "HasDate=\"" + QString::number( ev.hasDueDate() ) + "\" ";
382 str += "Priority=\"" + QString::number( ev.priority() ) + "\" "; 380 str += "Priority=\"" + QString::number( ev.priority() ) + "\" ";
383 str += "Progress=\"" + QString::number(ev.progress() ) + "\" "; 381 str += "Progress=\"" + QString::number(ev.progress() ) + "\" ";
384 382
385 str += "Categories=\"" + toString( ev.categories() ) + "\" "; 383 str += "Categories=\"" + toString( ev.categories() ) + "\" ";
386 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" "; 384 str += "Description=\"" + Qtopia::escapeString( ev.description() ) + "\" ";
387 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" "; 385 str += "Summary=\"" + Qtopia::escapeString( ev.summary() ) + "\" ";
388 386
389 if ( ev.hasDueDate() ) { 387 if ( ev.hasDueDate() ) {
390 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" "; 388 str += "DateYear=\"" + QString::number( ev.dueDate().year() ) + "\" ";
391 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" "; 389 str += "DateMonth=\"" + QString::number( ev.dueDate().month() ) + "\" ";
392 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" "; 390 str += "DateDay=\"" + QString::number( ev.dueDate().day() ) + "\" ";
393 } 391 }
394// qWarning( "Uid %d", ev.uid() ); 392// qWarning( "Uid %d", ev.uid() );
395 str += "Uid=\"" + QString::number( ev.uid() ) + "\" "; 393 str += "Uid=\"" + QString::number( ev.uid() ) + "\" ";
396 394
397// append the extra options 395// append the extra options
398 /* FIXME Qtopia::Record this is currently not 396 /* FIXME Qtopia::Record this is currently not
399 * possible you can set custom fields 397 * possible you can set custom fields
400 * but don' iterate over the list 398 * but don' iterate over the list
401 * I may do #define private protected 399 * I may do #define private protected
402 * for this case - cough --zecke 400 * for this case - cough --zecke
403 */ 401 */
404 /* 402 /*
405 QMap<QString, QString> extras = ev.extras(); 403 QMap<QString, QString> extras = ev.extras();
406 QMap<QString, QString>::Iterator extIt; 404 QMap<QString, QString>::Iterator extIt;
407 for (extIt = extras.begin(); extIt != extras.end(); ++extIt ) 405 for (extIt = extras.begin(); extIt != extras.end(); ++extIt )
408 str += extIt.key() + "=\"" + extIt.data() + "\" "; 406 str += extIt.key() + "=\"" + extIt.data() + "\" ";
409 */ 407 */
410 // cross refernce 408 // cross refernce
411 409
412 410
413 return str; 411 return str;
414} 412}
415QString OTodoAccessXML::toString( const QArray<int>& ints ) const { 413QString OTodoAccessXML::toString( const QArray<int>& ints ) const {
416 return Qtopia::Record::idsToString( ints ); 414 return Qtopia::Record::idsToString( ints );
417} 415}
418 416
419/* internal class for sorting 417/* internal class for sorting
420 * 418 *
421 * Inspired by todoxmlio.cpp from TT 419 * Inspired by todoxmlio.cpp from TT
422 */ 420 */
423 421
424struct OTodoXMLContainer { 422struct OTodoXMLContainer {
425 OTodo todo; 423 OTodo todo;
426}; 424};
427 425
428namespace { 426namespace {
429 inline QString string( const OTodo& todo) { 427 inline QString string( const OTodo& todo) {
430 return todo.summary().isEmpty() ? 428 return todo.summary().isEmpty() ?
431 todo.description().left(20 ) : 429 todo.description().left(20 ) :
432 todo.summary(); 430 todo.summary();
433 } 431 }
434 inline int completed( const OTodo& todo1, const OTodo& todo2) { 432 inline int completed( const OTodo& todo1, const OTodo& todo2) {
435 int ret = 0; 433 int ret = 0;
436 if ( todo1.isCompleted() ) ret++; 434 if ( todo1.isCompleted() ) ret++;
437 if ( todo2.isCompleted() ) ret--; 435 if ( todo2.isCompleted() ) ret--;
438 return ret; 436 return ret;
439 } 437 }
440 inline int priority( const OTodo& t1, const OTodo& t2) { 438 inline int priority( const OTodo& t1, const OTodo& t2) {
441 return ( t1.priority() - t2.priority() ); 439 return ( t1.priority() - t2.priority() );
442 } 440 }
443 inline int description( const OTodo& t1, const OTodo& t2) { 441 inline int description( const OTodo& t1, const OTodo& t2) {
444 return QString::compare( string(t1), string(t2) ); 442 return QString::compare( string(t1), string(t2) );
445 } 443 }
446 inline int deadline( const OTodo& t1, const OTodo& t2) { 444 inline int deadline( const OTodo& t1, const OTodo& t2) {
447 int ret = 0; 445 int ret = 0;
448 if ( t1.hasDueDate() && 446 if ( t1.hasDueDate() &&
449 t2.hasDueDate() ) 447 t2.hasDueDate() )
450 ret = t2.dueDate().daysTo( t1.dueDate() ); 448 ret = t2.dueDate().daysTo( t1.dueDate() );
451 else if ( t1.hasDueDate() ) 449 else if ( t1.hasDueDate() )
452 ret = -1; 450 ret = -1;
453 else if ( t2.hasDueDate() ) 451 else if ( t2.hasDueDate() )
454 ret = 1; 452 ret = 1;
455 else 453 else
456 ret = 0; 454 ret = 0;
457 455
458 return ret; 456 return ret;
459 } 457 }
460 458
461}; 459};
462 460
463/* 461/*
464 * Returns: 462 * Returns:
465 * 0 if item1 == item2 463 * 0 if item1 == item2
466 * 464 *
467 * non-zero if item1 != item2 465 * non-zero if item1 != item2
468 * 466 *
469 * This function returns int rather than bool so that reimplementations 467 * This function returns int rather than bool so that reimplementations
470 * can return one of three values and use it to sort by: 468 * can return one of three values and use it to sort by:
471 * 469 *
472 * 0 if item1 == item2 470 * 0 if item1 == item2
473 * 471 *
474 * > 0 (positive integer) if item1 > item2 472 * > 0 (positive integer) if item1 > item2
475 * 473 *
476 * < 0 (negative integer) if item1 < item2 474 * < 0 (negative integer) if item1 < item2
477 * 475 *
478 */ 476 */
479class OTodoXMLVector : public QVector<OTodoXMLContainer> { 477class OTodoXMLVector : public QVector<OTodoXMLContainer> {
480public: 478public:
481 OTodoXMLVector(int size, bool asc, int sort) 479 OTodoXMLVector(int size, bool asc, int sort)
482 : QVector<OTodoXMLContainer>( size ) 480 : QVector<OTodoXMLContainer>( size )
483 { 481 {
484 setAutoDelete( true ); 482 setAutoDelete( true );
485 m_asc = asc; 483 m_asc = asc;
486 m_sort = sort; 484 m_sort = sort;
487 } 485 }
488 /* return the summary/description */ 486 /* return the summary/description */
489 QString string( const OTodo& todo) { 487 QString string( const OTodo& todo) {
490 return todo.summary().isEmpty() ? 488 return todo.summary().isEmpty() ?
491 todo.description().left(20 ) : 489 todo.description().left(20 ) :
492 todo.summary(); 490 todo.summary();
493 } 491 }
494 /** 492 /**
495 * we take the sortorder( switch on it ) 493 * we take the sortorder( switch on it )
496 * 494 *
497 */ 495 */
498 int compareItems( Item d1, Item d2 ) { 496 int compareItems( Item d1, Item d2 ) {
499 bool seComp, sePrio, seDesc, seDeadline; 497 bool seComp, sePrio, seDesc, seDeadline;
500 seComp = sePrio = seDeadline = seDesc = false; 498 seComp = sePrio = seDeadline = seDesc = false;
501 int ret =0; 499 int ret =0;
502 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1; 500 OTodoXMLContainer* con1 = (OTodoXMLContainer*)d1;
503 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2; 501 OTodoXMLContainer* con2 = (OTodoXMLContainer*)d2;
504 502
505 /* same item */ 503 /* same item */
506 if ( con1->todo.uid() == con2->todo.uid() ) 504 if ( con1->todo.uid() == con2->todo.uid() )
507 return 0; 505 return 0;
508 506
509 switch ( m_sort ) { 507 switch ( m_sort ) {
510 /* completed */ 508 /* completed */
511 case 0: { 509 case 0: {
512 ret = completed( con1->todo, con2->todo ); 510 ret = completed( con1->todo, con2->todo );
513 seComp = TRUE; 511 seComp = TRUE;
514 break; 512 break;
515 } 513 }
516 /* priority */ 514 /* priority */
517 case 1: { 515 case 1: {
518 ret = priority( con1->todo, con2->todo ); 516 ret = priority( con1->todo, con2->todo );
519 sePrio = TRUE; 517 sePrio = TRUE;
520 break; 518 break;
521 } 519 }
522 /* description */ 520 /* description */
523 case 2: { 521 case 2: {
524 ret = description( con1->todo, con2->todo ); 522 ret = description( con1->todo, con2->todo );
525 seDesc = TRUE; 523 seDesc = TRUE;
526 break; 524 break;
527 } 525 }
528 /* deadline */ 526 /* deadline */
529 case 3: { 527 case 3: {
530 ret = deadline( con1->todo, con2->todo ); 528 ret = deadline( con1->todo, con2->todo );
531 seDeadline = TRUE; 529 seDeadline = TRUE;
532 break; 530 break;
533 } 531 }
534 default: 532 default:
535 ret = 0; 533 ret = 0;
536 break; 534 break;
537 }; 535 };
538 /* 536 /*
539 * FIXME do better sorting if the first sort criteria 537 * FIXME do better sorting if the first sort criteria
540 * ret equals 0 start with complete and so on... 538 * ret equals 0 start with complete and so on...
541 */ 539 */
542 540
543 /* twist it we're not ascending*/ 541 /* twist it we're not ascending*/
544 if (!m_asc) 542 if (!m_asc)
545 ret = ret * -1; 543 ret = ret * -1;
546 544
547 if ( ret ) 545 if ( ret )
548 return ret; 546 return ret;
549 547
550 // default did not gave difference let's try it other way around 548 // default did not gave difference let's try it other way around
551 /* 549 /*
552 * General try if already checked if not test 550 * General try if already checked if not test
553 * and return 551 * and return
554 * 1.Completed 552 * 1.Completed
555 * 2.Priority 553 * 2.Priority
556 * 3.Description 554 * 3.Description
557 * 4.DueDate 555 * 4.DueDate
558 */ 556 */
559 if (!seComp ) { 557 if (!seComp ) {
560 if ( (ret = completed( con1->todo, con2->todo ) ) ) { 558 if ( (ret = completed( con1->todo, con2->todo ) ) ) {
561 if (!m_asc ) ret *= -1; 559 if (!m_asc ) ret *= -1;
562 return ret; 560 return ret;
563 } 561 }
564 } 562 }
565 if (!sePrio ) { 563 if (!sePrio ) {
566 if ( (ret = priority( con1->todo, con2->todo ) ) ) { 564 if ( (ret = priority( con1->todo, con2->todo ) ) ) {
567 if (!m_asc ) ret *= -1; 565 if (!m_asc ) ret *= -1;
568 return ret; 566 return ret;
569 } 567 }
570 } 568 }
571 if (!seDesc ) { 569 if (!seDesc ) {
572 if ( (ret = description(con1->todo, con2->todo ) ) ) { 570 if ( (ret = description(con1->todo, con2->todo ) ) ) {
573 if (!m_asc) ret *= -1; 571 if (!m_asc) ret *= -1;
574 return ret; 572 return ret;
575 } 573 }
576 } 574 }
577 if (!seDeadline) { 575 if (!seDeadline) {
578 if ( (ret = deadline( con1->todo, con2->todo ) ) ) { 576 if ( (ret = deadline( con1->todo, con2->todo ) ) ) {
579 if (!m_asc) ret *= -1; 577 if (!m_asc) ret *= -1;
580 return ret; 578 return ret;
581 } 579 }
582 } 580 }
583 581
584 return 0; 582 return 0;
585 } 583 }
586 private: 584 private:
587 bool m_asc; 585 bool m_asc;
588 int m_sort; 586 int m_sort;
589 587
590}; 588};
591 589
592QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder, 590QArray<int> OTodoAccessXML::sorted( bool asc, int sortOrder,
593 int sortFilter, int cat ) { 591 int sortFilter, int cat ) {
594 qWarning("sorted! %d cat", cat); 592 qWarning("sorted! %d cat", cat);
595 OTodoXMLVector vector(m_events.count(), asc,sortOrder ); 593 OTodoXMLVector vector(m_events.count(), asc,sortOrder );
596 QMap<int, OTodo>::Iterator it; 594 QMap<int, OTodo>::Iterator it;
597 int item = 0; 595 int item = 0;
598 596
599 bool bCat = sortFilter & 1 ? true : false; 597 bool bCat = sortFilter & 1 ? true : false;
600 bool bOnly = sortFilter & 2 ? true : false; 598 bool bOnly = sortFilter & 2 ? true : false;
601 bool comp = sortFilter & 4 ? true : false; 599 bool comp = sortFilter & 4 ? true : false;
602 for ( it = m_events.begin(); it != m_events.end(); ++it ) { 600 for ( it = m_events.begin(); it != m_events.end(); ++it ) {
603 601
604 /* show category */ 602 /* show category */
605 if ( bCat && cat != 0) 603 if ( bCat && cat != 0)
606 if (!(*it).categories().contains( cat ) ) { 604 if (!(*it).categories().contains( cat ) ) {
607 qWarning("category mis match"); 605 qWarning("category mis match");
608 continue; 606 continue;
609 } 607 }
610 /* isOverdue but we should not show overdue - why?*/ 608 /* isOverdue but we should not show overdue - why?*/
611/* if ( (*it).isOverdue() && !bOnly ) { 609/* if ( (*it).isOverdue() && !bOnly ) {
612 qWarning("item is overdue but !bOnly"); 610 qWarning("item is overdue but !bOnly");
613 continue; 611 continue;
614 } 612 }
615*/ 613*/
616 if ( !(*it).isOverdue() && bOnly ) { 614 if ( !(*it).isOverdue() && bOnly ) {
617 qWarning("item is not overdue but bOnly checked"); 615 qWarning("item is not overdue but bOnly checked");
618 continue; 616 continue;
619 } 617 }
620 618
621 if ((*it).isCompleted() && comp ) { 619 if ((*it).isCompleted() && comp ) {
622 qWarning("completed continue!"); 620 qWarning("completed continue!");
623 continue; 621 continue;
624 } 622 }
625 623
626 624
627 OTodoXMLContainer* con = new OTodoXMLContainer(); 625 OTodoXMLContainer* con = new OTodoXMLContainer();
628 con->todo = (*it); 626 con->todo = (*it);
629 vector.insert(item, con ); 627 vector.insert(item, con );
630 item++; 628 item++;
631 } 629 }
632 qWarning("XXX %d Items added", item); 630 qWarning("XXX %d Items added", item);
633 vector.resize( item ); 631 vector.resize( item );
634 /* sort it now */ 632 /* sort it now */
635 vector.sort(); 633 vector.sort();
636 /* now get the uids */ 634 /* now get the uids */
637 QArray<int> array( vector.count() ); 635 QArray<int> array( vector.count() );
638 for (uint i= 0; i < vector.count(); i++ ) { 636 for (uint i= 0; i < vector.count(); i++ ) {
639 array[i] = ( vector.at(i) )->todo.uid(); 637 array[i] = ( vector.at(i) )->todo.uid();
640 } 638 }
641 qWarning("array count = %d %d", array.count(), vector.count() ); 639 qWarning("array count = %d %d", array.count(), vector.count() );
642 return array; 640 return array;
643}; 641};
644void OTodoAccessXML::removeAllCompleted() { 642void OTodoAccessXML::removeAllCompleted() {
645 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) { 643 for ( QMap<int, OTodo>::Iterator it = m_events.begin(); it != m_events.end(); ++it ) {
646 if ( (*it).isCompleted() ) 644 if ( (*it).isCompleted() )
647 m_events.remove( it ); 645 m_events.remove( it );
648 } 646 }
649} 647}
diff --git a/libopie/pim/test/oevent_test.cpp b/libopie/pim/test/oevent_test.cpp
index 50cc032..6f04995 100644
--- a/libopie/pim/test/oevent_test.cpp
+++ b/libopie/pim/test/oevent_test.cpp
@@ -1,23 +1,50 @@
1#include <qdatetime.h> 1#include <qdatetime.h>
2 2
3#include "../oevent.h" 3#include "../oevent.h"
4#include "../odatebookaccess.h"
4 5
5int main(int argc, char* argv ) { 6int main(int argc, char* argv ) {
6 OEvent ev; 7 OEvent ev;
7 ev.setUid( 20 ); 8 ev.setUid( 20 );
8 9
9 ev.setDescription( "Foo" ); 10 ev.setDescription( "Foo" );
10 11
11 OEvent ev2 = ev; 12 OEvent ev2 = ev;
12 ev2.setDescription("Foo2"); 13 ev2.setDescription("Foo2");
13 qWarning("%s", ev2.description().latin1() ); 14 qWarning("%s", ev2.description().latin1() );
14 qWarning("%s", ev.description().latin1() ); 15 qWarning("%s", ev.description().latin1() );
15 16
16 QDateTime time = QDateTime::currentDateTime(); 17 QDateTime time = QDateTime::currentDateTime();
17 ev2.setStartDateTime( time ); 18 ev2.setStartDateTime( time );
18 ev2.setTimeZone( "Europe/London" ); 19 ev2.setTimeZone( "Europe/London" );
19 20
20 qWarning("%s", ev2.startDateTime().toString().latin1() ); 21 qWarning("%s", ev2.startDateTime().toString().latin1() );
21 qWarning("%s", ev2.startDateTimeInZone().toString().latin1() ); 22 qWarning("%s", ev2.startDateTimeInZone().toString().latin1() );
23
24 ODateBookAccess acc;
25 if(!acc.load() ) qWarning("could not load");
26
27 ODateBookAccess::List::Iterator it;
28 ODateBookAccess::List list = acc.allRecords();
29
30 for( it = list.begin(); it != list.end(); ++it ){
31 OEvent ev = (*it);
32 qWarning("Summary: %s",ev.description().latin1() );
33 qWarning("Start: %s End: %s",ev.startDateTime().toString().latin1(), ev.endDateTime().toString().latin1() );
34 qWarning("All Day: %d",ev.isAllDay() );
35
36 }
37 QDate date1(2003,02,01 );
38 QDate date2(2003,03,01 );
39
40 OEffectiveEvent::ValueList effList = acc.effectiveEvents( date1,date2 );
41 OEffectiveEvent::ValueList::Iterator effIt;
42
43 for( effIt = effList.begin(); effIt != effList.end(); ++effIt ){
44 OEffectiveEvent ef = (*effIt);
45 qWarning("Summary: %s", ef.description().latin1() );
46 qWarning("Date: %s", ef.date().toString().latin1() );
47 }
48
22 return 0; 49 return 0;
23} 50}