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