• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdepimlibs-4.14.10 API Reference
  • KDE Home
  • Contact Us
 

KCal Library

  • kcal
scheduler.cpp
1/*
2 This file is part of the kcal library.
3
4 Copyright (c) 2001,2004 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22
23#include "scheduler.h"
24#include "calendar.h"
25#ifndef KDEPIM_NO_KRESOURCES
26#include "calendarresources.h"
27#endif
28#include "event.h"
29#include "todo.h"
30#include "freebusy.h"
31#include "freebusycache.h"
32#include "icalformat.h"
33#include "assignmentvisitor.h"
34
35#include <klocalizedstring.h>
36#include <kdebug.h>
37#include <kmessagebox.h>
38#include <kstandarddirs.h>
39
40using namespace KCal;
41
42//@cond PRIVATE
43class KCal::ScheduleMessage::Private
44{
45 public:
46 Private() {}
47
48 IncidenceBase *mIncidence;
49 iTIPMethod mMethod;
50 Status mStatus;
51 QString mError;
52};
53//@endcond
54
55ScheduleMessage::ScheduleMessage( IncidenceBase *incidence,
56 iTIPMethod method,
57 ScheduleMessage::Status status )
58 : d( new KCal::ScheduleMessage::Private )
59{
60 d->mIncidence = incidence;
61 d->mMethod = method;
62 d->mStatus = status;
63}
64
65ScheduleMessage::~ScheduleMessage()
66{
67 delete d;
68}
69
70IncidenceBase *ScheduleMessage::event()
71{
72 return d->mIncidence;
73}
74
75iTIPMethod ScheduleMessage::method()
76{
77 return d->mMethod;
78}
79
80ScheduleMessage::Status ScheduleMessage::status()
81{
82 return d->mStatus;
83}
84
85QString ScheduleMessage::statusName( ScheduleMessage::Status status )
86{
87 switch( status ) {
88 case PublishNew:
89 return i18nc( "@item this is a new scheduling message",
90 "New Scheduling Message" );
91 case PublishUpdate:
92 return i18nc( "@item this is an update to an existing scheduling message",
93 "Updated Scheduling Message" );
94 case Obsolete:
95 return i18nc( "@item obsolete status", "Obsolete" );
96 case RequestNew:
97 return i18nc( "@item this is a request for a new scheduling message",
98 "New Scheduling Message Request" );
99 case RequestUpdate:
100 return i18nc( "@item this is a request for an update to an existing scheduling message",
101 "Updated Scheduling Message Request" );
102 default:
103 return i18nc( "@item unknown status", "Unknown Status: %1", int( status ) );
104 }
105}
106
107QString ScheduleMessage::error()
108{
109 return d->mError;
110}
111
112//@cond PRIVATE
113struct KCal::Scheduler::Private
114{
115 Private()
116 : mFreeBusyCache( 0 )
117 {
118 }
119 FreeBusyCache *mFreeBusyCache;
120};
121//@endcond
122
123Scheduler::Scheduler( Calendar *calendar ) : d( new KCal::Scheduler::Private )
124{
125 mCalendar = calendar;
126 mFormat = new ICalFormat();
127 mFormat->setTimeSpec( calendar->timeSpec() );
128}
129
130Scheduler::~Scheduler()
131{
132 delete mFormat;
133 delete d;
134}
135
136void Scheduler::setFreeBusyCache( FreeBusyCache *c )
137{
138 d->mFreeBusyCache = c;
139}
140
141FreeBusyCache *Scheduler::freeBusyCache() const
142{
143 return d->mFreeBusyCache;
144}
145
146bool Scheduler::acceptTransaction( IncidenceBase *incidence,
147 iTIPMethod method,
148 ScheduleMessage::Status status )
149{
150 return acceptTransaction( incidence, method, status, QString() );
151}
152
153bool Scheduler::acceptTransaction( IncidenceBase *incidence,
154 iTIPMethod method,
155 ScheduleMessage::Status status,
156 const QString &email )
157{
158 kDebug() << "method=" << methodName( method );
159
160 switch ( method ) {
161 case iTIPPublish:
162 return acceptPublish( incidence, status, method );
163 case iTIPRequest:
164 return acceptRequest( incidence, status, email );
165 case iTIPAdd:
166 return acceptAdd( incidence, status );
167 case iTIPCancel:
168 return acceptCancel( incidence, status, email );
169 case iTIPDeclineCounter:
170 return acceptDeclineCounter( incidence, status );
171 case iTIPReply:
172 return acceptReply( incidence, status, method );
173 case iTIPRefresh:
174 return acceptRefresh( incidence, status );
175 case iTIPCounter:
176 return acceptCounter( incidence, status );
177 default:
178 break;
179 }
180 deleteTransaction( incidence );
181 return false;
182}
183
184QString Scheduler::methodName( iTIPMethod method )
185{
186 switch ( method ) {
187 case iTIPPublish:
188 return QLatin1String( "Publish" );
189 case iTIPRequest:
190 return QLatin1String( "Request" );
191 case iTIPRefresh:
192 return QLatin1String( "Refresh" );
193 case iTIPCancel:
194 return QLatin1String( "Cancel" );
195 case iTIPAdd:
196 return QLatin1String( "Add" );
197 case iTIPReply:
198 return QLatin1String( "Reply" );
199 case iTIPCounter:
200 return QLatin1String( "Counter" );
201 case iTIPDeclineCounter:
202 return QLatin1String( "Decline Counter" );
203 default:
204 return QLatin1String( "Unknown" );
205 }
206}
207
208QString Scheduler::translatedMethodName( iTIPMethod method )
209{
210 switch ( method ) {
211 case iTIPPublish:
212 return i18nc( "@item event, to-do, journal or freebusy posting", "Publish" );
213 case iTIPRequest:
214 return i18nc( "@item event, to-do or freebusy scheduling requests", "Request" );
215 case iTIPReply:
216 return i18nc( "@item event, to-do or freebusy reply to request", "Reply" );
217 case iTIPAdd:
218 return i18nc(
219 "@item event, to-do or journal additional property request", "Add" );
220 case iTIPCancel:
221 return i18nc( "@item event, to-do or journal cancellation notice", "Cancel" );
222 case iTIPRefresh:
223 return i18nc( "@item event or to-do description update request", "Refresh" );
224 case iTIPCounter:
225 return i18nc( "@item event or to-do submit counter proposal", "Counter" );
226 case iTIPDeclineCounter:
227 return i18nc( "@item event or to-do decline a counter proposal", "Decline Counter" );
228 default:
229 return i18nc( "@item no method", "Unknown" );
230 }
231}
232
233bool Scheduler::deleteTransaction( IncidenceBase * )
234{
235 return true;
236}
237
238bool Scheduler::acceptPublish( IncidenceBase *newIncBase,
239 ScheduleMessage::Status status,
240 iTIPMethod method )
241{
242 if( newIncBase->type() == "FreeBusy" ) {
243 return acceptFreeBusy( newIncBase, method );
244 }
245
246 bool res = false;
247
248 kDebug() << "status=" << ScheduleMessage::statusName( status );
249
250 Incidence *newInc = static_cast<Incidence *>( newIncBase );
251 Incidence *calInc = mCalendar->incidence( newIncBase->uid() );
252 switch ( status ) {
253 case ScheduleMessage::Unknown:
254 case ScheduleMessage::PublishNew:
255 case ScheduleMessage::PublishUpdate:
256 if ( calInc && newInc ) {
257 if ( ( newInc->revision() > calInc->revision() ) ||
258 ( newInc->revision() == calInc->revision() &&
259 newInc->lastModified() > calInc->lastModified() ) ) {
260 AssignmentVisitor visitor;
261 const QString oldUid = calInc->uid();
262 if ( !visitor.assign( calInc, newInc ) ) {
263 kError() << "assigning different incidence types";
264 } else {
265 calInc->setSchedulingID( newInc->uid() );
266 calInc->setUid( oldUid );
267 res = true;
268 }
269 }
270 }
271 break;
272 case ScheduleMessage::Obsolete:
273 res = true;
274 break;
275 default:
276 break;
277 }
278 deleteTransaction( newIncBase );
279 return res;
280}
281
282bool Scheduler::acceptRequest( IncidenceBase *incidence,
283 ScheduleMessage::Status status )
284{
285 return acceptRequest( incidence, status, QString() );
286}
287
288bool Scheduler::acceptRequest( IncidenceBase *incidence,
289 ScheduleMessage::Status status,
290 const QString &email )
291{
292 Incidence *inc = static_cast<Incidence *>( incidence );
293 if ( !inc ) {
294 return false;
295 }
296 if ( inc->type() == "FreeBusy" ) {
297 // reply to this request is handled in korganizer's incomingdialog
298 return true;
299 }
300
301 const Incidence::List existingIncidences = mCalendar->incidencesFromSchedulingID( inc->uid() );
302 kDebug() << "status=" << ScheduleMessage::statusName( status )
303 << ": found " << existingIncidences.count()
304 << " incidences with schedulingID " << inc->schedulingID();
305 Incidence::List::ConstIterator incit = existingIncidences.begin();
306 for ( ; incit != existingIncidences.end() ; ++incit ) {
307 Incidence *i = *incit;
308 kDebug() << "Considering this found event ("
309 << ( i->isReadOnly() ? "readonly" : "readwrite" )
310 << ") :" << mFormat->toString( i );
311 // If it's readonly, we can't possible update it.
312 if ( i->isReadOnly() ) {
313 continue;
314 }
315 if ( i->revision() <= inc->revision() ) {
316 // The new incidence might be an update for the found one
317 bool isUpdate = true;
318 // Code for new invitations:
319 // If you think we could check the value of "status" to be RequestNew: we can't.
320 // It comes from a similar check inside libical, where the event is compared to
321 // other events in the calendar. But if we have another version of the event around
322 // (e.g. shared folder for a group), the status could be RequestNew, Obsolete or Updated.
323 kDebug() << "looking in " << i->uid() << "'s attendees";
324 // This is supposed to be a new request, not an update - however we want to update
325 // the existing one to handle the "clicking more than once on the invitation" case.
326 // So check the attendee status of the attendee.
327 const KCal::Attendee::List attendees = i->attendees();
328 KCal::Attendee::List::ConstIterator ait;
329 for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
330 if( (*ait)->email() == email && (*ait)->status() == Attendee::NeedsAction ) {
331 // This incidence wasn't created by me - it's probably in a shared folder
332 // and meant for someone else, ignore it.
333 kDebug() << "ignoring " << i->uid() << " since I'm still NeedsAction there";
334 isUpdate = false;
335 break;
336 }
337 }
338 if ( isUpdate ) {
339 if ( i->revision() == inc->revision() &&
340 i->lastModified() > inc->lastModified() ) {
341 // This isn't an update - the found incidence was modified more recently
342 kDebug() << "This isn't an update - the found incidence was modified more recently";
343 deleteTransaction( i );
344 return false;
345 }
346 kDebug() << "replacing existing incidence " << i->uid();
347 bool res = true;
348 AssignmentVisitor visitor;
349 const QString oldUid = i->uid();
350 if ( !visitor.assign( i, inc ) ) {
351 kError() << "assigning different incidence types";
352 res = false;
353 } else {
354 i->setUid( oldUid );
355 i->setSchedulingID( inc->uid() );
356 }
357 deleteTransaction( incidence );
358 return res;
359 }
360 } else {
361 // This isn't an update - the found incidence has a bigger revision number
362 kDebug() << "This isn't an update - the found incidence has a bigger revision number";
363 deleteTransaction( incidence );
364 return false;
365 }
366 }
367
368 // Move the uid to be the schedulingID and make a unique UID
369 inc->setSchedulingID( inc->uid() );
370 inc->setUid( CalFormat::createUniqueId() );
371 // in case this is an update and we didn't find the to-be-updated incidence,
372 // ask whether we should create a new one, or drop the update
373 if ( existingIncidences.count() > 0 || inc->revision() == 0 ||
374 KMessageBox::questionYesNo(
375 0,
376 i18nc( "@info",
377 "The event, to-do or journal to be updated could not be found. "
378 "Maybe it has already been deleted, or the calendar that "
379 "contains it is disabled. Press 'Store' to create a new "
380 "one or 'Throw away' to discard this update." ),
381 i18nc( "@title", "Discard this update?" ),
382 KGuiItem( i18nc( "@option", "Store" ) ),
383 KGuiItem( i18nc( "@option", "Throw away" ) ),
384 "AcceptCantFindIncidence" ) == KMessageBox::Yes ) {
385 kDebug() << "Storing new incidence with scheduling uid=" << inc->schedulingID()
386 << " and uid=" << inc->uid();
387
388#ifndef KDEPIM_NO_KRESOURCES
389 CalendarResources *stdcal = dynamic_cast<CalendarResources *>( mCalendar );
390 if( stdcal && !stdcal->hasCalendarResources() ) {
391 KMessageBox::sorry(
392 0,
393 i18nc( "@info", "No calendars found, unable to save the invitation." ) );
394 return false;
395 }
396
397 // FIXME: This is a nasty hack, since we need to set a parent for the
398 // resource selection dialog. However, we don't have any UI methods
399 // in the calendar, only in the CalendarResources::DestinationPolicy
400 // So we need to type-cast it and extract it from the CalendarResources
401 if ( stdcal ) {
402 stdcal->setDialogParentWidget( 0 );
403 }
404#endif
405
406 TryAgain:
407 bool success = false;
408#ifndef KDEPIM_NO_KRESOURCES
409 if ( stdcal )
410 success = stdcal->addIncidence( inc );
411 else
412#endif
413 success = mCalendar->addIncidence( inc );
414
415 if ( !success ) {
416#ifndef KDEPIM_NO_KRESOURCES
417 ErrorFormat *e = stdcal ? stdcal->exception() : 0;
418#else
419 ErrorFormat *e = 0;
420#endif
421
422 if ( e && e->errorCode() == KCal::ErrorFormat::UserCancel &&
423 KMessageBox::warningYesNo(
424 0,
425 i18nc( "@info",
426 "You canceled the save operation. Therefore, the appointment will not be "
427 "stored in your calendar even though you accepted the invitation. "
428 "Are you certain you want to discard this invitation? " ),
429 i18nc( "@title", "Discard this invitation?" ),
430 KGuiItem( i18nc( "@option", "Discard" ) ),
431 KGuiItem( i18nc( "@option", "Go Back to Folder Selection" ) ) ) == KMessageBox::Yes ) {
432 KMessageBox::information(
433 0,
434 i18nc( "@info",
435 "The invitation \"%1\" was not saved to your calendar "
436 "but you are still listed as an attendee for that appointment.\n"
437 "If you mistakenly accepted the invitation or do not plan to attend, please "
438 "notify the organizer %2 and ask them to remove you from the attendee list.",
439 inc->summary(), inc->organizer().fullName() ) );
440 deleteTransaction( incidence );
441 return true;
442 } else {
443 goto TryAgain;
444 }
445
446 // We can have a failure if the user pressed [cancel] in the resource
447 // selectdialog, so check the exception.
448 if ( !e ||
449 ( e && ( e->errorCode() != KCal::ErrorFormat::UserCancel &&
450 e->errorCode() != KCal::ErrorFormat::NoWritableFound ) ) ) {
451 QString errMessage = i18nc( "@info", "Unable to save %1 \"%2\".",
452 i18n( inc->type() ), inc->summary() );
453 KMessageBox::sorry( 0, errMessage );
454 }
455 return false;
456 }
457 }
458 deleteTransaction( incidence );
459 return true;
460}
461
462bool Scheduler::acceptAdd( IncidenceBase *incidence, ScheduleMessage::Status /* status */)
463{
464 deleteTransaction( incidence );
465 return false;
466}
467
468bool Scheduler::acceptCancel( IncidenceBase *incidence,
469 ScheduleMessage::Status status,
470 const QString &attendee )
471{
472 Incidence *inc = static_cast<Incidence *>( incidence );
473 if ( !inc ) {
474 return false;
475 }
476
477 if ( inc->type() == "FreeBusy" ) {
478 // reply to this request is handled in korganizer's incomingdialog
479 return true;
480 }
481
482 const Incidence::List existingIncidences = mCalendar->incidencesFromSchedulingID( inc->uid() );
483 kDebug() << "Scheduler::acceptCancel="
484 << ScheduleMessage::statusName( status )
485 << ": found " << existingIncidences.count()
486 << " incidences with schedulingID " << inc->schedulingID();
487
488 bool ret = false;
489 Incidence::List::ConstIterator incit = existingIncidences.begin();
490 for ( ; incit != existingIncidences.end() ; ++incit ) {
491 Incidence *i = *incit;
492 kDebug() << "Considering this found event ("
493 << ( i->isReadOnly() ? "readonly" : "readwrite" )
494 << ") :" << mFormat->toString( i );
495
496 // If it's readonly, we can't possible remove it.
497 if ( i->isReadOnly() ) {
498 continue;
499 }
500
501 // Code for new invitations:
502 // We cannot check the value of "status" to be RequestNew because
503 // "status" comes from a similar check inside libical, where the event
504 // is compared to other events in the calendar. But if we have another
505 // version of the event around (e.g. shared folder for a group), the
506 // status could be RequestNew, Obsolete or Updated.
507 kDebug() << "looking in " << i->uid() << "'s attendees";
508
509 // This is supposed to be a new request, not an update - however we want
510 // to update the existing one to handle the "clicking more than once
511 // on the invitation" case. So check the attendee status of the attendee.
512 bool isMine = true;
513 const KCal::Attendee::List attendees = i->attendees();
514 KCal::Attendee::List::ConstIterator ait;
515 for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
516 if ( (*ait)->email() == attendee &&
517 (*ait)->status() == Attendee::NeedsAction ) {
518 // This incidence wasn't created by me - it's probably in a shared
519 // folder and meant for someone else, ignore it.
520 kDebug() << "ignoring " << i->uid()
521 << " since I'm still NeedsAction there";
522 isMine = false;
523 break;
524 }
525 }
526
527 if ( isMine ) {
528 kDebug() << "removing existing incidence " << i->uid();
529 if ( i->type() == "Event" ) {
530 Event *event = mCalendar->event( i->uid() );
531 ret = ( event && mCalendar->deleteEvent( event ) );
532 } else if ( i->type() == "Todo" ) {
533 Todo *todo = mCalendar->todo( i->uid() );
534 ret = ( todo && mCalendar->deleteTodo( todo ) );
535 }
536 deleteTransaction( incidence );
537 return ret;
538 }
539 }
540
541 // in case we didn't find the to-be-removed incidence
542 if ( existingIncidences.count() > 0 && inc->revision() > 0 ) {
543 KMessageBox::information(
544 0,
545 i18nc( "@info",
546 "The event or task could not be removed from your calendar. "
547 "Maybe it has already been deleted or is not owned by you. "
548 "Or it might belong to a read-only or disabled calendar." ) );
549 }
550 deleteTransaction( incidence );
551 return ret;
552}
553
554bool Scheduler::acceptCancel( IncidenceBase *incidence,
555 ScheduleMessage::Status status )
556{
557 Q_UNUSED( status );
558
559 const IncidenceBase *toDelete = mCalendar->incidenceFromSchedulingID( incidence->uid() );
560
561 bool ret = true;
562 if ( toDelete ) {
563 if ( toDelete->type() == "Event" ) {
564 Event *event = mCalendar->event( toDelete->uid() );
565 ret = ( event && mCalendar->deleteEvent( event ) );
566 } else if ( toDelete->type() == "Todo" ) {
567 Todo *todo = mCalendar->todo( toDelete->uid() );
568 ret = ( todo && mCalendar->deleteTodo( todo ) );
569 }
570 } else {
571 // only complain if we failed to determine the toDelete incidence
572 // on non-initial request.
573 Incidence *inc = static_cast<Incidence *>( incidence );
574 if ( inc->revision() > 0 ) {
575 ret = false;
576 }
577 }
578
579 if ( !ret ) {
580 KMessageBox::information(
581 0,
582 i18nc( "@info",
583 "The event or task to be canceled could not be removed from your calendar. "
584 "Maybe it has already been deleted or is not owned by you. "
585 "Or it might belong to a read-only or disabled calendar." ) );
586 }
587 deleteTransaction( incidence );
588 return ret;
589}
590
591bool Scheduler::acceptDeclineCounter( IncidenceBase *incidence,
592 ScheduleMessage::Status status )
593{
594 Q_UNUSED( status );
595 deleteTransaction( incidence );
596 return false;
597}
598
599bool Scheduler::acceptReply( IncidenceBase *incidence,
600 ScheduleMessage::Status status,
601 iTIPMethod method )
602{
603 Q_UNUSED( status );
604 if ( incidence->type() == "FreeBusy" ) {
605 return acceptFreeBusy( incidence, method );
606 }
607 bool ret = false;
608 Event *ev = mCalendar->event( incidence->uid() );
609 Todo *to = mCalendar->todo( incidence->uid() );
610
611 // try harder to find the correct incidence
612 if ( !ev && !to ) {
613 const Incidence::List list = mCalendar->incidences();
614 for ( Incidence::List::ConstIterator it=list.constBegin(), end=list.constEnd();
615 it != end; ++it ) {
616 if ( (*it)->schedulingID() == incidence->uid() ) {
617 ev = dynamic_cast<Event*>( *it );
618 to = dynamic_cast<Todo*>( *it );
619 break;
620 }
621 }
622 }
623
624 if ( ev || to ) {
625 //get matching attendee in calendar
626 kDebug() << "match found!";
627 Attendee::List attendeesIn = incidence->attendees();
628 Attendee::List attendeesEv;
629 Attendee::List attendeesNew;
630 if ( ev ) {
631 attendeesEv = ev->attendees();
632 }
633 if ( to ) {
634 attendeesEv = to->attendees();
635 }
636 Attendee::List::ConstIterator inIt;
637 Attendee::List::ConstIterator evIt;
638 for ( inIt = attendeesIn.constBegin(); inIt != attendeesIn.constEnd(); ++inIt ) {
639 Attendee *attIn = *inIt;
640 bool found = false;
641 for ( evIt = attendeesEv.constBegin(); evIt != attendeesEv.constEnd(); ++evIt ) {
642 Attendee *attEv = *evIt;
643 if ( attIn->email().toLower() == attEv->email().toLower() ) {
644 //update attendee-info
645 kDebug() << "update attendee";
646 attEv->setStatus( attIn->status() );
647 attEv->setDelegate( attIn->delegate() );
648 attEv->setDelegator( attIn->delegator() );
649 ret = true;
650 found = true;
651 }
652 }
653 if ( !found && attIn->status() != Attendee::Declined ) {
654 attendeesNew.append( attIn );
655 }
656 }
657
658 bool attendeeAdded = false;
659 for ( Attendee::List::ConstIterator it = attendeesNew.constBegin();
660 it != attendeesNew.constEnd(); ++it ) {
661 Attendee *attNew = *it;
662 QString msg =
663 i18nc( "@info", "%1 wants to attend %2 but was not invited.",
664 attNew->fullName(),
665 ( ev ? ev->summary() : to->summary() ) );
666 if ( !attNew->delegator().isEmpty() ) {
667 msg = i18nc( "@info", "%1 wants to attend %2 on behalf of %3.",
668 attNew->fullName(),
669 ( ev ? ev->summary() : to->summary() ), attNew->delegator() );
670 }
671 if ( KMessageBox::questionYesNo(
672 0, msg, i18nc( "@title", "Uninvited attendee" ),
673 KGuiItem( i18nc( "@option", "Accept Attendance" ) ),
674 KGuiItem( i18nc( "@option", "Reject Attendance" ) ) ) != KMessageBox::Yes ) {
675 KCal::Incidence *cancel = dynamic_cast<Incidence*>( incidence );
676 if ( cancel ) {
677 cancel->addComment(
678 i18nc( "@info",
679 "The organizer rejected your attendance at this meeting." ) );
680 }
681 performTransaction( cancel ? cancel : incidence, iTIPCancel, attNew->fullName() );
682 // ### can't delete cancel here because it is aliased to incidence which
683 // is accessed in the next loop iteration (CID 4232)
684 // delete cancel;
685 continue;
686 }
687
688 Attendee *a = new Attendee( attNew->name(), attNew->email(), attNew->RSVP(),
689 attNew->status(), attNew->role(), attNew->uid() );
690 a->setDelegate( attNew->delegate() );
691 a->setDelegator( attNew->delegator() );
692 if ( ev ) {
693 ev->addAttendee( a );
694 } else if ( to ) {
695 to->addAttendee( a );
696 }
697 ret = true;
698 attendeeAdded = true;
699 }
700
701 // send update about new participants
702 if ( attendeeAdded ) {
703 bool sendMail = false;
704 if ( ev || to ) {
705 if ( KMessageBox::questionYesNo(
706 0,
707 i18nc( "@info",
708 "An attendee was added to the incidence. "
709 "Do you want to email the attendees an update message?" ),
710 i18nc( "@title", "Attendee Added" ),
711 KGuiItem( i18nc( "@option", "Send Messages" ) ),
712 KGuiItem( i18nc( "@option", "Do Not Send" ) ) ) == KMessageBox::Yes ) {
713 sendMail = true;
714 }
715 }
716
717 if ( ev ) {
718 ev->setRevision( ev->revision() + 1 );
719 if ( sendMail ) {
720 performTransaction( ev, iTIPRequest );
721 }
722 }
723 if ( to ) {
724 to->setRevision( to->revision() + 1 );
725 if ( sendMail ) {
726 performTransaction( to, iTIPRequest );
727 }
728 }
729 }
730
731 if ( ret ) {
732 // We set at least one of the attendees, so the incidence changed
733 // Note: This should not result in a sequence number bump
734 if ( ev ) {
735 ev->updated();
736 } else if ( to ) {
737 to->updated();
738 }
739 }
740 if ( to ) {
741 // for VTODO a REPLY can be used to update the completion status of
742 // a to-do. see RFC2446 3.4.3
743 Todo *update = dynamic_cast<Todo*> ( incidence );
744 Q_ASSERT( update );
745 if ( update && ( to->percentComplete() != update->percentComplete() ) ) {
746 to->setPercentComplete( update->percentComplete() );
747 to->updated();
748 }
749 }
750 } else {
751 kError() << "No incidence for scheduling.";
752 }
753
754 if ( ret ) {
755 deleteTransaction( incidence );
756 }
757 return ret;
758}
759
760bool Scheduler::acceptRefresh( IncidenceBase *incidence, ScheduleMessage::Status status )
761{
762 Q_UNUSED( status );
763 // handled in korganizer's IncomingDialog
764 deleteTransaction( incidence );
765 return false;
766}
767
768bool Scheduler::acceptCounter( IncidenceBase *incidence, ScheduleMessage::Status status )
769{
770 Q_UNUSED( status );
771 deleteTransaction( incidence );
772 return false;
773}
774
775bool Scheduler::acceptFreeBusy( IncidenceBase *incidence, iTIPMethod method )
776{
777 if ( !d->mFreeBusyCache ) {
778 kError() << "KCal::Scheduler: no FreeBusyCache.";
779 return false;
780 }
781
782 FreeBusy *freebusy = static_cast<FreeBusy *>(incidence);
783
784 kDebug() << "freeBusyDirName:" << freeBusyDir();
785
786 Person from;
787 if( method == iTIPPublish ) {
788 from = freebusy->organizer();
789 }
790 if ( ( method == iTIPReply ) && ( freebusy->attendeeCount() == 1 ) ) {
791 Attendee *attendee = freebusy->attendees().first();
792 from.setName( attendee->name() );
793 from.setEmail( attendee->email() );
794 }
795
796 if ( !d->mFreeBusyCache->saveFreeBusy( freebusy, from ) ) {
797 return false;
798 }
799
800 deleteTransaction( incidence );
801 return true;
802}
calendar.h
This file is part of the API for handling calendar data and defines the Calendar class.
calendarresources.h
This file is part of the API for handling calendar data and defines the CalendarResources class.
KCal::AssignmentVisitor
Helper for type correct assignment of incidences via pointers.
Definition assignmentvisitor.h:55
KCal::Attendee
Represents information related to an attendee of an Calendar Incidence, typically a meeting or task (...
Definition attendee.h:59
KCal::Attendee::setStatus
void setStatus(PartStat status)
Sets the PartStat of the attendee to status.
Definition attendee.cpp:120
KCal::Attendee::NeedsAction
@ NeedsAction
Event, to-do or journal needs action (default)
Definition attendee.h:72
KCal::Attendee::Declined
@ Declined
Event, to-do or journal declined.
Definition attendee.h:74
KCal::Attendee::setName
void setName(const QString &name)
Sets the name of the person to name.
Definition person.cpp:154
KCal::Attendee::List
ListBase< Attendee > List
List of attendees.
Definition attendee.h:95
KCal::CalFormat::createUniqueId
static QString createUniqueId()
Creates a unique id string.
Definition calformat.cpp:115
KCal::CalendarResources
This class provides a Calendar which is composed of other Calendars known as "Resources".
Definition calendarresources.h:59
KCal::Calendar
Represents the main calendar class.
Definition calendar.h:121
KCal::Calendar::addIncidence
virtual bool addIncidence(Incidence *incidence)
Inserts an Incidence into the calendar.
Definition calendar.cpp:573
KCal::Calendar::event
virtual Event * event(const QString &uid)=0
Returns the Event associated with the given unique identifier.
KCal::Calendar::incidences
virtual Incidence::List incidences()
Returns a filtered list of all Incidences for this Calendar.
Definition calendar.cpp:282
KCal::Calendar::todo
virtual Todo * todo(const QString &uid)=0
Returns the Todo associated with the given unique identifier.
KCal::Calendar::deleteEvent
virtual bool deleteEvent(Event *event)=0
Removes an Event from the calendar.
KCal::Calendar::incidencesFromSchedulingID
Incidence::List incidencesFromSchedulingID(const QString &sid)
Searches all events and todos for an incidence with this scheduling identifiere.
Definition calendar.cpp:685
KCal::Calendar::deleteTodo
virtual bool deleteTodo(Todo *todo)=0
Removes a Todo from the calendar.
KCal::Calendar::incidenceFromSchedulingID
Incidence * incidenceFromSchedulingID(const QString &sid)
Returns the Incidence associated with the given scheduling identifier.
Definition calendar.cpp:698
KCal::Calendar::incidence
Incidence * incidence(const QString &uid)
Returns the Incidence associated with the given unique identifier.
Definition calendar.cpp:669
KCal::Calendar::timeSpec
KDateTime::Spec timeSpec() const
Get the time specification (time zone etc.) used for creating or modifying incidences in the Calendar...
Definition calendar.cpp:145
KCal::ErrorFormat
Calendar format related error class.
Definition exceptions.h:83
KCal::ErrorFormat::NoWritableFound
@ NoWritableFound
No writable resource is available.
Definition exceptions.h:99
KCal::ErrorFormat::UserCancel
@ UserCancel
User canceled the operation.
Definition exceptions.h:98
KCal::Event
This class provides an Event in the sense of RFC2445.
Definition event.h:42
KCal::FreeBusyCache
An abstract base class to allow different implementations of storing free busy information,...
Definition freebusycache.h:45
KCal::FreeBusy
Provides information about the free/busy time of a calendar.
Definition freebusy.h:51
KCal::ICalFormat
iCalendar format implementation.
Definition icalformat.h:53
KCal::ICalFormat::toString
QString toString(Calendar *calendar)
Definition icalformat.cpp:229
KCal::ICalFormat::setTimeSpec
void setTimeSpec(const KDateTime::Spec &timeSpec)
Sets the iCalendar time specification (time zone, etc.).
Definition icalformat.cpp:578
KCal::IncidenceBase
An abstract class that provides a common base for all calendar incidence classes.
Definition incidencebase.h:103
KCal::IncidenceBase::type
virtual QByteArray type() const =0
Prints the type of Incidence as a string.
KCal::IncidenceBase::addComment
void addComment(const QString &comment)
Adds a comment to thieincidence.
Definition incidencebase.cpp:332
KCal::IncidenceBase::attendees
const Attendee::List & attendees() const
Returns a list of incidence attendees.
Definition incidencebase.cpp:378
KCal::IncidenceBase::uid
QString uid() const
Returns the unique id (uid) for the incidence.
Definition incidencebase.cpp:184
KCal::IncidenceBase::lastModified
KDateTime lastModified() const
Returns the time the incidence was last modified.
Definition incidencebase.cpp:203
KCal::IncidenceBase::setUid
void setUid(const QString &uid)
Returns the type of Incidence as a translated string.
Definition incidencebase.cpp:178
KCal::IncidenceBase::isReadOnly
bool isReadOnly() const
Returns true the object is read-only; false otherwise.
Definition incidencebase.h:318
KCal::Incidence
Provides the abstract base class common to non-FreeBusy (Events, To-dos, Journals) calendar component...
Definition incidence.h:70
KCal::Incidence::setSchedulingID
void setSchedulingID(const QString &sid)
Set the incidence scheduling ID.
Definition incidence.cpp:981
KCal::Incidence::revision
int revision() const
Returns the number of revisions this incidence has seen.
Definition incidence.cpp:344
KCal::ListBase
This class provides a template for lists of pointers.
Definition listbase.h:45
KCal::Person
Represents a person, by name ane email address.
Definition person.h:49
KCal::ScheduleMessage
A Scheduling message class.
Definition scheduler.h:59
KCal::ScheduleMessage::ScheduleMessage
ScheduleMessage(IncidenceBase *incidence, iTIPMethod method, Status status)
Creates a scheduling message with method as defined in iTIPMethod and a status.
Definition scheduler.cpp:55
KCal::ScheduleMessage::~ScheduleMessage
~ScheduleMessage()
Destructor.
Definition scheduler.cpp:65
KCal::ScheduleMessage::event
IncidenceBase * event()
Returns the event associated with this message.
Definition scheduler.cpp:70
KCal::ScheduleMessage::error
QString error()
Returns the error message if there is any.
Definition scheduler.cpp:107
KCal::ScheduleMessage::method
iTIPMethod method()
Returns the iTIP method associated with this message.
Definition scheduler.cpp:75
KCal::ScheduleMessage::status
Status status()
Returns the status of this message.
Definition scheduler.cpp:80
KCal::ScheduleMessage::Status
Status
Message status.
Definition scheduler.h:64
KCal::ScheduleMessage::RequestUpdate
@ RequestUpdate
Request updated message.
Definition scheduler.h:69
KCal::ScheduleMessage::PublishNew
@ PublishNew
New message posting.
Definition scheduler.h:65
KCal::ScheduleMessage::RequestNew
@ RequestNew
Request new message posting.
Definition scheduler.h:68
KCal::ScheduleMessage::PublishUpdate
@ PublishUpdate
Updated message.
Definition scheduler.h:66
KCal::ScheduleMessage::Obsolete
@ Obsolete
obsolete
Definition scheduler.h:67
KCal::ScheduleMessage::Unknown
@ Unknown
No status.
Definition scheduler.h:70
KCal::ScheduleMessage::statusName
static QString statusName(Status status)
Returns a human-readable name for an iTIP message status.
Definition scheduler.cpp:85
KCal::Scheduler
This class provides an encapsulation of iTIP transactions (RFC 2446).
Definition scheduler.h:121
KCal::Scheduler::freeBusyCache
FreeBusyCache * freeBusyCache() const
Returns the free/busy cache.
Definition scheduler.cpp:141
KCal::Scheduler::Scheduler
Scheduler(Calendar *calendar)
Creates a scheduler for calendar specified as argument.
Definition scheduler.cpp:123
KCal::Scheduler::acceptTransaction
bool KCAL_DEPRECATED acceptTransaction(IncidenceBase *incidence, iTIPMethod method, ScheduleMessage::Status status)
Definition scheduler.cpp:146
KCal::Scheduler::acceptRequest
bool KCAL_DEPRECATED acceptRequest(IncidenceBase *, ScheduleMessage::Status status)
Definition scheduler.cpp:282
KCal::Scheduler::methodName
static QString methodName(iTIPMethod method)
Returns a machine-readable name for a iTIP method.
Definition scheduler.cpp:184
KCal::Scheduler::freeBusyDir
virtual QString freeBusyDir()=0
Returns the directory where the free-busy information is stored.
KCal::Scheduler::setFreeBusyCache
void setFreeBusyCache(FreeBusyCache *)
Sets the free/busy cache used to store free/busy information.
Definition scheduler.cpp:136
KCal::Scheduler::performTransaction
virtual bool performTransaction(IncidenceBase *incidence, iTIPMethod method)=0
Performs iTIP transaction on incidence.
KCal::Scheduler::translatedMethodName
static QString translatedMethodName(iTIPMethod method)
Returns a translated human-readable name for a iTIP method.
Definition scheduler.cpp:208
KCal::Todo
Provides a To-do in the sense of RFC2445.
Definition todo.h:45
KCal::Todo::percentComplete
int percentComplete() const
Returns what percentage of the to-do is completed.
Definition todo.cpp:463
event.h
This file is part of the API for handling calendar data and defines the Event class.
freebusy.h
This file is part of the API for handling calendar data and defines the FreeBusy class.
freebusycache.h
This file is part of the API for handling calendar data and defines the FreeBusyCache abstract base c...
icalformat.h
This file is part of the API for handling calendar data and defines the ICalFormat class.
todo.h
This file is part of the API for handling calendar data and defines the Todo class.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Wed Jan 24 2024 00:00:00 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCal Library

Skip menu "KCal Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepimlibs-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal