author | mickeyl <mickeyl> | 2004-02-24 12:46:23 (UTC) |
---|---|---|
committer | mickeyl <mickeyl> | 2004-02-24 12:46:23 (UTC) |
commit | 911473db35a9fce5f3589f03c27210456faaba86 (patch) (unidiff) | |
tree | 7d55b6117b24de6ab18747b00a4641d38001c0ed /libopie2/opiepim/core/opimevent.cpp | |
parent | a2ead23c3614fe581261455cb4c3f31cee2098f3 (diff) | |
download | opie-911473db35a9fce5f3589f03c27210456faaba86.zip opie-911473db35a9fce5f3589f03c27210456faaba86.tar.gz opie-911473db35a9fce5f3589f03c27210456faaba86.tar.bz2 |
*phew* here is the class and file rename patch. not converted yet: backend,
but that will be not visible to application classes so we can change it later.
Diffstat (limited to 'libopie2/opiepim/core/opimevent.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libopie2/opiepim/core/opimevent.cpp | 1025 |
1 files changed, 1025 insertions, 0 deletions
diff --git a/libopie2/opiepim/core/opimevent.cpp b/libopie2/opiepim/core/opimevent.cpp new file mode 100644 index 0000000..3ddbf85 --- a/dev/null +++ b/libopie2/opiepim/core/opimevent.cpp | |||
@@ -0,0 +1,1025 @@ | |||
1 | /* | ||
2 | This file is part of the Opie Project | ||
3 | Copyright (C) Stefan Eilers <Eilers.Stefan@epost.de> | ||
4 | =. Copyright (C) The Opie Team <opie-devel@handhelds.org> | ||
5 | .=l. | ||
6 | .>+-= | ||
7 | _;:, .> :=|. This program is free software; you can | ||
8 | .> <`_, > . <= redistribute it and/or modify it under | ||
9 | :`=1 )Y*s>-.-- : the terms of the GNU Library General Public | ||
10 | .="- .-=="i, .._ License as published by the Free Software | ||
11 | - . .-<_> .<> Foundation; either version 2 of the License, | ||
12 | ._= =} : or (at your option) any later version. | ||
13 | .%`+i> _;_. | ||
14 | .i_,=:_. -<s. This program is distributed in the hope that | ||
15 | + . -:. = it will be useful, but WITHOUT ANY WARRANTY; | ||
16 | : .. .:, . . . without even the implied warranty of | ||
17 | =_ + =;=|` MERCHANTABILITY or FITNESS FOR A | ||
18 | _.=:. : :=>`: PARTICULAR PURPOSE. See the GNU | ||
19 | ..}^=.= = ; Library General Public License for more | ||
20 | ++= -. .` .: details. | ||
21 | : = ...= . :.=- | ||
22 | -. .:....=;==+<; You should have received a copy of the GNU | ||
23 | -_. . . )=. = Library General Public License along with | ||
24 | -- :-=` this library; see the file COPYING.LIB. | ||
25 | If not, write to the Free Software Foundation, | ||
26 | Inc., 59 Temple Place - Suite 330, | ||
27 | Boston, MA 02111-1307, USA. | ||
28 | */ | ||
29 | |||
30 | #include "opimevent.h" | ||
31 | |||
32 | /* OPIE */ | ||
33 | #include <opie2/opimrecurrence.h> | ||
34 | #include <opie2/opimresolver.h> | ||
35 | #include <opie2/opimnotifymanager.h> | ||
36 | #include <qpe/categories.h> | ||
37 | #include <qpe/palmtopuidgen.h> | ||
38 | #include <qpe/stringutil.h> | ||
39 | |||
40 | /* QT */ | ||
41 | #include <qshared.h> | ||
42 | #include <qarray.h> | ||
43 | |||
44 | namespace Opie | ||
45 | { | ||
46 | |||
47 | int OCalendarHelper::week( const QDate& date ) | ||
48 | { | ||
49 | // Calculates the week this date is in within that | ||
50 | // month. Equals the "row" is is in in the month view | ||
51 | int week = 1; | ||
52 | QDate tmp( date.year(), date.month(), 1 ); | ||
53 | if ( date.dayOfWeek() < tmp.dayOfWeek() ) | ||
54 | ++week; | ||
55 | |||
56 | week += ( date.day() - 1 ) / 7; | ||
57 | |||
58 | return week; | ||
59 | } | ||
60 | |||
61 | |||
62 | int OCalendarHelper::ocurrence( const QDate& date ) | ||
63 | { | ||
64 | // calculates the number of occurrances of this day of the | ||
65 | // week till the given date (e.g 3rd Wednesday of the month) | ||
66 | return ( date.day() - 1 ) / 7 + 1; | ||
67 | } | ||
68 | |||
69 | |||
70 | int OCalendarHelper::dayOfWeek( char day ) | ||
71 | { | ||
72 | int dayOfWeek = 1; | ||
73 | char i = OPimRecurrence::MON; | ||
74 | while ( !( i & day ) && i <= OPimRecurrence::SUN ) | ||
75 | { | ||
76 | i <<= 1; | ||
77 | ++dayOfWeek; | ||
78 | } | ||
79 | return dayOfWeek; | ||
80 | } | ||
81 | |||
82 | |||
83 | int OCalendarHelper::monthDiff( const QDate& first, const QDate& second ) | ||
84 | { | ||
85 | return ( second.year() - first.year() ) * 12 + | ||
86 | second.month() - first.month(); | ||
87 | } | ||
88 | |||
89 | |||
90 | struct OPimEvent::Data : public QShared | ||
91 | { | ||
92 | Data() : QShared() | ||
93 | { | ||
94 | child = 0; | ||
95 | recur = 0; | ||
96 | manager = 0; | ||
97 | isAllDay = false; | ||
98 | parent = 0; | ||
99 | } | ||
100 | ~Data() | ||
101 | { | ||
102 | delete manager; | ||
103 | delete recur; | ||
104 | } | ||
105 | QString description; | ||
106 | QString location; | ||
107 | OPimNotifyManager* manager; | ||
108 | OPimRecurrence* recur; | ||
109 | QString note; | ||
110 | QDateTime created; | ||
111 | QDateTime start; | ||
112 | QDateTime end; | ||
113 | bool isAllDay : 1; | ||
114 | QString timezone; | ||
115 | QArray<int>* child; | ||
116 | int parent; | ||
117 | }; | ||
118 | |||
119 | |||
120 | OPimEvent::OPimEvent( int uid ) | ||
121 | : OPimRecord( uid ) | ||
122 | { | ||
123 | data = new Data; | ||
124 | } | ||
125 | |||
126 | |||
127 | OPimEvent::OPimEvent( const OPimEvent& ev ) | ||
128 | : OPimRecord( ev ), data( ev.data ) | ||
129 | { | ||
130 | data->ref(); | ||
131 | } | ||
132 | |||
133 | |||
134 | OPimEvent::OPimEvent( const QMap<int, QString> map ) | ||
135 | : OPimRecord( 0 ) | ||
136 | { | ||
137 | data = new Data; | ||
138 | |||
139 | fromMap( map ); | ||
140 | } | ||
141 | |||
142 | |||
143 | OPimEvent::~OPimEvent() | ||
144 | { | ||
145 | if ( data->deref() ) | ||
146 | { | ||
147 | delete data; | ||
148 | data = 0; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | |||
153 | OPimEvent& OPimEvent::operator=( const OPimEvent& ev ) | ||
154 | { | ||
155 | if ( this == &ev ) return * this; | ||
156 | |||
157 | OPimRecord::operator=( ev ); | ||
158 | ev.data->ref(); | ||
159 | deref(); | ||
160 | data = ev.data; | ||
161 | |||
162 | |||
163 | return *this; | ||
164 | } | ||
165 | |||
166 | |||
167 | QString OPimEvent::description() const | ||
168 | { | ||
169 | return data->description; | ||
170 | } | ||
171 | |||
172 | |||
173 | void OPimEvent::setDescription( const QString& description ) | ||
174 | { | ||
175 | changeOrModify(); | ||
176 | data->description = description; | ||
177 | } | ||
178 | |||
179 | |||
180 | void OPimEvent::setLocation( const QString& loc ) | ||
181 | { | ||
182 | changeOrModify(); | ||
183 | data->location = loc; | ||
184 | } | ||
185 | |||
186 | |||
187 | QString OPimEvent::location() const | ||
188 | { | ||
189 | return data->location; | ||
190 | } | ||
191 | |||
192 | |||
193 | OPimNotifyManager &OPimEvent::notifiers() const | ||
194 | { | ||
195 | // I hope we can skip the changeOrModify here | ||
196 | // the notifier should take care of it | ||
197 | // and OPimNotify is shared too | ||
198 | if ( !data->manager ) | ||
199 | data->manager = new OPimNotifyManager; | ||
200 | |||
201 | return *data->manager; | ||
202 | } | ||
203 | |||
204 | |||
205 | bool OPimEvent::hasNotifiers() const | ||
206 | { | ||
207 | if ( !data->manager ) | ||
208 | return false; | ||
209 | if ( data->manager->reminders().isEmpty() && | ||
210 | data->manager->alarms().isEmpty() ) | ||
211 | return false; | ||
212 | |||
213 | return true; | ||
214 | } | ||
215 | |||
216 | |||
217 | OPimRecurrence OPimEvent::recurrence() const | ||
218 | { | ||
219 | if ( !data->recur ) | ||
220 | data->recur = new OPimRecurrence; | ||
221 | |||
222 | return *data->recur; | ||
223 | } | ||
224 | |||
225 | |||
226 | void OPimEvent::setRecurrence( const OPimRecurrence& rec ) | ||
227 | { | ||
228 | changeOrModify(); | ||
229 | if ( data->recur ) | ||
230 | ( *data->recur ) = rec; | ||
231 | else | ||
232 | data->recur = new OPimRecurrence( rec ); | ||
233 | } | ||
234 | |||
235 | |||
236 | bool OPimEvent::hasRecurrence() const | ||
237 | { | ||
238 | if ( !data->recur ) return false; | ||
239 | return data->recur->doesRecur(); | ||
240 | } | ||
241 | |||
242 | |||
243 | QString OPimEvent::note() const | ||
244 | { | ||
245 | return data->note; | ||
246 | } | ||
247 | |||
248 | |||
249 | void OPimEvent::setNote( const QString& note ) | ||
250 | { | ||
251 | changeOrModify(); | ||
252 | data->note = note; | ||
253 | } | ||
254 | |||
255 | |||
256 | QDateTime OPimEvent::createdDateTime() const | ||
257 | { | ||
258 | return data->created; | ||
259 | } | ||
260 | |||
261 | |||
262 | void OPimEvent::setCreatedDateTime( const QDateTime& time ) | ||
263 | { | ||
264 | changeOrModify(); | ||
265 | data->created = time; | ||
266 | } | ||
267 | |||
268 | |||
269 | QDateTime OPimEvent::startDateTime() const | ||
270 | { | ||
271 | if ( data->isAllDay ) | ||
272 | return QDateTime( data->start.date(), QTime( 0, 0, 0 ) ); | ||
273 | return data->start; | ||
274 | } | ||
275 | |||
276 | |||
277 | QDateTime OPimEvent::startDateTimeInZone() const | ||
278 | { | ||
279 | /* if no timezone, or all day event or if the current and this timeZone match... */ | ||
280 | if ( data->timezone.isEmpty() || data->isAllDay || data->timezone == OPimTimeZone::current().timeZone() ) return startDateTime(); | ||
281 | |||
282 | OPimTimeZone zone( data->timezone ); | ||
283 | return zone.toDateTime( data->start, OPimTimeZone::current() ); | ||
284 | } | ||
285 | |||
286 | |||
287 | void OPimEvent::setStartDateTime( const QDateTime& dt ) | ||
288 | { | ||
289 | changeOrModify(); | ||
290 | data->start = dt; | ||
291 | } | ||
292 | |||
293 | |||
294 | QDateTime OPimEvent::endDateTime() const | ||
295 | { | ||
296 | /* | ||
297 | * if all Day event the end time needs | ||
298 | * to be on the same day as the start | ||
299 | */ | ||
300 | if ( data->isAllDay ) | ||
301 | return QDateTime( data->start.date(), QTime( 23, 59, 59 ) ); | ||
302 | return data->end; | ||
303 | } | ||
304 | |||
305 | |||
306 | QDateTime OPimEvent::endDateTimeInZone() const | ||
307 | { | ||
308 | /* if no timezone, or all day event or if the current and this timeZone match... */ | ||
309 | if ( data->timezone.isEmpty() || data->isAllDay || data->timezone == OPimTimeZone::current().timeZone() ) return endDateTime(); | ||
310 | |||
311 | OPimTimeZone zone( data->timezone ); | ||
312 | return zone.toDateTime( data->end, OPimTimeZone::current() ); | ||
313 | } | ||
314 | |||
315 | |||
316 | void OPimEvent::setEndDateTime( const QDateTime& dt ) | ||
317 | { | ||
318 | changeOrModify(); | ||
319 | data->end = dt; | ||
320 | } | ||
321 | |||
322 | |||
323 | bool OPimEvent::isMultipleDay() const | ||
324 | { | ||
325 | return data->end.date().day() - data->start.date().day(); | ||
326 | } | ||
327 | |||
328 | |||
329 | bool OPimEvent::isAllDay() const | ||
330 | { | ||
331 | return data->isAllDay; | ||
332 | } | ||
333 | |||
334 | |||
335 | void OPimEvent::setAllDay( bool allDay ) | ||
336 | { | ||
337 | changeOrModify(); | ||
338 | data->isAllDay = allDay; | ||
339 | if ( allDay ) data->timezone = "UTC"; | ||
340 | } | ||
341 | |||
342 | |||
343 | void OPimEvent::setTimeZone( const QString& tz ) | ||
344 | { | ||
345 | changeOrModify(); | ||
346 | data->timezone = tz; | ||
347 | } | ||
348 | |||
349 | |||
350 | QString OPimEvent::timeZone() const | ||
351 | { | ||
352 | if ( data->isAllDay ) return QString::fromLatin1( "UTC" ); | ||
353 | return data->timezone; | ||
354 | } | ||
355 | |||
356 | |||
357 | bool OPimEvent::match( const QRegExp& re ) const | ||
358 | { | ||
359 | if ( re.match( data->description ) != -1 ) | ||
360 | { | ||
361 | setLastHitField( Qtopia::DatebookDescription ); | ||
362 | return true; | ||
363 | } | ||
364 | if ( re.match( data->note ) != -1 ) | ||
365 | { | ||
366 | setLastHitField( Qtopia::Note ); | ||
367 | return true; | ||
368 | } | ||
369 | if ( re.match( data->location ) != -1 ) | ||
370 | { | ||
371 | setLastHitField( Qtopia::Location ); | ||
372 | return true; | ||
373 | } | ||
374 | if ( re.match( data->start.toString() ) != -1 ) | ||
375 | { | ||
376 | setLastHitField( Qtopia::StartDateTime ); | ||
377 | return true; | ||
378 | } | ||
379 | if ( re.match( data->end.toString() ) != -1 ) | ||
380 | { | ||
381 | setLastHitField( Qtopia::EndDateTime ); | ||
382 | return true; | ||
383 | } | ||
384 | return false; | ||
385 | } | ||
386 | |||
387 | |||
388 | QString OPimEvent::toRichText() const | ||
389 | { | ||
390 | QString text, value; | ||
391 | |||
392 | // description | ||
393 | text += "<b><h3><img src=\"datebook/DateBook\">"; | ||
394 | if ( !description().isEmpty() ) | ||
395 | { | ||
396 | text += Qtopia::escapeString( description() ).replace( QRegExp( "[\n]" ), "" ); | ||
397 | } | ||
398 | text += "</h3></b><br><hr><br>"; | ||
399 | |||
400 | // location | ||
401 | if ( !( value = location() ).isEmpty() ) | ||
402 | { | ||
403 | text += "<b>" + QObject::tr( "Location:" ) + "</b> "; | ||
404 | text += Qtopia::escapeString( value ) + "<br>"; | ||
405 | } | ||
406 | |||
407 | // all day event | ||
408 | if ( isAllDay() ) | ||
409 | { | ||
410 | text += "<b><i>" + QObject::tr( "This is an all day event" ) + "</i></b><br>"; | ||
411 | } | ||
412 | // multiple day event | ||
413 | else if ( isMultipleDay () ) | ||
414 | { | ||
415 | text += "<b><i>" + QObject::tr( "This is a multiple day event" ) + "</i></b><br>"; | ||
416 | } | ||
417 | // start & end times | ||
418 | else | ||
419 | { | ||
420 | // start time | ||
421 | if ( startDateTime().isValid() ) | ||
422 | { | ||
423 | text += "<b>" + QObject::tr( "Start:" ) + "</b> "; | ||
424 | text += Qtopia::escapeString( startDateTime().toString() ). | ||
425 | replace( QRegExp( "[\n]" ), "<br>" ) + "<br>"; | ||
426 | } | ||
427 | |||
428 | // end time | ||
429 | if ( endDateTime().isValid() ) | ||
430 | { | ||
431 | text += "<b>" + QObject::tr( "End:" ) + "</b> "; | ||
432 | text += Qtopia::escapeString( endDateTime().toString() ). | ||
433 | replace( QRegExp( "[\n]" ), "<br>" ) + "<br>"; | ||
434 | } | ||
435 | } | ||
436 | |||
437 | // categories | ||
438 | if ( categoryNames( "Calendar" ).count() ) | ||
439 | { | ||
440 | text += "<b>" + QObject::tr( "Category:" ) + "</b> "; | ||
441 | text += categoryNames( "Calendar" ).join( ", " ); | ||
442 | text += "<br>"; | ||
443 | } | ||
444 | |||
445 | //notes | ||
446 | if ( !note().isEmpty() ) | ||
447 | { | ||
448 | text += "<b>" + QObject::tr( "Note:" ) + "</b><br>"; | ||
449 | text += note(); | ||
450 | // text += Qtopia::escapeString(note() ). | ||
451 | // replace(QRegExp( "[\n]"), "<br>" ) + "<br>"; | ||
452 | } | ||
453 | return text; | ||
454 | } | ||
455 | |||
456 | |||
457 | QString OPimEvent::toShortText() const | ||
458 | { | ||
459 | QString text; | ||
460 | text += QString::number( startDateTime().date().day() ); | ||
461 | text += "."; | ||
462 | text += QString::number( startDateTime().date().month() ); | ||
463 | text += "."; | ||
464 | text += QString::number( startDateTime().date().year() ); | ||
465 | text += " "; | ||
466 | text += QString::number( startDateTime().time().hour() ); | ||
467 | text += ":"; | ||
468 | text += QString::number( startDateTime().time().minute() ); | ||
469 | text += " - "; | ||
470 | text += description(); | ||
471 | return text; | ||
472 | } | ||
473 | |||
474 | |||
475 | QString OPimEvent::type() const | ||
476 | { | ||
477 | return QString::fromLatin1( "OPimEvent" ); | ||
478 | } | ||
479 | |||
480 | |||
481 | QString OPimEvent::recordField( int /*id */ ) const | ||
482 | { | ||
483 | return QString::null; | ||
484 | } | ||
485 | |||
486 | |||
487 | int OPimEvent::rtti() | ||
488 | { | ||
489 | return OPimResolver::DateBook; | ||
490 | } | ||
491 | |||
492 | |||
493 | bool OPimEvent::loadFromStream( QDataStream& ) | ||
494 | { | ||
495 | return true; | ||
496 | } | ||
497 | |||
498 | |||
499 | bool OPimEvent::saveToStream( QDataStream& ) const | ||
500 | { | ||
501 | return true; | ||
502 | } | ||
503 | |||
504 | |||
505 | void OPimEvent::changeOrModify() | ||
506 | { | ||
507 | if ( data->count != 1 ) | ||
508 | { | ||
509 | data->deref(); | ||
510 | Data* d2 = new Data; | ||
511 | d2->description = data->description; | ||
512 | d2->location = data->location; | ||
513 | |||
514 | if ( data->manager ) | ||
515 | d2->manager = new OPimNotifyManager( *data->manager ); | ||
516 | |||
517 | if ( data->recur ) | ||
518 | d2->recur = new OPimRecurrence( *data->recur ); | ||
519 | |||
520 | d2->note = data->note; | ||
521 | d2->created = data->created; | ||
522 | d2->start = data->start; | ||
523 | d2->end = data->end; | ||
524 | d2->isAllDay = data->isAllDay; | ||
525 | d2->timezone = data->timezone; | ||
526 | d2->parent = data->parent; | ||
527 | |||
528 | if ( data->child ) | ||
529 | { | ||
530 | d2->child = new QArray<int>( *data->child ); | ||
531 | d2->child->detach(); | ||
532 | } | ||
533 | |||
534 | data = d2; | ||
535 | } | ||
536 | } | ||
537 | |||
538 | |||
539 | void OPimEvent::deref() | ||
540 | { | ||
541 | if ( data->deref() ) | ||
542 | { | ||
543 | delete data; | ||
544 | data = 0; | ||
545 | } | ||
546 | } | ||
547 | // Exporting Event data to map. Using the same | ||
548 | // encoding as ODateBookAccessBackend_xml does.. | ||
549 | // Thus, we could remove the stuff there and use this | ||
550 | // for it and for all other places.. | ||
551 | // Encoding should happen at one place, only ! (eilers) | ||
552 | QMap<int, QString> OPimEvent::toMap() const | ||
553 | { | ||
554 | QMap<int, QString> retMap; | ||
555 | |||
556 | retMap.insert( OPimEvent::FUid, QString::number( uid() ) ); | ||
557 | retMap.insert( OPimEvent::FCategories, Qtopia::escapeString( Qtopia::Record::idsToString( categories() ) ) ); | ||
558 | retMap.insert( OPimEvent::FDescription, Qtopia::escapeString( description() ) ); | ||
559 | retMap.insert( OPimEvent::FLocation, Qtopia::escapeString( location() ) ); | ||
560 | retMap.insert( OPimEvent::FType, isAllDay() ? "AllDay" : "" ); | ||
561 | OPimAlarm alarm = notifiers().alarms() [ 0 ]; | ||
562 | retMap.insert( OPimEvent::FAlarm, QString::number( alarm.dateTime().secsTo( startDateTime() ) / 60 ) ); | ||
563 | retMap.insert( OPimEvent::FSound, ( alarm.sound() == OPimAlarm::Loud ) ? "loud" : "silent" ); | ||
564 | |||
565 | OPimTimeZone zone( timeZone().isEmpty() ? OPimTimeZone::current() : timeZone() ); | ||
566 | retMap.insert( OPimEvent::FStart, QString::number( zone.fromUTCDateTime( zone.toDateTime( startDateTime(), OPimTimeZone::utc() ) ) ) ); | ||
567 | retMap.insert( OPimEvent::FEnd, QString::number( zone.fromUTCDateTime( zone.toDateTime( endDateTime(), OPimTimeZone::utc() ) ) ) ); | ||
568 | retMap.insert( OPimEvent::FNote, Qtopia::escapeString( note() ) ); | ||
569 | retMap.insert( OPimEvent::FTimeZone, timeZone().isEmpty() ? QString( "None" ) : timeZone() ); | ||
570 | if ( parent() ) | ||
571 | retMap.insert( OPimEvent::FRecParent, QString::number( parent() ) ); | ||
572 | if ( children().count() ) | ||
573 | { | ||
574 | QArray<int> childr = children(); | ||
575 | QString buf; | ||
576 | for ( uint i = 0; i < childr.count(); i++ ) | ||
577 | { | ||
578 | if ( i != 0 ) buf += " "; | ||
579 | buf += QString::number( childr[ i ] ); | ||
580 | } | ||
581 | retMap.insert( OPimEvent::FRecChildren, buf ); | ||
582 | } | ||
583 | |||
584 | // Add recurrence stuff | ||
585 | if ( hasRecurrence() ) | ||
586 | { | ||
587 | OPimRecurrence recur = recurrence(); | ||
588 | QMap<int, QString> recFields = recur.toMap(); | ||
589 | retMap.insert( OPimEvent::FRType, recFields[ OPimRecurrence::RType ] ); | ||
590 | retMap.insert( OPimEvent::FRWeekdays, recFields[ OPimRecurrence::RWeekdays ] ); | ||
591 | retMap.insert( OPimEvent::FRPosition, recFields[ OPimRecurrence::RPosition ] ); | ||
592 | retMap.insert( OPimEvent::FRFreq, recFields[ OPimRecurrence::RFreq ] ); | ||
593 | retMap.insert( OPimEvent::FRHasEndDate, recFields[ OPimRecurrence::RHasEndDate ] ); | ||
594 | retMap.insert( OPimEvent::FREndDate, recFields[ OPimRecurrence::EndDate ] ); | ||
595 | retMap.insert( OPimEvent::FRCreated, recFields[ OPimRecurrence::Created ] ); | ||
596 | retMap.insert( OPimEvent::FRExceptions, recFields[ OPimRecurrence::Exceptions ] ); | ||
597 | } | ||
598 | else | ||
599 | { | ||
600 | OPimRecurrence recur = recurrence(); | ||
601 | QMap<int, QString> recFields = recur.toMap(); | ||
602 | retMap.insert( OPimEvent::FRType, recFields[ OPimRecurrence::RType ] ); | ||
603 | } | ||
604 | |||
605 | return retMap; | ||
606 | } | ||
607 | |||
608 | |||
609 | void OPimEvent::fromMap( const QMap<int, QString>& map ) | ||
610 | { | ||
611 | |||
612 | // We just want to set the UID if it is really stored. | ||
613 | if ( !map[ OPimEvent::FUid ].isEmpty() ) | ||
614 | setUid( map[ OPimEvent::FUid ].toInt() ); | ||
615 | |||
616 | setCategories( idsFromString( map[ OPimEvent::FCategories ] ) ); | ||
617 | setDescription( map[ OPimEvent::FDescription ] ); | ||
618 | setLocation( map[ OPimEvent::FLocation ] ); | ||
619 | |||
620 | if ( map[ OPimEvent::FType ] == "AllDay" ) | ||
621 | setAllDay( true ); | ||
622 | else | ||
623 | setAllDay( false ); | ||
624 | |||
625 | int alarmTime = -1; | ||
626 | if ( !map[ OPimEvent::FAlarm ].isEmpty() ) | ||
627 | alarmTime = map[ OPimEvent::FAlarm ].toInt(); | ||
628 | |||
629 | int sound = ( ( map[ OPimEvent::FSound ] == "loud" ) ? OPimAlarm::Loud : OPimAlarm::Silent ); | ||
630 | if ( ( alarmTime != -1 ) ) | ||
631 | { | ||
632 | QDateTime dt = startDateTime().addSecs( -1 * alarmTime * 60 ); | ||
633 | OPimAlarm al( sound , dt ); | ||
634 | notifiers().add( al ); | ||
635 | } | ||
636 | if ( !map[ OPimEvent::FTimeZone ].isEmpty() && ( map[ OPimEvent::FTimeZone ] != "None" ) ) | ||
637 | { | ||
638 | setTimeZone( map[ OPimEvent::FTimeZone ] ); | ||
639 | } | ||
640 | |||
641 | time_t start = ( time_t ) map[ OPimEvent::FStart ].toLong(); | ||
642 | time_t end = ( time_t ) map[ OPimEvent::FEnd ].toLong(); | ||
643 | |||
644 | /* AllDay is always in UTC */ | ||
645 | if ( isAllDay() ) | ||
646 | { | ||
647 | OPimTimeZone utc = OPimTimeZone::utc(); | ||
648 | setStartDateTime( utc.fromUTCDateTime( start ) ); | ||
649 | setEndDateTime ( utc.fromUTCDateTime( end ) ); | ||
650 | setTimeZone( "UTC" ); // make sure it is really utc | ||
651 | } | ||
652 | else | ||
653 | { | ||
654 | /* to current date time */ | ||
655 | // qWarning(" Start is %d", start ); | ||
656 | OPimTimeZone zone( timeZone().isEmpty() ? OPimTimeZone::current() : timeZone() ); | ||
657 | QDateTime date = zone.toDateTime( start ); | ||
658 | qWarning( " Start is %s", date.toString().latin1() ); | ||
659 | setStartDateTime( zone.toDateTime( date, OPimTimeZone::current() ) ); | ||
660 | |||
661 | date = zone.toDateTime( end ); | ||
662 | setEndDateTime ( zone.toDateTime( date, OPimTimeZone::current() ) ); | ||
663 | } | ||
664 | |||
665 | if ( !map[ OPimEvent::FRecParent ].isEmpty() ) | ||
666 | setParent( map[ OPimEvent::FRecParent ].toInt() ); | ||
667 | |||
668 | if ( !map[ OPimEvent::FRecChildren ].isEmpty() ) | ||
669 | { | ||
670 | QStringList list = QStringList::split( ' ', map[ OPimEvent::FRecChildren ] ); | ||
671 | for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) | ||
672 | { | ||
673 | addChild( ( *it ).toInt() ); | ||
674 | } | ||
675 | } | ||
676 | |||
677 | // Fill recurrence stuff and put it directly into the OPimRecurrence-Object using fromMap.. | ||
678 | if ( !map[ OPimEvent::FRType ].isEmpty() ) | ||
679 | { | ||
680 | QMap<int, QString> recFields; | ||
681 | recFields.insert( OPimRecurrence::RType, map[ OPimEvent::FRType ] ); | ||
682 | recFields.insert( OPimRecurrence::RWeekdays, map[ OPimEvent::FRWeekdays ] ); | ||
683 | recFields.insert( OPimRecurrence::RPosition, map[ OPimEvent::FRPosition ] ); | ||
684 | recFields.insert( OPimRecurrence::RFreq, map[ OPimEvent::FRFreq ] ); | ||
685 | recFields.insert( OPimRecurrence::RHasEndDate, map[ OPimEvent::FRHasEndDate ] ); | ||
686 | recFields.insert( OPimRecurrence::EndDate, map[ OPimEvent::FREndDate ] ); | ||
687 | recFields.insert( OPimRecurrence::Created, map[ OPimEvent::FRCreated ] ); | ||
688 | recFields.insert( OPimRecurrence::Exceptions, map[ OPimEvent::FRExceptions ] ); | ||
689 | OPimRecurrence recur( recFields ); | ||
690 | setRecurrence( recur ); | ||
691 | } | ||
692 | |||
693 | } | ||
694 | |||
695 | |||
696 | int OPimEvent::parent() const | ||
697 | { | ||
698 | return data->parent; | ||
699 | } | ||
700 | |||
701 | |||
702 | void OPimEvent::setParent( int uid ) | ||
703 | { | ||
704 | changeOrModify(); | ||
705 | data->parent = uid; | ||
706 | } | ||
707 | |||
708 | |||
709 | QArray<int> OPimEvent::children() const | ||
710 | { | ||
711 | if ( !data->child ) return QArray<int>(); | ||
712 | else | ||
713 | return data->child->copy(); | ||
714 | } | ||
715 | |||
716 | |||
717 | void OPimEvent::setChildren( const QArray<int>& arr ) | ||
718 | { | ||
719 | changeOrModify(); | ||
720 | if ( data->child ) delete data->child; | ||
721 | |||
722 | data->child = new QArray<int>( arr ); | ||
723 | data->child->detach(); | ||
724 | } | ||
725 | |||
726 | |||
727 | void OPimEvent::addChild( int uid ) | ||
728 | { | ||
729 | changeOrModify(); | ||
730 | if ( !data->child ) | ||
731 | { | ||
732 | data->child = new QArray<int>( 1 ); | ||
733 | ( *data->child ) [ 0 ] = uid; | ||
734 | } | ||
735 | else | ||
736 | { | ||
737 | int count = data->child->count(); | ||
738 | data->child->resize( count + 1 ); | ||
739 | ( *data->child ) [ count ] = uid; | ||
740 | } | ||
741 | } | ||
742 | |||
743 | |||
744 | void OPimEvent::removeChild( int uid ) | ||
745 | { | ||
746 | if ( !data->child || !data->child->contains( uid ) ) return ; | ||
747 | changeOrModify(); | ||
748 | QArray<int> newAr( data->child->count() - 1 ); | ||
749 | int j = 0; | ||
750 | uint count = data->child->count(); | ||
751 | for ( uint i = 0; i < count; i++ ) | ||
752 | { | ||
753 | if ( ( *data->child ) [ i ] != uid ) | ||
754 | { | ||
755 | newAr[ j ] = ( *data->child ) [ i ]; | ||
756 | j++; | ||
757 | } | ||
758 | } | ||
759 | ( *data->child ) = newAr; | ||
760 | } | ||
761 | |||
762 | |||
763 | struct OEffectiveEvent::Data : public QShared | ||
764 | { | ||
765 | Data() : QShared() | ||
766 | {} | ||
767 | OPimEvent event; | ||
768 | QDate date; | ||
769 | QTime start, end; | ||
770 | QDate startDate, endDate; | ||
771 | bool dates : 1; | ||
772 | }; | ||
773 | |||
774 | |||
775 | OEffectiveEvent::OEffectiveEvent() | ||
776 | { | ||
777 | data = new Data; | ||
778 | data->date = QDate::currentDate(); | ||
779 | data->start = data->end = QTime::currentTime(); | ||
780 | data->dates = false; | ||
781 | } | ||
782 | |||
783 | |||
784 | OEffectiveEvent::OEffectiveEvent( const OPimEvent& ev, const QDate& startDate, | ||
785 | Position pos ) | ||
786 | { | ||
787 | data = new Data; | ||
788 | data->event = ev; | ||
789 | data->date = startDate; | ||
790 | if ( pos & Start ) | ||
791 | data->start = ev.startDateTime().time(); | ||
792 | else | ||
793 | data->start = QTime( 0, 0, 0 ); | ||
794 | |||
795 | if ( pos & End ) | ||
796 | data->end = ev.endDateTime().time(); | ||
797 | else | ||
798 | data->end = QTime( 23, 59, 59 ); | ||
799 | |||
800 | data->dates = false; | ||
801 | } | ||
802 | |||
803 | |||
804 | OEffectiveEvent::OEffectiveEvent( const OEffectiveEvent& ev ) | ||
805 | { | ||
806 | data = ev.data; | ||
807 | data->ref(); | ||
808 | } | ||
809 | |||
810 | |||
811 | OEffectiveEvent::~OEffectiveEvent() | ||
812 | { | ||
813 | if ( data->deref() ) | ||
814 | { | ||
815 | delete data; | ||
816 | data = 0; | ||
817 | } | ||
818 | } | ||
819 | |||
820 | |||
821 | OEffectiveEvent& OEffectiveEvent::operator=( const OEffectiveEvent& ev ) | ||
822 | { | ||
823 | if ( *this == ev ) return * this; | ||
824 | |||
825 | ev.data->ref(); | ||
826 | deref(); | ||
827 | data = ev.data; | ||
828 | |||
829 | return *this; | ||
830 | } | ||
831 | |||
832 | |||
833 | void OEffectiveEvent::setStartTime( const QTime& ti ) | ||
834 | { | ||
835 | changeOrModify(); | ||
836 | data->start = ti; | ||
837 | } | ||
838 | |||
839 | |||
840 | void OEffectiveEvent::setEndTime( const QTime& en ) | ||
841 | { | ||
842 | changeOrModify(); | ||
843 | data->end = en; | ||
844 | } | ||
845 | |||
846 | |||
847 | void OEffectiveEvent::setEvent( const OPimEvent& ev ) | ||
848 | { | ||
849 | changeOrModify(); | ||
850 | data->event = ev; | ||
851 | } | ||
852 | |||
853 | |||
854 | void OEffectiveEvent::setDate( const QDate& da ) | ||
855 | { | ||
856 | changeOrModify(); | ||
857 | data->date = da; | ||
858 | } | ||
859 | |||
860 | |||
861 | void OEffectiveEvent::setEffectiveDates( const QDate& from, | ||
862 | const QDate& to ) | ||
863 | { | ||
864 | if ( !from.isValid() ) | ||
865 | { | ||
866 | data->dates = false; | ||
867 | return ; | ||
868 | } | ||
869 | |||
870 | data->startDate = from; | ||
871 | data->endDate = to; | ||
872 | } | ||
873 | |||
874 | |||
875 | QString OEffectiveEvent::description() const | ||
876 | { | ||
877 | return data->event.description(); | ||
878 | } | ||
879 | |||
880 | |||
881 | QString OEffectiveEvent::location() const | ||
882 | { | ||
883 | return data->event.location(); | ||
884 | } | ||
885 | |||
886 | |||
887 | QString OEffectiveEvent::note() const | ||
888 | { | ||
889 | return data->event.note(); | ||
890 | } | ||
891 | |||
892 | |||
893 | OPimEvent OEffectiveEvent::event() const | ||
894 | { | ||
895 | return data->event; | ||
896 | } | ||
897 | |||
898 | |||
899 | QTime OEffectiveEvent::startTime() const | ||
900 | { | ||
901 | return data->start; | ||
902 | } | ||
903 | |||
904 | |||
905 | QTime OEffectiveEvent::endTime() const | ||
906 | { | ||
907 | return data->end; | ||
908 | } | ||
909 | |||
910 | |||
911 | QDate OEffectiveEvent::date() const | ||
912 | { | ||
913 | return data->date; | ||
914 | } | ||
915 | |||
916 | |||
917 | int OEffectiveEvent::length() const | ||
918 | { | ||
919 | return ( data->end.hour() * 60 - data->start.hour() * 60 ) | ||
920 | + QABS( data->start.minute() - data->end.minute() ); | ||
921 | } | ||
922 | |||
923 | |||
924 | int OEffectiveEvent::size() const | ||
925 | { | ||
926 | return ( data->end.hour() - data->start.hour() ) * 3600 | ||
927 | + ( data->end.minute() - data->start.minute() * 60 | ||
928 | + data->end.second() - data->start.second() ); | ||
929 | } | ||
930 | |||
931 | |||
932 | QDate OEffectiveEvent::startDate() const | ||
933 | { | ||
934 | if ( data->dates ) | ||
935 | return data->startDate; | ||
936 | else if ( data->event.hasRecurrence() ) // single day, since multi-day should have a d pointer | ||
937 | return data->date; | ||
938 | else | ||
939 | return data->event.startDateTime().date(); | ||
940 | } | ||
941 | |||
942 | |||
943 | QDate OEffectiveEvent::endDate() const | ||
944 | { | ||
945 | if ( data->dates ) | ||
946 | return data->endDate; | ||
947 | else if ( data->event.hasRecurrence() ) | ||
948 | return data->date; | ||
949 | else | ||
950 | return data->event.endDateTime().date(); | ||
951 | } | ||
952 | |||
953 | |||
954 | void OEffectiveEvent::deref() | ||
955 | { | ||
956 | if ( data->deref() ) | ||
957 | { | ||
958 | delete data; | ||
959 | data = 0; | ||
960 | } | ||
961 | } | ||
962 | |||
963 | |||
964 | void OEffectiveEvent::changeOrModify() | ||
965 | { | ||
966 | if ( data->count != 1 ) | ||
967 | { | ||
968 | data->deref(); | ||
969 | Data* d2 = new Data; | ||
970 | d2->event = data->event; | ||
971 | d2->date = data->date; | ||
972 | d2->start = data->start; | ||
973 | d2->end = data->end; | ||
974 | d2->startDate = data->startDate; | ||
975 | d2->endDate = data->endDate; | ||
976 | d2->dates = data->dates; | ||
977 | data = d2; | ||
978 | } | ||
979 | } | ||
980 | |||
981 | |||
982 | bool OEffectiveEvent::operator<( const OEffectiveEvent &e ) const | ||
983 | { | ||
984 | if ( data->date < e.date() ) | ||
985 | return TRUE; | ||
986 | if ( data->date == e.date() ) | ||
987 | return ( startTime() < e.startTime() ); | ||
988 | else | ||
989 | return FALSE; | ||
990 | } | ||
991 | |||
992 | |||
993 | bool OEffectiveEvent::operator<=( const OEffectiveEvent &e ) const | ||
994 | { | ||
995 | return ( data->date <= e.date() ); | ||
996 | } | ||
997 | |||
998 | |||
999 | bool OEffectiveEvent::operator==( const OEffectiveEvent &e ) const | ||
1000 | { | ||
1001 | return ( date() == e.date() | ||
1002 | && startTime() == e.startTime() | ||
1003 | && endTime() == e.endTime() | ||
1004 | && event() == e.event() ); | ||
1005 | } | ||
1006 | |||
1007 | |||
1008 | bool OEffectiveEvent::operator!=( const OEffectiveEvent &e ) const | ||
1009 | { | ||
1010 | return !( *this == e ); | ||
1011 | } | ||
1012 | |||
1013 | |||
1014 | bool OEffectiveEvent::operator>( const OEffectiveEvent &e ) const | ||
1015 | { | ||
1016 | return !( *this <= e ); | ||
1017 | } | ||
1018 | |||
1019 | |||
1020 | bool OEffectiveEvent::operator>= ( const OEffectiveEvent &e ) const | ||
1021 | { | ||
1022 | return !( *this < e ); | ||
1023 | } | ||
1024 | |||
1025 | } | ||