libkcal

calendar.cpp
Go to the documentation of this file.
1/*
2 This file is part of libkcal.
3
4 Copyright (c) 1998 Preston Brown <pbrown@kde.org>
5 Copyright (c) 2000-2004 Cornelius Schumacher <schumacher@kde.org>
6 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
22*/
31#include <stdlib.h>
32
33#include <kdebug.h>
34#include <tdelocale.h>
35
36#include "exceptions.h"
37#include "calfilter.h"
38
39#include "calendar.h"
40
41using namespace KCal;
42
43Calendar::Calendar( const TQString &timeZoneId )
44{
45 mTimeZoneId = timeZoneId;
46 mLocalTime = false;
47
48 init();
49}
50
51void Calendar::init()
52{
53 mException = 0;
54 mNewObserver = false;
55 mObserversEnabled = true;
56
57 mModified = false;
58
59 // Setup default filter, which does nothing
60 mDefaultFilter = new CalFilter;
61 mFilter = mDefaultFilter;
62 mFilter->setEnabled( false );
63
64 // user information...
65 setOwner( Person( i18n( "Unknown Name" ), i18n( "unknown@nowhere" ) ) );
66}
67
69{
71 delete mDefaultFilter;
72}
73
75{
76 delete mException;
77 mException = 0;
78}
79
81{
82 return mException;
83}
84
86{
87 delete mException;
88 mException = e;
89}
90
92{
93 return mOwner;
94}
95
96void Calendar::setOwner( const Person &owner )
97{
98 mOwner = owner;
99
100 setModified( true );
101}
102
103void Calendar::setTimeZoneId( const TQString &timeZoneId )
104{
105 mTimeZoneId = timeZoneId;
106 mLocalTime = false;
107
108 setModified( true );
110}
111
112TQString Calendar::timeZoneId() const
113{
114 return mTimeZoneId;
115}
116
118{
119 mLocalTime = true;
120 mTimeZoneId = "";
121
122 setModified( true );
123}
124
126{
127 return mLocalTime;
128}
129
131{
132 if ( filter ) {
133 mFilter = filter;
134 } else {
135 mFilter = mDefaultFilter;
136 }
137}
138
140{
141 return mFilter;
142}
143
145{
146 emit batchAddingBegins();
147}
148
150{
151 emit batchAddingEnds();
152}
153
155{
156 Incidence::List rawInc( rawIncidences() );
157 TQStringList cats, thisCats;
158 // @TODO: For now just iterate over all incidences. In the future,
159 // the list of categories should be built when reading the file.
160 for ( Incidence::List::ConstIterator i = rawInc.constBegin();
161 i != rawInc.constEnd(); ++i ) {
162 thisCats = (*i)->categories();
163 for ( TQStringList::ConstIterator si = thisCats.constBegin();
164 si != thisCats.constEnd(); ++si ) {
165 if ( cats.find( *si ) == cats.end() ) {
166 cats.append( *si );
167 }
168 }
169 }
170 return cats;
171}
172
174{
175 return mergeIncidenceList( events( date ), todos( date ), journals( date ) );
176}
177
179{
180 return mergeIncidenceList( events(), todos(), journals() );
181}
182
184{
186}
187
189 EventSortField sortField,
190 SortDirection sortDirection )
191{
192 Event::List eventListSorted;
193 Event::List tempList;
194 Event::List alphaList;
195 Event::List::Iterator sortIt;
196 Event::List::Iterator eit;
197
198 // Notice we alphabetically presort Summaries first.
199 // We do this so comparison "ties" stay in a nice order.
200
201 switch( sortField ) {
203 eventListSorted = *eventList;
204 break;
205
207 alphaList = sortEvents( eventList, EventSortSummary, sortDirection );
208 for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
209 if ( (*eit)->doesFloat() ) {
210 tempList.append( *eit );
211 continue;
212 }
213 sortIt = eventListSorted.begin();
214 if ( sortDirection == SortDirectionAscending ) {
215 while ( sortIt != eventListSorted.end() &&
216 (*eit)->dtStart() >= (*sortIt)->dtStart() ) {
217 ++sortIt;
218 }
219 } else {
220 while ( sortIt != eventListSorted.end() &&
221 (*eit)->dtStart() < (*sortIt)->dtStart() ) {
222 ++sortIt;
223 }
224 }
225 eventListSorted.insert( sortIt, *eit );
226 }
227 if ( sortDirection == SortDirectionAscending ) {
228 // Prepend the list of all-day Events
229 tempList += eventListSorted;
230 eventListSorted = tempList;
231 } else {
232 // Append the list of all-day Events
233 eventListSorted += tempList;
234 }
235 break;
236
237 case EventSortEndDate:
238 alphaList = sortEvents( eventList, EventSortSummary, sortDirection );
239 for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
240 if ( (*eit)->hasEndDate() ) {
241 sortIt = eventListSorted.begin();
242 if ( sortDirection == SortDirectionAscending ) {
243 while ( sortIt != eventListSorted.end() &&
244 (*eit)->dtEnd() >= (*sortIt)->dtEnd() ) {
245 ++sortIt;
246 }
247 } else {
248 while ( sortIt != eventListSorted.end() &&
249 (*eit)->dtEnd() < (*sortIt)->dtEnd() ) {
250 ++sortIt;
251 }
252 }
253 } else {
254 // Keep a list of the Events without End DateTimes
255 tempList.append( *eit );
256 }
257 eventListSorted.insert( sortIt, *eit );
258 }
259 if ( sortDirection == SortDirectionAscending ) {
260 // Append the list of Events without End DateTimes
261 eventListSorted += tempList;
262 } else {
263 // Prepend the list of Events without End DateTimes
264 tempList += eventListSorted;
265 eventListSorted = tempList;
266 }
267 break;
268
269 case EventSortSummary:
270 for ( eit = eventList->begin(); eit != eventList->end(); ++eit ) {
271 sortIt = eventListSorted.begin();
272 if ( sortDirection == SortDirectionAscending ) {
273 while ( sortIt != eventListSorted.end() &&
274 (*eit)->summary() >= (*sortIt)->summary() ) {
275 ++sortIt;
276 }
277 } else {
278 while ( sortIt != eventListSorted.end() &&
279 (*eit)->summary() < (*sortIt)->summary() ) {
280 ++sortIt;
281 }
282 }
283 eventListSorted.insert( sortIt, *eit );
284 }
285 break;
286 }
287
288 return eventListSorted;
289}
290
292 const TQDate &date,
293 EventSortField sortField,
294 SortDirection sortDirection )
295{
296 Event::List eventListSorted;
297 Event::List tempList;
298 Event::List alphaList;
299 Event::List::Iterator sortIt;
300 Event::List::Iterator eit;
301
302 switch( sortField ) {
304 alphaList = sortEvents( eventList, EventSortSummary, sortDirection );
305 for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
306 if ( (*eit)->doesFloat() ) {
307 tempList.append( *eit );
308 continue;
309 }
310 sortIt = eventListSorted.begin();
311 if ( sortDirection == SortDirectionAscending ) {
312 while ( sortIt != eventListSorted.end() ) {
313 if ( !(*eit)->doesRecur() ) {
314 if ( (*eit)->dtStart().time() >= (*sortIt)->dtStart().time() ) {
315 ++sortIt;
316 } else {
317 break;
318 }
319 } else {
320 if ( (*eit)->recursOn( date ) ) {
321 if ( (*eit)->dtStart().time() >= (*sortIt)->dtStart().time() ) {
322 ++sortIt;
323 } else {
324 break;
325 }
326 } else {
327 ++sortIt;
328 }
329 }
330 }
331 } else { // descending
332 while ( sortIt != eventListSorted.end() ) {
333 if ( !(*eit)->doesRecur() ) {
334 if ( (*eit)->dtStart().time() < (*sortIt)->dtStart().time() ) {
335 ++sortIt;
336 } else {
337 break;
338 }
339 } else {
340 if ( (*eit)->recursOn( date ) ) {
341 if ( (*eit)->dtStart().time() < (*sortIt)->dtStart().time() ) {
342 ++sortIt;
343 } else {
344 break;
345 }
346 } else {
347 ++sortIt;
348 }
349 }
350 }
351 }
352 eventListSorted.insert( sortIt, *eit );
353 }
354 if ( sortDirection == SortDirectionAscending ) {
355 // Prepend the list of all-day Events
356 tempList += eventListSorted;
357 eventListSorted = tempList;
358 } else {
359 // Append the list of all-day Events
360 eventListSorted += tempList;
361 }
362 break;
363
364 case EventSortEndDate:
365 alphaList = sortEvents( eventList, EventSortSummary, sortDirection );
366 for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
367 if ( (*eit)->hasEndDate() ) {
368 sortIt = eventListSorted.begin();
369 if ( sortDirection == SortDirectionAscending ) {
370 while ( sortIt != eventListSorted.end() ) {
371 if ( !(*eit)->doesRecur() ) {
372 if ( (*eit)->dtEnd().time() >= (*sortIt)->dtEnd().time() ) {
373 ++sortIt;
374 } else {
375 break;
376 }
377 } else {
378 if ( (*eit)->recursOn( date ) ) {
379 if ( (*eit)->dtEnd().time() >= (*sortIt)->dtEnd().time() ) {
380 ++sortIt;
381 } else {
382 break;
383 }
384 } else {
385 ++sortIt;
386 }
387 }
388 }
389 } else { // descending
390 while ( sortIt != eventListSorted.end() ) {
391 if ( !(*eit)->doesRecur() ) {
392 if ( (*eit)->dtEnd().time() < (*sortIt)->dtEnd().time() ) {
393 ++sortIt;
394 } else {
395 break;
396 }
397 } else {
398 if ( (*eit)->recursOn( date ) ) {
399 if ( (*eit)->dtEnd().time() < (*sortIt)->dtEnd().time() ) {
400 ++sortIt;
401 } else {
402 break;
403 }
404 } else {
405 ++sortIt;
406 }
407 }
408 }
409 }
410 } else {
411 // Keep a list of the Events without End DateTimes
412 tempList.append( *eit );
413 }
414 eventListSorted.insert( sortIt, *eit );
415 }
416 if ( sortDirection == SortDirectionAscending ) {
417 // Prepend the list of Events without End DateTimes
418 tempList += eventListSorted;
419 eventListSorted = tempList;
420 } else {
421 // Append the list of Events without End DateTimes
422 eventListSorted += tempList;
423 }
424 break;
425
426 default:
427 eventListSorted = sortEvents( eventList, sortField, sortDirection );
428 break;
429 }
430
431 return eventListSorted;
432}
433
434Event::List Calendar::events( const TQDate &date,
435 EventSortField sortField,
436 SortDirection sortDirection )
437{
438 Event::List el = rawEventsForDate( date, sortField, sortDirection );
439 mFilter->apply( &el );
440 return el;
441}
442
443Event::List Calendar::events( const TQDateTime &qdt )
444{
445 Event::List el = rawEventsForDate( qdt );
446 mFilter->apply( &el );
447 return el;
448}
449
450Event::List Calendar::events( const TQDate &start, const TQDate &end,
451 bool inclusive)
452{
453 Event::List el = rawEvents( start, end, inclusive );
454 mFilter->apply( &el );
455 return el;
456}
457
459 SortDirection sortDirection )
460{
461 Event::List el = rawEvents( sortField, sortDirection );
462 mFilter->apply( &el );
463 return el;
464}
465
467{
469
470 return incidence->accept(v);
471}
472
474{
475 if ( beginChange( incidence ) ) {
476 if (incidence->hasRecurrenceID()) {
477 // Delete this event's UID from the parent's list of children
478 Incidence *parentIncidence;
479 IncidenceList il = incidence->childIncidences();
480 IncidenceListIterator it;
481 it = il.begin();
482 if (it != il.end()) {
483 parentIncidence = this->incidence(*it);
484 parentIncidence->deleteChildIncidence(incidence->uid());
485 }
486 }
487 else {
488 // Delete all children as well
489 IncidenceList il = incidence->childIncidences();
490 IncidenceListIterator it;
491 for ( it = il.begin(); it != il.end(); ++it ) {
492 deleteIncidence( this->incidence(*it) );
493 // Avoid a crash, reset the iterator every time the list is modified
494 it = il.begin();
495 }
496 }
498 bool result = incidence->accept( v );
500 return result;
501 } else
502 return false;
503}
504
509 bool single )
510{
511 if ( !incidence || !incidence->doesRecur() )
512 return 0;
513
514 Incidence *newInc = incidence->clone();
515 newInc->recreate();
516 newInc->setHasRecurrenceID(false);
517// newInc->setRecurrenceID(TQString());
518 newInc->setRelatedTo( incidence );
519 Recurrence *recur = newInc->recurrence();
520 if ( single ) {
521 recur->clear();
522 } else {
523 // Adjust the recurrence for the future incidences. In particular
524 // adjust the "end after n occurrences" rules! "No end date" and "end by ..."
525 // don't need to be modified.
526 int duration = recur->duration();
527 if ( duration > 0 ) {
528 int doneduration = recur->durationTo( date.addDays(-1) );
529 if ( doneduration >= duration ) {
530 kdDebug(5850) << "The dissociated event already occurred more often "
531 << "than it was supposed to ever occur. ERROR!" << endl;
532 recur->clear();
533 } else {
534 recur->setDuration( duration - doneduration );
535 }
536 }
537 }
538 // Adjust the date of the incidence
539 if ( incidence->type() == "Event" ) {
540 Event *ev = static_cast<Event *>( newInc );
541 TQDateTime start( ev->dtStart() );
542 int daysTo = start.date().daysTo( date );
543 ev->setDtStart( start.addDays( daysTo ) );
544 ev->setDtEnd( ev->dtEnd().addDays( daysTo ) );
545 } else if ( incidence->type() == "Todo" ) {
546 Todo *td = static_cast<Todo *>( newInc );
547 bool haveOffset = false;
548 int daysTo = 0;
549 if ( td->hasDueDate() ) {
550 TQDateTime due( td->dtDue() );
551 daysTo = due.date().daysTo( date );
552 td->setDtDue( due.addDays( daysTo ), true );
553 haveOffset = true;
554 }
555 if ( td->hasStartDate() ) {
556 TQDateTime start( td->dtStart() );
557 if ( !haveOffset )
558 daysTo = start.date().daysTo( date );
559 td->setDtStart( start.addDays( daysTo ) );
560 haveOffset = true;
561 }
562 }
563 recur = incidence->recurrence();
564 if ( recur ) {
565 if ( single ) {
566 recur->addExDate( date );
567 } else {
568 // Make sure the recurrence of the past events ends
569 // at the corresponding day
570 recur->setEndDate( date.addDays(-1) );
571 }
572 }
573 return newInc;
574}
575
576Incidence *Calendar::incidence( const TQString &uid )
577{
578 Incidence *i = event( uid );
579 if ( i )
580 return i;
581 i = todo( uid );
582 if ( i )
583 return i;
584 i = journal( uid );
585 return i;
586}
587
589{
590 Incidence::List result;
592 Incidence::List::iterator it = incidences.begin();
593 for ( ; it != incidences.end(); ++it )
594 if ( (*it)->schedulingID() == UID )
595 result.append( *it );
596 return result;
597}
598
600{
602 Incidence::List::iterator it = incidences.begin();
603 for ( ; it != incidences.end(); ++it )
604 if ( (*it)->schedulingID() == UID )
605 // Touchdown, and the crowd goes wild
606 return *it;
607 // Not found
608 return 0;
609}
610
612 TodoSortField sortField,
613 SortDirection sortDirection )
614{
615 Todo::List todoListSorted;
616 Todo::List tempList, t;
617 Todo::List alphaList;
618 Todo::List::Iterator sortIt;
619 Todo::List::Iterator eit;
620
621 // Notice we alphabetically presort Summaries first.
622 // We do this so comparison "ties" stay in a nice order.
623
624 // Note that Todos may not have Start DateTimes nor due DateTimes.
625
626 switch( sortField ) {
627 case TodoSortUnsorted:
628 todoListSorted = *todoList;
629 break;
630
632 alphaList = sortTodos( todoList, TodoSortSummary, sortDirection );
633 for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
634 if ( (*eit)->hasStartDate() ) {
635 sortIt = todoListSorted.begin();
636 if ( sortDirection == SortDirectionAscending ) {
637 while ( sortIt != todoListSorted.end() &&
638 (*eit)->dtStart() >= (*sortIt)->dtStart() ) {
639 ++sortIt;
640 }
641 } else {
642 while ( sortIt != todoListSorted.end() &&
643 (*eit)->dtStart() < (*sortIt)->dtStart() ) {
644 ++sortIt;
645 }
646 }
647 todoListSorted.insert( sortIt, *eit );
648 } else {
649 // Keep a list of the Todos without Start DateTimes
650 tempList.append( *eit );
651 }
652 }
653 if ( sortDirection == SortDirectionAscending ) {
654 // Append the list of Todos without Start DateTimes
655 todoListSorted += tempList;
656 } else {
657 // Prepend the list of Todos without Start DateTimes
658 tempList += todoListSorted;
659 todoListSorted = tempList;
660 }
661 break;
662
663 case TodoSortDueDate:
664 alphaList = sortTodos( todoList, TodoSortSummary, sortDirection );
665 for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
666 if ( (*eit)->hasDueDate() ) {
667 sortIt = todoListSorted.begin();
668 if ( sortDirection == SortDirectionAscending ) {
669 while ( sortIt != todoListSorted.end() &&
670 (*eit)->dtDue() >= (*sortIt)->dtDue() ) {
671 ++sortIt;
672 }
673 } else {
674 while ( sortIt != todoListSorted.end() &&
675 (*eit)->dtDue() < (*sortIt)->dtDue() ) {
676 ++sortIt;
677 }
678 }
679 todoListSorted.insert( sortIt, *eit );
680 } else {
681 // Keep a list of the Todos without Due DateTimes
682 tempList.append( *eit );
683 }
684 }
685 if ( sortDirection == SortDirectionAscending ) {
686 // Append the list of Todos without Due DateTimes
687 todoListSorted += tempList;
688 } else {
689 // Prepend the list of Todos without Due DateTimes
690 tempList += todoListSorted;
691 todoListSorted = tempList;
692 }
693 break;
694
695 case TodoSortPriority:
696 alphaList = sortTodos( todoList, TodoSortSummary, sortDirection );
697 for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
698 sortIt = todoListSorted.begin();
699 if ( sortDirection == SortDirectionAscending ) {
700 while ( sortIt != todoListSorted.end() &&
701 (*eit)->priority() >= (*sortIt)->priority() ) {
702 ++sortIt;
703 }
704 } else {
705 while ( sortIt != todoListSorted.end() &&
706 (*eit)->priority() < (*sortIt)->priority() ) {
707 ++sortIt;
708 }
709 }
710 todoListSorted.insert( sortIt, *eit );
711 }
712 break;
713
715 alphaList = sortTodos( todoList, TodoSortSummary, sortDirection );
716 for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
717 sortIt = todoListSorted.begin();
718 if ( sortDirection == SortDirectionAscending ) {
719 while ( sortIt != todoListSorted.end() &&
720 (*eit)->percentComplete() >= (*sortIt)->percentComplete() ) {
721 ++sortIt;
722 }
723 } else {
724 while ( sortIt != todoListSorted.end() &&
725 (*eit)->percentComplete() < (*sortIt)->percentComplete() ) {
726 ++sortIt;
727 }
728 }
729 todoListSorted.insert( sortIt, *eit );
730 }
731 break;
732
733 case TodoSortSummary:
734 for ( eit = todoList->begin(); eit != todoList->end(); ++eit ) {
735 sortIt = todoListSorted.begin();
736 if ( sortDirection == SortDirectionAscending ) {
737 while ( sortIt != todoListSorted.end() &&
738 (*eit)->summary() >= (*sortIt)->summary() ) {
739 ++sortIt;
740 }
741 } else {
742 while ( sortIt != todoListSorted.end() &&
743 (*eit)->summary() < (*sortIt)->summary() ) {
744 ++sortIt;
745 }
746 }
747 todoListSorted.insert( sortIt, *eit );
748 }
749 break;
750 }
751
752 return todoListSorted;
753}
754
756 SortDirection sortDirection )
757{
758 Todo::List tl = rawTodos( sortField, sortDirection );
759 mFilter->apply( &tl );
760 return tl;
761}
762
763Todo::List Calendar::todos( const TQDate &date )
764{
765 Todo::List el = rawTodosForDate( date );
766 mFilter->apply( &el );
767 return el;
768}
769
771 JournalSortField sortField,
772 SortDirection sortDirection )
773{
774 Journal::List journalListSorted;
775 Journal::List::Iterator sortIt;
776 Journal::List::Iterator eit;
777
778 switch( sortField ) {
780 journalListSorted = *journalList;
781 break;
782
783 case JournalSortDate:
784 for ( eit = journalList->begin(); eit != journalList->end(); ++eit ) {
785 sortIt = journalListSorted.begin();
786 if ( sortDirection == SortDirectionAscending ) {
787 while ( sortIt != journalListSorted.end() &&
788 (*eit)->dtStart() >= (*sortIt)->dtStart() ) {
789 ++sortIt;
790 }
791 } else {
792 while ( sortIt != journalListSorted.end() &&
793 (*eit)->dtStart() < (*sortIt)->dtStart() ) {
794 ++sortIt;
795 }
796 }
797 journalListSorted.insert( sortIt, *eit );
798 }
799 break;
800
802 for ( eit = journalList->begin(); eit != journalList->end(); ++eit ) {
803 sortIt = journalListSorted.begin();
804 if ( sortDirection == SortDirectionAscending ) {
805 while ( sortIt != journalListSorted.end() &&
806 (*eit)->summary() >= (*sortIt)->summary() ) {
807 ++sortIt;
808 }
809 } else {
810 while ( sortIt != journalListSorted.end() &&
811 (*eit)->summary() < (*sortIt)->summary() ) {
812 ++sortIt;
813 }
814 }
815 journalListSorted.insert( sortIt, *eit );
816 }
817 break;
818 }
819
820 return journalListSorted;
821}
822
824 SortDirection sortDirection )
825{
826 Journal::List jl = rawJournals( sortField, sortDirection );
827 mFilter->apply( &jl );
828 return jl;
829}
830
832{
834 mFilter->apply( &el );
835 return el;
836}
837
838// When this is called, the todo have already been added to the calendar.
839// This method is only about linking related todos
841{
842 if ( !forincidence ) return;
843// kdDebug(5850) << "Calendar::setupRelations for incidence " << forincidence << " with UID " << forincidence->uid() << ", summary: " << forincidence->summary() << endl;
844 TQString uid = forincidence->uid();
845
846 // First, go over the list of orphans and see if this is their parent
847 while ( Incidence* i = mOrphans[ uid ] ) {
848 mOrphans.remove( uid );
849 i->setRelatedTo( forincidence );
850 forincidence->addRelation( i );
851 mOrphanUids.remove( i->uid() );
852 }
853
854 // Now see about this incidences parent
855 if ( !forincidence->relatedTo() && !forincidence->relatedToUid().isEmpty() ) {
856 // This incidence has a uid it is related to but is not registered to it yet
857 // Try to find it
858 Incidence* parent = incidence( forincidence->relatedToUid() );
859 if ( parent ) {
860 // Found it
861 forincidence->setRelatedTo( parent );
862 parent->addRelation( forincidence );
863 } else {
864 // Not found, put this in the mOrphans list
865 // Note that the mOrphans dict might have several entries with the same key! That are
866 // multiple children that wait for the parent incidence to be inserted.
867 mOrphans.insert( forincidence->relatedToUid(), forincidence );
868 mOrphanUids.insert( forincidence->uid(), forincidence );
869 }
870 }
871}
872
873// If a task with subtasks is deleted, move it's subtasks to the orphans list
875{
876 if( !incidence ) {
877 kdDebug(5800) << "Warning: Calendar::removeRelations( 0 )!\n";
878 return;
879 }
880
881// kdDebug(5850) << "Calendar::removeRelations for incidence " << forincidence << " with UID " << forincidence->uid() << ", summary: " << forincidence->summary() << endl;
882 TQString uid = incidence->uid();
883
884 Incidence::List relations = incidence->relations();
885 Incidence::List::ConstIterator it;
886 for ( it = relations.begin(); it != relations.end(); ++it ) {
887 Incidence *i = *it;
888 if ( !mOrphanUids.find( i->uid() ) ) {
889 mOrphans.insert( uid, i );
890 mOrphanUids.insert( i->uid(), i );
891 i->setRelatedTo( 0 );
892 i->setRelatedToUid( uid );
893 }
894 }
895
896 // If this incidence is related to something else, tell that about it
897 if ( incidence->relatedTo() )
899
900 // Remove this one from the orphans list
901 if ( mOrphanUids.remove( uid ) ) {
902 // This incidence is located in the orphans list - it should be removed
903 // Since the mOrphans dict might contain the same key (with different
904 // child incidence pointers!) multiple times, take care that we remove
905 // the correct one. So we need to remove all items with the given
906 // parent UID, and readd those that are not for this item. Also, there
907 // might be other entries with differnet UID that point to this
908 // incidence (this might happen when the relatedTo of the item is
909 // changed before its parent is inserted. This might happen with
910 // groupware servers....). Remove them, too
911 TQStringList relatedToUids;
912 // First get the list of all keys in the mOrphans list that point to the removed item
913 relatedToUids << incidence->relatedToUid();
914 for ( TQDictIterator<Incidence> it( mOrphans ); it.current(); ++it ) {
915 if ( it.current()->uid() == uid ) {
916 relatedToUids << it.currentKey();
917 }
918 }
919
920 // now go through all uids that have one entry that point to the incidence
921 for ( TQStringList::Iterator uidit = relatedToUids.begin();
922 uidit != relatedToUids.end(); ++uidit ) {
923 Incidence::List tempList;
924 // Remove all to get access to the remaining entries
925 while( Incidence* i = mOrphans[ *uidit ] ) {
926 mOrphans.remove( *uidit );
927 if ( i != incidence ) tempList.append( i );
928 }
929 // Readd those that point to a different orphan incidence
930 for ( Incidence::List::Iterator incit = tempList.begin();
931 incit != tempList.end(); ++incit ) {
932 mOrphans.insert( *uidit, *incit );
933 }
934 }
935 }
936}
937
939{
940 if( !mObservers.contains( observer ) )
941 mObservers.append( observer );
942 mNewObserver = true;
943}
944
946{
947 mObservers.remove( observer );
948}
949
950void Calendar::setModified( bool modified )
951{
952 if ( modified != mModified || mNewObserver ) {
953 mNewObserver = false;
954 Observer *observer;
955 for ( observer = mObservers.first(); observer;
956 observer = mObservers.next() ) {
957 observer->calendarModified( modified, this );
958 }
959 mModified = modified;
960 }
961}
962
964{
965 incidence->setSyncStatus( Event::SYNCMOD );
966 incidence->setLastModified( TQDateTime::currentDateTime() );
967 // we should probably update the revision number here,
968 // or internally in the Event itself when certain things change.
969 // need to verify with ical documentation.
970
971 // The static_cast is ok as the CalendarLocal only observes Incidence objects
972 notifyIncidenceChanged( static_cast<Incidence *>( incidence ) );
973
974 setModified( true );
975}
976
978{
979 if ( !mObserversEnabled )
980 return;
981
982 Observer *observer;
983 for ( observer = mObservers.first(); observer;
984 observer = mObservers.next() ) {
985 observer->calendarIncidenceAdded( i );
986 }
987}
988
990{
991 if ( !mObserversEnabled )
992 return;
993
994 Observer *observer;
995 for ( observer = mObservers.first(); observer;
996 observer = mObservers.next() ) {
997 observer->calendarIncidenceChanged( i );
998 }
999}
1000
1002{
1003 if ( !mObserversEnabled )
1004 return;
1005
1006 Observer *observer;
1007 for ( observer = mObservers.first(); observer;
1008 observer = mObservers.next() ) {
1009 observer->calendarIncidenceDeleted( i );
1010 }
1011}
1012
1014{
1015 setModified( true );
1016}
1017
1018void Calendar::setProductId( const TQString &productId )
1019{
1020 mProductId = productId;
1021}
1022
1024{
1025 return mProductId;
1026}
1027
1029 const Todo::List &todos,
1030 const Journal::List &journals )
1031{
1033
1034 Event::List::ConstIterator it1;
1035 for ( it1 = events.begin(); it1 != events.end(); ++it1 )
1036 incidences.append( *it1 );
1037
1038 Todo::List::ConstIterator it2;
1039 for ( it2 = todos.begin(); it2 != todos.end(); ++it2 )
1040 incidences.append( *it2 );
1041
1042 Journal::List::ConstIterator it3;
1043 for ( it3 = journals.begin(); it3 != journals.end(); ++it3 )
1044 incidences.append( *it3 );
1045
1046 return incidences;
1047}
1048
1050{
1051 return true;
1052}
1053
1055{
1056 return true;
1057}
1058
1060{
1061 mObserversEnabled = enabled;
1062}
1063
1064#include "calendar.moc"
Provides the main "calendar" object class.
Filter for calendar objects.
Definition: calfilter.h:39
void apply(Event::List *eventlist) const
Apply filter to eventlist, all events not matching filter criterias are removed from the list.
Definition: calfilter.cpp:49
void setEnabled(bool)
Enable or disable filter.
Definition: calfilter.cpp:178
The Observer class.
Definition: calendar.h:869
virtual void calendarIncidenceAdded(Incidence *)
Notify the Observer that an Incidence has been inserted.
Definition: calendar.h:887
virtual void calendarIncidenceDeleted(Incidence *)
Notify the Observer that an Incidence has been removed.
Definition: calendar.h:901
virtual void calendarModified(bool, Calendar *)
Notify the Observer that a Calendar has been modified.
Definition: calendar.h:879
virtual void calendarIncidenceChanged(Incidence *)
Notify the Observer that an Incidence has been modified.
Definition: calendar.h:894
void clearException()
Clears the exception status.
Definition: calendar.cpp:74
static Todo::List sortTodos(Todo::List *todoList, TodoSortField sortField, SortDirection sortDirection)
Sort a list of Todos.
Definition: calendar.cpp:611
void setLocalTime()
Set to store calendar Incidences without a time zone.
Definition: calendar.cpp:117
Incidence * dissociateOccurrence(Incidence *incidence, TQDate date, bool single=true)
Dissociate an Incidence from a recurring Incidence.
Definition: calendar.cpp:508
void setTimeZoneId(const TQString &timeZoneId)
Set the Time Zone Id for the Calendar.
Definition: calendar.cpp:103
virtual void doSetTimeZoneId(const TQString &)
Let Calendar subclasses set the Time Zone ID.
Definition: calendar.h:974
virtual Journal::List rawJournals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending)=0
Return a sorted, unfiltered list of all Journals for this Calendar.
virtual Journal::List rawJournalsForDate(const TQDate &date)=0
Return an unfiltered list of all Journals for on the specifed date.
virtual ~Calendar()
Destructor.
Definition: calendar.cpp:68
TQStringList categories()
Return a list of all categories used by Incidences in this Calendar.
Definition: calendar.cpp:154
virtual bool addIncidence(Incidence *incidence)
Insert an Incidence into the Calendar.
Definition: calendar.cpp:466
virtual bool beginChange(Incidence *incidence)
Flag that a change to a Calendar Incidence is starting.
Definition: calendar.cpp:1049
bool isLocalTime() const
Determine if Calendar Incidences are to be written without a time zone.
Definition: calendar.cpp:125
virtual Event::List rawEventsForDate(const TQDateTime &qdt)=0
Return an unfiltered list of all Events which occur on the given timestamp.
TQString productId()
Get the Calendar's Product ID.
Definition: calendar.cpp:1023
virtual Incidence::List rawIncidences()
Return an unfiltered list of all Incidences for this Calendar.
Definition: calendar.cpp:183
void incidenceUpdated(IncidenceBase *incidenceBase)
The Observer interface.
Definition: calendar.cpp:963
virtual Incidence::List incidences()
Return a filtered list of all Incidences for this Calendar.
Definition: calendar.cpp:178
static Incidence::List mergeIncidenceList(const Event::List &events, const Todo::List &todos, const Journal::List &journals)
Create a merged list of Events, Todos, and Journals.
Definition: calendar.cpp:1028
Incidence * incidenceFromSchedulingID(const TQString &sid)
Returns the Incidence associated with the given scheduling identifier.
Definition: calendar.cpp:599
virtual void setupRelations(Incidence *incidence)
Setup Relations for an Incidence.
Definition: calendar.cpp:840
void notifyIncidenceDeleted(Incidence *incidence)
Let Calendar subclasses notify that they removed an Incidence.
Definition: calendar.cpp:1001
void registerObserver(Observer *observer)
Register an Observer for this Calendar.
Definition: calendar.cpp:938
void setFilter(CalFilter *filter)
Set the Calendar filter.
Definition: calendar.cpp:130
virtual bool deleteIncidence(Incidence *incidence)
Remove an Incidence from the Calendar.
Definition: calendar.cpp:473
static Event::List sortEvents(Event::List *eventList, EventSortField sortField, SortDirection sortDirection)
Sort a list of Events.
Definition: calendar.cpp:188
void notifyIncidenceChanged(Incidence *incidence)
Let Calendar subclasses notify that they modified an Incidence.
Definition: calendar.cpp:989
ErrorFormat * exception() const
Returns an exception, if there is any, containing information about the last error that occurred.
Definition: calendar.cpp:80
const Person & getOwner() const
Get the owner of the Calendar.
Definition: calendar.cpp:91
virtual Todo * todo(const TQString &uid)=0
Returns the Todo associated with the given unique identifier.
virtual void customPropertyUpdated()
Definition: calendar.cpp:1013
void unregisterObserver(Observer *observer)
Unregister an Observer for this Calendar.
Definition: calendar.cpp:945
void setModified(bool modified)
Set if the Calendar had been modified.
Definition: calendar.cpp:950
virtual void removeRelations(Incidence *incidence)
Remove all Relations from an Incidence.
Definition: calendar.cpp:874
static Event::List sortEventsForDate(Event::List *eventList, const TQDate &date, EventSortField sortField, SortDirection sortDirection)
Sort a list of Events that occur on a specified date.
Definition: calendar.cpp:291
CalFilter * filter()
Return the Calendar filter.
Definition: calendar.cpp:139
virtual bool endChange(Incidence *incidence)
Flag that a change to a Calendar Incidence has completed.
Definition: calendar.cpp:1054
void setProductId(const TQString &productId)
Set the Calendar Product ID.
Definition: calendar.cpp:1018
void setOwner(const Person &owner)
Set the owner of the Calendar.
Definition: calendar.cpp:96
void setObserversEnabled(bool enabled)
Let Calendar subclasses notify that they enabled an Observer.
Definition: calendar.cpp:1059
virtual Event::List rawEvents(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)=0
Return a sorted, unfiltered list of all Events for this Calendar.
TQString timeZoneId() const
Get the Time Zone ID for the Calendar.
Definition: calendar.cpp:112
virtual Journal * journal(const TQString &uid)=0
Returns the Journal associated with the given unique identifier.
virtual Event::List events(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Events for this Calendar.
Definition: calendar.cpp:458
Incidence::List incidencesFromSchedulingID(const TQString &UID)
Searches all events and todos for (an incidence with this scheduling ID.
Definition: calendar.cpp:588
void setException(ErrorFormat *e)
Sets information about the last error occurred.
Definition: calendar.cpp:85
void notifyIncidenceAdded(Incidence *incidence)
Let Calendar subclasses notify that they inserted an Incidence.
Definition: calendar.cpp:977
virtual Journal::List journals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Journals for this Calendar.
Definition: calendar.cpp:823
virtual Todo::List rawTodos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)=0
Return a sorted, unfiltered list of all Todos for this Calendar.
void batchAddingEnds()
virtual Todo::List rawTodosForDate(const TQDate &date)=0
Return an unfiltered list of all Todos which due on the specified date.
void beginBatchAdding()
Emits the beginBatchAdding() signal.
Definition: calendar.cpp:144
void batchAddingBegins()
Incidence * incidence(const TQString &uid)
Returns the Incidence associated with the given unique identifier.
Definition: calendar.cpp:576
virtual Todo::List todos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Return a sorted, filtered list of all Todos for this Calendar.
Definition: calendar.cpp:755
static Journal::List sortJournals(Journal::List *journalList, JournalSortField sortField, SortDirection sortDirection)
Sort a list of Journals.
Definition: calendar.cpp:770
virtual Event * event(const TQString &uid)=0
Returns the Event associated with the given unique identifier.
void endBatchAdding()
Emits the endBatchAdding() signal.
Definition: calendar.cpp:149
Calendar format related error class.
Definition: exceptions.h:65
This class provides an Event in the sense of RFC2445.
Definition: event.h:33
virtual TQDateTime dtEnd() const
Return end date and time.
Definition: event.cpp:85
void setDtEnd(const TQDateTime &dtEnd)
Set end date and time.
Definition: event.cpp:73
This class provides the base class common to all calendar components.
Definition: incidencebase.h:46
TQString uid() const
Return the unique id for the event.
virtual TQDateTime dtStart() const
returns an event's starting date/time as a TQDateTime.
virtual bool accept(Visitor &)
Accept IncidenceVisitor.
void setSyncStatus(int status)
Set synchronisation satus.
void setLastModified(const TQDateTime &lm)
Sets the time the incidence was last modified.
This class implements a visitor for adding an Incidence to a resource supporting addEvent(),...
Definition: incidence.h:56
This class implements a visitor for deleting an Incidence from a resource supporting deleteEvent(),...
Definition: incidence.h:104
This class provides the base class common to all calendar components.
Definition: incidence.h:48
TQString relatedToUid() const
What event does this one relate to? This function should only be used when constructing a calendar be...
Definition: incidence.cpp:340
void recreate()
Recreate event.
Definition: incidence.cpp:208
void setRelatedTo(Incidence *relatedTo)
Point at some other event to which the event relates.
Definition: incidence.cpp:345
IncidenceList childIncidences() const
Returns an EventList of all child incidences.
Definition: incidence.cpp:934
Incidence * relatedTo() const
What event does this one relate to?
Definition: incidence.cpp:360
void removeRelation(Incidence *)
Remove event that is related to this event.
Definition: incidence.cpp:377
void setRelatedToUid(const TQString &)
Point at some other event to which the event relates.
Definition: incidence.cpp:333
bool doesRecur() const
Forward to Recurrence::doesRecur().
Definition: incidence.cpp:416
virtual Incidence * clone()=0
Return copy of this object.
virtual void setDtStart(const TQDateTime &dtStart)
Set starting date/time.
Definition: incidence.cpp:264
bool hasRecurrenceID() const
Returns true if the incidence has recurrenceID, otherwise return false.
Definition: incidence.cpp:893
Incidence::List relations() const
All events that are related to this event.
Definition: incidence.cpp:365
Recurrence * recurrence() const
Return the recurrence rule associated with this incidence.
Definition: incidence.cpp:390
void deleteChildIncidence(TQString childIncidence)
Detach a child incidence from its parent incidence.
Definition: incidence.cpp:929
void addRelation(Incidence *)
Add an event which is related to this event.
Definition: incidence.cpp:370
void setHasRecurrenceID(bool hasRecurrenceID)
Sets if the incidence has recurrenceID.
Definition: incidence.cpp:898
This class represents a person.
Definition: person.h:35
This class represents a recurrence rule for a calendar incidence.
Definition: recurrence.h:90
int durationTo(const TQDateTime &) const
Returns the number of recurrences up to and including the date/time specified.
Definition: recurrence.cpp:407
int duration() const
Returns -1 if the event recurs infinitely, 0 if the end date is set, otherwise the total number of re...
Definition: recurrence.cpp:395
void clear()
Removes all recurrence and exception rules and dates.
Definition: recurrence.cpp:431
void setEndDate(const TQDate &endDate)
Sets the date of the last recurrence.
Definition: recurrence.cpp:378
void setDuration(int duration)
Sets the total number of times the event is to occur, including both the first and last.
Definition: recurrence.cpp:415
This class provides a Todo in the sense of RFC2445.
Definition: todo.h:32
bool hasDueDate() const
Returns true if the todo has a due date, otherwise return false.
Definition: todo.cpp:144
bool hasStartDate() const
Returns true if the todo has a start date, otherwise return false.
Definition: todo.cpp:157
void setDtDue(const TQDateTime &dtDue, bool first=false)
Sets due date and time.
Definition: todo.cpp:85
TQDateTime dtStart(bool first=false) const
Returns the startdate of the todo.
Definition: todo.cpp:177
void setDtStart(const TQDateTime &dtStart)
Sets the startdate of the todo.
Definition: todo.cpp:192
TQDateTime dtDue(bool first=false) const
Returns due date and time.
Definition: todo.cpp:117
Namespace KCal is for global classes, objects and/or functions in libkcal.
Definition: alarm.h:38
TodoSortField
How Todos are to be sorted.
Definition: calendar.h:91
@ TodoSortSummary
Sort Todos alphabetically, by summary.
Definition: calendar.h:103
@ TodoSortDueDate
Sort Todos chronologically, by due date.
Definition: calendar.h:97
@ TodoSortPriority
Sort Todos by priority.
Definition: calendar.h:99
@ TodoSortPercentComplete
Sort Todos by percentage completed.
Definition: calendar.h:101
@ TodoSortStartDate
Sort Todos chronologically, by start date.
Definition: calendar.h:95
@ TodoSortUnsorted
Todos are to be unsorted.
Definition: calendar.h:93
JournalSortField
How Journals are to be sorted.
Definition: calendar.h:111
@ JournalSortUnsorted
Journals are to be unsorted.
Definition: calendar.h:113
@ JournalSortDate
Sort Journals chronologically by date.
Definition: calendar.h:115
@ JournalSortSummary
Sort Journals alphabetically, by summary.
Definition: calendar.h:117
EventSortField
How Events are to be sorted.
Definition: calendar.h:75
@ EventSortUnsorted
Events are to be unsorted.
Definition: calendar.h:77
@ EventSortEndDate
Sort Events chronologically, by end date.
Definition: calendar.h:81
@ EventSortSummary
Sort Events alphabetically, by summary.
Definition: calendar.h:83
@ EventSortStartDate
Sort Events chronologically, by start date.
Definition: calendar.h:79
SortDirection
Sort direction.
Definition: calendar.h:63
@ SortDirectionAscending
Sort in ascending order (first to last)
Definition: calendar.h:65