summaryrefslogtreecommitdiff
path: root/libopie2/opiepim/backend
authorzecke <zecke>2003-02-21 23:31:52 (UTC)
committer zecke <zecke>2003-02-21 23:31:52 (UTC)
commit46f47c0a1e542a8b4222f3ced8f3304534c7509d (patch) (unidiff)
tree82dc97a07bae77387987711c0c21697691955937 /libopie2/opiepim/backend
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 'libopie2/opiepim/backend') (more/less context) (ignore whitespace changes)
-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
4 files changed, 472 insertions, 14 deletions
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
@@ -10,12 +10,22 @@
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 *
@@ -47,6 +57,7 @@
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"
@@ -64,9 +75,9 @@ class OBackendFactory
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" );
@@ -78,34 +89,40 @@ class OBackendFactory
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
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
@@ -15,8 +15,6 @@
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,