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