summaryrefslogtreecommitdiff
path: root/libopie2
authorzecke <zecke>2003-02-22 16:11:16 (UTC)
committer zecke <zecke>2003-02-22 16:11:16 (UTC)
commit397a7b1635488deda02b36df70692e27f59bb3e0 (patch) (unidiff)
tree1232b1b7e8ac84c5d48df79b635ba61acbdf0f62 /libopie2
parente7981098a5c373748d98158e8a6c59750bb0d7dc (diff)
downloadopie-397a7b1635488deda02b36df70692e27f59bb3e0.zip
opie-397a7b1635488deda02b36df70692e27f59bb3e0.tar.gz
opie-397a7b1635488deda02b36df70692e27f59bb3e0.tar.bz2
Implement saving of events
Implement the ExceptionList Add Children and parent to OEvent Make ORecur honor exceptions Extend the test app to add and save
Diffstat (limited to 'libopie2') (more/less context) (ignore whitespace changes)
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp184
-rw-r--r--libopie2/opiepim/core/orecur.cpp66
-rw-r--r--libopie2/opiepim/core/orecur.h4
-rw-r--r--libopie2/opiepim/oevent.cpp64
-rw-r--r--libopie2/opiepim/oevent.h10
5 files changed, 312 insertions, 16 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,83 +1,213 @@
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>
7 10
8#include <unistd.h> 11#include <unistd.h>
9 12
10#include <qasciidict.h> 13#include <qasciidict.h>
11#include <qfile.h> 14#include <qfile.h>
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"
18#include "otimezone.h" 22#include "otimezone.h"
19#include "odatebookaccessbackend_xml.h" 23#include "odatebookaccessbackend_xml.h"
20 24
21namespace { 25namespace {
22 time_t start, end, created, rp_end; 26 time_t start, end, created, rp_end;
23 ORecur* rec; 27 ORecur* rec;
24 ORecur* recur() { 28 ORecur* recur() {
25 if (!rec) 29 if (!rec)
26 rec = new ORecur; 30 rec = new ORecur;
27 31
28 return rec; 32 return rec;
29 } 33 }
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,
41 FRWeekdays, 45 FRWeekdays,
42 FRPosition, 46 FRPosition,
43 FRFreq, 47 FRFreq,
44 FRHasEndDate, 48 FRHasEndDate,
45 FREndDate, 49 FREndDate,
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& ,
54 const QString& fileName ) 139 const QString& fileName )
55 : ODateBookAccessBackend() { 140 : ODateBookAccessBackend() {
56 m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName; 141 m_name = fileName.isEmpty() ? Global::applicationFileName( "datebook", "datebook.xml" ) : fileName;
57 m_changed = false; 142 m_changed = false;
58} 143}
59ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() { 144ODateBookAccessBackend_XML::~ODateBookAccessBackend_XML() {
60} 145}
61bool ODateBookAccessBackend_XML::load() { 146bool ODateBookAccessBackend_XML::load() {
62 return loadFile(); 147 return loadFile();
63} 148}
64bool ODateBookAccessBackend_XML::reload() { 149bool ODateBookAccessBackend_XML::reload() {
65 clear(); 150 clear();
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 {
75 QArray<int> ints( m_raw.count()+ m_rep.count() ); 205 QArray<int> ints( m_raw.count()+ m_rep.count() );
76 uint i = 0; 206 uint i = 0;
77 QMap<int, OEvent>::ConstIterator it; 207 QMap<int, OEvent>::ConstIterator it;
78 208
79 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) { 209 for ( it = m_raw.begin(); it != m_raw.end(); ++it ) {
80 ints[i] = it.key(); 210 ints[i] = it.key();
81 i++; 211 i++;
82 } 212 }
83 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) { 213 for ( it = m_rep.begin(); it != m_rep.end(); ++it ) {
@@ -174,43 +304,47 @@ bool ODateBookAccessBackend_XML::loadFile() {
174 ::close( fd ); 304 ::close( fd );
175 return false; 305 return false;
176 } 306 }
177 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 ); 307 void* map_addr = ::mmap(NULL, attribute.st_size, PROT_READ, MAP_SHARED, fd, 0 );
178 if ( map_addr == ( (caddr_t)-1) ) { 308 if ( map_addr == ( (caddr_t)-1) ) {
179 ::close( fd ); 309 ::close( fd );
180 return false; 310 return false;
181 } 311 }
182 312
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) );
190 dict.insert( "categories", new int(FCategories) ); 320 dict.insert( "categories", new int(FCategories) );
191 dict.insert( "uid", new int(FUid) ); 321 dict.insert( "uid", new int(FUid) );
192 dict.insert( "type", new int(FType) ); 322 dict.insert( "type", new int(FType) );
193 dict.insert( "alarm", new int(FAlarm) ); 323 dict.insert( "alarm", new int(FAlarm) );
194 dict.insert( "sound", new int(FSound) ); 324 dict.insert( "sound", new int(FSound) );
195 dict.insert( "rtype", new int(FRType) ); 325 dict.insert( "rtype", new int(FRType) );
196 dict.insert( "rweekdays", new int(FRWeekdays) ); 326 dict.insert( "rweekdays", new int(FRWeekdays) );
197 dict.insert( "rposition", new int(FRPosition) ); 327 dict.insert( "rposition", new int(FRPosition) );
198 dict.insert( "rfreq", new int(FRFreq) ); 328 dict.insert( "rfreq", new int(FRFreq) );
199 dict.insert( "rhasenddate", new int(FRHasEndDate) ); 329 dict.insert( "rhasenddate", new int(FRHasEndDate) );
200 dict.insert( "enddt", new int(FREndDate) ); 330 dict.insert( "enddt", new int(FREndDate) );
201 dict.insert( "start", new int(FRStart) ); 331 dict.insert( "start", new int(FRStart) );
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;
208 int i = 0; 342 int i = 0;
209 char* point; 343 char* point;
210 const char* collectionString = "<event "; 344 const char* collectionString = "<event ";
211 int strLen = ::strlen(collectionString); 345 int strLen = ::strlen(collectionString);
212 int *find; 346 int *find;
213 while ( dt + 1 != 0 && (( point = ::strstr( dt+i, collectionString ) ) != 0 ) ) { 347 while ( dt + 1 != 0 && (( point = ::strstr( dt+i, collectionString ) ) != 0 ) ) {
214 i = point -dt; 348 i = point -dt;
215 i+= strLen; 349 i+= strLen;
216 350
@@ -280,28 +414,33 @@ bool ODateBookAccessBackend_XML::loadFile() {
280 } 414 }
281 ::munmap(map_addr, attribute.st_size ); 415 ::munmap(map_addr, attribute.st_size );
282 m_changed = false; // changed during add 416 m_changed = false; // changed during add
283 417
284 return true; 418 return true;
285} 419}
286void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) { 420void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) {
287 /* AllDay is alway in UTC */ 421 /* AllDay is alway in UTC */
288 if ( ev.isAllDay() ) { 422 if ( ev.isAllDay() ) {
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();
299 ORecur recu( *rec ); // call copy c'tor; 438 ORecur recu( *rec ); // call copy c'tor;
300 recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() ); 439 recu.setEndDate ( utc.fromUTCDateTime( rp_end ).date() );
301 recu.setCreatedDateTime( utc.fromUTCDateTime( created ) ); 440 recu.setCreatedDateTime( utc.fromUTCDateTime( created ) );
302 recu.setStart( ev.startDateTime().date() ); 441 recu.setStart( ev.startDateTime().date() );
303 ev.setRecurrence( recu ); 442 ev.setRecurrence( recu );
304 } 443 }
305 444
306 if (alarmTime != -1 ) { 445 if (alarmTime != -1 ) {
307 QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 ); 446 QDateTime dt = ev.startDateTime().addSecs( -1*alarmTime*60 );
@@ -380,16 +519,39 @@ void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& val
380 break; 519 break;
381 } 520 }
382 case FREnd: { 521 case FREnd: {
383 end = ( (time_t) value.toLong() ); 522 end = ( (time_t) value.toLong() );
384 break; 523 break;
385 } 524 }
386 case FNote: 525 case FNote:
387 e.setNote( value ); 526 e.setNote( value );
388 break; 527 break;
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 }
395} 557}
diff --git a/libopie2/opiepim/core/orecur.cpp b/libopie2/opiepim/core/orecur.cpp
index e6a4787..e3b45b4 100644
--- a/libopie2/opiepim/core/orecur.cpp
+++ b/libopie2/opiepim/core/orecur.cpp
@@ -1,16 +1,19 @@
1#include <time.h>
2
1#include <qshared.h> 3#include <qshared.h>
2 4
3#include <qtopia/timeconversion.h> 5#include <qtopia/timeconversion.h>
4 6
7#include "otimezone.h"
5#include "orecur.h" 8#include "orecur.h"
6 9
7struct ORecur::Data : public QShared { 10struct ORecur::Data : public QShared {
8 Data() : QShared() { 11 Data() : QShared() {
9 type = ORecur::NoRepeat; 12 type = ORecur::NoRepeat;
10 freq = -1; 13 freq = -1;
11 days = 0; 14 days = 0;
12 pos = 0; 15 pos = 0;
13 create = QDateTime::currentDateTime(); 16 create = QDateTime::currentDateTime();
14 hasEnd = FALSE; 17 hasEnd = FALSE;
15 end = QDate::currentDate(); 18 end = QDate::currentDate();
16 } 19 }
@@ -72,39 +75,47 @@ bool ORecur::doesRecur( const QDate& date ) {
72 QDate da = date.addDays(-1); 75 QDate da = date.addDays(-1);
73 76
74 QDate recur; 77 QDate recur;
75 if (!nextOcurrence( da, recur ) ) 78 if (!nextOcurrence( da, recur ) )
76 return false; 79 return false;
77 80
78 return (recur == date); 81 return (recur == date);
79} 82}
80// FIXME unuglify! 83// FIXME unuglify!
81// GPL from Datebookdb.cpp 84// GPL from Datebookdb.cpp
82// FIXME exception list! 85// FIXME exception list!
83bool ORecur::nextOcurrence( const QDate& from, QDate& next ) { 86bool ORecur::nextOcurrence( const QDate& from, QDate& next ) {
87 bool stillLooking;
88 stillLooking = p_nextOccurrence( from, next );
89 while ( stillLooking && data->list.contains(next) )
90 stillLooking = p_nextOccurrence( next.addDays(1), next );
91
92 return stillLooking;
93}
94bool ORecur::p_nextOccurrence( const QDate& from, QDate& next ) {
84 95
85 // easy checks, first are we too far in the future or too far in the past? 96 // easy checks, first are we too far in the future or too far in the past?
86 QDate tmpDate; 97 QDate tmpDate;
87 int freq = frequency(); 98 int freq = frequency();
88 int diff, diff2, a; 99 int diff, diff2, a;
89 int iday, imonth, iyear; 100 int iday, imonth, iyear;
90 int dayOfWeek = 0; 101 int dayOfWeek = 0;
91 int firstOfWeek = 0; 102 int firstOfWeek = 0;
92 int weekOfMonth; 103 int weekOfMonth;
93 104
94 105
95 if (hasEndDate() && endDate() < from) 106 if (hasEndDate() && endDate() < from)
96 return FALSE; 107 return FALSE;
97 108
98 if (start() >= from) { 109 if (start() >= from ) {
99 next = start(); 110 next = start();
100 return TRUE; 111 return TRUE;
101 } 112 }
102 113
103 switch ( type() ) { 114 switch ( type() ) {
104 case Weekly: 115 case Weekly:
105 /* weekly is just daily by 7 */ 116 /* weekly is just daily by 7 */
106 /* first convert the repeatPattern.Days() mask to the next 117 /* first convert the repeatPattern.Days() mask to the next
107 day of week valid after from */ 118 day of week valid after from */
108 dayOfWeek = from.dayOfWeek(); 119 dayOfWeek = from.dayOfWeek();
109 dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */ 120 dayOfWeek--; /* we want 0-6, doco for above specs 1-7 */
110 121
@@ -434,13 +445,66 @@ void ORecur::checkOrModify() {
434 d2->freq = data->freq; 445 d2->freq = data->freq;
435 d2->pos = data->pos; 446 d2->pos = data->pos;
436 d2->hasEnd = data->hasEnd; 447 d2->hasEnd = data->hasEnd;
437 d2->end = data->end; 448 d2->end = data->end;
438 d2->create = data->create; 449 d2->create = data->create;
439 d2->rep = data->rep; 450 d2->rep = data->rep;
440 d2->app = data->app; 451 d2->app = data->app;
441 d2->list = data->list; 452 d2->list = data->list;
442 d2->start = data->start; 453 d2->start = data->start;
443 data = d2; 454 data = d2;
444 } 455 }
445} 456}
457QString ORecur::toString()const {
458 QString buf;
459
460 buf += " rtype=\"";
461 switch ( data->type ) {
462 case ORecur::Daily:
463 buf += "Daily";
464 break;
465 case ORecur::Weekly:
466 buf += "Weekly";
467 break;
468 case ORecur::MonthlyDay:
469 buf += "MonthlyDay";
470 break;
471 case ORecur::MonthlyDate:
472 buf += "MonthlyDate";
473 break;
474 case ORecur::Yearly:
475 buf += "Yearly";
476 break;
477 default:
478 buf += "NoRepeat";
479 break;
480 }
481 buf += "\"";
482 if (data->days > 0 )
483 buf += " rweekdays=\"" + QString::number( static_cast<int>( data->days ) ) + "\"";
484 if ( data->pos != 0 )
485 buf += " rposition=\"" + QString::number(data->pos ) + "\"";
486
487 buf += " rfreq=\"" + QString::number( data->freq ) + "\"";
488 buf += " rhasenddate=\"" + QString::number( static_cast<int>( data->hasEnd ) ) + "\"";
489 if ( data->hasEnd )
490 buf += " enddt=\""
491 + QString::number( OTimeZone::utc().fromUTCDateTime( QDateTime( data->end, QTime(12,0,0) ) ) )
492 + "\"";
493 buf += " created=\"" + QString::number( OTimeZone::utc().fromUTCDateTime( data->create ) ) + "\"";
494
495 if ( data->list.isEmpty() ) return buf;
496 // save exceptions list here!!
497 ExceptionList::ConstIterator it;
498 ExceptionList list = data->list;
499 buf += " exceptions=\"";
500 QDate date;
501 for ( it = list.begin(); it != list.end(); ++it ) {
502 date = (*it);
503 if ( it != list.begin() ) buf += " ";
504
505 buf += QCString().sprintf("%04d%02d%02d", date.year(), date.month(), date.day() );
506 }
507 buf += "\"";
446 508
509 return buf;
510}
diff --git a/libopie2/opiepim/core/orecur.h b/libopie2/opiepim/core/orecur.h
index 1e0014b..b214b3f 100644
--- a/libopie2/opiepim/core/orecur.h
+++ b/libopie2/opiepim/core/orecur.h
@@ -64,24 +64,28 @@ public:
64 64
65 void setType( const RepeatType& ); 65 void setType( const RepeatType& );
66 void setFrequency( int freq ); 66 void setFrequency( int freq );
67 void setPosition( int pos ); 67 void setPosition( int pos );
68 void setDays( char c); 68 void setDays( char c);
69 void setEndDate( const QDate& dt ); 69 void setEndDate( const QDate& dt );
70 void setStart( const QDate& dt ); 70 void setStart( const QDate& dt );
71 void setCreatedDateTime( const QDateTime& ); 71 void setCreatedDateTime( const QDateTime& );
72 void setHasEndDate( bool b ); 72 void setHasEndDate( bool b );
73 void setRepitition(int ); 73 void setRepitition(int );
74 74
75 void setService( const QString& ser ); 75 void setService( const QString& ser );
76
77 /* almost internal */
78 QString toString()const;
76private: 79private:
80 bool p_nextOccurrence( const QDate& from, QDate& next );
77 void deref(); 81 void deref();
78 inline void checkOrModify(); 82 inline void checkOrModify();
79 83
80 84
81 class Data; 85 class Data;
82 Data* data; 86 Data* data;
83 class ORecurPrivate; 87 class ORecurPrivate;
84 ORecurPrivate *d; 88 ORecurPrivate *d;
85}; 89};
86 90
87#endif 91#endif
diff --git a/libopie2/opiepim/oevent.cpp b/libopie2/opiepim/oevent.cpp
index ada596c..c3eeee2 100644
--- a/libopie2/opiepim/oevent.cpp
+++ b/libopie2/opiepim/oevent.cpp
@@ -33,42 +33,46 @@ int OCalendarHelper::dayOfWeek( char day ) {
33 i <<= 1; 33 i <<= 1;
34 ++dayOfWeek; 34 ++dayOfWeek;
35 } 35 }
36 return dayOfWeek; 36 return dayOfWeek;
37} 37}
38int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) { 38int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) {
39 return ( second.year() - first.year() ) * 12 + 39 return ( second.year() - first.year() ) * 12 +
40 second.month() - first.month(); 40 second.month() - first.month();
41} 41}
42 42
43struct OEvent::Data : public QShared { 43struct OEvent::Data : public QShared {
44 Data() : QShared() { 44 Data() : QShared() {
45 child = 0;
45 recur = 0; 46 recur = 0;
46 manager = 0; 47 manager = 0;
47 isAllDay = false; 48 isAllDay = false;
49 parent = 0;
48 } 50 }
49 ~Data() { 51 ~Data() {
50 delete manager; 52 delete manager;
51 delete recur; 53 delete recur;
52 } 54 }
53 QString description; 55 QString description;
54 QString location; 56 QString location;
55 OPimNotifyManager* manager; 57 OPimNotifyManager* manager;
56 ORecur* recur; 58 ORecur* recur;
57 QString note; 59 QString note;
58 QDateTime created; 60 QDateTime created;
59 QDateTime start; 61 QDateTime start;
60 QDateTime end; 62 QDateTime end;
61 bool isAllDay : 1; 63 bool isAllDay : 1;
62 QString timezone; 64 QString timezone;
65 QArray<int>* child;
66 int parent;
63}; 67};
64 68
65OEvent::OEvent( int uid ) 69OEvent::OEvent( int uid )
66 : OPimRecord( uid ) { 70 : OPimRecord( uid ) {
67 data = new Data; 71 data = new Data;
68} 72}
69OEvent::OEvent( const OEvent& ev) 73OEvent::OEvent( const OEvent& ev)
70 : OPimRecord( ev ), data( ev.data ) 74 : OPimRecord( ev ), data( ev.data )
71{ 75{
72 data->ref(); 76 data->ref();
73} 77}
74OEvent::~OEvent() { 78OEvent::~OEvent() {
@@ -93,35 +97,41 @@ QString OEvent::description()const {
93} 97}
94void OEvent::setDescription( const QString& description ) { 98void OEvent::setDescription( const QString& description ) {
95 changeOrModify(); 99 changeOrModify();
96 data->description = description; 100 data->description = description;
97} 101}
98void OEvent::setLocation( const QString& loc ) { 102void OEvent::setLocation( const QString& loc ) {
99 changeOrModify(); 103 changeOrModify();
100 data->location = loc; 104 data->location = loc;
101} 105}
102QString OEvent::location()const { 106QString OEvent::location()const {
103 return data->location; 107 return data->location;
104} 108}
105OPimNotifyManager &OEvent::notifiers() { 109OPimNotifyManager &OEvent::notifiers()const {
106 // I hope we can skip the changeOrModify here 110 // I hope we can skip the changeOrModify here
107 // the notifier should take care of it 111 // the notifier should take care of it
108 // and OPimNotify is shared too 112 // and OPimNotify is shared too
109 if (!data->manager ) 113 if (!data->manager )
110 data->manager = new OPimNotifyManager; 114 data->manager = new OPimNotifyManager;
111 115
112 return *data->manager; 116 return *data->manager;
113} 117}
114bool OEvent::hasNotifiers()const { 118bool OEvent::hasNotifiers()const {
115 return ( data->manager); 119 if (!data->manager )
120 return false;
121 if (data->manager->reminders().isEmpty() &&
122 data->manager->alarms().isEmpty() )
123 return false;
124
125 return true;
116} 126}
117ORecur OEvent::recurrence()const { 127ORecur OEvent::recurrence()const {
118 if (!data->recur) 128 if (!data->recur)
119 data->recur = new ORecur; 129 data->recur = new ORecur;
120 130
121 return *data->recur; 131 return *data->recur;
122} 132}
123void OEvent::setRecurrence( const ORecur& rec) { 133void OEvent::setRecurrence( const ORecur& rec) {
124 changeOrModify(); 134 changeOrModify();
125 if (data->recur ) 135 if (data->recur )
126 (*data->recur) = rec; 136 (*data->recur) = rec;
127 else 137 else
@@ -188,24 +198,25 @@ bool OEvent::isAllDay()const {
188 return data->isAllDay; 198 return data->isAllDay;
189} 199}
190void OEvent::setAllDay( bool allDay ) { 200void OEvent::setAllDay( bool allDay ) {
191 changeOrModify(); 201 changeOrModify();
192 data->isAllDay = allDay; 202 data->isAllDay = allDay;
193 if (allDay ) data->timezone = "UTC"; 203 if (allDay ) data->timezone = "UTC";
194} 204}
195void OEvent::setTimeZone( const QString& tz ) { 205void OEvent::setTimeZone( const QString& tz ) {
196 changeOrModify(); 206 changeOrModify();
197 data->timezone = tz; 207 data->timezone = tz;
198} 208}
199QString OEvent::timeZone()const { 209QString OEvent::timeZone()const {
210 if (data->isAllDay ) return QString::fromLatin1("UTC");
200 return data->timezone; 211 return data->timezone;
201} 212}
202bool OEvent::match( const QRegExp& )const { 213bool OEvent::match( const QRegExp& )const {
203 // FIXME 214 // FIXME
204 return false; 215 return false;
205} 216}
206QString OEvent::toRichText()const { 217QString OEvent::toRichText()const {
207 // FIXME 218 // FIXME
208 return "OEvent test"; 219 return "OEvent test";
209} 220}
210QString OEvent::toShortText()const { 221QString OEvent::toShortText()const {
211 return "OEvent shotText"; 222 return "OEvent shotText";
@@ -230,43 +241,90 @@ void OEvent::changeOrModify() {
230 data->deref(); 241 data->deref();
231 Data* d2 = new Data; 242 Data* d2 = new Data;
232 d2->description = data->description; 243 d2->description = data->description;
233 d2->location = data->location; 244 d2->location = data->location;
234 d2->manager = data->manager; 245 d2->manager = data->manager;
235 d2->recur = data->recur; 246 d2->recur = data->recur;
236 d2->note = data->note; 247 d2->note = data->note;
237 d2->created = data->created; 248 d2->created = data->created;
238 d2->start = data->start; 249 d2->start = data->start;
239 d2->end = data->end; 250 d2->end = data->end;
240 d2->isAllDay = data->isAllDay; 251 d2->isAllDay = data->isAllDay;
241 d2->timezone = data->timezone; 252 d2->timezone = data->timezone;
253 d2->parent = data->parent;
254 d2->child = data->child;
255
256 if (d2->child )
257 d2->child->detach();
242 258
243 data = d2; 259 data = d2;
244 } 260 }
245} 261}
246void OEvent::deref() { 262void OEvent::deref() {
247 if ( data->deref() ) { 263 if ( data->deref() ) {
248 delete data; 264 delete data;
249 data = 0; 265 data = 0;
250 } 266 }
251} 267}
252// FIXME 268// FIXME
253QMap<int, QString> OEvent::toMap()const { 269QMap<int, QString> OEvent::toMap()const {
254 return QMap<int, QString>(); 270 return QMap<int, QString>();
255} 271}
256QMap<QString, QString> OEvent::toExtraMap()const { 272QMap<QString, QString> OEvent::toExtraMap()const {
257 return QMap<QString, QString>(); 273 return QMap<QString, QString>();
258} 274}
275int OEvent::parent()const {
276 return data->parent;
277}
278void OEvent::setParent( int uid ) {
279 changeOrModify();
280 data->parent = uid;
281}
282QArray<int> OEvent::children() const{
283 if (!data->child) return QArray<int>();
284 else
285 return data->child->copy();
286}
287void OEvent::setChildren( const QArray<int>& arr ) {
288 changeOrModify();
289 if (data->child) delete data->child;
259 290
260 291 data->child = new QArray<int>( arr );
292 data->child->detach();
293}
294void OEvent::addChild( int uid ) {
295 changeOrModify();
296 if (!data->child ) {
297 data->child = new QArray<int>(1);
298 (*data->child)[0] = uid;
299 }else{
300 int count = data->child->count();
301 data->child->resize( count + 1 );
302 (*data->child)[count] = uid;
303 }
304}
305void OEvent::removeChild( int uid ) {
306 if (!data->child || !data->child->contains( uid ) ) return;
307 changeOrModify();
308 QArray<int> newAr( data->child->count() - 1 );
309 int j = 0;
310 uint count = data->child->count();
311 for ( uint i = 0; i < count; i++ ) {
312 if ( (*data->child)[i] != uid ) {
313 newAr[j] = (*data->child)[i];
314 j++;
315 }
316 }
317 (*data->child) = newAr;
318}
261struct OEffectiveEvent::Data : public QShared { 319struct OEffectiveEvent::Data : public QShared {
262 Data() : QShared() { 320 Data() : QShared() {
263 } 321 }
264 OEvent event; 322 OEvent event;
265 QDate date; 323 QDate date;
266 QTime start, end; 324 QTime start, end;
267 QDate startDate, endDate; 325 QDate startDate, endDate;
268 bool dates : 1; 326 bool dates : 1;
269}; 327};
270 328
271OEffectiveEvent::OEffectiveEvent() { 329OEffectiveEvent::OEffectiveEvent() {
272 data = new Data; 330 data = new Data;
diff --git a/libopie2/opiepim/oevent.h b/libopie2/opiepim/oevent.h
index c718e2e..585515c 100644
--- a/libopie2/opiepim/oevent.h
+++ b/libopie2/opiepim/oevent.h
@@ -52,25 +52,25 @@ public:
52 OEvent(int uid = 0); 52 OEvent(int uid = 0);
53 OEvent( const OEvent& ); 53 OEvent( const OEvent& );
54 ~OEvent(); 54 ~OEvent();
55 OEvent &operator=( const OEvent& ); 55 OEvent &operator=( const OEvent& );
56 56
57 QString description()const; 57 QString description()const;
58 void setDescription( const QString& description ); 58 void setDescription( const QString& description );
59 59
60 QString location()const; 60 QString location()const;
61 void setLocation( const QString& loc ); 61 void setLocation( const QString& loc );
62 62
63 bool hasNotifiers()const; 63 bool hasNotifiers()const;
64 OPimNotifyManager &notifiers(); 64 OPimNotifyManager &notifiers()const;
65 65
66 ORecur recurrence()const; 66 ORecur recurrence()const;
67 void setRecurrence( const ORecur& ); 67 void setRecurrence( const ORecur& );
68 bool hasRecurrence()const; 68 bool hasRecurrence()const;
69 69
70 QString note()const; 70 QString note()const;
71 void setNote( const QString& note ); 71 void setNote( const QString& note );
72 72
73 73
74 QDateTime createdDateTime()const; 74 QDateTime createdDateTime()const;
75 void setCreatedDateTime( const QDateTime& dt); 75 void setCreatedDateTime( const QDateTime& dt);
76 76
@@ -90,25 +90,33 @@ public:
90 90
91 bool isMultipleDay()const; 91 bool isMultipleDay()const;
92 bool isAllDay()const; 92 bool isAllDay()const;
93 void setAllDay( bool isAllDay ); 93 void setAllDay( bool isAllDay );
94 94
95 /* pin this event to a timezone! FIXME */ 95 /* pin this event to a timezone! FIXME */
96 void setTimeZone( const QString& timeZone ); 96 void setTimeZone( const QString& timeZone );
97 QString timeZone()const; 97 QString timeZone()const;
98 98
99 99
100 bool match( const QRegExp& )const; 100 bool match( const QRegExp& )const;
101 101
102 /** For exception to recurrence here is a list of children... */
103 QArray<int> children()const;
104 void setChildren( const QArray<int>& );
105 void addChild( int uid );
106 void removeChild( int uid );
102 107
108 /** return the parent OEvent */
109 int parent()const;
110 void setParent( int uid );
103 111
104 112
105 /* needed reimp */ 113 /* needed reimp */
106 QString toRichText()const; 114 QString toRichText()const;
107 QString toShortText()const; 115 QString toShortText()const;
108 QString type()const; 116 QString type()const;
109 117
110 QMap<int, QString> toMap()const; 118 QMap<int, QString> toMap()const;
111 QMap<QString, QString> toExtraMap()const; 119 QMap<QString, QString> toExtraMap()const;
112 QString recordField(int )const; 120 QString recordField(int )const;
113 121
114 static int rtti(); 122 static int rtti();