• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDE-PIM Libraries
  • Sitemap
  • Contact Us
 

KCal Library

scheduler.cpp

00001 /*
00002   This file is part of the kcal library.
00003 
00004   Copyright (c) 2001,2004 Cornelius Schumacher <schumacher@kde.org>
00005   Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00006 
00007   This library is free software; you can redistribute it and/or
00008   modify it under the terms of the GNU Library General Public
00009   License as published by the Free Software Foundation; either
00010   version 2 of the License, or (at your option) any later version.
00011 
00012   This library is distributed in the hope that it will be useful,
00013   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015   Library General Public License for more details.
00016 
00017   You should have received a copy of the GNU Library General Public License
00018   along with this library; see the file COPYING.LIB.  If not, write to
00019   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020   Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "scheduler.h"
00024 #include "calendar.h"
00025 #include "event.h"
00026 #include "todo.h"
00027 #include "freebusy.h"
00028 #include "freebusycache.h"
00029 #include "icalformat.h"
00030 #include "assignmentvisitor.h"
00031 
00032 #include <klocale.h>
00033 #include <kdebug.h>
00034 #include <kmessagebox.h>
00035 #include <kstandarddirs.h>
00036 
00037 using namespace KCal;
00038 
00039 //@cond PRIVATE
00040 class KCal::ScheduleMessage::Private
00041 {
00042   public:
00043     Private() {}
00044 
00045     IncidenceBase *mIncidence;
00046     iTIPMethod mMethod;
00047     Status mStatus;
00048     QString mError;
00049 };
00050 //@endcond
00051 
00052 ScheduleMessage::ScheduleMessage( IncidenceBase *incidence,
00053                                   iTIPMethod method,
00054                                   ScheduleMessage::Status status )
00055   : d( new KCal::ScheduleMessage::Private )
00056 {
00057   d->mIncidence = incidence;
00058   d->mMethod = method;
00059   d->mStatus = status;
00060 }
00061 
00062 ScheduleMessage::~ScheduleMessage()
00063 {
00064   delete d;
00065 }
00066 
00067 IncidenceBase *ScheduleMessage::event()
00068 {
00069   return d->mIncidence;
00070 }
00071 
00072 iTIPMethod ScheduleMessage::method()
00073 {
00074   return d->mMethod;
00075 }
00076 
00077 ScheduleMessage::Status ScheduleMessage::status()
00078 {
00079   return d->mStatus;
00080 }
00081 
00082 QString ScheduleMessage::statusName( ScheduleMessage::Status status )
00083 {
00084   switch( status ) {
00085   case PublishNew:
00086     return i18nc( "@item new message posting", "New Message Publish" );
00087   case PublishUpdate:
00088     return i18nc( "@item updated message", "Updated Message Published" );
00089   case Obsolete:
00090     return i18nc( "@item obsolete status", "Obsolete" );
00091   case RequestNew:
00092     return i18nc( "@item request new message posting", "Request New Message" );
00093   case RequestUpdate:
00094     return i18nc( "@item request updated posting", "Request Updated Message" );
00095   default:
00096     return i18nc( "@item unknown status", "Unknown Status: %1", int( status ) );
00097   }
00098 }
00099 
00100 QString ScheduleMessage::error()
00101 {
00102   return d->mError;
00103 }
00104 
00105 //@cond PRIVATE
00106 struct KCal::Scheduler::Private
00107 {
00108   Private()
00109     : mFreeBusyCache( 0 )
00110     {
00111     }
00112     FreeBusyCache *mFreeBusyCache;
00113 };
00114 //@endcond
00115 
00116 Scheduler::Scheduler( Calendar *calendar ) : d( new KCal::Scheduler::Private )
00117 {
00118   mCalendar = calendar;
00119   mFormat = new ICalFormat();
00120   mFormat->setTimeSpec( calendar->timeSpec() );
00121 }
00122 
00123 Scheduler::~Scheduler()
00124 {
00125   delete mFormat;
00126   delete d;
00127 }
00128 
00129 void Scheduler::setFreeBusyCache( FreeBusyCache *c )
00130 {
00131   d->mFreeBusyCache = c;
00132 }
00133 
00134 FreeBusyCache *Scheduler::freeBusyCache() const
00135 {
00136   return d->mFreeBusyCache;
00137 }
00138 
00139 bool Scheduler::acceptTransaction( IncidenceBase *incidence,
00140                                    iTIPMethod method,
00141                                    ScheduleMessage::Status status )
00142 {
00143   return acceptTransaction( incidence, method, status, QString() );
00144 }
00145 
00146 bool Scheduler::acceptTransaction( IncidenceBase *incidence,
00147                                    iTIPMethod method,
00148                                    ScheduleMessage::Status status,
00149                                    const QString &email )
00150 {
00151   kDebug() << "method=" << methodName( method );
00152 
00153   switch ( method ) {
00154   case iTIPPublish:
00155     return acceptPublish( incidence, status, method );
00156   case iTIPRequest:
00157     return acceptRequest( incidence, status, email );
00158   case iTIPAdd:
00159     return acceptAdd( incidence, status );
00160   case iTIPCancel:
00161     return acceptCancel( incidence, status, email );
00162   case iTIPDeclineCounter:
00163     return acceptDeclineCounter( incidence, status );
00164   case iTIPReply:
00165     return acceptReply( incidence, status, method );
00166   case iTIPRefresh:
00167     return acceptRefresh( incidence, status );
00168   case iTIPCounter:
00169     return acceptCounter( incidence, status );
00170   default:
00171     break;
00172   }
00173   deleteTransaction( incidence );
00174   return false;
00175 }
00176 
00177 QString Scheduler::methodName( iTIPMethod method )
00178 {
00179   switch ( method ) {
00180   case iTIPPublish:
00181     return QLatin1String( "Publish" );
00182   case iTIPRequest:
00183     return QLatin1String( "Request" );
00184   case iTIPRefresh:
00185     return QLatin1String( "Refresh" );
00186   case iTIPCancel:
00187     return QLatin1String( "Cancel" );
00188   case iTIPAdd:
00189     return QLatin1String( "Add" );
00190   case iTIPReply:
00191     return QLatin1String( "Reply" );
00192   case iTIPCounter:
00193     return QLatin1String( "Counter" );
00194   case iTIPDeclineCounter:
00195     return QLatin1String( "Decline Counter" );
00196   default:
00197     return QLatin1String( "Unknown" );
00198   }
00199 }
00200 
00201 QString Scheduler::translatedMethodName( iTIPMethod method )
00202 {
00203   switch ( method ) {
00204   case iTIPPublish:
00205     return i18nc( "@item event, to-do, journal or freebusy posting", "Publish" );
00206   case iTIPRequest:
00207     return i18nc( "@item event, to-do or freebusy scheduling requests", "Request" );
00208   case iTIPReply:
00209     return i18nc( "@item event, to-do or freebusy reply to request", "Reply" );
00210   case iTIPAdd:
00211     return i18nc(
00212       "@item event, to-do or journal additional property request", "Add" );
00213   case iTIPCancel:
00214     return i18nc( "@item event, to-do or journal cancellation notice", "Cancel" );
00215   case iTIPRefresh:
00216     return i18nc( "@item event or to-do description update request", "Refresh" );
00217   case iTIPCounter:
00218     return i18nc( "@item event or to-do submit counter proposal", "Counter" );
00219   case iTIPDeclineCounter:
00220     return i18nc( "@item event or to-do decline a counter proposal", "Decline Counter" );
00221   default:
00222     return i18nc( "@item no method", "Unknown" );
00223   }
00224 }
00225 
00226 bool Scheduler::deleteTransaction( IncidenceBase * )
00227 {
00228   return true;
00229 }
00230 
00231 bool Scheduler::acceptPublish( IncidenceBase *newIncBase,
00232                                ScheduleMessage::Status status,
00233                                iTIPMethod method )
00234 {
00235   if( newIncBase->type() == "FreeBusy" ) {
00236     return acceptFreeBusy( newIncBase, method );
00237   }
00238 
00239   bool res = false;
00240 
00241   kDebug() << "status=" << ScheduleMessage::statusName( status );
00242 
00243   Incidence *newInc = static_cast<Incidence *>( newIncBase );
00244   Incidence *calInc = mCalendar->incidence( newIncBase->uid() );
00245   switch ( status ) {
00246     case ScheduleMessage::Unknown:
00247     case ScheduleMessage::PublishNew:
00248     case ScheduleMessage::PublishUpdate:
00249       if ( calInc && newInc ) {
00250         if ( ( newInc->revision() > calInc->revision() ) ||
00251              ( newInc->revision() == calInc->revision() &&
00252                newInc->lastModified() > calInc->lastModified() ) ) {
00253           AssignmentVisitor visitor;
00254           const QString oldUid = calInc->uid();
00255           if ( !visitor.assign( calInc, newInc ) ) {
00256             kError() << "assigning different incidence types";
00257           } else {
00258             calInc->setUid( oldUid );
00259             calInc->setSchedulingID( newInc->uid() );
00260             res = true;
00261           }
00262         }
00263       }
00264       break;
00265     case ScheduleMessage::Obsolete:
00266       res = true;
00267       break;
00268     default:
00269       break;
00270   }
00271   deleteTransaction( newIncBase );
00272   return res;
00273 }
00274 
00275 bool Scheduler::acceptRequest( IncidenceBase *incidence,
00276                                ScheduleMessage::Status status )
00277 {
00278   return acceptRequest( incidence, status, QString() );
00279 }
00280 
00281 bool Scheduler::acceptRequest( IncidenceBase *incidence,
00282                                ScheduleMessage::Status status,
00283                                const QString &email )
00284 {
00285   Incidence *inc = static_cast<Incidence *>( incidence );
00286   if ( !inc ) {
00287     return false;
00288   }
00289   if ( inc->type() == "FreeBusy" ) {
00290     // reply to this request is handled in korganizer's incomingdialog
00291     return true;
00292   }
00293 
00294   const Incidence::List existingIncidences = mCalendar->incidencesFromSchedulingID( inc->uid() );
00295   kDebug() << "status=" << ScheduleMessage::statusName( status )
00296            << ": found " << existingIncidences.count()
00297            << " incidences with schedulingID " << inc->schedulingID();
00298   Incidence::List::ConstIterator incit = existingIncidences.begin();
00299   for ( ; incit != existingIncidences.end() ; ++incit ) {
00300     Incidence *i = *incit;
00301     kDebug() << "Considering this found event ("
00302              << ( i->isReadOnly() ? "readonly" : "readwrite" )
00303              << ") :" << mFormat->toString( i );
00304     // If it's readonly, we can't possible update it.
00305     if ( i->isReadOnly() ) {
00306       continue;
00307     }
00308     if ( i->revision() <= inc->revision() ) {
00309       // The new incidence might be an update for the found one
00310       bool isUpdate = true;
00311       // Code for new invitations:
00312       // If you think we could check the value of "status" to be RequestNew:  we can't.
00313       // It comes from a similar check inside libical, where the event is compared to
00314       // other events in the calendar. But if we have another version of the event around
00315       // (e.g. shared folder for a group), the status could be RequestNew, Obsolete or Updated.
00316       kDebug() << "looking in " << i->uid() << "'s attendees";
00317       // This is supposed to be a new request, not an update - however we want to update
00318       // the existing one to handle the "clicking more than once on the invitation" case.
00319       // So check the attendee status of the attendee.
00320       const KCal::Attendee::List attendees = i->attendees();
00321       KCal::Attendee::List::ConstIterator ait;
00322       for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
00323         if( (*ait)->email() == email && (*ait)->status() == Attendee::NeedsAction ) {
00324           // This incidence wasn't created by me - it's probably in a shared folder
00325           // and meant for someone else, ignore it.
00326           kDebug() << "ignoring " << i->uid() << " since I'm still NeedsAction there";
00327           isUpdate = false;
00328           break;
00329         }
00330       }
00331       if ( isUpdate ) {
00332         if ( i->revision() == inc->revision() &&
00333              i->lastModified() > inc->lastModified() ) {
00334           // This isn't an update - the found incidence was modified more recently
00335           kDebug() << "This isn't an update - the found incidence was modified more recently";
00336           deleteTransaction( i );
00337           return false;
00338         }
00339         kDebug() << "replacing existing incidence " << i->uid();
00340         bool res = true;
00341         AssignmentVisitor visitor;
00342         const QString oldUid = i->uid();
00343         if ( !visitor.assign( i, inc ) ) {
00344           kError() << "assigning different incidence types";
00345           res = false;
00346         } else {
00347           i->setUid( oldUid );
00348           i->setSchedulingID( inc->uid() );
00349         }
00350         deleteTransaction( incidence );
00351         return res;
00352       }
00353     } else {
00354       // This isn't an update - the found incidence has a bigger revision number
00355       kDebug() << "This isn't an update - the found incidence has a bigger revision number";
00356       deleteTransaction( incidence );
00357       return false;
00358     }
00359   }
00360 
00361   // Move the uid to be the schedulingID and make a unique UID
00362   inc->setSchedulingID( inc->uid() );
00363   inc->setUid( CalFormat::createUniqueId() );
00364   // in case this is an update and we didn't find the to-be-updated incidence,
00365   // ask whether we should create a new one, or drop the update
00366   if ( existingIncidences.count() > 0 || inc->revision() == 0 ||
00367        KMessageBox::warningYesNo(
00368          0,
00369          i18nc( "@info",
00370                 "The event, to-do or journal to be updated could not be found. "
00371                 "Maybe it has already been deleted, or the calendar that "
00372                 "contains it is disabled. Press 'Store' to create a new "
00373                 "one or 'Throw away' to discard this update." ),
00374          i18nc( "@title", "Discard this update?" ),
00375          KGuiItem( i18nc( "@option", "Store" ) ),
00376          KGuiItem( i18nc( "@option", "Throw away" ) ) ) == KMessageBox::Yes ) {
00377     kDebug() << "Storing new incidence with scheduling uid=" << inc->schedulingID()
00378              << " and uid=" << inc->uid();
00379     mCalendar->addIncidence( inc );
00380   }
00381   deleteTransaction( incidence );
00382   return true;
00383 }
00384 
00385 bool Scheduler::acceptAdd( IncidenceBase *incidence, ScheduleMessage::Status /* status */)
00386 {
00387   deleteTransaction( incidence );
00388   return false;
00389 }
00390 
00391 bool Scheduler::acceptCancel( IncidenceBase *incidence,
00392                               ScheduleMessage::Status status,
00393                               const QString &attendee )
00394 {
00395   Incidence *inc = static_cast<Incidence *>( incidence );
00396   if ( !inc ) {
00397     return false;
00398   }
00399 
00400   if ( inc->type() == "FreeBusy" ) {
00401     // reply to this request is handled in korganizer's incomingdialog
00402     return true;
00403   }
00404 
00405   const Incidence::List existingIncidences = mCalendar->incidencesFromSchedulingID( inc->uid() );
00406   kDebug() << "Scheduler::acceptCancel="
00407            << ScheduleMessage::statusName( status )
00408            << ": found " << existingIncidences.count()
00409            << " incidences with schedulingID " << inc->schedulingID();
00410 
00411   bool ret = false;
00412   Incidence::List::ConstIterator incit = existingIncidences.begin();
00413   for ( ; incit != existingIncidences.end() ; ++incit ) {
00414     Incidence *i = *incit;
00415     kDebug() << "Considering this found event ("
00416              << ( i->isReadOnly() ? "readonly" : "readwrite" )
00417              << ") :" << mFormat->toString( i );
00418 
00419     // If it's readonly, we can't possible remove it.
00420     if ( i->isReadOnly() ) {
00421       continue;
00422     }
00423 
00424     // Code for new invitations:
00425     // We cannot check the value of "status" to be RequestNew because
00426     // "status" comes from a similar check inside libical, where the event
00427     // is compared to other events in the calendar. But if we have another
00428     // version of the event around (e.g. shared folder for a group), the
00429     // status could be RequestNew, Obsolete or Updated.
00430     kDebug() << "looking in " << i->uid() << "'s attendees";
00431 
00432     // This is supposed to be a new request, not an update - however we want
00433     // to update the existing one to handle the "clicking more than once
00434     // on the invitation" case. So check the attendee status of the attendee.
00435     bool isMine = true;
00436     const KCal::Attendee::List attendees = i->attendees();
00437     KCal::Attendee::List::ConstIterator ait;
00438     for ( ait = attendees.begin(); ait != attendees.end(); ++ait ) {
00439       if ( (*ait)->email() == attendee &&
00440            (*ait)->status() == Attendee::NeedsAction ) {
00441         // This incidence wasn't created by me - it's probably in a shared
00442         // folder and meant for someone else, ignore it.
00443         kDebug() << "ignoring " << i->uid()
00444                  << " since I'm still NeedsAction there";
00445         isMine = false;
00446         break;
00447       }
00448     }
00449 
00450     if ( isMine ) {
00451       kDebug() << "removing existing incidence " << i->uid();
00452       if ( i->type() == "Event" ) {
00453         Event *event = mCalendar->event( i->uid() );
00454         ret = ( event && mCalendar->deleteEvent( event ) );
00455       } else if ( i->type() == "Todo" ) {
00456         Todo *todo = mCalendar->todo( i->uid() );
00457         ret = ( todo && mCalendar->deleteTodo( todo ) );
00458       }
00459       deleteTransaction( incidence );
00460       return ret;
00461     }
00462   }
00463 
00464   // in case we didn't find the to-be-removed incidence
00465   if ( existingIncidences.count() > 0 && inc->revision() > 0 ) {
00466     KMessageBox::information(
00467       0,
00468       i18nc( "@info",
00469              "The event or task could not be removed from your calendar. "
00470              "Maybe it has already been deleted or is not owned by you. "
00471              "Or it might belong to a read-only or disabled calendar." ) );
00472   }
00473   deleteTransaction( incidence );
00474   return ret;
00475 }
00476 
00477 bool Scheduler::acceptCancel( IncidenceBase *incidence,
00478                               ScheduleMessage::Status status )
00479 {
00480   Q_UNUSED( status );
00481 
00482   const IncidenceBase *toDelete = mCalendar->incidenceFromSchedulingID( incidence->uid() );
00483 
00484   bool ret = true;
00485   if ( toDelete ) {
00486     if ( toDelete->type() == "Event" ) {
00487       Event *event = mCalendar->event( toDelete->uid() );
00488       ret = ( event && mCalendar->deleteEvent( event ) );
00489     } else if ( toDelete->type() == "Todo" ) {
00490       Todo *todo = mCalendar->todo( toDelete->uid() );
00491       ret = ( todo && mCalendar->deleteTodo( todo ) );
00492     }
00493   } else {
00494     // only complain if we failed to determine the toDelete incidence
00495     // on non-initial request.
00496     Incidence *inc = static_cast<Incidence *>( incidence );
00497     if ( inc->revision() > 0 ) {
00498       ret = false;
00499     }
00500   }
00501 
00502   if ( !ret ) {
00503     KMessageBox::information(
00504       0,
00505       i18nc( "@info",
00506              "The event or task to be canceled could not be removed from your calendar. "
00507              "Maybe it has already been deleted or is not owned by you. "
00508              "Or it might belong to a read-only or disabled calendar." ) );
00509   }
00510   deleteTransaction( incidence );
00511   return ret;
00512 }
00513 
00514 bool Scheduler::acceptDeclineCounter( IncidenceBase *incidence,
00515                                       ScheduleMessage::Status status )
00516 {
00517   Q_UNUSED( status );
00518   deleteTransaction( incidence );
00519   return false;
00520 }
00521 
00522 bool Scheduler::acceptReply( IncidenceBase *incidence,
00523                              ScheduleMessage::Status status,
00524                              iTIPMethod method )
00525 {
00526   Q_UNUSED( status );
00527   if ( incidence->type() == "FreeBusy" ) {
00528     return acceptFreeBusy( incidence, method );
00529   }
00530   bool ret = false;
00531   Event *ev = mCalendar->event( incidence->uid() );
00532   Todo *to = mCalendar->todo( incidence->uid() );
00533 
00534   // try harder to find the correct incidence
00535   if ( !ev && !to ) {
00536     const Incidence::List list = mCalendar->incidences();
00537     for ( Incidence::List::ConstIterator it=list.constBegin(), end=list.constEnd();
00538           it != end; ++it ) {
00539       if ( (*it)->schedulingID() == incidence->uid() ) {
00540         ev = dynamic_cast<Event*>( *it );
00541         to = dynamic_cast<Todo*>( *it );
00542         break;
00543       }
00544     }
00545   }
00546 
00547   if ( ev || to ) {
00548     //get matching attendee in calendar
00549     kDebug() << "match found!";
00550     Attendee::List attendeesIn = incidence->attendees();
00551     Attendee::List attendeesEv;
00552     Attendee::List attendeesNew;
00553     if ( ev ) {
00554       attendeesEv = ev->attendees();
00555     }
00556     if ( to ) {
00557       attendeesEv = to->attendees();
00558     }
00559     Attendee::List::ConstIterator inIt;
00560     Attendee::List::ConstIterator evIt;
00561     for ( inIt = attendeesIn.constBegin(); inIt != attendeesIn.constEnd(); ++inIt ) {
00562       Attendee *attIn = *inIt;
00563       bool found = false;
00564       for ( evIt = attendeesEv.constBegin(); evIt != attendeesEv.constEnd(); ++evIt ) {
00565         Attendee *attEv = *evIt;
00566         if ( attIn->email().toLower() == attEv->email().toLower() ) {
00567           //update attendee-info
00568           kDebug() << "update attendee";
00569           attEv->setStatus( attIn->status() );
00570           attEv->setDelegate( attIn->delegate() );
00571           attEv->setDelegator( attIn->delegator() );
00572           ret = true;
00573           found = true;
00574         }
00575       }
00576       if ( !found && attIn->status() != Attendee::Declined ) {
00577         attendeesNew.append( attIn );
00578       }
00579     }
00580 
00581     bool attendeeAdded = false;
00582     for ( Attendee::List::ConstIterator it = attendeesNew.constBegin();
00583           it != attendeesNew.constEnd(); ++it ) {
00584       Attendee *attNew = *it;
00585       QString msg =
00586         i18nc( "@info", "%1 wants to attend %2 but was not invited.",
00587                attNew->fullName(),
00588                ( ev ? ev->summary() : to->summary() ) );
00589       if ( !attNew->delegator().isEmpty() ) {
00590         msg = i18nc( "@info", "%1 wants to attend %2 on behalf of %3.",
00591                      attNew->fullName(),
00592                      ( ev ? ev->summary() : to->summary() ), attNew->delegator() );
00593       }
00594       if ( KMessageBox::questionYesNo(
00595              0, msg, i18nc( "@title", "Uninvited attendee" ),
00596              KGuiItem( i18nc( "@option", "Accept Attendance" ) ),
00597              KGuiItem( i18nc( "@option", "Reject Attendance" ) ) ) != KMessageBox::Yes ) {
00598         KCal::Incidence *cancel = dynamic_cast<Incidence*>( incidence );
00599         if ( cancel ) {
00600           cancel->addComment(
00601             i18nc( "@info",
00602                    "The organizer rejected your attendance at this meeting." ) );
00603         }
00604         performTransaction( cancel ? cancel : incidence, iTIPCancel, attNew->fullName() );
00605         // ### can't delete cancel here because it is aliased to incidence which
00606         // is accessed in the next loop iteration (CID 4232)
00607         // delete cancel;
00608         continue;
00609       }
00610 
00611       Attendee *a = new Attendee( attNew->name(), attNew->email(), attNew->RSVP(),
00612                                   attNew->status(), attNew->role(), attNew->uid() );
00613       a->setDelegate( attNew->delegate() );
00614       a->setDelegator( attNew->delegator() );
00615       if ( ev ) {
00616         ev->addAttendee( a );
00617       } else if ( to ) {
00618         to->addAttendee( a );
00619       }
00620       ret = true;
00621       attendeeAdded = true;
00622     }
00623 
00624     // send update about new participants
00625     if ( attendeeAdded ) {
00626       if ( ev ) {
00627         ev->setRevision( ev->revision() + 1 );
00628         performTransaction( ev, iTIPRequest );
00629       }
00630       if ( to ) {
00631         to->setRevision( to->revision() + 1 );
00632         performTransaction( to, iTIPRequest );
00633       }
00634     }
00635 
00636     if ( ret ) {
00637       // We set at least one of the attendees, so the incidence changed
00638       // Note: This should not result in a sequence number bump
00639       if ( ev ) {
00640         ev->updated();
00641       } else if ( to ) {
00642         to->updated();
00643       }
00644     }
00645     if ( to ) {
00646       // for VTODO a REPLY can be used to update the completion status of
00647       // a to-do. see RFC2446 3.4.3
00648       Todo *update = dynamic_cast<Todo*> ( incidence );
00649       Q_ASSERT( update );
00650       if ( update && ( to->percentComplete() != update->percentComplete() ) ) {
00651         to->setPercentComplete( update->percentComplete() );
00652         to->updated();
00653       }
00654     }
00655   } else {
00656     kError() << "No incidence for scheduling.";
00657   }
00658 
00659   if ( ret ) {
00660     deleteTransaction( incidence );
00661   }
00662   return ret;
00663 }
00664 
00665 bool Scheduler::acceptRefresh( IncidenceBase *incidence, ScheduleMessage::Status status )
00666 {
00667   Q_UNUSED( status );
00668   // handled in korganizer's IncomingDialog
00669   deleteTransaction( incidence );
00670   return false;
00671 }
00672 
00673 bool Scheduler::acceptCounter( IncidenceBase *incidence, ScheduleMessage::Status status )
00674 {
00675   Q_UNUSED( status );
00676   deleteTransaction( incidence );
00677   return false;
00678 }
00679 
00680 bool Scheduler::acceptFreeBusy( IncidenceBase *incidence, iTIPMethod method )
00681 {
00682   if ( !d->mFreeBusyCache ) {
00683     kError() << "KCal::Scheduler: no FreeBusyCache.";
00684     return false;
00685   }
00686 
00687   FreeBusy *freebusy = static_cast<FreeBusy *>(incidence);
00688 
00689   kDebug() << "freeBusyDirName:" << freeBusyDir();
00690 
00691   Person from;
00692   if( method == iTIPPublish ) {
00693     from = freebusy->organizer();
00694   }
00695   if ( ( method == iTIPReply ) && ( freebusy->attendeeCount() == 1 ) ) {
00696     Attendee *attendee = freebusy->attendees().first();
00697     from.setName( attendee->name() );
00698     from.setEmail( attendee->email() );
00699   }
00700 
00701   if ( !d->mFreeBusyCache->saveFreeBusy( freebusy, from ) ) {
00702     return false;
00703   }
00704 
00705   deleteTransaction( incidence );
00706   return true;
00707 }

KCal Library

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

KDE-PIM Libraries

Skip menu "KDE-PIM Libraries"
  • akonadi
  •   contact
  •   kmime
  • kabc
  • kblog
  • kcal
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  •   richtextbuilders
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
Generated for KDE-PIM Libraries by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal