libkcal Library API Documentation

scheduler.cpp

00001 /*
00002     This file is part of libkcal.
00003 
00004     Copyright (c) 2001,2004 Cornelius Schumacher <schumacher@kde.org>
00005 
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 of the License, or (at your option) any later version.
00010 
00011     This library is distributed in the hope that it will be useful,
00012     but WITHOUT ANY WARRANTY; without even the implied warranty of
00013     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public License
00017     along with this library; see the file COPYING.LIB.  If not, write to
00018     the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019     Boston, MA 02111-1307, USA.
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 // TODO: Add string when i18n freeze is over.
00053 //      return i18n("Updated Publish");
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 /* status */)
00222 {
00223   Incidence *inc = static_cast<Incidence *>(incidence);
00224   if (inc->type()=="FreeBusy") {
00225     // reply to this request is handled in korganizer's incomingdialog
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 /* status */)
00264 {
00265   deleteTransaction(incidence);
00266   return false;
00267 }
00268 
00269 bool Scheduler::acceptCancel(IncidenceBase *incidence,ScheduleMessage::Status /* 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 /* status */)
00288 {
00289   deleteTransaction(incidence);
00290   return false;
00291 }
00292 
00293 //bool Scheduler::acceptFreeBusy(Incidence *incidence,ScheduleMessage::Status status)
00294 //{
00295 //  deleteTransaction(incidence);
00296 //  return false;
00297 //}
00298 
00299 bool Scheduler::acceptReply(IncidenceBase *incidence,ScheduleMessage::Status /* 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     //get matching attendee in calendar
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           //update attendee-info
00322           kdDebug(5800) << "Scheduler::acceptTransaction update attendee" << endl;
00323           attEv->setStatus(attIn->status());
00324           ret = true;
00325         }
00326       }
00327     }
00328     if ( ret ) {
00329       // We set at least one of the attendees, so the incidence changed
00330       // Note: This should not result in a sequence number bump
00331       if ( ev )
00332         ev->updated();
00333       else if ( to )
00334         to->updated();
00335     }
00336   }
00337   if (ret) deleteTransaction(incidence);
00338   return ret;
00339 }
00340 
00341 bool Scheduler::acceptRefresh(IncidenceBase *incidence,ScheduleMessage::Status /* status */)
00342 {
00343   // handled in korganizer's IncomingDialog
00344   deleteTransaction(incidence);
00345   return false;
00346 }
00347 
00348 bool Scheduler::acceptCounter(IncidenceBase *incidence,ScheduleMessage::Status /* status */)
00349 {
00350   deleteTransaction(incidence);
00351   return false;
00352 }
00353 
00354 bool Scheduler::acceptFreeBusy(IncidenceBase *incidence, Method method)
00355 {
00356   if ( !d->mFreeBusyCache ) {
00357     kdError() << "KCal::Scheduler: no FreeBusyCache." << endl;
00358     return false;
00359   }
00360 
00361   FreeBusy *freebusy = static_cast<FreeBusy *>(incidence);
00362 
00363   kdDebug(5800) << "acceptFreeBusy:: freeBusyDirName: " << freeBusyDir() << endl;
00364 
00365   Person from;
00366   if(method == Scheduler::Publish) {
00367     from = freebusy->organizer();
00368   }
00369   if((method == Scheduler::Reply) && (freebusy->attendeeCount() == 1)) {
00370     Attendee *attendee = freebusy->attendees().first();
00371     from = attendee->email();
00372   }
00373 
00374   if ( !d->mFreeBusyCache->saveFreeBusy( freebusy, from ) ) return false;
00375 
00376   deleteTransaction(incidence);
00377   return true;
00378 }
KDE Logo
This file is part of the documentation for libkcal Library Version 3.3.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Mar 23 22:38:36 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003