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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "kogroupware.h"
00038 #include "freebusymanager.h"
00039 #include "calendarview.h"
00040 #include "mailscheduler.h"
00041 #include "koprefs.h"
00042 #include "koincidenceeditor.h"
00043 #include <libemailfunctions/email.h>
00044 #include <libkcal/attendee.h>
00045 #include <libkcal/calhelper.h>
00046 #include <libkcal/journal.h>
00047 #include <libkcal/incidenceformatter.h>
00048 #include <kdebug.h>
00049 #include <kmessagebox.h>
00050 #include <kstandarddirs.h>
00051 #include <kdirwatch.h>
00052 #include <qfile.h>
00053 #include <qregexp.h>
00054 #include <qdir.h>
00055 #include <qtimer.h>
00056
00057 FreeBusyManager *KOGroupware::mFreeBusyManager = 0;
00058
00059 KOGroupware *KOGroupware::mInstance = 0;
00060
00061 KOGroupware *KOGroupware::create( CalendarView *view,
00062 KCal::CalendarResources *calendar )
00063 {
00064 if( !mInstance )
00065 mInstance = new KOGroupware( view, calendar );
00066 return mInstance;
00067 }
00068
00069 KOGroupware *KOGroupware::instance()
00070 {
00071
00072 Q_ASSERT( mInstance );
00073 return mInstance;
00074 }
00075
00076
00077 KOGroupware::KOGroupware( CalendarView* view, KCal::CalendarResources* cal )
00078 : QObject( 0, "kmgroupware_instance" ), mView( view ), mCalendar( cal ), mDoNotNotify( false )
00079 {
00080
00081 KDirWatch* watcher = KDirWatch::self();
00082 watcher->addDir( locateLocal( "data", "korganizer/income.accepted/" ) );
00083 watcher->addDir( locateLocal( "data", "korganizer/income.tentative/" ) );
00084 watcher->addDir( locateLocal( "data", "korganizer/income.counter/" ) );
00085 watcher->addDir( locateLocal( "data", "korganizer/income.cancel/" ) );
00086 watcher->addDir( locateLocal( "data", "korganizer/income.reply/" ) );
00087 watcher->addDir( locateLocal( "data", "korganizer/income.delegated/" ) );
00088 connect( watcher, SIGNAL( dirty( const QString& ) ),
00089 this, SLOT( incomingDirChanged( const QString& ) ) );
00090
00091 QTimer::singleShot( 0, this, SLOT(initialCheckForChanges()) );
00092
00093
00094 lastUsedDialogAnswer = KMessageBox::Yes;
00095 }
00096
00097 void KOGroupware::initialCheckForChanges()
00098 {
00099 incomingDirChanged( locateLocal( "data", "korganizer/income.accepted/" ) );
00100 incomingDirChanged( locateLocal( "data", "korganizer/income.tentative/" ) );
00101 incomingDirChanged( locateLocal( "data", "korganizer/income.counter/" ) );
00102 incomingDirChanged( locateLocal( "data", "korganizer/income.cancel/" ) );
00103 incomingDirChanged( locateLocal( "data", "korganizer/income.reply/" ) );
00104 incomingDirChanged( locateLocal( "data", "korganizer/income.delegated/" ) );
00105 }
00106
00107 void KOGroupware::slotViewNewIncidenceChanger( IncidenceChangerBase* changer )
00108 {
00109
00110 connect( changer, SIGNAL( incidenceAdded( Incidence* ) ),
00111 mFreeBusyManager, SLOT( slotPerhapsUploadFB() ) );
00112 connect( changer, SIGNAL( incidenceChanged( Incidence*, Incidence*, KOGlobals::WhatChanged ) ),
00113 mFreeBusyManager, SLOT( slotPerhapsUploadFB() ) );
00114 connect( changer, SIGNAL( incidenceDeleted( Incidence * ) ),
00115 mFreeBusyManager, SLOT( slotPerhapsUploadFB() ) );
00116 }
00117
00118 FreeBusyManager *KOGroupware::freeBusyManager()
00119 {
00120 if ( !mFreeBusyManager ) {
00121 mFreeBusyManager = new FreeBusyManager( this, "freebusymanager" );
00122 mFreeBusyManager->setCalendar( mCalendar );
00123 connect( mCalendar, SIGNAL( calendarChanged() ),
00124 mFreeBusyManager, SLOT( slotPerhapsUploadFB() ) );
00125 connect( mView, SIGNAL( newIncidenceChanger( IncidenceChangerBase* ) ),
00126 this, SLOT( slotViewNewIncidenceChanger( IncidenceChangerBase* ) ) );
00127 slotViewNewIncidenceChanger( mView->incidenceChanger() );
00128 }
00129
00130 return mFreeBusyManager;
00131 }
00132
00133 void KOGroupware::incomingDirChanged( const QString& path )
00134 {
00135 const QString incomingDirName = locateLocal( "data","korganizer/" )
00136 + "income.";
00137 if ( !path.startsWith( incomingDirName ) ) {
00138 kdDebug(5850) << "incomingDirChanged: Wrong dir " << path << endl;
00139 return;
00140 }
00141 QString action = path.mid( incomingDirName.length() );
00142 while ( action.length() > 0 && action[ action.length()-1 ] == '/' )
00143
00144 action.truncate( action.length()-1 );
00145
00146
00147 QDir dir( path );
00148 const QStringList files = dir.entryList( QDir::Files );
00149 if ( files.isEmpty() )
00150
00151 return;
00152
00153
00154 QFile f( path + "/" + files[0] );
00155 if (!f.open(IO_ReadOnly)) {
00156 kdError(5850) << "Can't open file '" << files[0] << "'" << endl;
00157 return;
00158 }
00159 QTextStream t(&f);
00160 t.setEncoding( QTextStream::UnicodeUTF8 );
00161 QString receiver = KPIM::getFirstEmailAddress( t.readLine() );
00162 QString iCal = t.read();
00163
00164 f.remove();
00165
00166 ScheduleMessage *message = mFormat.parseScheduleMessage( mCalendar, iCal );
00167 if ( !message ) {
00168 QString errorMessage;
00169 if (mFormat.exception())
00170 errorMessage = i18n( "Error message: %1" ).arg( mFormat.exception()->message() );
00171 kdDebug(5850) << "MailScheduler::retrieveTransactions() Error parsing "
00172 << errorMessage << endl;
00173 KMessageBox::detailedError( mView,
00174 i18n("Error while processing an invitation or update."),
00175 errorMessage );
00176 return;
00177 }
00178
00179 KCal::Scheduler::Method method =
00180 static_cast<KCal::Scheduler::Method>( message->method() );
00181 KCal::ScheduleMessage::Status status = message->status();
00182 KCal::Incidence* incidence =
00183 dynamic_cast<KCal::Incidence*>( message->event() );
00184 if(!incidence) {
00185 delete message;
00186 return;
00187 }
00188 KCal::MailScheduler scheduler( mCalendar );
00189 if ( action.startsWith( "accepted" ) || action.startsWith( "tentative" ) ||
00190 action.startsWith( "delegated" ) || action.startsWith( "counter" ) ) {
00191
00192
00193 KCal::Attendee::List attendees = incidence->attendees();
00194 KCal::Attendee::List::ConstIterator it;
00195 for ( it = attendees.begin(); it != attendees.end(); ++it ) {
00196 if( (*it)->email() == receiver ) {
00197 if ( action.startsWith( "accepted" ) )
00198 (*it)->setStatus( KCal::Attendee::Accepted );
00199 else if ( action.startsWith( "tentative" ) )
00200 (*it)->setStatus( KCal::Attendee::Tentative );
00201 else if ( KOPrefs::instance()->outlookCompatCounterProposals() && action.startsWith( "counter" ) )
00202 (*it)->setStatus( KCal::Attendee::Tentative );
00203 else if ( action.startsWith( "delegated" ) )
00204 (*it)->setStatus( KCal::Attendee::Delegated );
00205 break;
00206 }
00207 }
00208 if ( KOPrefs::instance()->outlookCompatCounterProposals() || !action.startsWith( "counter" ) ) {
00209 if ( scheduler.acceptTransaction( incidence, method, status, receiver ) ) {
00210 mCalendar->save();
00211 }
00212 }
00213 } else if ( action.startsWith( "cancel" ) ) {
00214
00215 if ( scheduler.acceptTransaction( incidence, KCal::Scheduler::Cancel, status, receiver ) ) {
00216 mCalendar->save();
00217 }
00218 } else if ( action.startsWith( "reply" ) ) {
00219 if ( method != Scheduler::Counter ) {
00220 if ( scheduler.acceptTransaction( incidence, method, status ) ) {
00221 mCalendar->save();
00222 }
00223 } else {
00224
00225 if ( scheduler.acceptCounterProposal( incidence ) ) {
00226 mCalendar->save();
00227
00228 sendICalMessage( mView, Scheduler::Request, incidence, 0,
00229 KOGlobals::INCIDENCEEDITED, false );
00230 }
00231 }
00232 } else {
00233 kdError(5850) << "Unknown incoming action " << action << endl;
00234 }
00235
00236 if ( action.startsWith( "counter" ) ) {
00237 mView->editIncidence( incidence, QDate(), true );
00238 KOIncidenceEditor *tmp = mView->editorDialog( incidence );
00239 tmp->selectInvitationCounterProposal( true );
00240 }
00241 mView->updateView();
00242 }
00243
00244 class KOInvitationFormatterHelper : public InvitationFormatterHelper
00245 {
00246 public:
00247 virtual QString generateLinkURL( const QString &id ) { return "kmail:groupware_request_" + id; }
00248 };
00249
00250
00251 static bool stringCompare( const QString &s1, const QString &s2 )
00252 {
00253 return ( s1.isEmpty() && s2.isEmpty() ) || ( s1 == s2 );
00254 }
00255
00256 static bool compareIncsExceptAttendees( Incidence *i1, Incidence *i2 )
00257 {
00258 if( i1->alarms().count() != i2->alarms().count() ) {
00259 return false;
00260 }
00261
00262 Alarm::List::ConstIterator a1 = i1->alarms().begin();
00263 Alarm::List::ConstIterator a2 = i2->alarms().begin();
00264 for( ; a1 != i1->alarms().end() && a2 != i2->alarms().end(); ++a1, ++a2 ) {
00265 if( **a1 == **a2 ) {
00266 continue;
00267 } else {
00268 return false;
00269 }
00270 }
00271
00272 bool recurrenceEqual = ( i1->recurrence() == 0 && i2->recurrence() == 0 );
00273 if ( !recurrenceEqual ) {
00274 recurrenceEqual = i1->recurrence() != 0 &&
00275 i2->recurrence() != 0 &&
00276 i2->recurrence() == i2->recurrence();
00277 }
00278
00279 return
00280 recurrenceEqual &&
00281 i1->dtStart() == i2->dtStart() &&
00282 i1->organizer() == i2->organizer() &&
00283 i1->doesFloat() == i2->doesFloat() &&
00284 i1->duration() == i2->duration() &&
00285 i2->hasDuration() == i2->hasDuration() &&
00286 stringCompare( i1->description(), i2->description() ) &&
00287 stringCompare( i1->summary(), i2->summary() ) &&
00288 i1->categories() == i2->categories() &&
00289 i1->attachments() == i2->attachments() &&
00290 i1->secrecy() == i2->secrecy() &&
00291 i1->priority() == i2->priority() &&
00292 stringCompare( i1->location(), i2->location() );
00293 }
00294
00295 static QStringList recipients( Attendee::List attendees )
00296 {
00297 QStringList attStrList;
00298 for ( Attendee::List::ConstIterator it = attendees.begin(); it != attendees.end(); ++it ) {
00299 attStrList << (*it)->fullName();
00300 }
00301 return attStrList;
00302 }
00303
00304
00305
00306
00307
00308
00309
00310 bool KOGroupware::sendICalMessage( QWidget* parent,
00311 KCal::Scheduler::Method method,
00312 Incidence *incidence,
00313 Incidence *oldincidence,
00314 KOGlobals::HowChanged action,
00315 bool attendeeStatusChanged,
00316 bool useLastDialogAnswer )
00317 {
00318
00319 if ( incidence->attendees().isEmpty() )
00320 return true;
00321
00322 bool isOrganizer = KOPrefs::instance()->thatIsMe( incidence->organizer().email() );
00323 int rc = 0;
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 if ( isOrganizer ) {
00339
00340
00341 if ( incidence->attendees().count() > 1
00342 || incidence->attendees().first()->email() != incidence->organizer().email() ) {
00343
00344 QString txt;
00345 switch( action ) {
00346 case KOGlobals::INCIDENCEEDITED:
00347 {
00348 bool sendUpdate = true;
00349
00350 Attendee::List attendees = incidence->attendees();
00351 Attendee::List::ConstIterator it;
00352
00353
00354 Attendee::List sameAtts;
00355 for ( it = attendees.begin(); it != attendees.end(); ++it ) {
00356 if ( (*it)->email() != incidence->organizer().email() ) {
00357 sameAtts << *it;
00358 }
00359 }
00360
00361 if ( incidence->summary().isEmpty() ) {
00362 incidence->setSummary( i18n( "<No summary given>" ) );
00363 }
00364
00365 if ( oldincidence ) {
00366
00367
00368
00369
00370
00371 Attendee::List oldattendees = oldincidence->attendees();
00372 Attendee::List::ConstIterator ot;
00373
00374 Attendee::List newAtts;
00375 Attendee::List remAtts;
00376 sameAtts.clear();
00377
00378
00379 for ( it = attendees.begin(); it != attendees.end(); ++it ) {
00380 bool found = false;
00381 for ( ot = oldattendees.begin(); ot != oldattendees.end(); ++ot ) {
00382 if ( (*it)->email() == (*ot)->email() ) {
00383 found = true;
00384 break;
00385 }
00386 }
00387 if ( !found ) {
00388 newAtts << *it;
00389 } else {
00390 if ( (*it)->email() != incidence->organizer().email() ) {
00391 sameAtts << *it;
00392 }
00393 }
00394 }
00395
00396
00397 for ( ot = oldattendees.begin(); ot != oldattendees.end(); ++ot ) {
00398 bool found = false;
00399 for ( it = attendees.begin(); it != attendees.end(); ++it ) {
00400 if ( (*it)->email() == (*ot)->email() ) {
00401 found = true;
00402 break;
00403 }
00404 }
00405 if ( !found ) {
00406 remAtts << *ot;
00407 }
00408 }
00409
00410
00411 if ( compareIncsExceptAttendees( incidence, oldincidence ) ) {
00412
00413 sendUpdate = false;
00414 }
00415
00416
00417 if ( newAtts.count() > 0 ) {
00418 const QStringList rList = recipients( newAtts );
00419 int newMail = KMessageBox::questionYesNoList(
00420 parent,
00421 i18n( "You are adding new attendees to the invitation \"%1\".\n"
00422 "Do you want to email an invitation to these new attendees?" ).
00423 arg( incidence->summary() ),
00424 rList,
00425 i18n( "New Attendees" ),
00426 KGuiItem( i18n( "Send Email" ) ), KGuiItem( i18n( "Do Not Send" ) ) );
00427 if ( newMail == KMessageBox::Yes ) {
00428 KCal::MailScheduler scheduler( mCalendar );
00429 incidence->setRevision( 0 );
00430 scheduler.performTransaction( incidence, Scheduler::Request, rList.join( "," ) );
00431 }
00432 }
00433
00434
00435 if ( remAtts.count() > 0 ) {
00436 const QStringList rList = recipients( remAtts );
00437 int newMail = KMessageBox::questionYesNoList(
00438 parent,
00439 i18n( "You removed attendees from the invitation \"%1\".\n"
00440 "Do you want to email a cancellation message to these attendees?" ).
00441 arg( incidence->summary() ),
00442 rList,
00443 i18n( "Removed Attendees" ),
00444 KGuiItem( i18n( "Send Email" ) ), KGuiItem( i18n( "Do Not Send" ) ) );
00445 if ( newMail == KMessageBox::Yes ) {
00446 KCal::MailScheduler scheduler( mCalendar );
00447 scheduler.performTransaction( incidence, Scheduler::Cancel, rList.join( "," ) );
00448 }
00449 }
00450 }
00451
00452
00453 if ( sameAtts.count() > 0 ) {
00454 const QStringList rList = recipients( sameAtts );
00455 int newMail;
00456 if ( sendUpdate ) {
00457 newMail = KMessageBox::questionYesNoList(
00458 parent,
00459 i18n( "You changed the invitation \"%1\".\n"
00460 "Do you want to email an updated invitation to these attendees?" ).
00461 arg( incidence->summary() ),
00462 rList,
00463 i18n( "Send Invitation Update" ),
00464 KGuiItem( i18n( "Send Email" ) ), KGuiItem( i18n( "Do Not Send" ) ) );
00465 } else {
00466 newMail = KMessageBox::questionYesNoList(
00467 parent,
00468 i18n( "You changed the invitation attendee list only.\n"
00469 "Do you want to email an updated invitation showing the new attendees?" ),
00470 rList,
00471 i18n( "Send Invitation Update" ),
00472 KGuiItem( i18n( "Send Email" ) ), KGuiItem( i18n( "Do Not Send" ) ) );
00473 }
00474 if ( newMail == KMessageBox::Yes ) {
00475 KCal::MailScheduler scheduler( mCalendar );
00476 incidence->setRevision( incidence->revision() + 1 );
00477 scheduler.performTransaction( incidence, Scheduler::Request, rList.join( "," ) );
00478 }
00479 }
00480 return true;
00481 }
00482
00483 case KOGlobals::INCIDENCEDELETED:
00484 Q_ASSERT( incidence->type() == "Event" || incidence->type() == "Todo" );
00485 if ( incidence->type() == "Event" ) {
00486 txt = i18n( "You removed the invitation \"%1\".\n"
00487 "Do you want to email the attendees that the event is canceled?" ).
00488 arg( incidence->summary() );
00489 } else if ( incidence->type() == "Todo" ) {
00490 txt = i18n( "You removed the invitation \"%1\".\n"
00491 "Do you want to email the attendees that the todo is canceled?" ).
00492 arg( incidence->summary() );
00493 }
00494 break;
00495
00496 case KOGlobals::INCIDENCEADDED:
00497 if ( incidence->type() == "Event" ) {
00498 txt = i18n( "The event \"%1\" includes other people.\n"
00499 "Do you want to email the invitation to the attendees?" ).
00500 arg( incidence->summary() );
00501 } else if ( incidence->type() == "Todo" ) {
00502 txt = i18n( "The todo \"%1\" includes other people.\n"
00503 "Do you want to email the invitation to the attendees?" ).
00504 arg( incidence->summary() );
00505 } else {
00506 txt = i18n( "This incidence includes other people. "
00507 "Should an email be sent to the attendees?" );
00508 }
00509 break;
00510
00511 default:
00512 kdError() << "Unsupported HowChanged action" << int( action ) << endl;
00513 break;
00514 }
00515
00516 if ( useLastDialogAnswer ) {
00517 rc = lastUsedDialogAnswer;
00518 } else {
00519 lastUsedDialogAnswer = rc = KMessageBox::questionYesNo(
00520 parent, txt, i18n( "Group Scheduling Email" ),
00521 KGuiItem( i18n( "Send Email" ) ), KGuiItem( i18n( "Do Not Send" ) ) );
00522 }
00523 } else {
00524 return true;
00525 }
00526 } else if( incidence->type() == "Todo" ) {
00527 QString txt;
00528 Todo *todo = static_cast<Todo *>( incidence );
00529 Todo *oldtodo = static_cast<Todo *>( oldincidence );
00530 if ( todo && oldtodo &&
00531 todo->percentComplete() != oldtodo->percentComplete() &&
00532 method == Scheduler::Request ) {
00533 txt = i18n( "Your completion status in this task has been changed. "
00534 "Do you want to send a status update to the task organizer?" );
00535 method = Scheduler::Reply;
00536 if ( useLastDialogAnswer ) {
00537 rc = lastUsedDialogAnswer;
00538 } else {
00539 lastUsedDialogAnswer = rc = KMessageBox::questionYesNo(
00540 parent, txt, i18n( "Group Scheduling Email" ),
00541 KGuiItem( i18n( "Send Update" ) ), KGuiItem( i18n( "Do Not Send" ) ) );
00542 }
00543 } else if ( attendeeStatusChanged && method == Scheduler::Request ) {
00544 txt = i18n( "Your status as a participant in this task changed. "
00545 "Do you want to send a status update to the task organizer?" );
00546 method = Scheduler::Reply;
00547 if ( useLastDialogAnswer ) {
00548 rc = lastUsedDialogAnswer;
00549 } else {
00550 lastUsedDialogAnswer = rc = KMessageBox::questionYesNo(
00551 parent, txt, i18n( "Group Scheduling Email" ),
00552 KGuiItem( i18n( "Send Update" ) ), KGuiItem( i18n( "Do Not Send" ) ) );
00553 }
00554 } else {
00555 if ( action == KOGlobals::INCIDENCEDELETED ) {
00556 const QStringList myEmails = KOPrefs::instance()->allEmails();
00557 bool askConfirmation = false;
00558 for ( QStringList::ConstIterator it = myEmails.begin(); it != myEmails.end(); ++it ) {
00559 QString email = *it;
00560 Attendee *me = incidence->attendeeByMail(email);
00561 if ( me &&
00562 ( me->status() == KCal::Attendee::Accepted ||
00563 me->status() == KCal::Attendee::Delegated ) ) {
00564 askConfirmation = true;
00565 break;
00566 }
00567 }
00568
00569 if ( !askConfirmation ) {
00570 return true;
00571 }
00572
00573 txt = i18n( "You had previously accepted your participation in this task. "
00574 "Do you want to send an updated response to the organizer "
00575 "removing yourself from the task?" );
00576 if ( useLastDialogAnswer ) {
00577 rc = lastUsedDialogAnswer;
00578 } else {
00579 lastUsedDialogAnswer = rc = KMessageBox::questionYesNo(
00580 parent, txt, i18n( "Group Scheduling Email" ),
00581 KGuiItem( i18n( "Send Update" ) ), KGuiItem( i18n( "Do Not Send" ) ) );
00582 setDoNotNotify( rc == KMessageBox::No );
00583 }
00584 } else {
00585 if ( useLastDialogAnswer ) {
00586 rc = lastUsedDialogAnswer;
00587 } else {
00588 if ( CalHelper::incOrganizerOwnsCalendar( mCalendar, incidence ) ) {
00589 txt = i18n( "<qt>"
00590 "You are modifying the organizer's task. "
00591 "Do you really want to edit it?<p>"
00592 "If \"yes\", all the attendees will be emailed the updated invitation."
00593 "</qt>" );
00594 lastUsedDialogAnswer = rc = KMessageBox::warningYesNo( parent, txt );
00595 if ( rc == KMessageBox::Yes ) {
00596 KCal::MailScheduler scheduler( mCalendar );
00597 scheduler.performTransaction( incidence, Scheduler::Request,
00598 recipients( incidence->attendees() ).join( "," ) );
00599 }
00600 } else {
00601 txt = i18n( "<qt>"
00602 "You are not the organizer of this task. Editing it will "
00603 "bring your invitation out of sync with the organizer's invitation. "
00604 "Do you really want to edit it?<p>"
00605 "If \"yes\", your local copy of the invitation will be different than "
00606 "the organizer and any other task participants."
00607 "</qt>" );
00608 lastUsedDialogAnswer = rc = KMessageBox::warningYesNo( parent, txt );
00609 }
00610 }
00611 return ( rc == KMessageBox::Yes );
00612 }
00613 }
00614 } else if ( incidence->type() == "Event" ) {
00615 QString txt;
00616 if ( attendeeStatusChanged && method == Scheduler::Request ) {
00617 txt = i18n( "Your status as an attendee of this event changed. "
00618 "Do you want to send a status update to the event organizer?" );
00619 method = Scheduler::Reply;
00620 if ( useLastDialogAnswer ) {
00621 rc = lastUsedDialogAnswer;
00622 } else {
00623 lastUsedDialogAnswer = rc = KMessageBox::questionYesNo(
00624 parent, txt, i18n( "Group Scheduling Email" ),
00625 KGuiItem( i18n( "Send Update" ) ), KGuiItem( i18n( "Do Not Send" ) ) );
00626 }
00627 } else {
00628 if ( action == KOGlobals::INCIDENCEDELETED ) {
00629 const QStringList myEmails = KOPrefs::instance()->allEmails();
00630 bool askConfirmation = false;
00631 for ( QStringList::ConstIterator it = myEmails.begin(); it != myEmails.end(); ++it ) {
00632 QString email = *it;
00633 Attendee *me = incidence->attendeeByMail(email);
00634 if ( me &&
00635 ( me->status() == KCal::Attendee::Accepted ||
00636 me->status() == KCal::Attendee::Delegated ) ) {
00637 askConfirmation = true;
00638 break;
00639 }
00640 }
00641
00642 if ( !askConfirmation ) {
00643 return true;
00644 }
00645
00646 txt = i18n( "You had previously accepted an invitation to this event. "
00647 "Do you want to send an updated response to the organizer "
00648 "declining the invitation?" );
00649 if ( useLastDialogAnswer ) {
00650 rc = lastUsedDialogAnswer;
00651 } else {
00652 lastUsedDialogAnswer = rc = KMessageBox::questionYesNo(
00653 parent, txt, i18n( "Group Scheduling Email" ),
00654 KGuiItem( i18n( "Send Update" ) ), KGuiItem( i18n( "Do Not Send" ) ) );
00655 setDoNotNotify( rc == KMessageBox::No );
00656 }
00657 } else {
00658 if ( useLastDialogAnswer ) {
00659 rc = lastUsedDialogAnswer;
00660 } else {
00661 if ( CalHelper::incOrganizerOwnsCalendar( mCalendar, incidence ) ) {
00662 txt = i18n( "<qt>"
00663 "You are modifying the organizer's event. "
00664 "Do you really want to edit it?<p>"
00665 "If \"yes\", all the attendees will be emailed the updated invitation."
00666 "</qt>" );
00667 lastUsedDialogAnswer = rc = KMessageBox::warningYesNo( parent, txt );
00668 if ( rc == KMessageBox::Yes ) {
00669 KCal::MailScheduler scheduler( mCalendar );
00670 scheduler.performTransaction( incidence, Scheduler::Request,
00671 recipients( incidence->attendees() ).join( "," ) );
00672 }
00673 } else {
00674 txt = i18n( "<qt>"
00675 "You are not the organizer of this event. Editing it will "
00676 "bring your invitation out of sync with the organizer's invitation. "
00677 "Do you really want to edit it?<p>"
00678 "If \"yes\", your local copy of the invitation will be different than "
00679 "the organizer and any other event participants."
00680 "</qt>" );
00681 lastUsedDialogAnswer = rc = KMessageBox::warningYesNo( parent, txt );
00682 }
00683 }
00684 return ( rc == KMessageBox::Yes );
00685 }
00686 }
00687 } else {
00688 kdWarning(5850) << "Groupware messages for Journals are not implemented yet!" << endl;
00689 return true;
00690 }
00691
00692 if ( rc == KMessageBox::Yes ) {
00693
00694
00695 if( incidence->summary().isEmpty() )
00696 incidence->setSummary( i18n("<No summary given>") );
00697
00698
00699 KCal::MailScheduler scheduler( mCalendar );
00700 scheduler.performTransaction( incidence, method );
00701
00702 return true;
00703 } else if ( rc == KMessageBox::No ) {
00704 return true;
00705 } else {
00706 return false;
00707 }
00708 }
00709
00710 void KOGroupware::sendCounterProposal(KCal::Calendar *calendar, KCal::Event * oldEvent, KCal::Event * newEvent) const
00711 {
00712 if ( !oldEvent || !newEvent || *oldEvent == *newEvent || !KOPrefs::instance()->mUseGroupwareCommunication )
00713 return;
00714 if ( KOPrefs::instance()->outlookCompatCounterProposals() ) {
00715 Incidence* tmp = oldEvent->clone();
00716 tmp->setSummary( i18n("Counter proposal: %1").arg( newEvent->summary() ) );
00717 tmp->setDescription( newEvent->description() );
00718 tmp->addComment( i18n("Proposed new meeting time: %1 - %2").
00719 arg( IncidenceFormatter::dateToString( newEvent->dtStart() ),
00720 IncidenceFormatter::dateToString( newEvent->dtEnd() ) ) );
00721 KCal::MailScheduler scheduler( calendar );
00722 scheduler.performTransaction( tmp, Scheduler::Reply );
00723 delete tmp;
00724 } else {
00725 KCal::MailScheduler scheduler( calendar );
00726 scheduler.performTransaction( newEvent, Scheduler::Counter );
00727 }
00728 }
00729
00730 #include "kogroupware.moc"