00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "scheduler.h"
00024 #include "calendar.h"
00025 #include "calendarresources.h"
00026 #include "event.h"
00027 #include "todo.h"
00028 #include "freebusy.h"
00029 #include "freebusycache.h"
00030 #include "icalformat.h"
00031 #include "assignmentvisitor.h"
00032
00033 #include <klocale.h>
00034 #include <kdebug.h>
00035 #include <kmessagebox.h>
00036 #include <kstandarddirs.h>
00037
00038 using namespace KCal;
00039
00040
00041 class KCal::ScheduleMessage::Private
00042 {
00043 public:
00044 Private() {}
00045
00046 IncidenceBase *mIncidence;
00047 iTIPMethod mMethod;
00048 Status mStatus;
00049 QString mError;
00050 };
00051
00052
00053 ScheduleMessage::ScheduleMessage( IncidenceBase *incidence,
00054 iTIPMethod method,
00055 ScheduleMessage::Status status )
00056 : d( new KCal::ScheduleMessage::Private )
00057 {
00058 d->mIncidence = incidence;
00059 d->mMethod = method;
00060 d->mStatus = status;
00061 }
00062
00063 ScheduleMessage::~ScheduleMessage()
00064 {
00065 delete d;
00066 }
00067
00068 IncidenceBase *ScheduleMessage::event()
00069 {
00070 return d->mIncidence;
00071 }
00072
00073 iTIPMethod ScheduleMessage::method()
00074 {
00075 return d->mMethod;
00076 }
00077
00078 ScheduleMessage::Status ScheduleMessage::status()
00079 {
00080 return d->mStatus;
00081 }
00082
00083 QString ScheduleMessage::statusName( ScheduleMessage::Status status )
00084 {
00085 switch( status ) {
00086 case PublishNew:
00087 return i18nc( "@item new message posting", "New Message Publish" );
00088 case PublishUpdate:
00089 return i18nc( "@item updated message", "Updated Message Published" );
00090 case Obsolete:
00091 return i18nc( "@item obsolete status", "Obsolete" );
00092 case RequestNew:
00093 return i18nc( "@item request new message posting", "Request New Message" );
00094 case RequestUpdate:
00095 return i18nc( "@item request updated posting", "Request Updated Message" );
00096 default:
00097 return i18nc( "@item unknown status", "Unknown Status: %1", int( status ) );
00098 }
00099 }
00100
00101 QString ScheduleMessage::error()
00102 {
00103 return d->mError;
00104 }
00105
00106
00107 struct KCal::Scheduler::Private
00108 {
00109 Private()
00110 : mFreeBusyCache( 0 )
00111 {
00112 }
00113 FreeBusyCache *mFreeBusyCache;
00114 };
00115
00116
00117 Scheduler::Scheduler( Calendar *calendar ) : d( new KCal::Scheduler::Private )
00118 {
00119 mCalendar = calendar;
00120 mFormat = new ICalFormat();
00121 mFormat->setTimeSpec( calendar->timeSpec() );
00122 }
00123
00124 Scheduler::~Scheduler()
00125 {
00126 delete mFormat;
00127 delete d;
00128 }
00129
00130 void Scheduler::setFreeBusyCache( FreeBusyCache *c )
00131 {
00132 d->mFreeBusyCache = c;
00133 }
00134
00135 FreeBusyCache *Scheduler::freeBusyCache() const
00136 {
00137 return d->mFreeBusyCache;
00138 }
00139
00140 bool Scheduler::acceptTransaction( IncidenceBase *incidence,
00141 iTIPMethod method,
00142 ScheduleMessage::Status status )
00143 {
00144 return acceptTransaction( incidence, method, status, QString() );
00145 }
00146
00147 bool Scheduler::acceptTransaction( IncidenceBase *incidence,
00148 iTIPMethod method,
00149 ScheduleMessage::Status status,
00150 const QString &email )
00151 {
00152 kDebug() << "method=" << methodName( method );
00153
00154 switch ( method ) {
00155 case iTIPPublish:
00156 return acceptPublish( incidence, status, method );
00157 case iTIPRequest:
00158 return acceptRequest( incidence, status, email );
00159 case iTIPAdd:
00160 return acceptAdd( incidence, status );
00161 case iTIPCancel:
00162 return acceptCancel( incidence, status, email );
00163 case iTIPDeclineCounter:
00164 return acceptDeclineCounter( incidence, status );
00165 case iTIPReply:
00166 return acceptReply( incidence, status, method );
00167 case iTIPRefresh:
00168 return acceptRefresh( incidence, status );
00169 case iTIPCounter:
00170 return acceptCounter( incidence, status );
00171 default:
00172 break;
00173 }
00174 deleteTransaction( incidence );
00175 return false;
00176 }
00177
00178 QString Scheduler::methodName( iTIPMethod method )
00179 {
00180 switch ( method ) {
00181 case iTIPPublish:
00182 return QLatin1String( "Publish" );
00183 case iTIPRequest:
00184 return QLatin1String( "Request" );
00185 case iTIPRefresh:
00186 return QLatin1String( "Refresh" );
00187 case iTIPCancel:
00188 return QLatin1String( "Cancel" );
00189 case iTIPAdd:
00190 return QLatin1String( "Add" );
00191 case iTIPReply:
00192 return QLatin1String( "Reply" );
00193 case iTIPCounter:
00194 return QLatin1String( "Counter" );
00195 case iTIPDeclineCounter:
00196 return QLatin1String( "Decline Counter" );
00197 default:
00198 return QLatin1String( "Unknown" );
00199 }
00200 }
00201
00202 QString Scheduler::translatedMethodName( iTIPMethod method )
00203 {
00204 switch ( method ) {
00205 case iTIPPublish:
00206 return i18nc( "@item event, to-do, journal or freebusy posting", "Publish" );
00207 case iTIPRequest:
00208 return i18nc( "@item event, to-do or freebusy scheduling requests", "Request" );
00209 case iTIPReply:
00210 return i18nc( "@item event, to-do or freebusy reply to request", "Reply" );
00211 case iTIPAdd:
00212 return i18nc(
00213 "@item event, to-do or journal additional property request", "Add" );
00214 case iTIPCancel:
00215 return i18nc( "@item event, to-do or journal cancellation notice", "Cancel" );
00216 case iTIPRefresh:
00217 return i18nc( "@item event or to-do description update request", "Refresh" );
00218 case iTIPCounter:
00219 return i18nc( "@item event or to-do submit counter proposal", "Counter" );
00220 case iTIPDeclineCounter:
00221 return i18nc( "@item event or to-do decline a counter proposal", "Decline Counter" );
00222 default:
00223 return i18nc( "@item no method", "Unknown" );
00224 }
00225 }
00226
00227 bool Scheduler::deleteTransaction( IncidenceBase * )
00228 {
00229 return true;
00230 }
00231
00232 bool Scheduler::acceptPublish( IncidenceBase *newIncBase,
00233 ScheduleMessage::Status status,
00234 iTIPMethod method )
00235 {
00236 if( newIncBase->type() == "FreeBusy" ) {
00237 return acceptFreeBusy( newIncBase, method );
00238 }
00239
00240 bool res = false;
00241
00242 kDebug() << "status=" << ScheduleMessage::statusName( status );
00243
00244 Incidence *newInc = static_cast<Incidence *>( newIncBase );
00245 Incidence *calInc = mCalendar->incidence( newIncBase->uid() );
00246 switch ( status ) {
00247 case ScheduleMessage::Unknown:
00248 case ScheduleMessage::PublishNew:
00249 case ScheduleMessage::PublishUpdate:
00250 if ( calInc && newInc ) {
00251 if ( ( newInc->revision() > calInc->revision() ) ||
00252 ( newInc->revision() == calInc->revision() &&
00253 newInc->lastModified() > calInc->lastModified() ) ) {
00254 AssignmentVisitor visitor;
00255 const QString oldUid = calInc->uid();
00256 if ( !visitor.assign( calInc, newInc ) ) {
00257 kError() << "assigning different incidence types";
00258 } else {
00259 calInc->setUid( oldUid );
00260 calInc->setSchedulingID( newInc->uid() );
00261 res = true;
00262 }
00263 }
00264 }
00265 break;
00266 case ScheduleMessage::Obsolete:
00267 res = true;
00268 break;
00269 default:
00270 break;
00271 }
00272 deleteTransaction( newIncBase );
00273 return res;
00274 }
00275
00276 bool Scheduler::acceptRequest( IncidenceBase *incidence,
00277 ScheduleMessage::Status status )
00278 {
00279 return acceptRequest( incidence, status, QString() );
00280 }
00281
00282 bool Scheduler::acceptRequest( IncidenceBase *incidence,
00283 ScheduleMessage::Status status,
00284 const QString &email )
00285 {
00286 Incidence *inc = static_cast<Incidence *>( incidence );
00287 if ( !inc ) {
00288 return false;
00289 }
00290 if ( inc->type() == "FreeBusy" ) {
00291
00292 return true;
00293 }
00294
00295 const Incidence::List existingIncidences = mCalendar->incidencesFromSchedulingID( inc->uid() );
00296 kDebug() << "status=" << ScheduleMessage::statusName( status )
00297 << ": found " << existingIncidences.count()
00298 << " incidences with schedulingID " << inc->schedulingID();
00299 Incidence::List::ConstIterator incit = existingIncidences.begin();
00300 for ( ; incit != existingIncidences.end() ; ++incit ) {
00301 Incidence *i = *incit;
00302 kDebug() << "Considering this found event ("
00303 << ( i->isReadOnly() ? "readonly" : "readwrite" )
00304 << ") :" << mFormat->toString( i );
00305
00306 if ( i->isReadOnly() ) {
00307 continue;
00308 }
00309 if ( i->revision() <= inc->revision() ) {
00310
00311 bool isUpdate = true;
00312
00313
00314
00315
00316
00317 kDebug() << "looking in " << i->uid() << "'s attendees";
00318
00319
00320
00321 const KCal::Attendee::List attendees = i->attendees();
00322 KCal::Attendee::List::ConstIterator ait;
00323 for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
00324 if( (*ait)->email() == email && (*ait)->status() == Attendee::NeedsAction ) {
00325
00326
00327 kDebug() << "ignoring " << i->uid() << " since I'm still NeedsAction there";
00328 isUpdate = false;
00329 break;
00330 }
00331 }
00332 if ( isUpdate ) {
00333 if ( i->revision() == inc->revision() &&
00334 i->lastModified() > inc->lastModified() ) {
00335
00336 kDebug() << "This isn't an update - the found incidence was modified more recently";
00337 deleteTransaction( i );
00338 return false;
00339 }
00340 kDebug() << "replacing existing incidence " << i->uid();
00341 bool res = true;
00342 AssignmentVisitor visitor;
00343 const QString oldUid = i->uid();
00344 if ( !visitor.assign( i, inc ) ) {
00345 kError() << "assigning different incidence types";
00346 res = false;
00347 } else {
00348 i->setUid( oldUid );
00349 i->setSchedulingID( inc->uid() );
00350 }
00351 deleteTransaction( incidence );
00352 return res;
00353 }
00354 } else {
00355
00356 kDebug() << "This isn't an update - the found incidence has a bigger revision number";
00357 deleteTransaction( incidence );
00358 return false;
00359 }
00360 }
00361
00362
00363 inc->setSchedulingID( inc->uid() );
00364 inc->setUid( CalFormat::createUniqueId() );
00365
00366
00367 if ( existingIncidences.count() > 0 || inc->revision() == 0 ||
00368 KMessageBox::questionYesNo(
00369 0,
00370 i18nc( "@info",
00371 "The event, to-do or journal to be updated could not be found. "
00372 "Maybe it has already been deleted, or the calendar that "
00373 "contains it is disabled. Press 'Store' to create a new "
00374 "one or 'Throw away' to discard this update." ),
00375 i18nc( "@title", "Discard this update?" ),
00376 KGuiItem( i18nc( "@option", "Store" ) ),
00377 KGuiItem( i18nc( "@option", "Throw away" ) ),
00378 "AcceptCantFindIncidence" ) == KMessageBox::Yes ) {
00379 kDebug() << "Storing new incidence with scheduling uid=" << inc->schedulingID()
00380 << " and uid=" << inc->uid();
00381
00382 #ifndef KDEPIM_NO_KRESOURCES
00383 CalendarResources *stdcal = dynamic_cast<CalendarResources *>( mCalendar );
00384 if( stdcal && !stdcal->hasCalendarResources() ) {
00385 KMessageBox::sorry(
00386 0,
00387 i18nc( "@info", "No calendars found, unable to save the invitation." ) );
00388 return false;
00389 }
00390
00391
00392
00393
00394
00395 QWidget *tmpparent = 0;
00396 if ( stdcal ) {
00397 tmpparent = stdcal->dialogParentWidget();
00398 stdcal->setDialogParentWidget( 0 );
00399 }
00400 #endif
00401
00402 TryAgain:
00403 bool success = false;
00404 #ifndef KDEPIM_NO_KRESOURCES
00405 if ( stdcal )
00406 success = stdcal->addIncidence( inc );
00407 else
00408 #endif
00409 success = mCalendar->addIncidence( inc );
00410
00411 if ( !success ) {
00412 #ifndef KDEPIM_NO_KRESOURCES
00413 ErrorFormat *e = stdcal ? stdcal->exception() : 0;
00414 #else
00415 ErrorFormat *e = 0;
00416 #endif
00417
00418 if ( e && e->errorCode() == KCal::ErrorFormat::UserCancel &&
00419 KMessageBox::warningYesNo(
00420 0,
00421 i18nc( "@info",
00422 "You canceled the save operation. Therefore, the appointment will not be "
00423 "stored in your calendar even though you accepted the invitation. "
00424 "Are you certain you want to discard this invitation? " ),
00425 i18nc( "@title", "Discard this invitation?" ),
00426 KGuiItem( i18nc( "@option", "Discard" ) ),
00427 KGuiItem( i18nc( "@option", "Go Back to Folder Selection" ) ) ) == KMessageBox::Yes ) {
00428 KMessageBox::information(
00429 0,
00430 i18nc( "@info",
00431 "The invitation \"%1\" was not saved to your calendar "
00432 "but you are still listed as an attendee for that appointment.\n"
00433 "If you mistakenly accepted the invitation or do not plan to attend, please "
00434 "notify the organizer %2 and ask them to remove you from the attendee list.",
00435 inc->summary(), inc->organizer().fullName() ) );
00436 deleteTransaction( incidence );
00437 return true;
00438 } else {
00439 goto TryAgain;
00440 }
00441
00442
00443
00444 if ( !e ||
00445 ( e && ( e->errorCode() != KCal::ErrorFormat::UserCancel &&
00446 e->errorCode() != KCal::ErrorFormat::NoWritableFound ) ) ) {
00447 QString errMessage = i18nc( "@info", "Unable to save %1 \"%2\".",
00448 i18n( inc->type() ), inc->summary() );
00449 KMessageBox::sorry( 0, errMessage );
00450 }
00451 return false;
00452 }
00453 }
00454 deleteTransaction( incidence );
00455 return true;
00456 }
00457
00458 bool Scheduler::acceptAdd( IncidenceBase *incidence, ScheduleMessage::Status )
00459 {
00460 deleteTransaction( incidence );
00461 return false;
00462 }
00463
00464 bool Scheduler::acceptCancel( IncidenceBase *incidence,
00465 ScheduleMessage::Status status,
00466 const QString &attendee )
00467 {
00468 Incidence *inc = static_cast<Incidence *>( incidence );
00469 if ( !inc ) {
00470 return false;
00471 }
00472
00473 if ( inc->type() == "FreeBusy" ) {
00474
00475 return true;
00476 }
00477
00478 const Incidence::List existingIncidences = mCalendar->incidencesFromSchedulingID( inc->uid() );
00479 kDebug() << "Scheduler::acceptCancel="
00480 << ScheduleMessage::statusName( status )
00481 << ": found " << existingIncidences.count()
00482 << " incidences with schedulingID " << inc->schedulingID();
00483
00484 bool ret = false;
00485 Incidence::List::ConstIterator incit = existingIncidences.begin();
00486 for ( ; incit != existingIncidences.end() ; ++incit ) {
00487 Incidence *i = *incit;
00488 kDebug() << "Considering this found event ("
00489 << ( i->isReadOnly() ? "readonly" : "readwrite" )
00490 << ") :" << mFormat->toString( i );
00491
00492
00493 if ( i->isReadOnly() ) {
00494 continue;
00495 }
00496
00497
00498
00499
00500
00501
00502
00503 kDebug() << "looking in " << i->uid() << "'s attendees";
00504
00505
00506
00507
00508 bool isMine = true;
00509 const KCal::Attendee::List attendees = i->attendees();
00510 KCal::Attendee::List::ConstIterator ait;
00511 for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
00512 if ( (*ait)->email() == attendee &&
00513 (*ait)->status() == Attendee::NeedsAction ) {
00514
00515
00516 kDebug() << "ignoring " << i->uid()
00517 << " since I'm still NeedsAction there";
00518 isMine = false;
00519 break;
00520 }
00521 }
00522
00523 if ( isMine ) {
00524 kDebug() << "removing existing incidence " << i->uid();
00525 if ( i->type() == "Event" ) {
00526 Event *event = mCalendar->event( i->uid() );
00527 ret = ( event && mCalendar->deleteEvent( event ) );
00528 } else if ( i->type() == "Todo" ) {
00529 Todo *todo = mCalendar->todo( i->uid() );
00530 ret = ( todo && mCalendar->deleteTodo( todo ) );
00531 }
00532 deleteTransaction( incidence );
00533 return ret;
00534 }
00535 }
00536
00537
00538 if ( existingIncidences.count() > 0 && inc->revision() > 0 ) {
00539 KMessageBox::information(
00540 0,
00541 i18nc( "@info",
00542 "The event or task could not be removed from your calendar. "
00543 "Maybe it has already been deleted or is not owned by you. "
00544 "Or it might belong to a read-only or disabled calendar." ) );
00545 }
00546 deleteTransaction( incidence );
00547 return ret;
00548 }
00549
00550 bool Scheduler::acceptCancel( IncidenceBase *incidence,
00551 ScheduleMessage::Status status )
00552 {
00553 Q_UNUSED( status );
00554
00555 const IncidenceBase *toDelete = mCalendar->incidenceFromSchedulingID( incidence->uid() );
00556
00557 bool ret = true;
00558 if ( toDelete ) {
00559 if ( toDelete->type() == "Event" ) {
00560 Event *event = mCalendar->event( toDelete->uid() );
00561 ret = ( event && mCalendar->deleteEvent( event ) );
00562 } else if ( toDelete->type() == "Todo" ) {
00563 Todo *todo = mCalendar->todo( toDelete->uid() );
00564 ret = ( todo && mCalendar->deleteTodo( todo ) );
00565 }
00566 } else {
00567
00568
00569 Incidence *inc = static_cast<Incidence *>( incidence );
00570 if ( inc->revision() > 0 ) {
00571 ret = false;
00572 }
00573 }
00574
00575 if ( !ret ) {
00576 KMessageBox::information(
00577 0,
00578 i18nc( "@info",
00579 "The event or task to be canceled could not be removed from your calendar. "
00580 "Maybe it has already been deleted or is not owned by you. "
00581 "Or it might belong to a read-only or disabled calendar." ) );
00582 }
00583 deleteTransaction( incidence );
00584 return ret;
00585 }
00586
00587 bool Scheduler::acceptDeclineCounter( IncidenceBase *incidence,
00588 ScheduleMessage::Status status )
00589 {
00590 Q_UNUSED( status );
00591 deleteTransaction( incidence );
00592 return false;
00593 }
00594
00595 bool Scheduler::acceptReply( IncidenceBase *incidence,
00596 ScheduleMessage::Status status,
00597 iTIPMethod method )
00598 {
00599 Q_UNUSED( status );
00600 if ( incidence->type() == "FreeBusy" ) {
00601 return acceptFreeBusy( incidence, method );
00602 }
00603 bool ret = false;
00604 Event *ev = mCalendar->event( incidence->uid() );
00605 Todo *to = mCalendar->todo( incidence->uid() );
00606
00607
00608 if ( !ev && !to ) {
00609 const Incidence::List list = mCalendar->incidences();
00610 for ( Incidence::List::ConstIterator it=list.constBegin(), end=list.constEnd();
00611 it != end; ++it ) {
00612 if ( (*it)->schedulingID() == incidence->uid() ) {
00613 ev = dynamic_cast<Event*>( *it );
00614 to = dynamic_cast<Todo*>( *it );
00615 break;
00616 }
00617 }
00618 }
00619
00620 if ( ev || to ) {
00621
00622 kDebug() << "match found!";
00623 Attendee::List attendeesIn = incidence->attendees();
00624 Attendee::List attendeesEv;
00625 Attendee::List attendeesNew;
00626 if ( ev ) {
00627 attendeesEv = ev->attendees();
00628 }
00629 if ( to ) {
00630 attendeesEv = to->attendees();
00631 }
00632 Attendee::List::ConstIterator inIt;
00633 Attendee::List::ConstIterator evIt;
00634 for ( inIt = attendeesIn.constBegin(); inIt != attendeesIn.constEnd(); ++inIt ) {
00635 Attendee *attIn = *inIt;
00636 bool found = false;
00637 for ( evIt = attendeesEv.constBegin(); evIt != attendeesEv.constEnd(); ++evIt ) {
00638 Attendee *attEv = *evIt;
00639 if ( attIn->email().toLower() == attEv->email().toLower() ) {
00640
00641 kDebug() << "update attendee";
00642 attEv->setStatus( attIn->status() );
00643 attEv->setDelegate( attIn->delegate() );
00644 attEv->setDelegator( attIn->delegator() );
00645 ret = true;
00646 found = true;
00647 }
00648 }
00649 if ( !found && attIn->status() != Attendee::Declined ) {
00650 attendeesNew.append( attIn );
00651 }
00652 }
00653
00654 bool attendeeAdded = false;
00655 for ( Attendee::List::ConstIterator it = attendeesNew.constBegin();
00656 it != attendeesNew.constEnd(); ++it ) {
00657 Attendee *attNew = *it;
00658 QString msg =
00659 i18nc( "@info", "%1 wants to attend %2 but was not invited.",
00660 attNew->fullName(),
00661 ( ev ? ev->summary() : to->summary() ) );
00662 if ( !attNew->delegator().isEmpty() ) {
00663 msg = i18nc( "@info", "%1 wants to attend %2 on behalf of %3.",
00664 attNew->fullName(),
00665 ( ev ? ev->summary() : to->summary() ), attNew->delegator() );
00666 }
00667 if ( KMessageBox::questionYesNo(
00668 0, msg, i18nc( "@title", "Uninvited attendee" ),
00669 KGuiItem( i18nc( "@option", "Accept Attendance" ) ),
00670 KGuiItem( i18nc( "@option", "Reject Attendance" ) ) ) != KMessageBox::Yes ) {
00671 KCal::Incidence *cancel = dynamic_cast<Incidence*>( incidence );
00672 if ( cancel ) {
00673 cancel->addComment(
00674 i18nc( "@info",
00675 "The organizer rejected your attendance at this meeting." ) );
00676 }
00677 performTransaction( cancel ? cancel : incidence, iTIPCancel, attNew->fullName() );
00678
00679
00680
00681 continue;
00682 }
00683
00684 Attendee *a = new Attendee( attNew->name(), attNew->email(), attNew->RSVP(),
00685 attNew->status(), attNew->role(), attNew->uid() );
00686 a->setDelegate( attNew->delegate() );
00687 a->setDelegator( attNew->delegator() );
00688 if ( ev ) {
00689 ev->addAttendee( a );
00690 } else if ( to ) {
00691 to->addAttendee( a );
00692 }
00693 ret = true;
00694 attendeeAdded = true;
00695 }
00696
00697
00698 if ( attendeeAdded ) {
00699 bool sendMail = false;
00700 if ( ev || to ) {
00701 if ( KMessageBox::questionYesNo(
00702 0,
00703 i18nc( "@info",
00704 "An attendee was added to the incidence. "
00705 "Do you want to email the attendees an update message?" ),
00706 i18nc( "@title", "Attendee Added" ),
00707 KGuiItem( i18nc( "@option", "Send Messages" ) ),
00708 KGuiItem( i18nc( "@option", "Do Not Send" ) ) ) == KMessageBox::Yes ) {
00709 sendMail = true;
00710 }
00711 }
00712
00713 if ( ev ) {
00714 ev->setRevision( ev->revision() + 1 );
00715 if ( sendMail ) {
00716 performTransaction( ev, iTIPRequest );
00717 }
00718 }
00719 if ( to ) {
00720 to->setRevision( to->revision() + 1 );
00721 if ( sendMail ) {
00722 performTransaction( to, iTIPRequest );
00723 }
00724 }
00725 }
00726
00727 if ( ret ) {
00728
00729
00730 if ( ev ) {
00731 ev->updated();
00732 } else if ( to ) {
00733 to->updated();
00734 }
00735 }
00736 if ( to ) {
00737
00738
00739 Todo *update = dynamic_cast<Todo*> ( incidence );
00740 Q_ASSERT( update );
00741 if ( update && ( to->percentComplete() != update->percentComplete() ) ) {
00742 to->setPercentComplete( update->percentComplete() );
00743 to->updated();
00744 }
00745 }
00746 } else {
00747 kError() << "No incidence for scheduling.";
00748 }
00749
00750 if ( ret ) {
00751 deleteTransaction( incidence );
00752 }
00753 return ret;
00754 }
00755
00756 bool Scheduler::acceptRefresh( IncidenceBase *incidence, ScheduleMessage::Status status )
00757 {
00758 Q_UNUSED( status );
00759
00760 deleteTransaction( incidence );
00761 return false;
00762 }
00763
00764 bool Scheduler::acceptCounter( IncidenceBase *incidence, ScheduleMessage::Status status )
00765 {
00766 Q_UNUSED( status );
00767 deleteTransaction( incidence );
00768 return false;
00769 }
00770
00771 bool Scheduler::acceptFreeBusy( IncidenceBase *incidence, iTIPMethod method )
00772 {
00773 if ( !d->mFreeBusyCache ) {
00774 kError() << "KCal::Scheduler: no FreeBusyCache.";
00775 return false;
00776 }
00777
00778 FreeBusy *freebusy = static_cast<FreeBusy *>(incidence);
00779
00780 kDebug() << "freeBusyDirName:" << freeBusyDir();
00781
00782 Person from;
00783 if( method == iTIPPublish ) {
00784 from = freebusy->organizer();
00785 }
00786 if ( ( method == iTIPReply ) && ( freebusy->attendeeCount() == 1 ) ) {
00787 Attendee *attendee = freebusy->attendees().first();
00788 from.setName( attendee->name() );
00789 from.setEmail( attendee->email() );
00790 }
00791
00792 if ( !d->mFreeBusyCache->saveFreeBusy( freebusy, from ) ) {
00793 return false;
00794 }
00795
00796 deleteTransaction( incidence );
00797 return true;
00798 }