summaryrefslogtreecommitdiff
Unidiff
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
@@ -42,2 +42,3 @@ HEADERS = ofontmenu.h \
42 pim/odatebookaccessbackend.h \ 42 pim/odatebookaccessbackend.h \
43 pim/odatebookaccessbackend_xml.h \
43 orecurrancewidget.h \ 44 orecurrancewidget.h \
@@ -81,2 +82,3 @@ SOURCES = ofontmenu.cc \
81 pim/odatebookaccessbackend.cpp \ 82 pim/odatebookaccessbackend.cpp \
83 pim/odatebookaccessbackend_xml.cpp \
82 orecurrancewidget.cpp \ 84 orecurrancewidget.cpp \
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
@@ -12,3 +12,3 @@
12 * ===================================================================== 12 * =====================================================================
13 * ToDo: Use plugins 13 * ToDo: Use plugins
14 * ===================================================================== 14 * =====================================================================
@@ -18,2 +18,12 @@
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
@@ -49,2 +59,3 @@
49#include "ocontactaccessbackend_xml.h" 59#include "ocontactaccessbackend_xml.h"
60#include "odatebookaccessbackend_xml.h"
50 61
@@ -66,5 +77,5 @@ class OBackendFactory
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");
@@ -80,2 +91,3 @@ class OBackendFactory
80 dict.insert( "contact", new int (CONTACT) ); 91 dict.insert( "contact", new int (CONTACT) );
92 dict.insert( "datebook", new int(DATE) );
81 93
@@ -83,10 +95,13 @@ class OBackendFactory
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!");
@@ -96,3 +111,3 @@ class OBackendFactory
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!");
@@ -101,4 +116,6 @@ class OBackendFactory
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:
@@ -106,4 +123,4 @@ class OBackendFactory
106 } 123 }
107 124
108 125
109 } 126 }
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
@@ -10,2 +10,3 @@ ODateBookAccess::ODateBookAccess( ODateBookAccessBackend* back, enum Access ac )
10 m_backEnd = back; 10 m_backEnd = back;
11 setBackEnd( m_backEnd );
11} 12}
@@ -31,6 +32,6 @@ ODateBookAccess::List ODateBookAccess::nonRepeats()const {
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 );
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
@@ -22,4 +22,4 @@ public:
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
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
@@ -189,2 +189,7 @@ bool OEvent::isAllDay()const {
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 ) {
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
@@ -74,3 +74,3 @@ class 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 );
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
@@ -17,4 +17,2 @@
17 17
18#include <opie/xmltree.h>
19
20#include "otodoaccessxml.h" 18#include "otodoaccessxml.h"
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
@@ -3,2 +3,3 @@
3#include "../oevent.h" 3#include "../oevent.h"
4#include "../odatebookaccess.h"
4 5
@@ -21,2 +22,28 @@ int main(int argc, char* argv ) {
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;
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
@@ -12,3 +12,3 @@
12 * ===================================================================== 12 * =====================================================================
13 * ToDo: Use plugins 13 * ToDo: Use plugins
14 * ===================================================================== 14 * =====================================================================
@@ -18,2 +18,12 @@
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
@@ -49,2 +59,3 @@
49#include "ocontactaccessbackend_xml.h" 59#include "ocontactaccessbackend_xml.h"
60#include "odatebookaccessbackend_xml.h"
50 61
@@ -66,5 +77,5 @@ class OBackendFactory
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");
@@ -80,2 +91,3 @@ class OBackendFactory
80 dict.insert( "contact", new int (CONTACT) ); 91 dict.insert( "contact", new int (CONTACT) );
92 dict.insert( "datebook", new int(DATE) );
81 93
@@ -83,10 +95,13 @@ class OBackendFactory
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!");
@@ -96,3 +111,3 @@ class OBackendFactory
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!");
@@ -101,4 +116,6 @@ class OBackendFactory
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:
@@ -106,4 +123,4 @@ class OBackendFactory
106 } 123 }
107 124
108 125
109 } 126 }
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
@@ -17,4 +17,2 @@
17 17
18#include <opie/xmltree.h>
19
20#include "otodoaccessxml.h" 18#include "otodoaccessxml.h"
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
@@ -10,2 +10,3 @@ ODateBookAccess::ODateBookAccess( ODateBookAccessBackend* back, enum Access ac )
10 m_backEnd = back; 10 m_backEnd = back;
11 setBackEnd( m_backEnd );
11} 12}
@@ -31,6 +32,6 @@ ODateBookAccess::List ODateBookAccess::nonRepeats()const {
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 );
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
@@ -22,4 +22,4 @@ public:
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
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
@@ -74,3 +74,3 @@ class 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 );
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
@@ -189,2 +189,7 @@ bool OEvent::isAllDay()const {
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 ) {