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