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 <libemailfunctions/email.h>
00043 #include <libkcal/attendee.h>
00044 #include <libkcal/journal.h>
00045 #include <libkcal/incidenceformatter.h>
00046 #include <kdebug.h>
00047 #include <kmessagebox.h>
00048 #include <kstandarddirs.h>
00049 #include <kdirwatch.h>
00050 #include <qfile.h>
00051 #include <qregexp.h>
00052 #include <qdir.h>
00053
00054 FreeBusyManager *KOGroupware::mFreeBusyManager = 0;
00055
00056 KOGroupware *KOGroupware::mInstance = 0;
00057
00058 KOGroupware *KOGroupware::create( CalendarView *view,
00059 KCal::CalendarResources *calendar )
00060 {
00061 if( !mInstance )
00062 mInstance = new KOGroupware( view, calendar );
00063 return mInstance;
00064 }
00065
00066 KOGroupware *KOGroupware::instance()
00067 {
00068
00069 Q_ASSERT( mInstance );
00070 return mInstance;
00071 }
00072
00073
00074 KOGroupware::KOGroupware( CalendarView* view, KCal::CalendarResources* cal )
00075 : QObject( 0, "kmgroupware_instance" ), mView( view ), mCalendar( cal )
00076 {
00077
00078 KDirWatch* watcher = KDirWatch::self();
00079 watcher->addDir( locateLocal( "data", "korganizer/income.accepted/" ) );
00080 watcher->addDir( locateLocal( "data", "korganizer/income.tentative/" ) );
00081 watcher->addDir( locateLocal( "data", "korganizer/income.cancel/" ) );
00082 watcher->addDir( locateLocal( "data", "korganizer/income.reply/" ) );
00083 connect( watcher, SIGNAL( dirty( const QString& ) ),
00084 this, SLOT( incomingDirChanged( const QString& ) ) );
00085
00086 incomingDirChanged( locateLocal( "data", "korganizer/income.accepted/" ) );
00087 incomingDirChanged( locateLocal( "data", "korganizer/income.tentative/" ) );
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
00115 action.truncate( action.length()-1 );
00116
00117
00118 QDir dir( path );
00119 const QStringList files = dir.entryList( QDir::Files );
00120 if ( files.isEmpty() )
00121
00122 return;
00123
00124
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::getFirstEmailAddress( t.readLine() );
00133 QString iCal = t.read();
00134
00135 f.remove();
00136
00137 ScheduleMessage *message = mFormat.parseScheduleMessage( mCalendar, iCal );
00138 if ( !message ) {
00139 QString errorMessage;
00140 if (mFormat.exception())
00141 errorMessage = i18n( "Error message: %1" ).arg( mFormat.exception()->message() );
00142 kdDebug(5850) << "MailScheduler::retrieveTransactions() Error parsing "
00143 << errorMessage << endl;
00144 KMessageBox::detailedError( mView,
00145 i18n("Error while processing an invitation or update."),
00146 errorMessage );
00147 return;
00148 }
00149
00150 KCal::Scheduler::Method method =
00151 static_cast<KCal::Scheduler::Method>( message->method() );
00152 KCal::ScheduleMessage::Status status = message->status();
00153 KCal::Incidence* incidence =
00154 dynamic_cast<KCal::Incidence*>( message->event() );
00155 KCal::MailScheduler scheduler( mCalendar );
00156 if ( action.startsWith( "accepted" ) || action.startsWith( "tentative" ) ) {
00157
00158
00159 KCal::Attendee::List attendees = incidence->attendees();
00160 KCal::Attendee::List::ConstIterator it;
00161 for ( it = attendees.begin(); it != attendees.end(); ++it ) {
00162 if( (*it)->email() == receiver ) {
00163 if ( action.startsWith( "accepted" ) )
00164 (*it)->setStatus( KCal::Attendee::Accepted );
00165 else
00166 (*it)->setStatus( KCal::Attendee::Tentative );
00167 break;
00168 }
00169 }
00170 scheduler.acceptTransaction( incidence, method, status );
00171 } else if ( action.startsWith( "cancel" ) )
00172
00173 scheduler.acceptTransaction( incidence, KCal::Scheduler::Cancel, status );
00174 else if ( action.startsWith( "reply" ) )
00175 scheduler.acceptTransaction( incidence, method, status );
00176 else
00177 kdError(5850) << "Unknown incoming action " << action << endl;
00178 mView->updateView();
00179 }
00180
00181 class KOInvitationFormatterHelper : public InvitationFormatterHelper
00182 {
00183 public:
00184 virtual QString generateLinkURL( const QString &id ) { return "kmail:groupware_request_" + id; }
00185 };
00186
00187
00188
00189
00190
00191
00192
00193 bool KOGroupware::sendICalMessage( QWidget* parent,
00194 KCal::Scheduler::Method method,
00195 Incidence* incidence, bool isDeleting,
00196 bool statusChanged )
00197 {
00198
00199 if( incidence->attendees().isEmpty() )
00200 return true;
00201
00202 bool isOrganizer = KOPrefs::instance()->thatIsMe( incidence->organizer().email() );
00203 int rc = 0;
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218 if ( isOrganizer ) {
00219
00220
00221
00222 if ( incidence->attendees().count() > 1
00223 || incidence->attendees().first()->email() != incidence->organizer().email() ) {
00224 QString type;
00225 if( incidence->type() == "Event") type = i18n("event");
00226 else if( incidence->type() == "Todo" ) type = i18n("task");
00227 else if( incidence->type() == "Journal" ) type = i18n("journal entry");
00228 else type = incidence->type();
00229 QString txt = i18n( "This %1 includes other people. "
00230 "Should email be sent out to the attendees?" )
00231 .arg( type );
00232 rc = KMessageBox::questionYesNoCancel( parent, txt,
00233 i18n("Group Scheduling Email"), i18n("Send Email"), i18n("Do Not Send") );
00234 } else {
00235 return true;
00236 }
00237 } else if( incidence->type() == "Todo" ) {
00238 if( method == Scheduler::Request )
00239
00240 method = Scheduler::Reply;
00241
00242
00243 QString txt = i18n( "Do you want to send a status update to the "
00244 "organizer of this task?");
00245 rc = KMessageBox::questionYesNo( parent, txt, QString::null, i18n("Send Update"), i18n("Do Not Send") );
00246 } else if( incidence->type() == "Event" ) {
00247 QString txt;
00248 if ( statusChanged && method == Scheduler::Request ) {
00249 txt = i18n( "Your status as an attendee of this event "
00250 "changed. Do you want to send a status update to the "
00251 "organizer of this event?" );
00252 method = Scheduler::Reply;
00253 rc = KMessageBox::questionYesNo( parent, txt, QString::null, i18n("Send Update"), i18n("Do Not Send") );
00254 } else {
00255 if( isDeleting )
00256 txt = i18n( "You are not the organizer of this event. "
00257 "Deleting it will bring your calendar out of sync "
00258 "with the organizers calendar. Do you really want "
00259 "to delete it?" );
00260 else
00261 txt = i18n( "You are not the organizer of this event. "
00262 "Editing it will bring your calendar out of sync "
00263 "with the organizers calendar. Do you really want "
00264 "to edit it?" );
00265 rc = KMessageBox::warningYesNo( parent, txt );
00266 return ( rc == KMessageBox::Yes );
00267 }
00268 } else {
00269 kdWarning(5850) << "Groupware messages for Journals are not implemented yet!" << endl;
00270 return true;
00271 }
00272
00273 if( rc == KMessageBox::Yes ) {
00274
00275
00276 if( incidence->summary().isEmpty() )
00277 incidence->setSummary( i18n("<No summary given>") );
00278
00279
00280 KCal::MailScheduler scheduler( mCalendar );
00281 scheduler.performTransaction( incidence, method );
00282
00283 return true;
00284 } else if( rc == KMessageBox::No )
00285 return true;
00286 else
00287 return false;
00288 }
00289
00290
00291 #include "kogroupware.moc"