00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <stdlib.h>
00022
00023 #include <qdatetime.h>
00024 #include <qstring.h>
00025 #include <qptrlist.h>
00026 #include <qwidgetlist.h>
00027 #include <qwidget.h>
00028
00029 #include <kdebug.h>
00030 #include <kapplication.h>
00031 #include <kstringhandler.h>
00032
00033 #include <libkcal/calendarlocal.h>
00034 #include <libkcal/calendar.h>
00035 #include <libkcal/journal.h>
00036
00037 #include <kresources/configwidget.h>
00038
00039 #include <kabc/locknull.h>
00040
00041 #include "dateset.h"
00042 #include "exchangeaccount.h"
00043 #include "exchangeclient.h"
00044 #include "exchangemonitor.h"
00045
00046 #include "resourceexchange.h"
00047 #include "resourceexchangeconfig.h"
00048
00049 using namespace KCal;
00050 using namespace KPIM;
00051
00052 extern "C"
00053 {
00054 void* init_resourcecalendarexchange()
00055 {
00056 return new KRES::PluginFactory<ResourceExchange,ResourceExchangeConfig>();
00057 }
00058 }
00059
00060 class ResourceExchange::EventInfo {
00061 public:
00062 KCal::Event* event;
00063 KURL url;
00064 long updateWatch;
00065 };
00066
00067 ResourceExchange::ResourceExchange( const KConfig *config )
00068 : ResourceCalendar( config )
00069 {
00070 mLock = new KABC::LockNull( true );
00071
00072 mCache = 0;
00073 mTimeZoneId = QString::fromLatin1( "UTC" );
00074
00075 kdDebug() << "Creating ResourceExchange" << endl;
00076 if (config ) {
00077 mAccount = new ExchangeAccount(
00078 config->readEntry( "ExchangeHost" ),
00079 config->readEntry( "ExchangePort" ),
00080 config->readEntry( "ExchangeAccount" ),
00081 KStringHandler::obscure( config->readEntry( "ExchangePassword" ) ),
00082 config->readEntry( "ExchangeMailbox" ) );
00083 mCachedSeconds = config->readNumEntry( "ExchangeCacheTimeout", 600 );
00084 mAutoMailbox = config->readBoolEntry( "ExchangeAutoMailbox", true );
00085 } else {
00086 mAccount = new ExchangeAccount( "", "", "", "" );
00087 mCachedSeconds = 600;
00088 }
00089 }
00090
00091 ResourceExchange::~ResourceExchange()
00092 {
00093 kdDebug() << "Destructing ResourceExchange" << endl;
00094 close();
00095 }
00096
00097 void ResourceExchange::writeConfig( KConfig* config )
00098 {
00099 ResourceCalendar::writeConfig( config );
00100 config->writeEntry( "ExchangeHost", mAccount->host() );
00101 config->writeEntry( "ExchangePort", mAccount->port() );
00102 config->writeEntry( "ExchangeAccount", mAccount->account() );
00103 config->writeEntry( "ExchangeMailbox", mAccount->mailbox() );
00104 config->writeEntry( "ExchangePassword", KStringHandler::obscure( mAccount->password() ) );
00105 config->writeEntry( "ExchangeCacheTimeout", mCachedSeconds );
00106 config->writeEntry( "ExchangeAutoMailbox", mAutoMailbox );
00107 }
00108
00109 bool ResourceExchange::doOpen()
00110 {
00111 mClient = new ExchangeClient( mAccount );
00112 connect( mClient, SIGNAL( downloadFinished( int, const QString& ) ),
00113 this, SLOT( slotDownloadFinished( int, const QString& ) ) );
00114 connect( mClient, SIGNAL( event( KCal::Event*, const KURL& ) ),
00115 this, SLOT( downloadedEvent( KCal::Event*, const KURL& ) ) );
00116
00117 kdDebug() << "Creating monitor" << endl;
00118 QHostAddress ip;
00119 ip.setAddress( mAccount->host() );
00120 mMonitor = new ExchangeMonitor( mAccount, ExchangeMonitor::CallBack, ip );
00121 connect( mMonitor, SIGNAL(notify( const QValueList<long>& , const QValueList<KURL>& )), this, SLOT(slotMonitorNotify( const QValueList<long>& , const QValueList<KURL>& )) );
00122 connect( mMonitor, SIGNAL(error(int , const QString&)), this, SLOT(slotMonitorError(int , const QString&)) );
00123
00124 mMonitor->addWatch( mAccount->calendarURL(), ExchangeMonitor::UpdateNewMember, 1 );
00125
00126 QWidgetList* widgets = QApplication::topLevelWidgets();
00127 if ( !widgets->isEmpty() )
00128 mClient->setWindow( widgets->first() );
00129 delete widgets;
00130
00131 mDates = new DateSet();
00132
00133 mEventDates = new QMap<Event,QDateTime>();
00134 mCacheDates = new QMap<QDate, QDateTime>();
00135
00136 mCache = new CalendarLocal( mTimeZoneId );
00137
00138
00139
00140
00141 return true;
00142 }
00143
00144 void ResourceExchange::doClose()
00145 {
00146 kdDebug() << "ResourceExchange::doClose()" << endl;
00147
00148
00149 delete mDates; mDates = 0;
00150 delete mMonitor; mMonitor = 0;
00151 delete mClient; mClient = 0;
00152 delete mAccount; mAccount = 0;
00153 delete mEventDates; mEventDates = 0;
00154 delete mCacheDates; mCacheDates = 0;
00155 if (mCache) {
00156 mCache->close();
00157 delete mCache; mCache = 0;
00158 }
00159
00160 }
00161
00162 bool ResourceExchange::load()
00163 {
00164 return true;
00165 }
00166
00167 bool ResourceExchange::save()
00168 {
00169 return true;
00170 }
00171
00172 KABC::Lock *ResourceExchange::lock()
00173 {
00174 return mLock;
00175 }
00176
00177 void ResourceExchange::slotMonitorNotify( const QValueList<long>& IDs, const QValueList<KURL>& urls )
00178 {
00179 kdDebug() << "ResourceExchange::slotMonitorNotify()" << endl;
00180
00181 QString result;
00182 KPIM::ExchangeMonitor::IDList::ConstIterator it;
00183 for ( it = IDs.begin(); it != IDs.end(); ++it ) {
00184 if ( it == IDs.begin() )
00185 result += QString::number( (*it) );
00186 else
00187 result += "," + QString::number( (*it) );
00188 }
00189 kdDebug() << "Got signals for " << result << endl;
00190 QValueList<KURL>::ConstIterator it2;
00191 for ( it2 = urls.begin(); it2 != urls.end(); ++it2 ) {
00192 kdDebug() << "URL: " << (*it2).prettyURL() << endl;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 }
00211
00212 void ResourceExchange::slotMonitorError( int errorCode, const QString& moreInfo )
00213 {
00214 kdError() << "Ignoring error from Exchange monitor, code=" << errorCode << "; more info: " << moreInfo << endl;
00215 }
00216
00217
00218 bool ResourceExchange::addEvent(Event *anEvent)
00219 {
00220 if( !mCache )
00221 return false;
00222 kdDebug() << "ResourceExchange::addEvent" << endl;
00223
00224
00225
00226 mCache->addEvent( anEvent );
00227
00228 uploadEvent( anEvent );
00229
00230
00231 anEvent->registerObserver( this );
00232
00233
00234 return true;
00235 }
00236
00237 void ResourceExchange::uploadEvent( Event* event )
00238 {
00239 mClient->uploadSynchronous( event );
00240 }
00241
00242 void ResourceExchange::deleteEvent(Event *event)
00243 {
00244 if ( !mCache )
00245 return;
00246 kdDebug(5800) << "ResourceExchange::deleteEvent" << endl;
00247
00248 mClient->removeSynchronous( event );
00249
00250
00251 mCache->deleteEvent( event );
00252
00253
00254 }
00255
00256
00257 Event *ResourceExchange::event( const QString &uid )
00258 {
00259 kdDebug(5800) << "ResourceExchange::event(): " << uid << endl;
00260
00261
00262 return mCache->event( uid );
00263 }
00264
00265 void ResourceExchange::subscribeEvents( const QDate& start, const QDate& end )
00266 {
00267 kdDebug(5800) << "ResourceExchange::subscribeEvents()" << endl;
00268
00269
00270 mClient->download( start, end, false );
00271 }
00272
00273 void ResourceExchange::downloadedEvent( KCal::Event* event, const KURL& url )
00274 {
00275 kdDebug() << "Downloaded event: " << event->summary() << " from url " << url.prettyURL() << endl;
00276
00277
00278
00279
00280 }
00281
00282 void ResourceExchange::slotDownloadFinished( int result, const QString& moreinfo )
00283 {
00284 kdDebug() << "ResourceExchange::downloadFinished" << endl;
00285
00286 if ( result != KPIM::ExchangeClient::ResultOK ) {
00287
00288 kdError() << "ResourceExchange::slotDownloadFinished(): error " << result << ": " << moreinfo << endl;
00289 }
00290 }
00291
00292 void ResourceExchange::unsubscribeEvents( const QDate& start, const QDate& end )
00293 {
00294 kdDebug() << "ResourceExchange::unsubscribeEvents()" << endl;
00295 }
00296
00297 bool ResourceExchange::addTodo(Todo *todo)
00298 {
00299 if( !mCache)
00300 return false;
00301 mCache->addTodo( todo );
00302
00303 todo->registerObserver( this );
00304
00305
00306
00307 return true;
00308 }
00309
00310 void ResourceExchange::deleteTodo(Todo *todo)
00311 {
00312 if( !mCache )
00313 return;
00314 mCache->deleteTodo( todo );
00315
00316
00317 }
00318
00319 Todo::List ResourceExchange::rawTodos()
00320 {
00321 return mCache->rawTodos();
00322 }
00323
00324 Todo *ResourceExchange::todo( const QString &uid )
00325 {
00326 return mCache->todo( uid );
00327 }
00328
00329 Todo::List ResourceExchange::todos( const QDate &date )
00330 {
00331 return mCache->todos( date );
00332 }
00333
00334 Alarm::List ResourceExchange::alarmsTo( const QDateTime &to )
00335 {
00336 return mCache->alarmsTo( to );
00337 }
00338
00339 Alarm::List ResourceExchange::alarms( const QDateTime &from, const QDateTime &to )
00340 {
00341 kdDebug(5800) << "ResourceExchange::alarms(" << from.toString() << " - " << to.toString() << ")\n";
00342 return mCache->alarms( from, to );
00343 }
00344
00345
00346
00347
00348 void ResourceExchange::update(IncidenceBase *incidence)
00349 {
00350 Event* event = dynamic_cast<Event *>( incidence );
00351 if ( event ) {
00352 kdDebug() << "Event updated, resubmit to server..." << endl;
00353 uploadEvent( event );
00354 }
00355
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 Event::List ResourceExchange::rawEventsForDate(const QDate &qd, bool sorted)
00371 {
00372
00373
00374
00375
00376 QDateTime now = QDateTime::currentDateTime();
00377
00378
00379
00380 QDate start = QDate( qd.year(), qd.month(), 1 );
00381 if ( !mDates->contains( start ) || (*mCacheDates)[start].secsTo( now ) > mCachedSeconds ) {
00382 QDate end = start.addMonths( 1 ).addDays( -1 );
00383
00384 Event::List oldEvents = mCache->rawEvents( start, end, false );
00385
00386 Event::List::ConstIterator it;
00387 for( it = oldEvents.begin(); it != oldEvents.end(); ++it ) {
00388 mCache->deleteEvent( *it );
00389 }
00390
00391 kdDebug() << "Reading events for month of " << start.toString() << endl;
00392 mClient->downloadSynchronous( mCache, start, end, true );
00393 mDates->add( start );
00394 mCacheDates->insert( start, now );
00395 }
00396
00397
00398 Event::List events = mCache->rawEventsForDate( qd, sorted );
00399
00400 return events;
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 }
00430
00431
00432 Event::List ResourceExchange::rawEvents( const QDate &start, const QDate &end,
00433 bool inclusive )
00434 {
00435 kdDebug() << "ResourceExchange::rawEvents(start,end,inclusive)" << endl;
00436 return mCache->rawEvents( start, end, inclusive );
00437 }
00438
00439 Event::List ResourceExchange::rawEventsForDate(const QDateTime &qdt)
00440 {
00441 kdDebug() << "ResourceExchange::rawEventsForDate(qdt)" << endl;
00442 return rawEventsForDate( qdt.date() );
00443 }
00444
00445 Event::List ResourceExchange::rawEvents()
00446 {
00447 kdDebug() << "ResourceExchange::rawEvents()" << endl;
00448 return mCache->rawEvents();
00449 }
00450
00451 bool ResourceExchange::addJournal(Journal *journal)
00452 {
00453 kdDebug(5800) << "Adding Journal on " << journal->dtStart().toString() << endl;
00454 mCache->addJournal( journal );
00455
00456 journal->registerObserver( this );
00457
00458
00459
00460 return true;
00461 }
00462
00463 void ResourceExchange::deleteJournal(Journal *journal)
00464 {
00465 if( !mCache )
00466 return;
00467 mCache->deleteJournal( journal );
00468
00469
00470 }
00471
00472 Journal *ResourceExchange::journal(const QDate &date)
00473 {
00474 if( !mCache)
00475 return 0;
00476
00477 return mCache->journal( date );
00478 }
00479
00480 Journal *ResourceExchange::journal(const QString &uid)
00481 {
00482 if( !mCache )
00483 return 0;
00484 return mCache->journal( uid );
00485 }
00486
00487 Journal::List ResourceExchange::journals()
00488 {
00489 return mCache->journals();
00490 }
00491
00492 void ResourceExchange::setTimeZoneId( const QString &tzid )
00493 {
00494 mTimeZoneId = tzid;
00495 if ( mCache ) mCache->setTimeZoneId( tzid );
00496 }
00497 #include "resourceexchange.moc"