libkpimexchange Library API Documentation

resourceexchange.cpp

00001 /* 00002 This file is part of libkpimexchange. 00003 Copyright (c) 2002 Jan-Pascal van Best <janpascal@vanbest.org> 00004 00005 This library is free software; you can redistribute it and/or modify it 00006 under the terms of the GNU Library General Public License as published by 00007 the Free Software Foundation; either version 2 of the License, or (at your 00008 option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, but WITHOUT 00011 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 License for more details. 00014 00015 You should have received a copy of the GNU Library General Public License 00016 along with this library; see the file COPYING.LIB. If not, write to the 00017 Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00018 02111-1307, USA. 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 // mOldestDate = 0L; 00138 // mNewestDate = 0L; 00139 00140 // FIXME: check if server exists, account is OK, etc. 00141 return true; 00142 } 00143 00144 void ResourceExchange::doClose() 00145 { 00146 kdDebug() << "ResourceExchange::doClose()" << endl; 00147 // delete mNewestDate; 00148 // delete mOldestDate; 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 // setModified( false ); 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 /* Now find out what happened: 00196 * One or more of the following: 00197 * 1. Event added in period that we think we have cached 00198 * 2. Event deleted that we have in cache 00199 * 3. Event modified that we have in cache 00200 * 4. Something else happened that isn't relevant to us 00201 * Update cache, then notify whoever's watching us 00202 * We may be able to find (1) and (3) by looking at the 00203 * DAV:getlastmodified property 00204 * (2) is trickier: we might have to resort to checking 00205 * all uids in the cache 00206 * Or: put monitors on every event in the cache, so that 00207 * we know when one gets deleted or modified 00208 * Only look for new events using the global monitor 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 // FIXME: first check of upload finished successfully, only then 00225 // add to cache 00226 mCache->addEvent( anEvent ); 00227 00228 uploadEvent( anEvent ); 00229 // insertEvent(anEvent); 00230 00231 anEvent->registerObserver( this ); 00232 // setModified( true ); 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 // This also frees the event 00251 mCache->deleteEvent( event ); 00252 00253 // setModified( true ); 00254 } 00255 00256 00257 Event *ResourceExchange::event( const QString &uid ) 00258 { 00259 kdDebug(5800) << "ResourceExchange::event(): " << uid << endl; 00260 00261 // FIXME: Look in exchange server for uid! 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 // FIXME: possible race condition if several subscribe events are run close 00269 // to each other 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 // FIXME: add watches to the monitor for these events 00277 // KURL url = 00278 // mMonitor->addWatch( url, KPIM::ExchangeMonitor::Update, 0 ); 00279 // emit eventsAdded( events ); 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 // Do something useful with the error report 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 // setModified( true ); 00306 00307 return true; 00308 } 00309 00310 void ResourceExchange::deleteTodo(Todo *todo) 00311 { 00312 if( !mCache ) 00313 return; 00314 mCache->deleteTodo( todo ); 00315 00316 // setModified( true ); 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 /****************************** PROTECTED METHODS ****************************/ 00346 00347 // after changes are made to an event, this should be called. 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 // setModified( true ); 00356 } 00357 00358 // this function will take a VEvent and insert it into the event 00359 // dictionary for the ResourceExchange. If there is no list of events for that 00360 // particular location in the dictionary, a new one will be created. 00361 /* 00362 void ResourceExchange::insertEvent(const Event *anEvent) 00363 { 00364 kdDebug() << "ResourceExchange::insertEvent" << endl; 00365 00366 } 00367 */ 00368 // taking a QDate, this function will look for an eventlist in the dict 00369 // with that date attached - 00370 Event::List ResourceExchange::rawEventsForDate(const QDate &qd, bool sorted) 00371 { 00372 // kdDebug() << "ResourceExchange::rawEventsForDate(" << qd.toString() << "," << sorted << ")" << endl; 00373 00374 // If the events for this date are not in the cache, or if they are old, 00375 // get them again 00376 QDateTime now = QDateTime::currentDateTime(); 00377 // kdDebug() << "Now is " << now.toString() << endl; 00378 // kdDebug() << "mDates: " << mDates << endl; 00379 // kdDebug() << "mDates->contains(qd) is " << mDates->contains( qd ) << endl; 00380 QDate start = QDate( qd.year(), qd.month(), 1 ); // First day of month 00381 if ( !mDates->contains( start ) || (*mCacheDates)[start].secsTo( now ) > mCachedSeconds ) { 00382 QDate end = start.addMonths( 1 ).addDays( -1 ); // Last day of month 00383 // Get events that occur in this period from the cache 00384 Event::List oldEvents = mCache->rawEvents( start, end, false ); 00385 // And remove them all 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 ); // Show progress dialog 00393 mDates->add( start ); 00394 mCacheDates->insert( start, now ); 00395 } 00396 00397 // Events are safely in the cache now, return them from cache 00398 Event::List events = mCache->rawEventsForDate( qd, sorted ); 00399 // kdDebug() << "Found " << events.count() << " events." << endl; 00400 return events; 00401 00402 /* 00403 if (!sorted) { 00404 return eventList; 00405 } 00406 00407 // kdDebug(5800) << "Sorting events for date\n" << endl; 00408 // now, we have to sort it based on getDtStart.time() 00409 Event::List eventListSorted; 00410 for (anEvent = eventList.first(); anEvent; anEvent = eventList.next()) { 00411 if (!eventListSorted.isEmpty() && 00412 anEvent->dtStart().time() < eventListSorted.at(0)->dtStart().time()) { 00413 eventListSorted.insert(0,anEvent); 00414 goto nextToInsert; 00415 } 00416 for (i = 0; (uint) i+1 < eventListSorted.count(); i++) { 00417 if (anEvent->dtStart().time() > eventListSorted.at(i)->dtStart().time() && 00418 anEvent->dtStart().time() <= eventListSorted.at(i+1)->dtStart().time()) { 00419 eventListSorted.insert(i+1,anEvent); 00420 goto nextToInsert; 00421 } 00422 } 00423 eventListSorted.append(anEvent); 00424 nextToInsert: 00425 continue; 00426 } 00427 return eventListSorted; 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 // setModified( true ); 00459 00460 return true; 00461 } 00462 00463 void ResourceExchange::deleteJournal(Journal *journal) 00464 { 00465 if( !mCache ) 00466 return; 00467 mCache->deleteJournal( journal ); 00468 00469 // setModified( true ); 00470 } 00471 00472 Journal *ResourceExchange::journal(const QDate &date) 00473 { 00474 if( !mCache) 00475 return 0; 00476 // kdDebug(5800) << "ResourceExchange::journal() " << date.toString() << endl; 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"
KDE Logo
This file is part of the documentation for libkpimexchange Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:58:09 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003