• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdepim
  • Sitemap
  • Contact Us
 

korganizer

incidencechanger.cpp

Go to the documentation of this file.
00001 /*
00002   This file is part of KOrganizer.
00003 
00004   Copyright (C) 2004 Reinhold Kainhofer <reinhold@kainhofer.com>
00005 
00006   This program is free software; you can redistribute it and/or modify
00007   it under the terms of the GNU General Public License as published by
00008   the Free Software Foundation; either version 2 of the License, or
00009   (at your option) any later version.
00010 
00011   This program is distributed in the hope that it will be useful,
00012   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00014   GNU General Public License for more details.
00015 
00016   You should have received a copy of the GNU General Public License along
00017   with this program; if not, write to the Free Software Foundation, Inc.,
00018   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00019 
00020   As a special exception, permission is given to link this program
00021   with any edition of Qt, and distribute the resulting executable,
00022   without including the source code for Qt in the source distribution.
00023 */
00024 
00025 #include "incidencechanger.h"
00026 #include "koprefs.h"
00027 #include "kogroupware.h"
00028 #include "mailscheduler.h"
00029 
00030 #include <kcal/freebusy.h>
00031 #include <kcal/dndfactory.h>
00032 
00033 #include <kdebug.h>
00034 #include <kmessagebox.h>
00035 #include <klocale.h>
00036 
00037 bool IncidenceChanger::beginChange( Incidence *incidence )
00038 {
00039   if ( !incidence ) {
00040     return false;
00041   }
00042   kDebug() << "for incidence \"" << incidence->summary() << "\"";
00043   return mCalendar->beginChange( incidence );
00044 }
00045 
00046 bool IncidenceChanger::sendGroupwareMessage( Incidence *incidence,
00047                                              KCal::iTIPMethod method, bool deleting )
00048 {
00049   if ( KOPrefs::instance()->thatIsMe( incidence->organizer().email() ) &&
00050        incidence->attendeeCount() > 0 &&
00051        !KOPrefs::instance()->mUseGroupwareCommunication ) {
00052     emit schedule( method, incidence );
00053     return true;
00054   } else if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
00055     // FIXME: Find a widget to use as parent, instead of 0
00056     return KOGroupware::instance()->sendICalMessage( 0, method, incidence, deleting );
00057   }
00058   return true;
00059 }
00060 
00061 void IncidenceChanger::cancelAttendees( Incidence *incidence )
00062 {
00063   if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
00064     if ( KMessageBox::questionYesNo(
00065            0,
00066            i18n( "Some attendees were removed from the incidence. "
00067                  "Shall cancel messages be sent to these attendees?" ),
00068            i18n( "Attendees Removed" ), KGuiItem( i18n( "Send Messages" ) ),
00069            KGuiItem( i18n( "Do Not Send" ) ) ) == KMessageBox::Yes ) {
00070       // don't use KOGroupware::sendICalMessage here, because that asks just
00071       // a very general question "Other people are involved, send message to
00072       // them?", which isn't helpful at all in this situation. Afterwards, it
00073       // would only call the MailScheduler::performTransaction, so do this
00074       // manually.
00075       // FIXME: Groupware schedulling should be factored out to it's own class
00076       //        anyway
00077       KCal::MailScheduler scheduler( mCalendar );
00078       scheduler.performTransaction( incidence, iTIPCancel );
00079     }
00080   }
00081 }
00082 
00083 bool IncidenceChanger::endChange( Incidence *incidence )
00084 {
00085   // FIXME: if that's a groupware incidence, and I'm not the organizer,
00086   // send out a mail to the organizer with a counterproposal instead
00087   // of actually changing the incidence. Then no locking is needed.
00088   // FIXME: if that's a groupware incidence, and the incidence was
00089   // never locked, we can't unlock it with endChange().
00090   if ( !incidence ) {
00091     return false;
00092   }
00093 
00094   kDebug() << "\"" << incidence->summary() << "\"";
00095   return mCalendar->endChange( incidence );
00096 }
00097 
00098 bool IncidenceChanger::deleteIncidence( Incidence *incidence )
00099 {
00100   if ( !incidence ) {
00101     return true;
00102   }
00103 
00104   kDebug() << "\"" << incidence->summary() << "\"";
00105   bool doDelete = sendGroupwareMessage( incidence, KCal::iTIPCancel, true );
00106   if( doDelete ) {
00107     // @TODO: let Calendar::deleteIncidence do the locking...
00108     Incidence* tmp = incidence->clone();
00109     emit incidenceToBeDeleted( incidence );
00110     doDelete = mCalendar->deleteIncidence( incidence );
00111     if ( !KOPrefs::instance()->thatIsMe( tmp->organizer().email() ) ) {
00112       const QStringList myEmails = KOPrefs::instance()->allEmails();
00113       bool notifyOrganizer = false;
00114       for ( QStringList::ConstIterator it = myEmails.begin(); it != myEmails.end(); ++it ) {
00115         QString email = *it;
00116         Attendee *me = tmp->attendeeByMail(email);
00117         if ( me ) {
00118           if ( me->status() == KCal::Attendee::Accepted || me->status() == KCal::Attendee::Delegated )
00119             notifyOrganizer = true;
00120           Attendee *newMe = new Attendee( *me );
00121           newMe->setStatus( KCal::Attendee::Declined );
00122           tmp->clearAttendees();
00123           tmp->addAttendee( newMe );
00124           break;
00125         }
00126       }
00127 
00128       if ( notifyOrganizer ) {
00129         KCal::MailScheduler scheduler( mCalendar );
00130         scheduler.performTransaction( tmp, KCal::iTIPReply );
00131       }
00132     }
00133     emit incidenceDeleted( incidence );
00134   }
00135   return doDelete;
00136 }
00137 
00138 bool IncidenceChanger::cutIncidence( Incidence *incidence )
00139 {
00140   if ( !incidence ) {
00141     return true;
00142   }
00143 
00144   kDebug() << "\"" << incidence->summary() << "\"";
00145   bool doDelete = sendGroupwareMessage( incidence, KCal::iTIPCancel );
00146   if( doDelete ) {
00147     // @TODO: the factory needs to do the locking!
00148     DndFactory factory( mCalendar );
00149     emit incidenceToBeDeleted( incidence );
00150     factory.cutIncidence( incidence );
00151     emit incidenceDeleted( incidence );
00152   }
00153   return doDelete;
00154 }
00155 
00156 class IncidenceChanger::ComparisonVisitor : public IncidenceBase::Visitor
00157 {
00158   public:
00159     ComparisonVisitor() {}
00160     bool act( IncidenceBase *incidence, IncidenceBase *inc2 )
00161     {
00162       mIncidence2 = inc2;
00163       if ( incidence ) {
00164         return incidence->accept( *this );
00165       } else {
00166         return inc2 == 0;
00167       }
00168     }
00169 
00170   protected:
00171     bool visit( Event *event )
00172     {
00173       Event *ev2 = dynamic_cast<Event*>(mIncidence2);
00174       if ( event && ev2 ) {
00175         return *event == *ev2;
00176       } else {
00177         // either both 0, or return false;
00178         return ev2 == event;
00179       }
00180     }
00181     bool visit( Todo *todo )
00182     {
00183       Todo *to2 = dynamic_cast<Todo*>( mIncidence2 );
00184       if ( todo && to2 ) {
00185         return *todo == *to2;
00186       } else {
00187         // either both 0, or return false;
00188         return todo == to2;
00189       }
00190     }
00191     bool visit( Journal *journal )
00192     {
00193       Journal *j2 = dynamic_cast<Journal*>( mIncidence2 );
00194       if ( journal && j2 ) {
00195         return *journal == *j2;
00196       } else {
00197         // either both 0, or return false;
00198         return journal == j2;
00199       }
00200     }
00201     bool visit( FreeBusy *fb )
00202     {
00203       FreeBusy *fb2 = dynamic_cast<FreeBusy*>( mIncidence2 );
00204       if ( fb && fb2 ) {
00205         return *fb == *fb2;
00206       } else {
00207         // either both 0, or return false;
00208         return fb2 == fb;
00209       }
00210     }
00211 
00212   protected:
00213     IncidenceBase *mIncidence2;
00214 };
00215 
00216 class IncidenceChanger::AssignmentVisitor : public IncidenceBase::Visitor
00217 {
00218   public:
00219     AssignmentVisitor() {}
00220     bool act( IncidenceBase *incidence, IncidenceBase *inc2 )
00221     {
00222       mIncidence2 = inc2;
00223       if ( incidence ) {
00224         return incidence->accept( *this );
00225       } else {
00226         return false;
00227       }
00228     }
00229   protected:
00230     bool visit( Event *event )
00231     {
00232       Event *ev2 = dynamic_cast<Event*>( mIncidence2 );
00233       if ( event && ev2 ) {
00234         *event = *ev2;
00235         return true;
00236       } else {
00237         return false;
00238       }
00239     }
00240     bool visit( Todo *todo )
00241     {
00242       Todo *to2 = dynamic_cast<Todo*>( mIncidence2 );
00243       if ( todo && to2 ) {
00244         *todo = *to2;
00245         return true;
00246       } else {
00247         return false;
00248       }
00249     }
00250     bool visit( Journal *journal )
00251     {
00252       Journal *j2 = dynamic_cast<Journal*>(mIncidence2);
00253       if ( journal && j2 ) {
00254         *journal = *j2;
00255         return true;
00256       } else {
00257         return false;
00258       }
00259     }
00260     bool visit( FreeBusy *fb )
00261     {
00262       FreeBusy *fb2 = dynamic_cast<FreeBusy*>( mIncidence2 );
00263       if ( fb && fb2 ) {
00264         *fb = *fb2;
00265         return true;
00266       } else {
00267         return false;
00268       }
00269     }
00270   protected:
00271     IncidenceBase *mIncidence2;
00272 };
00273 
00274 bool IncidenceChanger::incidencesEqual( Incidence *inc1, Incidence *inc2 )
00275 {
00276   ComparisonVisitor v;
00277   return ( v.act( inc1, inc2 ) );
00278 }
00279 
00280 bool IncidenceChanger::assignIncidence( Incidence *inc1, Incidence *inc2 )
00281 {
00282   AssignmentVisitor v;
00283   return v.act( inc1, inc2 );
00284 }
00285 
00286 bool IncidenceChanger::myAttendeeStatusChanged( Incidence *oldInc, Incidence *newInc )
00287 {
00288   Attendee *oldMe = oldInc->attendeeByMails( KOPrefs::instance()->allEmails() );
00289   Attendee *newMe = newInc->attendeeByMails( KOPrefs::instance()->allEmails() );
00290   if ( oldMe && newMe && ( oldMe->status() != newMe->status() ) ) {
00291     return true;
00292   }
00293 
00294   return false;
00295 }
00296 
00297 bool IncidenceChanger::changeIncidence( Incidence *oldinc, Incidence *newinc,
00298                                         int action )
00299 {
00300   kDebug() << "for incidence \"" << newinc->summary()
00301            << "\" ( old one was \"" << oldinc->summary() << "\")";
00302 
00303   if ( incidencesEqual( newinc, oldinc ) ) {
00304     // Don't do anything
00305     kDebug() << "Incidence not changed";
00306   } else {
00307     kDebug() << "Changing incidence";
00308     bool statusChanged = myAttendeeStatusChanged( oldinc, newinc );
00309     int revision = newinc->revision();
00310     newinc->setRevision( revision + 1 );
00311     // FIXME: Use a generic method for this! Ideally, have an interface class
00312     //        for group cheduling. Each implementation could then just do what
00313     //        it wants with the event. If no groupware is used,use the null
00314     //        pattern...
00315     bool revert = KOPrefs::instance()->mUseGroupwareCommunication;
00316     if ( revert &&
00317         KOGroupware::instance()->sendICalMessage( 0,
00318                                                   KCal::iTIPRequest,
00319                                                   newinc, false, statusChanged ) ) {
00320       // Accept the event changes
00321       if ( action < 0 ) {
00322         emit incidenceChanged( oldinc, newinc );
00323       } else {
00324         emit incidenceChanged( oldinc, newinc, action );
00325       }
00326       revert = false;
00327     }
00328 
00329     if ( revert ) {
00330       assignIncidence( newinc, oldinc );
00331       return false;
00332     }
00333   }
00334   return true;
00335 }
00336 
00337 bool IncidenceChanger::addIncidence( Incidence *incidence, QWidget *parent )
00338 {
00339   kDebug() << "\"" << incidence->summary() << "\"";
00340   if ( KOPrefs::instance()->mUseGroupwareCommunication ) {
00341     if ( !KOGroupware::instance()->sendICalMessage( parent,
00342                                                     KCal::iTIPRequest,
00343                                                     incidence ) ) {
00344       kError() << "sendIcalMessage failed.";
00345     }
00346   }
00347   // FIXME: This is a nasty hack, since we need to set a parent for the
00348   //        resource selection dialog. However, we don't have any UI methods
00349   //        in the calendar, only in the CalendarResources::DestinationPolicy
00350   //        So we need to type-cast it and extract it from the CalendarResources
00351   CalendarResources *stdcal = dynamic_cast<CalendarResources*>(mCalendar);
00352   QWidget *tmpparent = 0;
00353   if ( stdcal ) {
00354     tmpparent = stdcal->dialogParentWidget();
00355     stdcal->setDialogParentWidget( parent );
00356   }
00357   bool success = mCalendar->addIncidence( incidence );
00358   if ( stdcal ) {
00359     // Reset the parent widget, otherwise we'll end up with pointers to deleted
00360     // widgets sooner or later
00361     stdcal->setDialogParentWidget( tmpparent );
00362   }
00363   if ( !success ) {
00364     kDebug() << "failed";
00365     KMessageBox::sorry( parent,
00366                         i18n( "Unable to save %1 \"%2\".",
00367                               i18n( incidence->type() ),
00368                               incidence->summary() ) );
00369     return false;
00370   }
00371   emit incidenceAdded( incidence );
00372   return true;
00373 }
00374 
00375 #include "incidencechanger.moc"

korganizer

Skip menu "korganizer"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members

kdepim

Skip menu "kdepim"
  • akonadi
  •   clients
  •   kabc
  •   kcal
  •   kcm
  • akregator
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt
  • kdgantt1
  • kjots
  • kleopatra
  • kmail
  • kmobiletools
  • knode
  • knotes
  • kontact
  • kontactinterfaces
  • korganizer
  •   korgac
  • kpilot
  • ktimetracker
  • libkdepim
  • libkholidays
  • libkleo
  • libkpgp
  • maildir
Generated for kdepim by doxygen 1.5.4
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal