23 #include "scheduler.h"
25 #ifndef KDEPIM_NO_KRESOURCES
33 #include "assignmentvisitor.h"
37 #include <kmessagebox.h>
38 #include <kstandarddirs.h>
43 class KCal::ScheduleMessage::Private
60 d->mIncidence = incidence;
89 return i18nc(
"@item this is a new scheduling message",
90 "New Scheduling Message" );
92 return i18nc(
"@item this is an update to an existing scheduling message",
93 "Updated Scheduling Message" );
95 return i18nc(
"@item obsolete status",
"Obsolete" );
97 return i18nc(
"@item this is a request for a new scheduling message",
98 "New Scheduling Message Request" );
100 return i18nc(
"@item this is a request for an update to an existing scheduling message",
101 "Updated Scheduling Message Request" );
103 return i18nc(
"@item unknown status",
"Unknown Status: %1",
int( status ) );
113 struct KCal::Scheduler::Private
116 : mFreeBusyCache( 0 )
125 mCalendar = calendar;
130 Scheduler::~Scheduler()
138 d->mFreeBusyCache = c;
143 return d->mFreeBusyCache;
156 const QString &email )
158 kDebug() <<
"method=" <<
methodName( method );
162 return acceptPublish( incidence, status, method );
166 return acceptAdd( incidence, status );
168 return acceptCancel( incidence, status, email );
170 return acceptDeclineCounter( incidence, status );
172 return acceptReply( incidence, status, method );
174 return acceptRefresh( incidence, status );
176 return acceptCounter( incidence, status );
180 deleteTransaction( incidence );
188 return QLatin1String(
"Publish" );
190 return QLatin1String(
"Request" );
192 return QLatin1String(
"Refresh" );
194 return QLatin1String(
"Cancel" );
196 return QLatin1String(
"Add" );
198 return QLatin1String(
"Reply" );
200 return QLatin1String(
"Counter" );
202 return QLatin1String(
"Decline Counter" );
204 return QLatin1String(
"Unknown" );
212 return i18nc(
"@item event, to-do, journal or freebusy posting",
"Publish" );
214 return i18nc(
"@item event, to-do or freebusy scheduling requests",
"Request" );
216 return i18nc(
"@item event, to-do or freebusy reply to request",
"Reply" );
219 "@item event, to-do or journal additional property request",
"Add" );
221 return i18nc(
"@item event, to-do or journal cancellation notice",
"Cancel" );
223 return i18nc(
"@item event or to-do description update request",
"Refresh" );
225 return i18nc(
"@item event or to-do submit counter proposal",
"Counter" );
227 return i18nc(
"@item event or to-do decline a counter proposal",
"Decline Counter" );
229 return i18nc(
"@item no method",
"Unknown" );
242 if( newIncBase->
type() ==
"FreeBusy" ) {
243 return acceptFreeBusy( newIncBase, method );
256 if ( calInc && newInc ) {
261 const QString oldUid = calInc->
uid();
262 if ( !visitor.
assign( calInc, newInc ) ) {
263 kError() <<
"assigning different incidence types";
278 deleteTransaction( newIncBase );
290 const QString &email )
296 if ( inc->
type() ==
"FreeBusy" ) {
303 <<
": found " << existingIncidences.count()
304 <<
" incidences with schedulingID " << inc->
schedulingID();
305 Incidence::List::ConstIterator incit = existingIncidences.begin();
306 for ( ; incit != existingIncidences.end() ; ++incit ) {
308 kDebug() <<
"Considering this found event ("
309 << ( i->
isReadOnly() ?
"readonly" :
"readwrite" )
317 bool isUpdate =
true;
323 kDebug() <<
"looking in " << i->
uid() <<
"'s attendees";
328 KCal::Attendee::List::ConstIterator ait;
329 for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
333 kDebug() <<
"ignoring " << i->
uid() <<
" since I'm still NeedsAction there";
342 kDebug() <<
"This isn't an update - the found incidence was modified more recently";
343 deleteTransaction( i );
346 kDebug() <<
"replacing existing incidence " << i->
uid();
349 const QString oldUid = i->
uid();
350 if ( !visitor.
assign( i, inc ) ) {
351 kError() <<
"assigning different incidence types";
357 deleteTransaction( incidence );
362 kDebug() <<
"This isn't an update - the found incidence has a bigger revision number";
363 deleteTransaction( incidence );
373 if ( existingIncidences.count() > 0 || inc->
revision() == 0 ||
374 KMessageBox::questionYesNo(
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();
388 #ifndef KDEPIM_NO_KRESOURCES
393 i18nc(
"@info",
"No calendars found, unable to save the invitation." ) );
407 bool success =
false;
408 #ifndef KDEPIM_NO_KRESOURCES
416 #ifndef KDEPIM_NO_KRESOURCES
423 KMessageBox::warningYesNo(
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(
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.",
440 deleteTransaction( incidence );
451 QString errMessage = i18nc(
"@info",
"Unable to save %1 \"%2\".",
453 KMessageBox::sorry( 0, errMessage );
458 deleteTransaction( incidence );
464 deleteTransaction( incidence );
470 const QString &attendee )
477 if ( inc->
type() ==
"FreeBusy" ) {
483 kDebug() <<
"Scheduler::acceptCancel="
485 <<
": found " << existingIncidences.count()
486 <<
" incidences with schedulingID " << inc->
schedulingID();
489 Incidence::List::ConstIterator incit = existingIncidences.begin();
490 for ( ; incit != existingIncidences.end() ; ++incit ) {
492 kDebug() <<
"Considering this found event ("
493 << ( i->
isReadOnly() ?
"readonly" :
"readwrite" )
507 kDebug() <<
"looking in " << i->
uid() <<
"'s attendees";
514 KCal::Attendee::List::ConstIterator ait;
515 for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
516 if ( (*ait)->email() == attendee &&
520 kDebug() <<
"ignoring " << i->
uid()
521 <<
" since I'm still NeedsAction there";
528 kDebug() <<
"removing existing incidence " << i->
uid();
529 if ( i->
type() ==
"Event" ) {
531 ret = (
event && mCalendar->
deleteEvent( event ) );
532 }
else if ( i->
type() ==
"Todo" ) {
534 ret = ( todo && mCalendar->
deleteTodo( todo ) );
536 deleteTransaction( incidence );
542 if ( existingIncidences.count() > 0 && inc->
revision() > 0 ) {
543 KMessageBox::information(
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." ) );
550 deleteTransaction( incidence );
563 if ( toDelete->
type() ==
"Event" ) {
565 ret = (
event && mCalendar->
deleteEvent( event ) );
566 }
else if ( toDelete->
type() ==
"Todo" ) {
568 ret = ( todo && mCalendar->
deleteTodo( todo ) );
580 KMessageBox::information(
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." ) );
587 deleteTransaction( incidence );
591 bool Scheduler::acceptDeclineCounter(
IncidenceBase *incidence,
595 deleteTransaction( incidence );
604 if ( incidence->
type() ==
"FreeBusy" ) {
605 return acceptFreeBusy( incidence, method );
614 for ( Incidence::List::ConstIterator it=list.constBegin(), end=list.constEnd();
616 if ( (*it)->schedulingID() == incidence->
uid() ) {
617 ev =
dynamic_cast<Event*
>( *it );
618 to =
dynamic_cast<Todo*
>( *it );
626 kDebug() <<
"match found!";
636 Attendee::List::ConstIterator inIt;
637 Attendee::List::ConstIterator evIt;
638 for ( inIt = attendeesIn.constBegin(); inIt != attendeesIn.constEnd(); ++inIt ) {
641 for ( evIt = attendeesEv.constBegin(); evIt != attendeesEv.constEnd(); ++evIt ) {
643 if ( attIn->
email().toLower() == attEv->
email().toLower() ) {
645 kDebug() <<
"update attendee";
654 attendeesNew.append( attIn );
658 bool attendeeAdded =
false;
659 for ( Attendee::List::ConstIterator it = attendeesNew.constBegin();
660 it != attendeesNew.constEnd(); ++it ) {
663 i18nc(
"@info",
"%1 wants to attend %2 but was not invited.",
667 msg = i18nc(
"@info",
"%1 wants to attend %2 on behalf of %3.",
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 ) {
679 "The organizer rejected your attendance at this meeting." ) );
698 attendeeAdded =
true;
702 if ( attendeeAdded ) {
703 bool sendMail =
false;
705 if ( KMessageBox::questionYesNo(
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 ) {
743 Todo *update =
dynamic_cast<Todo*
> ( incidence );
751 kError() <<
"No incidence for scheduling.";
755 deleteTransaction( incidence );
764 deleteTransaction( incidence );
771 deleteTransaction( incidence );
777 if ( !d->mFreeBusyCache ) {
778 kError() <<
"KCal::Scheduler: no FreeBusyCache.";
796 if ( !d->mFreeBusyCache->saveFreeBusy( freebusy, from ) ) {
800 deleteTransaction( incidence );