00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "incidencechanger.h"
00026 #include "koglobals.h"
00027 #include "koprefs.h"
00028 #include "kogroupware.h"
00029 #include "mailscheduler.h"
00030
00031 #include <libkcal/freebusy.h>
00032 #include <libkcal/dndfactory.h>
00033 #include <kdebug.h>
00034 #include <kmessagebox.h>
00035 #include <klocale.h>
00036
00037
00038
00039 bool IncidenceChanger::beginChange( Incidence *incidence,
00040 ResourceCalendar *res, const QString &subRes )
00041 {
00042 if ( !incidence ) {
00043 return false;
00044 }
00045
00046 kdDebug(5850) << "IncidenceChanger::beginChange for incidence \""
00047 << incidence->summary() << "\"" << endl;
00048
00049 CalendarResources *calRes = dynamic_cast<CalendarResources*>( mCalendar );
00050 if ( !calRes ) {
00051 return false;
00052 }
00053
00054 return calRes->beginChange( incidence, res, subRes );
00055 }
00056
00057 bool IncidenceChanger::sendGroupwareMessage( Incidence *incidence,
00058 KCal::Scheduler::Method method,
00059 KOGlobals::HowChanged action,
00060 QWidget *parent )
00061 {
00062 if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) &&
00063 ( incidence->attendeeCount() > 0 ) &&
00064 !KOPrefs::instance()->mUseGroupwareCommunication ) {
00065 emit schedule( method, incidence );
00066 return true;
00067 } else if( KOPrefs::instance()->mUseGroupwareCommunication ) {
00068 return
00069 KOGroupware::instance()->sendICalMessage( parent, method, incidence, 0, action, false );
00070 }
00071 return true;
00072 }
00073
00074 bool IncidenceChanger::endChange( Incidence *incidence,
00075 ResourceCalendar *res, const QString &subRes )
00076 {
00077
00078
00079
00080
00081
00082
00083 if ( !incidence ) {
00084 return false;
00085 }
00086
00087 kdDebug(5850) << "IncidenceChanger::endChange for incidence \""
00088 << incidence->summary() << "\"" << incidence->dtStart() << endl;
00089
00090 CalendarResources *calRes = dynamic_cast<CalendarResources*>( mCalendar );
00091 if ( !calRes ) {
00092 kdDebug() << "CalRes is null!" << endl;
00093 return false;
00094 }
00095
00096 return calRes->endChange( incidence, res, subRes );
00097 }
00098
00099 bool IncidenceChanger::deleteIncidence( Incidence *incidence, QWidget *parent )
00100 {
00101 if ( !incidence ) return true;
00102 kdDebug(5850) << "IncidenceChanger::deleteIncidence() Explicit delete for incidence \""
00103 << incidence->summary()
00104 << "\""
00105 << "; uid="
00106 << incidence->uid()
00107 << "; schedulingId=" << incidence->schedulingID()
00108 << endl;
00109 bool doDelete = sendGroupwareMessage( incidence, KCal::Scheduler::Cancel,
00110 KOGlobals::INCIDENCEDELETED, parent );
00111 if( doDelete ) {
00112
00113 Incidence* tmp = incidence->clone();
00114 emit incidenceToBeDeleted( incidence );
00115 doDelete = mCalendar->deleteIncidence( incidence );
00116 if ( !KOPrefs::instance()->thatIsMe( tmp->organizer().email() ) ) {
00117 const QStringList myEmails = KOPrefs::instance()->allEmails();
00118 bool notifyOrganizer = false;
00119 for ( QStringList::ConstIterator it = myEmails.begin(); it != myEmails.end(); ++it ) {
00120 QString email = *it;
00121 Attendee *me = tmp->attendeeByMail(email);
00122 if ( me ) {
00123 if ( me->status() == KCal::Attendee::Accepted || me->status() == KCal::Attendee::Delegated )
00124 notifyOrganizer = true;
00125 Attendee *newMe = new Attendee( *me );
00126 newMe->setStatus( KCal::Attendee::Declined );
00127 tmp->clearAttendees();
00128 tmp->addAttendee( newMe );
00129 break;
00130 }
00131 }
00132
00133 if ( !KOGroupware::instance()->doNotNotify() && notifyOrganizer ) {
00134 KCal::MailScheduler scheduler( mCalendar );
00135 scheduler.performTransaction( tmp, Scheduler::Reply );
00136 }
00137
00138 KOGroupware::instance()->setDoNotNotify( false );
00139 }
00140 emit incidenceDeleted( incidence );
00141 }
00142 return doDelete;
00143 }
00144
00145 bool IncidenceChanger::cutIncidences( const Incidence::List &incidences,
00146 QWidget *parent )
00147 {
00148 Incidence::List::ConstIterator it;
00149 bool doDelete = true;
00150 Incidence::List incsToCut;
00151 for ( it = incidences.constBegin(); it != incidences.constEnd(); ++it ) {
00152 if ( *it ) {
00153 doDelete = sendGroupwareMessage( *it, KCal::Scheduler::Cancel,
00154 KOGlobals::INCIDENCEDELETED, parent );
00155 if ( doDelete ) {
00156 emit incidenceToBeDeleted( *it );
00157 incsToCut.append( *it );
00158 }
00159 }
00160 }
00161
00162 DndFactory factory( mCalendar );
00163
00164 if ( factory.cutIncidences( incsToCut ) ) {
00165 for ( it = incsToCut.constBegin(); it != incsToCut.constEnd(); ++it ) {
00166 emit incidenceDeleted( *it );
00167 }
00168 return !incsToCut.isEmpty();
00169 } else {
00170 return false;
00171 }
00172 }
00173
00174 bool IncidenceChanger::cutIncidence( Incidence *incidence, QWidget *parent )
00175 {
00176 Incidence::List incidences;
00177 incidences.append( incidence );
00178 return cutIncidences( incidences, parent );
00179 }
00180
00181 class IncidenceChanger::ComparisonVisitor : public IncidenceBase::Visitor
00182 {
00183 public:
00184 ComparisonVisitor() {}
00185 bool act( IncidenceBase *incidence, IncidenceBase *inc2 )
00186 {
00187 mIncidence2 = inc2;
00188 if ( incidence )
00189 return incidence->accept( *this );
00190 else
00191 return (inc2 == 0);
00192 }
00193 protected:
00194 bool visit( Event *event )
00195 {
00196 Event *ev2 = dynamic_cast<Event*>(mIncidence2);
00197 if ( event && ev2 ) {
00198 return *event == *ev2;
00199 } else {
00200
00201 return ( ev2 == event );
00202 }
00203 }
00204 bool visit( Todo *todo )
00205 {
00206 Todo *to2 = dynamic_cast<Todo*>( mIncidence2 );
00207 if ( todo && to2 ) {
00208 return *todo == *to2;
00209 } else {
00210
00211 return ( todo == to2 );
00212 }
00213 }
00214 bool visit( Journal *journal )
00215 {
00216 Journal *j2 = dynamic_cast<Journal*>( mIncidence2 );
00217 if ( journal && j2 ) {
00218 return *journal == *j2;
00219 } else {
00220
00221 return ( journal == j2 );
00222 }
00223 }
00224 bool visit( FreeBusy *fb )
00225 {
00226 FreeBusy *fb2 = dynamic_cast<FreeBusy*>( mIncidence2 );
00227 if ( fb && fb2 ) {
00228 return *fb == *fb2;
00229 } else {
00230
00231 return ( fb2 == fb );
00232 }
00233 }
00234
00235 protected:
00236 IncidenceBase *mIncidence2;
00237 };
00238
00239 class IncidenceChanger::AssignmentVisitor : public IncidenceBase::Visitor
00240 {
00241 public:
00242 AssignmentVisitor() {}
00243 bool act( IncidenceBase *incidence, IncidenceBase *inc2 )
00244 {
00245 mIncidence2 = inc2;
00246 if ( incidence )
00247 return incidence->accept( *this );
00248 else
00249 return false;
00250 }
00251 protected:
00252 bool visit( Event *event )
00253 {
00254 Event *ev2 = dynamic_cast<Event*>( mIncidence2 );
00255 if ( event && ev2 ) {
00256 *event = *ev2;
00257 return true;
00258 } else {
00259 return false;
00260 }
00261 }
00262 bool visit( Todo *todo )
00263 {
00264 Todo *to2 = dynamic_cast<Todo*>( mIncidence2 );
00265 if ( todo && to2 ) {
00266 *todo = *to2;
00267 return true;
00268 } else {
00269 return false;
00270 }
00271 }
00272 bool visit( Journal *journal )
00273 {
00274 Journal *j2 = dynamic_cast<Journal*>(mIncidence2);
00275 if ( journal && j2 ) {
00276 *journal = *j2;
00277 return true;
00278 } else {
00279 return false;
00280 }
00281 }
00282 bool visit( FreeBusy *fb )
00283 {
00284 FreeBusy *fb2 = dynamic_cast<FreeBusy*>( mIncidence2 );
00285 if ( fb && fb2 ) {
00286 *fb = *fb2;
00287 return true;
00288 } else {
00289 return false;
00290 }
00291 }
00292
00293 protected:
00294 IncidenceBase *mIncidence2;
00295 };
00296
00297 bool IncidenceChanger::incidencesEqual( Incidence *inc1, Incidence *inc2 )
00298 {
00299 ComparisonVisitor v;
00300 return ( v.act( inc1, inc2 ) );
00301 }
00302
00303 bool IncidenceChanger::assignIncidence( Incidence *inc1, Incidence *inc2 )
00304 {
00305 AssignmentVisitor v;
00306 const bool result = v.act( inc1, inc2 );
00307
00308 if ( result ) {
00309
00310 inc1->updated();
00311 }
00312
00313 return result;
00314 }
00315
00316 bool IncidenceChanger::myAttendeeStatusChanged( Incidence *oldInc, Incidence *newInc )
00317 {
00318 Attendee *oldMe = oldInc->attendeeByMails( KOPrefs::instance()->allEmails() );
00319 Attendee *newMe = newInc->attendeeByMails( KOPrefs::instance()->allEmails() );
00320 if ( oldMe && newMe && ( oldMe->status() != newMe->status() ) )
00321 return true;
00322
00323 return false;
00324 }
00325
00326 bool IncidenceChanger::changeIncidence( Incidence *oldinc, Incidence *newinc,
00327 KOGlobals::WhatChanged action,
00328 QWidget *parent,
00329 bool useLastDialogAnswer )
00330 {
00331 kdDebug(5850)<<"IncidenceChanger::changeIncidence for incidence \""<<newinc->summary()<<"\" ( old one was \""<<oldinc->summary()<<"\")"<<endl;
00332 if ( incidencesEqual( newinc, oldinc ) ) {
00333
00334 kdDebug(5850) << "Incidence not changed\n";
00335 } else {
00336 kdDebug(5850) << "Incidence changed\n";
00337 bool attendeeStatusChanged = myAttendeeStatusChanged( oldinc, newinc );
00338 int revision = newinc->revision();
00339 newinc->setRevision( revision + 1 );
00340
00341
00342
00343
00344 bool success = true;
00345 if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
00346 success = KOGroupware::instance()->sendICalMessage(
00347 parent,
00348 KCal::Scheduler::Request,
00349 newinc, oldinc,
00350 KOGlobals::INCIDENCEEDITED, attendeeStatusChanged,
00351 useLastDialogAnswer );
00352 }
00353
00354 if ( success ) {
00355
00356 emit incidenceChanged( oldinc, newinc, action );
00357 } else {
00358
00359 assignIncidence( newinc, oldinc );
00360 return false;
00361 }
00362 }
00363 return true;
00364 }
00365
00366 bool IncidenceChanger::addIncidence( Incidence *incidence,
00367 ResourceCalendar *res, const QString &subRes,
00368 QWidget *parent, bool useLastDialogAnswer )
00369 {
00370 CalendarResources *stdcal = dynamic_cast<CalendarResources *>( mCalendar );
00371 if ( stdcal && !stdcal->hasCalendarResources() ) {
00372 KMessageBox::sorry(
00373 parent,
00374 i18n( "No calendars found, unable to save %1 \"%2\"." ).
00375 arg( i18n( incidence->type() ) ).
00376 arg( incidence->summary() ) );
00377 kdDebug(5850) << "IncidenceChanger: No calendars found" << endl;
00378 return false;
00379 }
00380
00381
00382
00383
00384
00385 QWidget *tmpparent = 0;
00386 if ( stdcal ) {
00387 tmpparent = stdcal->dialogParentWidget();
00388 stdcal->setDialogParentWidget( parent );
00389 }
00390
00391
00392
00393 ResourceCalendar *pRes = res;
00394 QString pSubRes = subRes;
00395 QString pResName;
00396 if ( !pRes ) {
00397 if ( stdcal ) {
00398 pRes = stdcal->resource( incidence );
00399 if ( pRes ) {
00400 pResName = pRes->resourceName();
00401 if ( pRes->canHaveSubresources() ) {
00402 pSubRes = pRes->subresourceIdentifier( incidence );
00403 pResName = pRes->labelForSubresource( pSubRes );
00404 }
00405 }
00406 }
00407 }
00408
00409 bool success = false;
00410 if ( stdcal && pRes && !pRes->readOnly() && pRes->subresourceWritable( pSubRes ) ) {
00411 success = stdcal->addIncidence( incidence, pRes, pSubRes );
00412 } else {
00413 success = mCalendar->addIncidence( incidence );
00414 }
00415
00416 if ( !success ) {
00417
00418
00419 ErrorFormat *e = stdcal ? stdcal->exception() : 0;
00420 if ( !e ||
00421 ( e && ( e->errorCode() != KCal::ErrorFormat::UserCancel &&
00422 e->errorCode() != KCal::ErrorFormat::NoWritableFound ) ) ) {
00423 QString errMessage;
00424 if ( pResName.isEmpty() ) {
00425 errMessage = i18n( "Unable to save %1 \"%2\"." ).
00426 arg( i18n( incidence->type() ) ).
00427 arg( incidence->summary() );
00428 } else {
00429 errMessage = i18n( "Unable to save %1 \"%2\" to calendar %3." ).
00430 arg( i18n( incidence->type() ) ).
00431 arg( incidence->summary() ).
00432 arg( pResName );
00433 }
00434 KMessageBox::sorry( parent, errMessage );
00435 }
00436 kdDebug(5850) << "IncidenceChanger: Can't add incidence" << endl;
00437 return false;
00438 }
00439
00440 if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
00441 if ( !KOGroupware::instance()->sendICalMessage(
00442 parent,
00443 KCal::Scheduler::Request,
00444 incidence, 0, KOGlobals::INCIDENCEADDED, false, useLastDialogAnswer ) ) {
00445 KMessageBox::sorry(
00446 parent,
00447 i18n( "Attempt to send the scheduling message failed. "
00448 "Please check your Group Scheduling settings. "
00449 "Contact your system administrator for more help.") );
00450 }
00451 }
00452
00453 emit incidenceAdded( incidence );
00454 return true;
00455 }
00456
00457
00458 #include "incidencechanger.moc"
00459 #include "incidencechangerbase.moc"