korganizer Library API Documentation

incomingdialog.cpp

00001 /*
00002     This file is part of KOrganizer.
00003 
00004     Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
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
00017     along with this program; if not, write to the Free Software
00018     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00019 */
00020 
00021 #include <qlistview.h>
00022 #include <qfile.h>
00023 #include <qdir.h>
00024 #include <qmap.h>
00025 
00026 #include <kglobal.h>
00027 #include <klocale.h>
00028 #include <kdebug.h>
00029 #include <kstandarddirs.h>
00030 #include <kmessagebox.h>
00031 
00032 #include <libkcal/incidence.h>
00033 #include <libkcal/event.h>
00034 #include <libkcal/calendar.h>
00035 #include <libkcal/freebusy.h>
00036 #include <libkcal/attendee.h>
00037 #include <libkcal/calendarresources.h>
00038 #include <libkcal/resourcecalendar.h>
00039 
00040 #ifndef KORG_NOMAIL
00041 #include "mailscheduler.h"
00042 #else
00043 #include <libkcal/dummyscheduler.h>
00044 #endif
00045 
00046 #ifndef KORG_NOKABC
00047  #include <kabc/stdaddressbook.h>
00048 #endif
00049 
00050 #include "incomingdialog.h"
00051 #include "koeventviewerdialog.h"
00052 #include "kocounterdialog.h"
00053 #include "koprefs.h"
00054 
00055 
00056 ScheduleItemIn::ScheduleItemIn(QListView *parent,IncidenceBase *ev,
00057                                Scheduler::Method method,ScheduleMessage::Status status)
00058   : QListViewItem(parent)
00059 {
00060   mIncidence = ev;
00061   mMethod = method;
00062   mStatus = status;
00063   setText(6,Scheduler::translatedMethodName(mMethod)+" ");
00064   setText(7,ScheduleMessage::statusName(status));
00065 }
00066 
00067 
00068 /* Visitor */
00069 ScheduleItemVisitor::ScheduleItemVisitor(ScheduleItemIn *item)
00070 {
00071   mItem = item;
00072 }
00073 
00074 ScheduleItemVisitor::~ScheduleItemVisitor()
00075 {
00076 }
00077 
00078 bool ScheduleItemVisitor::visit(Event *e)
00079 {
00080   mItem->setText(0,e->summary());
00081   mItem->setText(1,e->dtStartDateStr());
00082   if (e->doesFloat()) {
00083     mItem->setText(2,i18n("no time "));
00084     mItem->setText(4,i18n("no time "));
00085   }
00086   else {
00087     mItem->setText(2,e->dtStartTimeStr());
00088     mItem->setText(4,e->dtEndTimeStr());
00089   }
00090   if (e->hasEndDate()) {
00091     mItem->setText(3,e->dtEndDateStr());
00092   }
00093   else {
00094     mItem->setText(3,"");
00095   }
00096   mItem->setText(5,e->organizer()+" ");
00097 
00098   return true;
00099 }
00100 
00101 bool ScheduleItemVisitor::visit(Todo *e)
00102 {
00103   mItem->setText(0,e->summary());
00104   if (e->hasStartDate()) {
00105     mItem->setText(1,e->dtStartDateStr());
00106     if (!e->doesFloat()) {
00107       mItem->setText(2,e->dtStartTimeStr());
00108     }
00109   }
00110   if (e->hasDueDate()) {
00111     mItem->setText(1,e->dtDueDateStr());
00112     if (!e->doesFloat()) {
00113       mItem->setText(2,e->dtDueTimeStr());
00114     }
00115   }
00116   mItem->setText(5,e->organizer()+" ");
00117 
00118   return true;
00119 }
00120 
00121 bool ScheduleItemVisitor::visit(Journal *)
00122 {
00123   return false;
00124 }
00125 
00126 
00127 /*
00128  *  Constructs a IncomingDialog which is a child of 'parent', with the
00129  *  name 'name' and widget flags set to 'f'
00130  *
00131  *  The dialog will by default be modeless, unless you set 'modal' to
00132  *  true to construct a modal dialog.
00133  */
00134 IncomingDialog::IncomingDialog( Calendar *calendar, OutgoingDialog * outgoing,
00135                                 QWidget *parent, const char *name, bool modal,
00136                                 WFlags fl )
00137   : IncomingDialog_base( parent, name, modal, fl )
00138 {
00139   mCalendar = calendar;
00140   mOutgoing = outgoing;
00141 #ifndef KORG_NOMAIL
00142   mScheduler = new MailScheduler( mCalendar );
00143 #else
00144   mScheduler = new DummyScheduler( mCalendar );
00145 #endif
00146   mMessageListView->setColumnAlignment( 1, AlignHCenter );
00147   mMessageListView->setColumnAlignment( 2, AlignHCenter );
00148   mMessageListView->setColumnAlignment( 3, AlignHCenter );
00149   mMessageListView->setColumnAlignment( 4, AlignHCenter );
00150   connect( mMessageListView, SIGNAL( doubleClicked( QListViewItem * ) ),
00151            SLOT( showEvent( QListViewItem * ) ) );
00152   retrieve();
00153 }
00154 
00155 /*
00156  *  Destroys the object and frees any allocated resources
00157  */
00158 IncomingDialog::~IncomingDialog()
00159 {
00160   delete mScheduler;
00161   // no need to delete child widgets, Qt does it all for us
00162 }
00163 
00164 void IncomingDialog::setOutgoingDialog(OutgoingDialog *outgoing)
00165 {
00166   mOutgoing = outgoing;
00167 }
00168 
00169 void IncomingDialog::retrieve()
00170 {
00171   QPtrList <ScheduleMessage> messages = mScheduler->retrieveTransactions();
00172 
00173   ScheduleMessage *message;
00174   for(message = messages.first();message;message = messages.next()) {
00175     IncidenceBase *inc = message->event();
00176     Scheduler::Method method = (Scheduler::Method)message->method();
00177     ScheduleMessage::Status status = message->status();
00178     
00179     ScheduleItemIn *item = new ScheduleItemIn(mMessageListView,inc,method,status);
00180     if(inc->type()!="FreeBusy") {
00181       Incidence *incidence = static_cast<Incidence *>(inc);
00182       ScheduleItemVisitor v(item);
00183       if (!incidence->accept(v)) delete item;
00184     } else {
00185       FreeBusy *fb = static_cast<FreeBusy *>(item->event());
00186       item->setText(0, "FreeBusy");
00187       item->setText(1, KGlobal::locale()->formatDate( fb->dtStart().date() ) );
00188       item->setText(2, KGlobal::locale()->formatTime( fb->dtStart().time() ) );
00189       item->setText(3, KGlobal::locale()->formatDate( fb->dtEnd().date() ) );
00190       item->setText(4, KGlobal::locale()->formatTime( fb->dtEnd().time() ) );
00191       item->setText(5, fb->organizer());
00192     }
00193     automaticAction(item);
00194   }
00195   emit numMessagesChanged(mMessageListView->childCount());
00196 }
00197 
00198 void IncomingDialog::acceptAllMessages()
00199 {
00200   bool success = false;
00201 
00202   ScheduleItemIn *item = (ScheduleItemIn *)mMessageListView->firstChild();
00203   while(item) {
00204     ScheduleItemIn *nextitem = (ScheduleItemIn *)(item->nextSibling());
00205     if (acceptMessage(item)) success = true;
00206     item = nextitem;
00207   }
00208 
00209   if (success) emit calendarUpdated();
00210 }
00211 
00212 void IncomingDialog::acceptMessage()
00213 {
00214   ScheduleItemIn *item = (ScheduleItemIn *)mMessageListView->selectedItem();
00215   if (item) {
00216     if (acceptMessage(item)) emit calendarUpdated();
00217   }
00218 }
00219 
00220 bool IncomingDialog::acceptMessage(ScheduleItemIn *item)
00221 {
00222   switch (item->method()) {
00223     case Scheduler::Refresh:
00224         return incomeRefresh(item);
00225         break;
00226     case Scheduler::Counter:
00227         return incomeCounter(item);
00228         break;
00229     case Scheduler::Declinecounter:
00230         return incomeDeclineCounter(item);
00231         break;
00232     case Scheduler::Add:
00233         return incomeAdd(item);
00234         break;
00235     case Scheduler::Request:
00236         return incomeRequest(item);
00237         break;
00238     default:
00239         return incomeDefault(item);
00240   }
00241   return false;
00242 }
00243 
00244 void IncomingDialog::rejectMessage()
00245 {
00246   ScheduleItemIn *item = (ScheduleItemIn *)mMessageListView->selectedItem();
00247   if (item) {
00248     mScheduler->deleteTransaction(item->event());
00249     delete item;
00250     emit numMessagesChanged(mMessageListView->childCount());
00251   }
00252 }
00253 
00254 void IncomingDialog::showEvent(QListViewItem *item)
00255 {
00256   IncidenceBase *incidence = ((ScheduleItemIn *)item)->event();
00257   if( incidence && incidence->type() == "Event" ) {
00258     Event *event = static_cast<Event *>(incidence);
00259     KOEventViewerDialog *eventViewer = new KOEventViewerDialog(this);
00260     eventViewer->setEvent(event);
00261     eventViewer->show();
00262   }
00263 }
00264 
00265 bool IncomingDialog::incomeRefresh(ScheduleItemIn *item)
00266 {
00267   Event *ev = mCalendar->event(item->event()->uid());
00268   if (ev) {
00269     //user interaction before??
00270     Attendee::List attList = ev->attendees();
00271     Attendee::List::ConstIterator it;
00272     for( it = attList.begin(); it != attList.end(); ++it ) {
00273       // TODO: Why do we clone the event here?
00274       Event *event = new Event( *ev );
00275       mOutgoing->addMessage( event, Scheduler::Request, (*it)->email() );
00276       delete event;
00277     }
00278     mScheduler->deleteTransaction(item->event());
00279     delete item;
00280     emit numMessagesChanged(mMessageListView->childCount());
00281     return true;
00282   }
00283   mScheduler->deleteTransaction(item->event());
00284   delete item;
00285   emit numMessagesChanged(mMessageListView->childCount());
00286   return false;
00287 }
00288 
00289 bool IncomingDialog::incomeCounter(ScheduleItemIn *item)
00290 {
00291   IncidenceBase *incidence = ((ScheduleItemIn *)item)->event();
00292   // currently only events supportet - attetion at insertion below!
00293   if ( incidence->type() != "Event" ) return false;
00294 
00295   Event *counterEvent = static_cast<Event *>( incidence );
00296 
00297   Event *even = mCalendar->event(counterEvent->uid());
00298 
00299   KOCounterDialog *eventViewer = new KOCounterDialog(this);
00300   eventViewer->addText(i18n("counter proposal event","<b>Counter-event:</b><p>"));
00301   eventViewer->addEvent(counterEvent);
00302   eventViewer->addText("<hr>");
00303   eventViewer->addText(i18n("<b>Original event:</b><p>"));
00304   if (even) eventViewer->addEvent(even);
00305   else eventViewer->addText(i18n("A corresponding event is missing in your calendar!"));
00306   eventViewer->addText("<hr>");
00307   eventViewer->addText(i18n("If this counter-event is a good proposal for your event, press 'Accept'. All Attendees will then get the new version of this event"));
00308   eventViewer->show();
00309 
00310   eventViewer->exec();
00311   if (eventViewer->result()) {
00312     kdDebug(5850) << "IncomingDialog::Counter:Accept" << endl;
00313     int revision = 0;
00314     if (even) {
00315       revision = even->revision();
00316       mCalendar->deleteEvent(even);
00317     }
00318     mCalendar->addIncidence(counterEvent);
00319 
00320     even = mCalendar->event(item->event()->uid());
00321     if (even) {
00322       if (revision < even->revision())
00323         even->setRevision(even->revision()+1);
00324       else
00325         even->setRevision(revision+1);
00326       Event *ev = new Event(*even);
00327       mOutgoing->addMessage(ev,Scheduler::Request);
00328       delete(ev);
00329     }
00330     mScheduler->deleteTransaction(item->event());
00331     delete item;
00332     emit numMessagesChanged(mMessageListView->childCount());
00333     return true;
00334   } else {
00335     kdDebug(5850) << "IncomingDialog::Counter:Decline" << endl;
00336     //the counter-sender's email is missing...
00337     //now every attendee gets an declinecounter :-(
00338     mOutgoing->addMessage(counterEvent,Scheduler::Declinecounter);
00339     delete item;
00340     emit numMessagesChanged(mMessageListView->childCount());
00341     mScheduler->deleteTransaction(item->event());
00342     delete item;
00343     emit numMessagesChanged(mMessageListView->childCount());
00344     return true;
00345   }
00346   //mScheduler->deleteTransaction(item->event());
00347   delete item;
00348   emit numMessagesChanged(mMessageListView->childCount());
00349   return false;
00350 }
00351 
00352 bool IncomingDialog::incomeDeclineCounter(ScheduleItemIn *item)
00353 {
00354   Event *even = mCalendar->event(item->event()->uid());
00355   if (even) {
00356     mOutgoing->addMessage(even,Scheduler::Refresh);
00357     mScheduler->deleteTransaction(item->event());
00358     delete item;
00359     emit numMessagesChanged(mMessageListView->childCount());
00360     return true;
00361   }
00362   mScheduler->deleteTransaction(item->event());
00363   delete item;
00364   emit numMessagesChanged(mMessageListView->childCount());
00365   return false;
00366 }
00367 
00368 bool IncomingDialog::incomeAdd(ScheduleItemIn *item)
00369 {
00370   IncidenceBase *incidence = ((ScheduleItemIn *)item)->event();
00371   if (incidence->type() == "Event" ) {
00372     Event *refr = static_cast<Event *>( incidence );
00373     mOutgoing->addMessage(refr,Scheduler::Refresh);
00374     mScheduler->deleteTransaction( incidence );
00375     delete item;
00376     emit numMessagesChanged(mMessageListView->childCount());
00377     return true;
00378   }
00379   else {
00380     kdDebug(5850) << "IncomingDialog::incomeAdd - only Events are supportet yet" << endl;
00381     mScheduler->deleteTransaction( incidence );
00382     delete item;
00383     emit numMessagesChanged(mMessageListView->childCount());
00384     return false;
00385   }
00386 }
00387 
00388 bool IncomingDialog::incomeDefault(ScheduleItemIn *item)
00389 {
00390   if (mScheduler->acceptTransaction(item->event(),item->method(),item->status())) {
00391     delete item;
00392     emit numMessagesChanged(mMessageListView->childCount());
00393     return true;
00394   }
00395   else {
00396     KMessageBox::error(this,i18n("Unable to accept the IMIP-message. It may be a problem with the email addresses."));
00397     kdDebug(5850) << "IncomingDialog::acceptMessage(): Error!" << endl;
00398     return false;
00399   }
00400   return false;
00401 }
00402 
00403 bool IncomingDialog::incomeRequest(ScheduleItemIn *item)
00404 {
00405   if (item->event()->type()=="FreeBusy") {
00406     //handel freebusy request
00407     IncidenceBase *inc = item->event();
00408     QDateTime start = inc->dtStart();
00409     QDateTime end = start.addDays(inc->duration()/86400);
00410 
00411     FreeBusy *freebusy = new FreeBusy(mCalendar, start, end);
00412     freebusy->setOrganizer(inc->organizer());
00413     Attendee *att = new Attendee(KOPrefs::instance()->fullName(),
00414                                KOPrefs::instance()->email());
00415     freebusy->addAttendee(att);
00416 
00417     kdDebug(5850) << "calendarview: schedule_publish_freebusy: startDate: "
00418       << KGlobal::locale()->formatDateTime( start ) << " End Date: " 
00419       << KGlobal::locale()->formatDateTime( end ) << endl;
00420   
00421     if (mOutgoing->addMessage(freebusy,Scheduler::Reply)) {
00422       delete item;
00423       emit numMessagesChanged(mMessageListView->childCount());
00424       delete(freebusy);
00425       return true;
00426     }
00427     return false;     
00428   } else {
00429     return incomeDefault(item);
00430   }
00431   return false;
00432 }
00433 
00434 bool IncomingDialog::automaticAction(ScheduleItemIn *item)
00435 {
00436   bool autoAction = false;
00437   IncidenceBase *inc = item->event();
00438   Scheduler::Method method = item->method();
00439 
00440   if( inc->type()=="FreeBusy" ) {
00441     if ( method==Scheduler::Request ) {
00442       if ( KOPrefs::instance()->mIMIPAutoFreeBusy==KOPrefs::addressbookAuto ) {
00443         // reply freebusy information
00444         if ( checkOrganizerInAddressbook(inc->organizer()) ) {
00445           incomeRequest(item);
00446         }
00447       } else return false;
00448     } else {
00449 
00450       if ( method==Scheduler::Reply ) {
00451         if ( KOPrefs::instance()->mIMIPAutoFreeBusy==KOPrefs::addressbookAuto ) {
00452           // insert freebusy information
00453           //if ( checkAttendeesInAddressbook(inc) )
00454 
00455         } else return false;
00456       } else {
00457         if ( method==Scheduler::Publish) {
00458           if ( KOPrefs::instance()->mIMIPAutoFreeBusy==KOPrefs::addressbookAuto ) {
00459             // insert freebusy information
00460             //if ( checkOrganizerInAddressbook(inc->organizer()) )
00461 
00462           }
00463         } else return false;
00464       }
00465     }
00466   }
00467 
00468   if ( inc->type()=="Event" ) {
00469     if ( method==Scheduler::Request || method==Scheduler::Publish ) {
00470       if ( KOPrefs::instance()->mIMIPAutoInsertRequest==KOPrefs::addressbookAuto ) {
00471         // insert event
00472         if ( checkOrganizerInAddressbook(inc->organizer()) )
00473           autoAction = acceptMessage(item);
00474       } else return false;
00475     } else {
00476 
00477       if ( method==Scheduler::Reply ) {
00478         if ( KOPrefs::instance()->mIMIPAutoInsertReply==KOPrefs::addressbookAuto ) {
00479           //  update event information
00480           if ( checkAttendeesInAddressbook(inc) )
00481             autoAction = acceptMessage(item);
00482         } else return false;
00483       } else {
00484 
00485         if ( method==Scheduler::Refresh ) {
00486           if ( KOPrefs::instance()->mIMIPAutoRefresh==KOPrefs::addressbookAuto ) {
00487             // send refresh-information
00488             if ( checkAttendeesInAddressbook(inc) )
00489               autoAction = acceptMessage(item);
00490             else return false;
00491           } else return false;
00492         } else return false;
00493       }
00494     }
00495   }
00496   return autoAction;
00497 }
00498 
00499 bool IncomingDialog::checkOrganizerInAddressbook(QString organizer)
00500 {
00501   bool inBook = false;
00502 #ifndef KORG_NOKABC
00503   KABC::AddressBook *add_book = KABC::StdAddressBook::self();
00504   KABC::Addressee::List addressList;
00505   addressList = add_book->findByEmail(organizer);
00506   if ( addressList.size()>0 ) inBook = true;
00507 #endif
00508   return inBook;
00509 }
00510 
00511 bool IncomingDialog::checkAttendeesInAddressbook(IncidenceBase *inc)
00512 {
00513   bool inBook = false;
00514 #ifndef KORG_NOKABC
00515   KABC::AddressBook *add_book = KABC::StdAddressBook::self();
00516   KABC::Addressee::List addressList;
00517   Attendee::List attendees = inc->attendees();
00518   Attendee::List::ConstIterator it;
00519   for( it = attendees.begin(); it != attendees.end(); ++it ) {
00520     addressList = add_book->findByEmail( (*it)->email() );
00521     if ( addressList.size() > 0 ) inBook = true;
00522   }
00523 #endif
00524   return inBook;
00525 }
00526 
00527 #include "incomingdialog.moc"
KDE Logo
This file is part of the documentation for korganizer Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:38:27 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003