summaryrefslogtreecommitdiff
path: root/libopie2
Unidiff
Diffstat (limited to 'libopie2') (more/less context) (show whitespace changes)
-rw-r--r--libopie2/opiepim/backend/odatebookaccessbackend_xml.cpp174
-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, 307 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
@@ -3,2 +3,5 @@
3 3
4#include <stdio.h>
5#include <stdlib.h>
6
4#include <sys/types.h> 7#include <sys/types.h>
@@ -14,2 +17,3 @@
14#include <qtopia/stringutil.h> 17#include <qtopia/stringutil.h>
18#include <qtopia/timeconversion.h>
15 19
@@ -48,4 +52,85 @@ namespace {
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}
@@ -68,5 +153,50 @@ bool ODateBookAccessBackend_XML::reload() {
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 }
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 }
71 200
201 m_changed = false;
72 return true; 202 return true;
@@ -185,3 +315,3 @@ bool ODateBookAccessBackend_XML::loadFile() {
185 315
186 QAsciiDict<int> dict(FCreated+1); 316 QAsciiDict<int> dict(FExceptions+1);
187 dict.setAutoDelete( true ); 317 dict.setAutoDelete( true );
@@ -204,2 +334,6 @@ bool ODateBookAccessBackend_XML::loadFile() {
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
@@ -291,6 +425,11 @@ void ODateBookAccessBackend_XML::finalizeRecord( OEvent& ev ) {
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 }
@@ -391,2 +530,25 @@ void ODateBookAccessBackend_XML::setField( OEvent& e, int id, const QString& val
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:
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 +1,3 @@
1#include <time.h>
2
1#include <qshared.h> 3#include <qshared.h>
@@ -4,2 +6,3 @@
4 6
7#include "otimezone.h"
5#include "orecur.h" 8#include "orecur.h"
@@ -83,2 +86,10 @@ bool ORecur::doesRecur( const QDate& date ) {
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
@@ -445,2 +456,55 @@ void ORecur::checkOrModify() {
445} 456}
446 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 += "\"";
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
@@ -75,3 +75,7 @@ public:
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();
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
@@ -44,2 +44,3 @@ struct OEvent::Data : public QShared {
44 Data() : QShared() { 44 Data() : QShared() {
45 child = 0;
45 recur = 0; 46 recur = 0;
@@ -47,2 +48,3 @@ struct OEvent::Data : public QShared {
47 isAllDay = false; 48 isAllDay = false;
49 parent = 0;
48 } 50 }
@@ -62,2 +64,4 @@ struct OEvent::Data : public QShared {
62 QString timezone; 64 QString timezone;
65 QArray<int>* child;
66 int parent;
63}; 67};
@@ -104,3 +108,3 @@ QString OEvent::location()const {
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
@@ -114,3 +118,9 @@ OPimNotifyManager &OEvent::notifiers() {
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}
@@ -199,2 +209,3 @@ void OEvent::setTimeZone( const QString& tz ) {
199QString OEvent::timeZone()const { 209QString OEvent::timeZone()const {
210 if (data->isAllDay ) return QString::fromLatin1("UTC");
200 return data->timezone; 211 return data->timezone;
@@ -241,2 +252,7 @@ void OEvent::changeOrModify() {
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
@@ -258,4 +274,46 @@ QMap<QString, QString> OEvent::toExtraMap()const {
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 {
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
@@ -63,3 +63,3 @@ public:
63 bool hasNotifiers()const; 63 bool hasNotifiers()const;
64 OPimNotifyManager &notifiers(); 64 OPimNotifyManager &notifiers()const;
65 65
@@ -101,3 +101,11 @@ public:
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