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