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