korganizer Library API Documentation

kogroupware.cpp

00001 /*
00002   This file is part of the Groupware/KOrganizer integration.
00003 
00004   Requires the Qt and KDE widget libraries, available at no cost at
00005   http://www.trolltech.com and http://www.kde.org respectively
00006 
00007   Copyright (c) 2002-2004 Klarälvdalens Datakonsult AB
00008         <info@klaralvdalens-datakonsult.se>
00009 
00010   This program is free software; you can redistribute it and/or modify
00011   it under the terms of the GNU General Public License as published by
00012   the Free Software Foundation; either version 2 of the License, or
00013   (at your option) any later version.
00014 
00015   This program is distributed in the hope that it will be useful,
00016   but WITHOUT ANY WARRANTY; without even the implied warranty of
00017   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018   GNU General Public License for more details.
00019 
00020   You should have received a copy of the GNU General Public License
00021   along with this program; if not, write to the Free Software
00022   Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00023   MA  02111-1307, USA.
00024 
00025   In addition, as a special exception, the copyright holders give
00026   permission to link the code of this program with any edition of
00027   the Qt library by Trolltech AS, Norway (or with modified versions
00028   of Qt that use the same license as Qt), and distribute linked
00029   combinations including the two.  You must obey the GNU General
00030   Public License in all respects for all of the code used other than
00031   Qt.  If you modify this file, you may extend this exception to
00032   your version of the file, but you are not obligated to do so.  If
00033   you do not wish to do so, delete this exception statement from
00034   your version.
00035 */
00036 
00037 #include "kogroupware.h"
00038 #include "freebusymanager.h"
00039 #include "calendarview.h"
00040 #include "mailscheduler.h"
00041 #include "koprefs.h"
00042 #include <libkdepim/email.h>
00043 #include <libkcal/attendee.h>
00044 #include <libkcal/journal.h>
00045 #include <kdebug.h>
00046 #include <kmessagebox.h>
00047 #include <kstandarddirs.h>
00048 #include <kdirwatch.h>
00049 #include <qfile.h>
00050 #include <qregexp.h>
00051 #include <qdir.h>
00052 
00053 FreeBusyManager *KOGroupware::mFreeBusyManager = 0;
00054 
00055 KOGroupware *KOGroupware::mInstance = 0;
00056 
00057 KOGroupware *KOGroupware::create( CalendarView *view,
00058                                   KCal::Calendar *calendar )
00059 {
00060   if( !mInstance )
00061     mInstance = new KOGroupware( view, calendar );
00062   return mInstance;
00063 }
00064 
00065 KOGroupware *KOGroupware::instance()
00066 {
00067   // Doesn't create, that is the task of create()
00068   Q_ASSERT( mInstance );
00069   return mInstance;
00070 }
00071 
00072 
00073 KOGroupware::KOGroupware( CalendarView* view, KCal::Calendar* calendar )
00074   : QObject( 0, "kmgroupware_instance" )
00075 {
00076   mView = view;
00077   mCalendar = calendar;
00078 
00079   // Set up the dir watch of the three incoming dirs
00080   KDirWatch* watcher = KDirWatch::self();
00081   watcher->addDir( locateLocal( "data", "korganizer/income.accepted/" ) );
00082   watcher->addDir( locateLocal( "data", "korganizer/income.cancel/" ) );
00083   watcher->addDir( locateLocal( "data", "korganizer/income.reply/" ) );
00084   connect( watcher, SIGNAL( dirty( const QString& ) ),
00085            this, SLOT( incomingDirChanged( const QString& ) ) );
00086   // Now set the ball rolling
00087   incomingDirChanged( locateLocal( "data", "korganizer/income.accepted/" ) );
00088   incomingDirChanged( locateLocal( "data", "korganizer/income.cancel/" ) );
00089   incomingDirChanged( locateLocal( "data", "korganizer/income.reply/" ) );
00090 }
00091 
00092 FreeBusyManager *KOGroupware::freeBusyManager()
00093 {
00094   if ( !mFreeBusyManager ) {
00095     mFreeBusyManager = new FreeBusyManager( this, "freebusymanager" );
00096     mFreeBusyManager->setCalendar( mCalendar );
00097     connect( mCalendar, SIGNAL( calendarChanged() ),
00098              mFreeBusyManager, SLOT( slotPerhapsUploadFB() ) );
00099   }
00100 
00101   return mFreeBusyManager;
00102 }
00103 
00104 void KOGroupware::incomingDirChanged( const QString& path )
00105 {
00106   const QString incomingDirName = locateLocal( "data","korganizer/" )
00107                                   + "income.";
00108   if ( !path.startsWith( incomingDirName ) ) {
00109     kdDebug(5850) << "incomingDirChanged: Wrong dir " << path << endl;
00110     return;
00111   }
00112   QString action = path.mid( incomingDirName.length() );
00113   while ( action.length() > 0 && action[ action.length()-1 ] == '/' )
00114     // Strip slashes at the end
00115     action.truncate( action.length()-1 );
00116 
00117   // Handle accepted invitations
00118   QDir dir( path );
00119   QStringList files = dir.entryList( QDir::Files );
00120   if ( files.count() == 0 )
00121     // No more files here
00122     return;
00123 
00124   // Read the file and remove it
00125   QFile f( path + "/" + files[0] );
00126   if (!f.open(IO_ReadOnly)) {
00127     kdError(5850) << "Can't open file '" << files[0] << "'" << endl;
00128     return;
00129   }
00130   QTextStream t(&f);
00131   t.setEncoding( QTextStream::UnicodeUTF8 );
00132   QString receiver = KPIM::getEmailAddr( t.readLine() );
00133   QString iCal = t.read();
00134 
00135   ScheduleMessage *message = mFormat.parseScheduleMessage( mCalendar, iCal );
00136   if ( !message ) {
00137     QString errorMessage;
00138     if (mFormat.exception())
00139       errorMessage = "\nError message: " + mFormat.exception()->message();
00140     kdDebug(5850) << "MailScheduler::retrieveTransactions() Error parsing"
00141                   << errorMessage << endl;
00142     f.close();
00143     return;
00144   } else
00145     f.remove();
00146 
00147   KCal::Scheduler::Method method =
00148     static_cast<KCal::Scheduler::Method>( message->method() );
00149   KCal::ScheduleMessage::Status status = message->status();
00150   KCal::Incidence* incidence =
00151     dynamic_cast<KCal::Incidence*>( message->event() );
00152   KCal::MailScheduler scheduler( mCalendar );
00153   if ( action.startsWith( "accepted" ) ) {
00154     // Find myself and set to answered and accepted
00155     KCal::Attendee::List attendees = incidence->attendees();
00156     KCal::Attendee::List::ConstIterator it;
00157     for ( it = attendees.begin(); it != attendees.end(); ++it ) {
00158       if( (*it)->email() == receiver ) {
00159         (*it)->setStatus( KCal::Attendee::Accepted );
00160         break;
00161       }
00162     }
00163     scheduler.acceptTransaction( incidence, method, status );
00164   } else if ( action.startsWith( "cancel" ) )
00165     // TODO: Could this be done like the others?
00166     mCalendar->deleteIncidence( incidence );
00167   else if ( action.startsWith( "reply" ) )
00168     scheduler.acceptTransaction( incidence, method, status );
00169   else
00170     kdError(5850) << "Unknown incoming action " << action << endl;
00171   mView->updateView();
00172 }
00173 
00174 /* This function sends mails if necessary, and makes sure the user really
00175  * want to change his calendar.
00176  *
00177  * Return true means accept the changes
00178  * Return false means revert the changes
00179  */
00180 bool KOGroupware::sendICalMessage( QWidget* parent,
00181                                    KCal::Scheduler::Method method,
00182                                    Incidence* incidence, bool isDeleting )
00183 {
00184   bool isOrganizer = KOPrefs::instance()->thatIsMe( incidence->organizer().email() );
00185 
00186   int rc = 0;
00187   if( isOrganizer ) {
00188     // Figure out if there are other people involved in this incidence
00189     bool otherPeople = false;
00190     Attendee::List attendees = incidence->attendees();
00191     Attendee::List::ConstIterator it;
00192     for ( it = attendees.begin(); it != attendees.end(); ++it ) {
00193       // Don't send email to ourselves
00194       if ( !KOPrefs::instance()->thatIsMe( (*it)->email() ) ) {
00195         otherPeople = true;
00196         break;
00197       }
00198     }
00199     if( !otherPeople )
00200       // You never send something out if no others are involved
00201       return true;
00202 
00203     QString type;
00204     if( incidence->type() == "Event") type = i18n("event");
00205     else if( incidence->type() == "Todo" ) type = i18n("task");
00206     else if( incidence->type() == "Journal" ) type = i18n("journal entry");
00207     else type = incidence->type();
00208     QString txt = i18n( "This %1 includes other people. "
00209                         "Should email be sent out to the attendees?" )
00210       .arg( type );
00211     rc = KMessageBox::questionYesNoCancel( parent, txt,
00212                                            i18n("Group scheduling email") );
00213   } else if( incidence->type() == "Todo" ) {
00214     if( method == Scheduler::Request )
00215       // This is an update to be sent to the organizer
00216       method = Scheduler::Reply;
00217 
00218     // Ask if the user wants to tell the organizer about the current status
00219     QString txt = i18n( "Do you want to send a status update to the "
00220                         "organizer of this task?");
00221     rc = KMessageBox::questionYesNo( parent, txt );
00222   } else if( incidence->type() == "Event" ) {
00223     // When you're not the organizer of an event, an update mail can
00224     // never be sent out
00225     // Pending(Bo): So how will an attendee cancel his participation?
00226     QString txt;
00227     if( isDeleting )
00228       txt = i18n( "You are not the organizer of this event. "
00229                   "Deleting it will bring your calendar out of sync "
00230                   "with the organizers calendar. Do you really want "
00231                   "to delete it?" );
00232     else
00233       txt = i18n( "You are not the organizer of this event. "
00234                   "Editing it will bring your calendar out of sync "
00235                   "with the organizers calendar. Do you really want "
00236                   "to edit it?" );
00237     rc = KMessageBox::questionYesNo( parent, txt );
00238     return ( rc == KMessageBox::Yes );
00239   } else {
00240     qFatal( "Some unimplemented thing happened" );
00241   }
00242 
00243   if( rc == KMessageBox::Yes ) {
00244     // We will be sending out a message here. Now make sure there is
00245     // some summary
00246     if( incidence->summary().isEmpty() )
00247       incidence->setSummary( i18n("<No summary given>") );
00248 
00249     // Send the mail
00250     KCal::MailScheduler scheduler( mCalendar );
00251     scheduler.performTransaction( incidence, method );
00252 
00253     return true;
00254   } else if( rc == KMessageBox::No )
00255     return true;
00256   else
00257     return false;
00258 }
00259 
00260 
00261 #include "kogroupware.moc"
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 Wed Mar 23 22:45:25 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003