summaryrefslogtreecommitdiff
path: root/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
Unidiff
Diffstat (limited to 'libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp184
1 files changed, 173 insertions, 11 deletions
diff --git a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
index a4c514b..5239d84 100644
--- a/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
+++ b/libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp
@@ -1,6 +1,9 @@
1#include <errno.h> 1#include <errno.h>
2#include <fcntl.h> 2#include <fcntl.h>
3 3
4#include <stdio.h>
5#include <stdlib.h>
6
4#include <sys/types.h> 7#include <sys/types.h>
5#include <sys/mman.h> 8#include <sys/mman.h>
6#include <sys/stat.h> 9#include <sys/stat.h>
@@ -12,6 +15,7 @@
12 15
13#include <qtopia/global.h> 16#include <qtopia/global.h>
14#include <qtopia/stringutil.h> 17#include <qtopia/stringutil.h>
18#include <qtopia/timeconversion.h>
15 19
16#include "opimnotifymanager.h" 20#include "opimnotifymanager.h"
17#include "orecur.h" 21#include "orecur.h"
@@ -30,11 +34,11 @@ namespace {
30 int alarmTime; 34 int alarmTime;
31 int snd; 35 int snd;
32 enum Attribute{ 36 enum Attribute{
33 FDescription = 0, 37 FDescription = 0,
34 FLocation, 38 FLocation,
35 FCategories, 39 FCategories,
36 FUid, 40 FUid,
37 FType, 41 FType,
38 FAlarm, 42 FAlarm,
39 FSound, 43 FSound,
40 FRType, 44 FRType,
@@ -46,8 +50,89 @@ namespace {
46 FRStart, 50 FRStart,
47 FREnd, 51 FREnd,
48 FNote, 52 FNote,
49 FCreated 53 FCreated,
54 FTimeZone,
55 FRecParent,
56 FRecChildren,
57 FExceptions
50 }; 58 };
59 inline void save( const OEvent& ev, QString& buf ) {
60 buf += " description=\"" + Qtopia::escapeString(ev.description() ) + "\"";
61 if (!ev.location().isEmpty() )
62 buf += " location=\"" + Qtopia::escapeString(ev.location() ) + "\"";
63
64 buf += " categories=\""+ Qtopia::escapeString( Qtopia::Record::idsToString( ev.categories() ) ) + "\"";
65 buf += " uid=\"" + QString::number( ev.uid() ) + "\"";
66
67 if (ev.isAllDay() )
68 buf += " type=\"AllDay\"";
69
70 if (ev.hasNotifiers() ) {
71 OPimAlarm alarm = ev.notifiers().alarms()[0]; // take only the first
72 int minutes = alarm.dateTime().secsTo( ev.startDateTime() ) / 60;
73 buf += " alarm=\"" + QString::number(minutes) + "\" sound=\"";
74 if ( alarm.sound() == OPimAlarm::Loud )
75 buf += "loud";
76 else
77 buf += "silent";
78 buf += "\"";
79 }
80 if ( ev.hasRecurrence() ) {
81 buf += ev.recurrence().toString();
82 }
83
84 /*
85 * fscking timezones :) well, we'll first convert
86 * the QDateTime to a QDateTime in UTC time
87 * and then we'll create a nice time_t
88 */
89 OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() );
90 buf += " start=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.startDateTime(), OTimeZone::utc() ) ) ) + "\"";
91 buf += " end=\"" + QString::number( zone.fromUTCDateTime( zone.toDateTime( ev.endDateTime() , OTimeZone::utc() ) ) ) + "\"";
92 if (!ev.note().isEmpty() ) {
93 buf += " note=\"" + Qtopia::escapeString( ev.note() ) + "\"";
94 }
95
96 buf += " timezone=\"";
97 if ( ev.timeZone().isEmpty() )
98 buf += "None";
99 else
100 buf += ev.timeZone();
101
102 if (ev.parent() != 0 ) {
103 buf += " recparent=\""+QString::number(ev.parent() )+"\"";
104 }
105
106 if (ev.children().count() != 0 ) {
107 QArray<int> children = ev.children();
108 buf += " recchildren=\"";
109 for ( uint i = 0; i < children.count(); i++ ) {
110 if ( i != 0 ) buf += " ";
111 buf += QString::number( children[i] );
112 }
113 buf+= "\"";
114 }
115
116 // skip custom writing
117 }
118
119 inline bool forAll( const QMap<int, OEvent>& list, QFile& file ) {
120 QMap<int, OEvent>::ConstIterator it;
121 QString buf;
122 QCString str;
123 int total_written;
124 for ( it = list.begin(); it != list.end(); ++it ) {
125 buf = "<event";
126 save( it.data(), buf );
127 buf += " />\n";
128 str = buf.utf8();
129
130 total_written = file.writeBlock(str.data(), str.length() );
131 if ( total_written != int(str.length() ) )
132 return false;
133 }
134 return true;
135 }
51} 136}
52 137
53ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& , 138ODateBookAccessBackend_XML::ODateBookAccessBackend_XML( const QString& ,
@@ -66,9 +151,54 @@ bool ODateBookAccessBackend_XML::reload() {
66 return load(); 151 return load();
67} 152}
68bool ODateBookAccessBackend_XML::save() { 153bool ODateBookAccessBackend_XML::save() {
69 if (!m_changed) return true; 154 qWarning("going to save now");
70 m_changed = false; 155// if (!m_changed) return true;
156
157 int total_written;
158 QString strFileNew = m_name + ".new";
159
160 QFile f( strFileNew );
161 if (!f.open( IO_WriteOnly | IO_Raw ) ) return false;
162
163 QString buf( "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" );
164 buf += "<!DOCTYPE DATEBOOK><DATEBOOK>\n";
165 buf += "<events>\n";
166 QCString str = buf.utf8();
167 total_written = f.writeBlock( str.data(), str.length() );
168 if ( total_written != int(str.length() ) ) {
169 f.close();
170 QFile::remove( strFileNew );
171 return false;
172 }
71 173
174 if (!forAll( m_raw, f ) ) {
175 f.close();
176 QFile::remove( strFileNew );
177 return false;
178 }
179 if (!forAll( m_rep, f ) ) {
180 f.close();
181 QFile::remove( strFileNew );
182 return false;
183 }
184
185 buf = "</events>\n</DATEBOOK>\n";
186 str = buf.utf8();
187 total_written = f.writeBlock( str.data(), str.length() );
188 if ( total_written != int(str.length() ) ) {
189 f.close();
190 QFile::remove( strFileNew );
191 return false;
192 }
193 f.close();
194
195 exit(0);
196 if ( ::rename( strFileNew, m_name ) < 0 ) {
197 QFile::remove( strFileNew );
198 return false;
199 }
200
201 m_changed = false;
72 return true; 202 return true;
73} 203}
74QArray<int> ODateBookAccessBackend_XML::allRecords()const { 204QArray<int> ODateBookAccessBackend_XML::allRecords()const {
@@ -183,7 +313,7 @@ bool ODateBookAccessBackend_XML::loadFile() {
183 ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL ); 313 ::madvise( map_addr, attribute.st_size, MADV_SEQUENTIAL );
184 ::close( fd ); 314 ::close( fd );
185 315
186 QAsciiDict<int> dict(FCreated+1); 316 QAsciiDict<int> dict(FExceptions+1);
187 dict.setAutoDelete( true ); 317 dict.setAutoDelete( true );
188 dict.insert( "description", new int(FDescription) ); 318 dict.insert( "description", new int(FDescription) );
189 dict.insert( "location", new int(FLocation) ); 319 dict.insert( "location", new int(FLocation) );
@@ -202,6 +332,10 @@ bool ODateBookAccessBackend_XML::loadFile() {
202 dict.insert( "end", new int(FREnd) ); 332 dict.insert( "end", new int(FREnd) );
203 dict.insert( "note", new int(FNote) ); 333 dict.insert( "note", new int(FNote) );
204 dict.insert( "created", new int(FCreated) ); 334 dict.insert( "created", new int(FCreated) );
335 dict.insert( "recparent", new int(FRecParent) );
336 dict.insert( "recchildren", new int(FRecChildren) );
337 dict.insert( "exceptions", new int(FExceptions) );
338 dict.insert( "timezone", new int(FTimeZone) );
205 339
206 char* dt = (char*)map_addr; 340 char* dt = (char*)map_addr;
207 int len = attribute.st_size; 341 int len = attribute.st_size;
@@ -289,10 +423,15 @@ void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) {
289 OTimeZone utc = OTimeZone::utc(); 423 OTimeZone utc = OTimeZone::utc();
290 ev.setStartDateTime( utc.fromUTCDateTime( start ) ); 424 ev.setStartDateTime( utc.fromUTCDateTime( start ) );
291 ev.setEndDateTime ( utc.fromUTCDateTime( end ) ); 425 ev.setEndDateTime ( utc.fromUTCDateTime( end ) );
426 ev.setTimeZone( "UTC"); // make sure it is really utc
292 }else { 427 }else {
428 /* to current date time */
293 OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() ); 429 OTimeZone zone( ev.timeZone().isEmpty() ? OTimeZone::current() : ev.timeZone() );
294 ev.setStartDateTime( zone.toDateTime( start ) ); 430 QDateTime date = zone.toDateTime( start );
295 ev.setEndDateTime ( zone.toDateTime( end ) ); 431 ev.setStartDateTime( zone.toDateTime( date, OTimeZone::current() ) );
432
433 date = zone.toDateTime( end );
434 ev.setEndDateTime ( zone.toDateTime( date, OTimeZone::current() ) );
296 } 435 }
297 if ( rec && rec->doesRecur() ) { 436 if ( rec && rec->doesRecur() ) {
298 OTimeZone utc = OTimeZone::utc(); 437 OTimeZone utc = OTimeZone::utc();
@@ -389,6 +528,29 @@ void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& val
389 case FCreated: 528 case FCreated:
390 created = value.toInt(); 529 created = value.toInt();
391 break; 530 break;
531 case FRecParent:
532 e.setParent( value.toInt() );
533 break;
534 case FRecChildren:{
535 QStringList list = QStringList::split(' ', value );
536 for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
537 e.addChild( (*it).toInt() );
538 }
539 }
540 break;
541 case FExceptions:{
542 QStringList list = QStringList::split(' ', value );
543 for (QStringList::Iterator it = list.begin(); it != list.end(); ++it ) {
544 QDate date( (*it).left(4).toInt(), (*it).mid(4, 2).toInt(), (*it).right(2).toInt() );
545 qWarning("adding exception %s", date.toString().latin1() );
546 recur()->exceptions().append( date );
547 }
548 }
549 break;
550 case FTimeZone:
551 if ( value != "None" )
552 e.setTimeZone( value );
553 break;
392 default: 554 default:
393 break; 555 break;
394 } 556 }