summaryrefslogtreecommitdiff
authorzecke <zecke>2003-02-21 23:31:52 (UTC)
committer zecke <zecke>2003-02-21 23:31:52 (UTC)
commit46f47c0a1e542a8b4222f3ced8f3304534c7509d (patch) (unidiff)
tree82dc97a07bae77387987711c0c21697691955937
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 (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
-rw-r--r--libopie2/opiepim/backend/obackendfactory.h41
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp395
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.h48
-rw-r--r--libopie2/opiepim/backend/otodoaccessxml.cpp2
-rw-r--r--libopie2/opiepim/core/odatebookaccess.cpp5
-rw-r--r--libopie2/opiepim/core/odatebookaccess.h4
-rw-r--r--libopie2/opiepim/core/opimnotify.h2
-rw-r--r--libopie2/opiepim/oevent.cpp5
18 files changed, 995 insertions, 38 deletions
diff --git a/libopie/libopie.pro b/libopie/libopie.pro
index 70399ea..391f30e 100644
--- a/libopie/libopie.pro
+++ b/libopie/libopie.pro
@@ -37,12 +37,13 @@ HEADERS = ofontmenu.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 \
@@ -76,12 +77,13 @@ SOURCES = ofontmenu.cc \
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
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
@@ -7,18 +7,28 @@
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 ;)
@@ -44,12 +54,13 @@
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
@@ -61,53 +72,59 @@ class 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
@@ -5,12 +5,13 @@ ODateBookAccess::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
@@ -26,12 +27,12 @@ ODateBookAccess::List ODateBookAccess::rawRepeats()const {
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
@@ -17,14 +17,14 @@ public:
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};
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
@@ -184,12 +184,17 @@ void OEvent::setEndDateTime( const QDateTime& dt ) {
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;
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
@@ -69,13 +69,13 @@ private:
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& );
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
@@ -12,14 +12,12 @@
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{
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,9 +1,10 @@
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" );
@@ -16,8 +17,34 @@ int main(int argc, char* argv ) {
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}
diff --git a/libopie2/opiepim/backend/obackendfactory.h b/libopie2/opiepim/backend/obackendfactory.h
index b796fb8..3a73210 100644
--- a/libopie2/opiepim/backend/obackendfactory.h
+++ b/libopie2/opiepim/backend/obackendfactory.h
@@ -7,18 +7,28 @@
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 ;)
@@ -44,12 +54,13 @@
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
@@ -61,53 +72,59 @@ class 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/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
new file mode 100644
index 0000000..a4c514b
--- a/dev/null
+++ b/libopie2/opiepim/backend/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/libopie2/opiepim/backend/odatebookaccessbackend_xml.h b/libopie2/opiepim/backend/odatebookaccessbackend_xml.h
new file mode 100644
index 0000000..40f69d8
--- a/dev/null
+++ b/libopie2/opiepim/backend/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/libopie2/opiepim/backend/otodoaccessxml.cpp b/libopie2/opiepim/backend/otodoaccessxml.cpp
index c3416cb..22b2469 100644
--- a/libopie2/opiepim/backend/otodoaccessxml.cpp
+++ b/libopie2/opiepim/backend/otodoaccessxml.cpp
@@ -12,14 +12,12 @@
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{
diff --git a/libopie2/opiepim/core/odatebookaccess.cpp b/libopie2/opiepim/core/odatebookaccess.cpp
index 5f97e7c..08e61ff 100644
--- a/libopie2/opiepim/core/odatebookaccess.cpp
+++ b/libopie2/opiepim/core/odatebookaccess.cpp
@@ -5,12 +5,13 @@ ODateBookAccess::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
@@ -26,12 +27,12 @@ ODateBookAccess::List ODateBookAccess::rawRepeats()const {
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/libopie2/opiepim/core/odatebookaccess.h b/libopie2/opiepim/core/odatebookaccess.h
index 3f2c728..7047039 100644
--- a/libopie2/opiepim/core/odatebookaccess.h
+++ b/libopie2/opiepim/core/odatebookaccess.h
@@ -17,14 +17,14 @@ public:
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};
diff --git a/libopie2/opiepim/core/opimnotify.h b/libopie2/opiepim/core/opimnotify.h
index 3501948..b0de000 100644
--- a/libopie2/opiepim/core/opimnotify.h
+++ b/libopie2/opiepim/core/opimnotify.h
@@ -69,13 +69,13 @@ private:
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& );
diff --git a/libopie2/opiepim/oevent.cpp b/libopie2/opiepim/oevent.cpp
index aaae3b2..ada596c 100644
--- a/libopie2/opiepim/oevent.cpp
+++ b/libopie2/opiepim/oevent.cpp
@@ -184,12 +184,17 @@ void OEvent::setEndDateTime( const QDateTime& dt ) {
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;