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