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