libkcal
scheduler.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <klocale.h>
00024 #include <kdebug.h>
00025 #include <kstandarddirs.h>
00026
00027 #include "event.h"
00028 #include "todo.h"
00029 #include "freebusy.h"
00030 #include "icalformat.h"
00031 #include "calendar.h"
00032 #include "freebusycache.h"
00033
00034 #include "scheduler.h"
00035
00036 using namespace KCal;
00037
00038 ScheduleMessage::ScheduleMessage(IncidenceBase *incidence,int method,ScheduleMessage::Status status)
00039 {
00040 mIncidence = incidence;
00041 mMethod = method;
00042 mStatus = status;
00043 }
00044
00045 QString ScheduleMessage::statusName(ScheduleMessage::Status status)
00046 {
00047 switch (status) {
00048 case PublishUpdate:
00049 return i18n("Updated Publish");
00050 case PublishNew:
00051 return i18n("Publish");
00052 case Obsolete:
00053 return i18n("Obsolete");
00054 case RequestNew:
00055 return i18n("New Request");
00056 case RequestUpdate:
00057 return i18n("Updated Request");
00058 default:
00059 return i18n("Unknown Status: %1").arg(QString::number(status));
00060 }
00061 }
00062
00063 struct Scheduler::Private
00064 {
00065 Private() : mFreeBusyCache( 0 ) {}
00066
00067 FreeBusyCache *mFreeBusyCache;
00068 };
00069
00070 Scheduler::Scheduler(Calendar *calendar)
00071 {
00072 mCalendar = calendar;
00073 mFormat = new ICalFormat();
00074 mFormat->setTimeZone( calendar->timeZoneId(), !calendar->isLocalTime() );
00075
00076 d = new Private;
00077 }
00078
00079 Scheduler::~Scheduler()
00080 {
00081 delete d;
00082
00083 delete mFormat;
00084 }
00085
00086 void Scheduler::setFreeBusyCache( FreeBusyCache *c )
00087 {
00088 d->mFreeBusyCache = c;
00089 }
00090
00091 FreeBusyCache *Scheduler::freeBusyCache() const
00092 {
00093 return d->mFreeBusyCache;
00094 }
00095
00096 bool Scheduler::acceptTransaction(IncidenceBase *incidence,Method method,ScheduleMessage::Status status)
00097 {
00098 kdDebug(5800) << "Scheduler::acceptTransaction, method="
00099 << methodName( method ) << endl;
00100
00101 switch (method) {
00102 case Publish:
00103 return acceptPublish(incidence, status, method);
00104 case Request:
00105 return acceptRequest(incidence, status);
00106 case Add:
00107 return acceptAdd(incidence, status);
00108 case Cancel:
00109 return acceptCancel(incidence, status);
00110 case Declinecounter:
00111 return acceptDeclineCounter(incidence, status);
00112 case Reply:
00113 return acceptReply(incidence, status, method);
00114 case Refresh:
00115 return acceptRefresh(incidence, status);
00116 case Counter:
00117 return acceptCounter(incidence, status);
00118 default:
00119 break;
00120 }
00121 deleteTransaction(incidence);
00122 return false;
00123 }
00124
00125 QString Scheduler::methodName(Method method)
00126 {
00127 switch (method) {
00128 case Publish:
00129 return QString::fromLatin1("Publish");
00130 case Request:
00131 return QString::fromLatin1("Request");
00132 case Refresh:
00133 return QString::fromLatin1("Refresh");
00134 case Cancel:
00135 return QString::fromLatin1("Cancel");
00136 case Add:
00137 return QString::fromLatin1("Add");
00138 case Reply:
00139 return QString::fromLatin1("Reply");
00140 case Counter:
00141 return QString::fromLatin1("Counter");
00142 case Declinecounter:
00143 return QString::fromLatin1("Decline Counter");
00144 default:
00145 return QString::fromLatin1("Unknown");
00146 }
00147 }
00148
00149 QString Scheduler::translatedMethodName(Method method)
00150 {
00151 switch (method) {
00152 case Publish:
00153 return i18n("Publish");
00154 case Request:
00155 return i18n("Request");
00156 case Refresh:
00157 return i18n("Refresh");
00158 case Cancel:
00159 return i18n("Cancel");
00160 case Add:
00161 return i18n("Add");
00162 case Reply:
00163 return i18n("Reply");
00164 case Counter:
00165 return i18n("counter proposal","Counter");
00166 case Declinecounter:
00167 return i18n("decline counter proposal","Decline Counter");
00168 default:
00169 return i18n("Unknown");
00170 }
00171 }
00172
00173 bool Scheduler::deleteTransaction(IncidenceBase *)
00174 {
00175 return true;
00176 }
00177
00178 bool Scheduler::acceptPublish( IncidenceBase *newIncBase,
00179 ScheduleMessage::Status status, Method method )
00180 {
00181 if( newIncBase->type() == "FreeBusy" ) {
00182 return acceptFreeBusy( newIncBase, method );
00183 }
00184
00185 bool res = false;
00186 kdDebug(5800) << "Scheduler::acceptPublish, status="
00187 << ScheduleMessage::statusName( status ) << endl;
00188 Incidence *newInc = static_cast<Incidence *>( newIncBase );
00189 Incidence *calInc = mCalendar->incidence( newIncBase->uid() );
00190 switch ( status ) {
00191 case ScheduleMessage::Unknown:
00192 case ScheduleMessage::PublishNew:
00193 case ScheduleMessage::PublishUpdate:
00194 res = true;
00195 if ( calInc ) {
00196 if ( (newInc->revision() > calInc->revision()) ||
00197 (newInc->revision() == calInc->revision() &&
00198 newInc->lastModified() > calInc->lastModified() ) ) {
00199 mCalendar->deleteIncidence( calInc );
00200 } else
00201 res = false;
00202 }
00203 if ( res )
00204 mCalendar->addIncidence( newInc );
00205 break;
00206 case ScheduleMessage::Obsolete:
00207 res = true;
00208 break;
00209 default:
00210 break;
00211 }
00212 deleteTransaction( newIncBase );
00213 return res;
00214 }
00215
00216 bool Scheduler::acceptRequest(IncidenceBase *newIncBase, ScheduleMessage::Status )
00217 {
00218 if (newIncBase->type()=="FreeBusy") {
00219
00220 return true;
00221 }
00222 Incidence *newInc = dynamic_cast<Incidence *>( newIncBase );
00223 if ( newInc ) {
00224 bool res = true;
00225 Incidence *exInc = mCalendar->incidenceFromSchedulingID( newIncBase->uid() );
00226 if ( exInc ) {
00227 res = false;
00228 if ( (newInc->revision() > exInc->revision()) ||
00229 (newInc->revision() == exInc->revision() &&
00230 newInc->lastModified()>exInc->lastModified()) ) {
00231 mCalendar->deleteIncidence( exInc );
00232 res = true;
00233 }
00234 }
00235 if ( res ) {
00236
00237 newInc->setSchedulingID( newInc->uid() );
00238 newInc->setUid( CalFormat::createUniqueId() );
00239
00240 mCalendar->addIncidence(newInc);
00241 }
00242 deleteTransaction( newIncBase );
00243 return res;
00244 }
00245 return false;
00246 }
00247
00248 bool Scheduler::acceptAdd(IncidenceBase *incidence,ScheduleMessage::Status )
00249 {
00250 deleteTransaction(incidence);
00251 return false;
00252 }
00253
00254 bool Scheduler::acceptCancel(IncidenceBase *incidence,ScheduleMessage::Status )
00255 {
00256 bool ret = false;
00257 Incidence *inc = mCalendar->incidence( incidence->uid() );
00258 if ( inc ) {
00259 mCalendar->deleteIncidence( inc );
00260 ret = true;
00261 }
00262 deleteTransaction(incidence);
00263 return ret;
00264 }
00265
00266 bool Scheduler::acceptDeclineCounter(IncidenceBase *incidence,ScheduleMessage::Status )
00267 {
00268 deleteTransaction(incidence);
00269 return false;
00270 }
00271
00272
00273
00274
00275
00276
00277
00278 bool Scheduler::acceptReply(IncidenceBase *incidence,ScheduleMessage::Status , Method method)
00279 {
00280 if(incidence->type()=="FreeBusy") {
00281 return acceptFreeBusy(incidence, method);
00282 }
00283 bool ret = false;
00284 Event *ev = mCalendar->event(incidence->uid());
00285 Todo *to = mCalendar->todo(incidence->uid());
00286 if (ev || to) {
00287
00288 kdDebug(5800) << "Scheduler::acceptTransaction match found!" << endl;
00289 Attendee::List attendeesIn = incidence->attendees();
00290 Attendee::List attendeesEv;
00291 if (ev) attendeesEv = ev->attendees();
00292 if (to) attendeesEv = to->attendees();
00293 Attendee::List::ConstIterator inIt;
00294 Attendee::List::ConstIterator evIt;
00295 for ( inIt = attendeesIn.begin(); inIt != attendeesIn.end(); ++inIt ) {
00296 Attendee *attIn = *inIt;
00297 for ( evIt = attendeesEv.begin(); evIt != attendeesEv.end(); ++evIt ) {
00298 Attendee *attEv = *evIt;
00299 if (attIn->email().lower()==attEv->email().lower()) {
00300
00301 kdDebug(5800) << "Scheduler::acceptTransaction update attendee" << endl;
00302 attEv->setStatus(attIn->status());
00303 ret = true;
00304 }
00305 }
00306 }
00307 if ( ret ) {
00308
00309
00310 if ( ev )
00311 ev->updated();
00312 else if ( to )
00313 to->updated();
00314 }
00315 if ( to ) {
00316
00317
00318 Todo *update = dynamic_cast<Todo*> ( incidence );
00319 Q_ASSERT( update );
00320 if ( update && ( to->percentComplete() != update->percentComplete() ) ) {
00321 to->setPercentComplete( update->percentComplete() );
00322 to->updated();
00323 }
00324 }
00325 } else
00326 kdError(5800) << "No incidence for scheduling\n";
00327 if (ret) deleteTransaction(incidence);
00328 return ret;
00329 }
00330
00331 bool Scheduler::acceptRefresh(IncidenceBase *incidence,ScheduleMessage::Status )
00332 {
00333
00334 deleteTransaction(incidence);
00335 return false;
00336 }
00337
00338 bool Scheduler::acceptCounter(IncidenceBase *incidence,ScheduleMessage::Status )
00339 {
00340 deleteTransaction(incidence);
00341 return false;
00342 }
00343
00344 bool Scheduler::acceptFreeBusy(IncidenceBase *incidence, Method method)
00345 {
00346 if ( !d->mFreeBusyCache ) {
00347 kdError() << "KCal::Scheduler: no FreeBusyCache." << endl;
00348 return false;
00349 }
00350
00351 FreeBusy *freebusy = static_cast<FreeBusy *>(incidence);
00352
00353 kdDebug(5800) << "acceptFreeBusy:: freeBusyDirName: " << freeBusyDir() << endl;
00354
00355 Person from;
00356 if(method == Scheduler::Publish) {
00357 from = freebusy->organizer();
00358 }
00359 if((method == Scheduler::Reply) && (freebusy->attendeeCount() == 1)) {
00360 Attendee *attendee = freebusy->attendees().first();
00361 from = attendee->email();
00362 }
00363
00364 if ( !d->mFreeBusyCache->saveFreeBusy( freebusy, from ) ) return false;
00365
00366 deleteTransaction(incidence);
00367 return true;
00368 }
|