libkpimexchange Library API Documentation

exchangedownload.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 00006 modify it under the terms of the GNU Library General Public 00007 License as published by the Free Software Foundation; either 00008 version 2 of the License, or (at your option) any later version. 00009 00010 This library is distributed in the hope that it will be useful, 00011 but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 Library General Public 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 00017 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00018 Boston, MA 02111-1307, USA. 00019 */ 00020 00021 #include <qfile.h> 00022 #include <qtextstream.h> 00023 #include <qdatastream.h> 00024 #include <qcstring.h> 00025 #include <qregexp.h> 00026 00027 #include <kapplication.h> 00028 #include <kconfig.h> 00029 #include <kstandarddirs.h> 00030 #include <kmessagebox.h> 00031 #include <klocale.h> 00032 #include <kaction.h> 00033 #include <kurl.h> 00034 #include <kdebug.h> 00035 #include <krfcdate.h> 00036 00037 #include <kio/slave.h> 00038 #include <kio/scheduler.h> 00039 #include <kio/slavebase.h> 00040 #include <kio/davjob.h> 00041 #include <kio/http.h> 00042 #include <kio/job.h> 00043 00044 #include <libkcal/incidence.h> 00045 #include <libkcal/event.h> 00046 #include <libkcal/recurrence.h> 00047 #include <libkcal/icalformat.h> 00048 #include <libkcal/icalformatimpl.h> 00049 #include <libkcal/calendarlocal.h> 00050 00051 extern "C" { 00052 #include <ical.h> 00053 } 00054 00055 #include "exchangeclient.h" 00056 #include "exchangeaccount.h" 00057 #include "exchangeprogress.h" 00058 #include "utils.h" 00059 00060 #include "exchangedownload.h" 00061 00062 using namespace KPIM; 00063 00064 ExchangeDownload::ExchangeDownload( ExchangeAccount *account, QWidget *window ) 00065 : mWindow( window ) 00066 { 00067 kdDebug() << "ExchangeDownload()" << endl; 00068 00069 mAccount = account; 00070 mDownloadsBusy = 0; 00071 mProgress = 0; 00072 mCalendar = 0; 00073 mFormat = new KCal::ICalFormat(); 00074 } 00075 00076 ExchangeDownload::~ExchangeDownload() 00077 { 00078 kdDebug() << "ExchangeDownload destructor" << endl; 00079 delete mFormat; 00080 if ( mEvents ) delete mEvents; 00081 } 00082 00083 void ExchangeDownload::download( KCal::Calendar *calendar, const QDate &start, 00084 const QDate &end, bool showProgress ) 00085 { 00086 mCalendar = calendar; 00087 mEvents = 0; 00088 00089 #if 0 00090 if( showProgress ) { 00091 //kdDebug() << "Creating progress dialog" << endl; 00092 mProgress = new ExchangeProgress(); 00093 mProgress->show(); 00094 00095 connect( this, SIGNAL( startDownload() ), mProgress, 00096 SLOT( slotTransferStarted() ) ); 00097 connect( this, SIGNAL(finishDownload() ), mProgress, 00098 SLOT( slotTransferFinished() ) ); 00099 } 00100 #endif 00101 00102 QString sql = dateSelectQuery( start, end.addDays( 1 ) ); 00103 00104 kdDebug() << "Exchange download query: " << endl << sql << endl; 00105 00106 increaseDownloads(); 00107 00108 kdDebug() << "ExchangeDownload::download() davSearch URL: " 00109 << mAccount->calendarURL() << endl; 00110 00111 KIO::DavJob *job = KIO::davSearch( mAccount->calendarURL(), "DAV:", "sql", 00112 sql, false ); 00113 KIO::Scheduler::scheduleJob( job ); 00114 job->setWindow( mWindow ); 00115 connect( job, SIGNAL( result( KIO::Job * ) ), 00116 SLOT( slotSearchResult( KIO::Job *) ) ); 00117 } 00118 00119 void ExchangeDownload::download( const QDate& start, const QDate& end, bool showProgress ) 00120 { 00121 mCalendar = 0; 00122 mEvents = new QPtrList<KCal::Event>; 00123 00124 if( showProgress ) { 00125 //kdDebug() << "Creating progress dialog" << endl; 00126 mProgress = new ExchangeProgress(); 00127 mProgress->show(); 00128 00129 connect( this, SIGNAL(startDownload()), mProgress, SLOT(slotTransferStarted()) ); 00130 connect( this, SIGNAL(finishDownload()), mProgress, SLOT(slotTransferFinished()) ); 00131 } 00132 00133 QString sql = dateSelectQuery( start, end.addDays( 1 ) ); 00134 00135 increaseDownloads(); 00136 00137 KIO::DavJob *job = KIO::davSearch( mAccount->calendarURL(), "DAV:", "sql", sql, false ); 00138 KIO::Scheduler::scheduleJob(job); 00139 job->setWindow( mWindow ); 00140 connect( job, SIGNAL( result( KIO::Job * ) ), 00141 SLOT( slotSearchResult( KIO::Job * ) ) ); 00142 } 00143 00144 // Original query TODO: make query configurable 00145 #if 0 00146 QString ExchangeDownload::dateSelectQuery( const QDate& start, const QDate& end ) 00147 { 00148 QString startString; 00149 startString.sprintf("%04i/%02i/%02i",start.year(),start.month(),start.day()); 00150 QString endString; 00151 endString.sprintf("%04i/%02i/%02i",end.year(),end.month(),end.day()); 00152 QString sql = 00153 "SELECT \"DAV:href\", \"urn:schemas:calendar:instancetype\", \"urn:schemas:calendar:uid\"\r\n" 00154 "FROM Scope('shallow traversal of \"\"')\r\n" 00155 "WHERE \"urn:schemas:calendar:dtend\" > '" + startString + "'\r\n" 00156 "AND \"urn:schemas:calendar:dtstart\" < '" + endString + "'"; 00157 return sql; 00158 } 00159 #endif 00160 00161 QString ExchangeDownload::dateSelectQuery( const QDate& start, const QDate& end ) 00162 { 00163 QString startString; 00164 startString.sprintf( "%04i-%02i-%02iT00:00:00Z", start.year(), 00165 start.month(), start.day() ); 00166 QString endString; 00167 endString.sprintf( "%04i-%02i-%02iT23:59:59Z", end.year(), end.month(), 00168 end.day() ); 00169 QString sql = 00170 "SELECT \"DAV:href\", \"urn:schemas:calendar:instancetype\", " 00171 "\"urn:schemas:calendar:uid\"\r\n" 00172 "FROM Scope('shallow traversal of \"\"')\r\n" 00173 "WHERE \"urn:schemas:calendar:dtend\" > '" + startString + "'\r\n" 00174 "AND \"urn:schemas:calendar:dtstart\" < '" + endString + "'"; 00175 return sql; 00176 } 00177 00178 00179 void ExchangeDownload::slotSearchResult( KIO::Job *job ) 00180 { 00181 if ( job->error() ) { 00182 kdError() << "ExchangeDownload::slotSearchResult() error: " 00183 << job->error() << endl; 00184 QString text = i18n("ExchangeDownload\nError accessing '%1': %2") 00185 .arg( mAccount->calendarURL().prettyURL() ) 00186 .arg( job->errorString() ); 00187 KMessageBox::error( 0, text ); 00188 finishUp( ExchangeClient::CommunicationError, job ); 00189 return; 00190 } 00191 QDomDocument &response = static_cast<KIO::DavJob *>( job )->response(); 00192 00193 kdDebug() << "Search result: " << endl << response.toString() << endl; 00194 00195 handleAppointments( response, true ); 00196 00197 decreaseDownloads(); 00198 } 00199 00200 void ExchangeDownload::slotMasterResult( KIO::Job *job ) 00201 { 00202 if ( job->error() ) { 00203 kdError() << "Error result for Master search: " << job->error() << endl; 00204 job->showErrorDialog( 0 ); 00205 finishUp( ExchangeClient::CommunicationError, job ); 00206 return; 00207 } 00208 QDomDocument &response = static_cast<KIO::DavJob *>( job )->response(); 00209 00210 kdDebug() << "Search (master) result: " << endl << response.toString() << endl; 00211 00212 handleAppointments( response, false ); 00213 00214 decreaseDownloads(); 00215 } 00216 00217 void ExchangeDownload::handleAppointments( const QDomDocument &response, 00218 bool recurrence ) 00219 { 00220 kdDebug() << "Entering handleAppointments" << endl; 00221 int successCount = 0; 00222 00223 if ( response.documentElement().firstChild().toElement().isNull() ) { 00224 // Got an empty response, but no error. This would mean there are 00225 // no appointments in this time period. 00226 return; 00227 } 00228 00229 for( QDomElement item = response.documentElement().firstChild().toElement(); 00230 !item.isNull(); 00231 item = item.nextSibling().toElement() ) { 00232 //kdDebug() << "Current item:" << item.tagName() << endl; 00233 QDomNodeList propstats = item.elementsByTagNameNS( "DAV:", "propstat" ); 00234 // kdDebug() << "Item has " << propstats.count() << " propstat children" << endl; 00235 for( uint i=0; i < propstats.count(); i++ ) { 00236 QDomElement propstat = propstats.item(i).toElement(); 00237 QDomElement prop = propstat.namedItem( "prop" ).toElement(); 00238 if ( prop.isNull() ) { 00239 kdError() << "Error: no <prop> in response" << endl; 00240 continue; 00241 } 00242 00243 QDomElement instancetypeElement = prop.namedItem( "instancetype" ).toElement(); 00244 if ( instancetypeElement.isNull() ) { 00245 kdError() << "Error: no instance type in Exchange server reply" << endl; 00246 continue; 00247 } 00248 int instanceType = instancetypeElement.text().toInt(); 00249 //kdDebug() << "Instance type: " << instanceType << endl; 00250 00251 if ( recurrence && instanceType > 0 ) { 00252 QDomElement uidElement = prop.namedItem( "uid" ).toElement(); 00253 if ( uidElement.isNull() ) { 00254 kdError() << "Error: no uid in Exchange server reply" << endl; 00255 continue; 00256 } 00257 QString uid = uidElement.text(); 00258 if ( ! m_uids.contains( uid ) ) { 00259 m_uids[uid] = 1; 00260 handleRecurrence(uid); 00261 successCount++; 00262 } 00263 continue; 00264 } 00265 00266 QDomElement hrefElement = prop.namedItem( "href" ).toElement(); 00267 if ( hrefElement.isNull() ) { 00268 kdError() << "Error: no href in Exchange server reply" << endl; 00269 continue; 00270 } 00271 QString href = hrefElement.text(); 00272 KURL url(href); 00273 00274 kdDebug() << "Getting appointment from url: " << url.prettyURL() << endl; 00275 00276 readAppointment( toDAV( url ) ); 00277 successCount++; 00278 } 00279 } 00280 if ( !successCount ) { 00281 finishUp( ExchangeClient::ServerResponseError, 00282 "WebDAV SEARCH response:\n" + response.toString() ); 00283 } 00284 } 00285 00286 void ExchangeDownload::handleRecurrence( QString uid ) 00287 { 00288 // kdDebug() << "Handling recurrence info for uid=" << uid << endl; 00289 QString query = 00290 "SELECT \"DAV:href\", \"urn:schemas:calendar:instancetype\"\r\n" 00291 "FROM Scope('shallow traversal of \"\"')\r\n" 00292 "WHERE \"urn:schemas:calendar:uid\" = '" + uid + "'\r\n" 00293 " AND (\"urn:schemas:calendar:instancetype\" = 1)\r\n"; 00294 // " OR \"urn:schemas:calendar:instancetype\" = 3)\r\n" // FIXME: exception are not handled 00295 00296 // kdDebug() << "Exchange master query: " << endl << query << endl; 00297 00298 increaseDownloads(); 00299 00300 KIO::DavJob* job = KIO::davSearch( mAccount->calendarURL(), "DAV:", "sql", 00301 query, false ); 00302 KIO::Scheduler::scheduleJob( job ); 00303 job->setWindow( mWindow ); 00304 connect( job, SIGNAL( result( KIO::Job * ) ), 00305 SLOT( slotMasterResult( KIO::Job * ) ) ); 00306 } 00307 00308 void ExchangeDownload::readAppointment( const KURL& url ) 00309 { 00310 QDomDocument doc; 00311 QDomElement root = addElement( doc, doc, "DAV:", "propfind" ); 00312 QDomElement prop = addElement( doc, root, "DAV:", "prop" ); 00313 addElement( doc, prop, "urn:schemas:calendar:", "uid" ); 00314 addElement( doc, prop, "urn:schemas:calendar:", "timezoneid" ); 00315 addElement( doc, prop, "urn:schemas:calendar:", "timezone" ); 00316 addElement( doc, prop, "urn:schemas:calendar:", "lastmodified" ); 00317 addElement( doc, prop, "urn:schemas:calendar:", "organizer" ); 00318 addElement( doc, prop, "urn:schemas:calendar:", "contact" ); 00319 addElement( doc, prop, "urn:schemas:httpmail:", "to" ); 00320 addElement( doc, prop, "urn:schemas:calendar:", "attendeestatus" ); 00321 addElement( doc, prop, "urn:schemas:calendar:", "attendeerole" ); 00322 addElement( doc, prop, "DAV:", "isreadonly" ); 00323 addElement( doc, prop, "urn:schemas:calendar:", "instancetype" ); 00324 addElement( doc, prop, "urn:schemas:calendar:", "created" ); 00325 addElement( doc, prop, "urn:schemas:calendar:", "dtstart" ); 00326 addElement( doc, prop, "urn:schemas:calendar:", "dtend" ); 00327 addElement( doc, prop, "urn:schemas:calendar:", "alldayevent" ); 00328 addElement( doc, prop, "urn:schemas:calendar:", "transparent" ); 00329 addElement( doc, prop, "urn:schemas:httpmail:", "textdescription" ); 00330 addElement( doc, prop, "urn:schemas:httpmail:", "subject" ); 00331 addElement( doc, prop, "urn:schemas:calendar:", "location" ); 00332 addElement( doc, prop, "urn:schemas:calendar:", "rrule" ); 00333 addElement( doc, prop, "urn:schemas:calendar:", "exdate" ); 00334 addElement( doc, prop, "urn:schemas:mailheader:", "sensitivity" ); 00335 addElement( doc, prop, "urn:schemas:calendar:", "reminderoffset" ); 00336 00337 addElement( doc, prop, "urn:schemas-microsoft-com:office:office", 00338 "Keywords" ); 00339 00340 // addElement( doc, prop, "", "" ); 00341 // addElement( doc, prop, "DAV:", "" ); 00342 // addElement( doc, prop, "urn:schemas:calendar:", "" ); 00343 // addElement( doc, prop, "urn:content-classes:appointment", "" ); 00344 // addElement( doc, prop, "urn:schemas:httpmail:", "" ); 00345 00346 increaseDownloads(); 00347 00348 KIO::DavJob* job = KIO::davPropFind( url, doc, "0", false ); 00349 KIO::Scheduler::scheduleJob( job ); 00350 job->setWindow( mWindow ); 00351 job->addMetaData( "errorPage", "false" ); 00352 connect( job, SIGNAL( result( KIO::Job * ) ), 00353 SLOT( slotPropFindResult( KIO::Job * ) ) ); 00354 } 00355 00356 void ExchangeDownload::slotPropFindResult( KIO::Job *job ) 00357 { 00358 kdDebug() << "slotPropFindResult" << endl; 00359 00360 int error = job->error(); 00361 if ( error ) { 00362 job->showErrorDialog( 0 ); 00363 finishUp( ExchangeClient::CommunicationError, job ); 00364 return; 00365 } 00366 00367 QDomDocument response = static_cast<KIO::DavJob *>( job )->response(); 00368 kdDebug() << "Response: " << endl; 00369 kdDebug() << response.toString() << endl; 00370 00371 QDomElement prop = response.documentElement().namedItem( "response" ) 00372 .namedItem( "propstat" ).namedItem( "prop" ).toElement(); 00373 00374 KCal::Event* event = new KCal::Event(); 00375 00376 QDomElement uidElement = prop.namedItem( "uid" ).toElement(); 00377 if ( uidElement.isNull() ) { 00378 kdError() << "Error: no uid in Exchange server reply" << endl; 00379 finishUp( ExchangeClient::IllegalAppointmentError, 00380 "WebDAV server response:\n" + response.toString() ); 00381 return; 00382 } 00383 event->setUid( uidElement.text() ); 00384 // kdDebug() << "Got UID: " << uidElement.text() << endl; 00385 00386 QString timezoneid = prop.namedItem( "timezoneid" ).toElement().text(); 00387 // kdDebug() << "DEBUG: timezoneid = " << timezoneid << endl; 00388 00389 QString timezone = prop.namedItem( "timezone" ).toElement().text(); 00390 // kdDebug() << "DEBUG: timezone = " << timezone << endl; 00391 00392 // mFormat is used for parsing recurrence rules. 00393 QString localTimeZoneId; 00394 if ( mCalendar ) { 00395 mFormat->setTimeZone( mCalendar->timeZoneId(), !mCalendar->isLocalTime() ); 00396 localTimeZoneId = mCalendar->timeZoneId(); 00397 } else { 00398 localTimeZoneId = "UTC"; 00399 // If no mCalendar, stay in UTC 00400 } 00401 00402 QString lastModified = prop.namedItem( "lastmodified" ).toElement().text(); 00403 if ( !lastModified.isEmpty() ) { 00404 QDateTime dt = utcAsZone( QDateTime::fromString( lastModified, Qt::ISODate ), localTimeZoneId ); 00405 event->setLastModified( dt ); 00406 kdDebug() << "Got lastModified:" << lastModified << ", " << dt.toString() << endl; 00407 } 00408 00409 QString organizer = prop.namedItem( "organizer" ).toElement().text(); 00410 event->setOrganizer( organizer ); 00411 // kdDebug() << "Got organizer: " << organizer << endl; 00412 00413 // Trying to find attendees, not working yet 00414 QString contact = prop.namedItem( "contact" ).toElement().text(); 00415 // event->setOrganizer( organizer ); 00416 // kdDebug() << "DEBUG: Got contact: " << contact << endl; 00417 00418 // This looks promising for finding attendees 00419 // FIXME: get this to work 00420 QString to = prop.namedItem( "to" ).toElement().text(); 00421 // kdDebug() << "DEBUG: Got to: " << to << endl; 00422 QStringList attn = QStringList::split( ",", to ); // This doesn't work: there can be commas between "" 00423 QStringList::iterator it; 00424 for ( it = attn.begin(); it != attn.end(); ++it ) { 00425 // kdDebug() << " attendee: " << (*it) << endl; 00426 QString name = ""; 00427 // KCal::Attendee* a = new KCal::Attendee( name, email ); 00428 00429 // event->addAttendee( a ); 00430 } 00431 00432 QString readonly = prop.namedItem( "isreadonly" ).toElement().text(); 00433 event->setReadOnly( readonly == "1" ); 00434 kdDebug() << "Got readonly: " << readonly << ":" << (readonly != "0") << endl; 00435 00436 QString created = prop.namedItem( "created" ).toElement().text(); 00437 if ( !created.isEmpty() ) { 00438 QDateTime dt = utcAsZone( QDateTime::fromString( created, Qt::ISODate ), 00439 localTimeZoneId ); 00440 event->setCreated( dt ); 00441 kdDebug() << "got created: " << dt.toString() << endl; 00442 } 00443 00444 QString dtstart = prop.namedItem( "dtstart" ).toElement().text(); 00445 if ( !dtstart.isEmpty() ) { 00446 QDateTime dt = utcAsZone( QDateTime::fromString( dtstart, Qt::ISODate ), 00447 localTimeZoneId ); 00448 event->setDtStart( dt ); 00449 kdDebug() << "got dtstart: " << dtstart << " becomes in timezone " << dt.toString() << endl; 00450 } 00451 00452 QString alldayevent = prop.namedItem( "alldayevent" ).toElement().text(); 00453 bool floats = alldayevent.toInt() != 0; 00454 event->setFloats( floats ); 00455 kdDebug() << "Got alldayevent: \"" << alldayevent << "\":" << floats << endl; 00456 00457 QString dtend = prop.namedItem( "dtend" ).toElement().text(); 00458 if ( !dtend.isEmpty() ) { 00459 QDateTime dt = utcAsZone( QDateTime::fromString( dtend, Qt::ISODate ), 00460 localTimeZoneId ); 00461 // Outlook thinks differently about floating event timing than libkcal 00462 if ( floats ) dt = dt.addDays( -1 ); 00463 event->setDtEnd( dt ); 00464 kdDebug() << "got dtend: " << dtend << " becomes in timezone " << dt.toString() << endl; 00465 } 00466 00467 QString transparent = prop.namedItem( "transparent" ).toElement().text(); 00468 event->setTransparency( transparent.toInt() > 0 ? KCal::Event::Transparent 00469 : KCal::Event::Opaque ); 00470 // kdDebug() << "Got transparent: " << transparent << endl; 00471 00472 QString description = prop.namedItem( "textdescription" ).toElement().text(); 00473 event->setDescription( description ); 00474 kdDebug() << "Got description: " << description << endl; 00475 00476 QString subject = prop.namedItem( "subject" ).toElement().text(); 00477 event->setSummary( subject ); 00478 kdDebug() << "Got summary: " << subject << endl; 00479 00480 QString location = prop.namedItem( "location" ).toElement().text(); 00481 event->setLocation( location ); 00482 // kdDebug() << "Got location: " << location << endl; 00483 00484 QString rrule = prop.namedItem( "rrule" ).toElement().text(); 00485 kdDebug() << "Got rrule: " << rrule << endl; 00486 if ( !rrule.isEmpty() ) { 00487 // Timezone should be handled automatically 00488 // because we used mFormat->setTimeZone() earlier 00489 if ( ! mFormat->fromString( event->recurrence(), rrule ) ) { 00490 kdError() << "ERROR parsing rrule " << rrule << endl; 00491 } 00492 } 00493 00494 QDomElement keywords = prop.namedItem( "Keywords" ).toElement(); 00495 QStringList categories; 00496 QDomNodeList list = keywords.elementsByTagNameNS( "xml:", "v" ); 00497 for( uint i=0; i < list.count(); i++ ) { 00498 QDomElement item = list.item(i).toElement(); 00499 categories.append( item.text() ); 00500 } 00501 event->setCategories( categories ); 00502 // kdDebug() << "Got categories: " << categories.join( ", " ) << endl; 00503 00504 00505 QDomElement exdate = prop.namedItem( "exdate" ).toElement(); 00506 KCal::DateList exdates; 00507 list = exdate.elementsByTagNameNS( "xml:", "v" ); 00508 for( uint i=0; i < list.count(); i++ ) { 00509 QDomElement item = list.item(i).toElement(); 00510 QDate date = utcAsZone( QDateTime::fromString( item.text(), Qt::ISODate ), localTimeZoneId ).date(); 00511 exdates.append( date ); 00512 // kdDebug() << "Got exdate: " << date.toString() << endl; 00513 } 00514 event->setExDates( exdates ); 00515 00516 // Exchange sentitivity values: 00517 // 0 None 00518 // 1 Personal 00519 // 2 Private 00520 // 3 Company Confidential 00521 QString sensitivity = prop.namedItem( "sensitivity" ).toElement().text(); 00522 if ( ! sensitivity.isNull() ) 00523 switch( sensitivity.toInt() ) { 00524 case 0: event->setSecrecy( KCal::Incidence::SecrecyPublic ); break; 00525 case 1: event->setSecrecy( KCal::Incidence::SecrecyPrivate ); break; 00526 case 2: event->setSecrecy( KCal::Incidence::SecrecyPrivate ); break; 00527 case 3: event->setSecrecy( KCal::Incidence::SecrecyConfidential ); break; 00528 default: kdWarning() << "Unknown sensitivity: " << sensitivity << endl; 00529 } 00530 // kdDebug() << "Got sensitivity: " << sensitivity << endl; 00531 00532 00533 QString reminder = prop.namedItem( "reminderoffset" ).toElement().text(); 00534 // kdDebug() << "Reminder offset: " << reminder << endl; 00535 if ( !reminder.isEmpty() ) { 00536 // Duration before event in seconds 00537 KCal::Duration offset( - reminder.toInt() ); 00538 KCal::Alarm *alarm = event->newAlarm(); 00539 alarm->setStartOffset( offset ); 00540 alarm->setEnabled( true ); 00541 // TODO: multiple alarms; alarm->setType( KCal::Alarm::xxxx ); 00542 } 00544 //Alarm* newAlarm(); 00546 //void addAlarm(Alarm*); 00547 00549 //void setRelatedTo(Incidence *relatedTo); 00551 //void addRelation(Incidence *); 00552 00554 //void setAttachments(const QStringList &attachments); 00555 00557 //void setResources(const QStringList &resources); 00558 00560 //void setPriority(int priority); 00561 00567 //void addAttendee(Attendee *a, bool doupdate=true ); 00568 00569 // THE FOLLOWING EVENT PROPERTIES ARE NOT READ 00570 00571 // Revision ID in webdav is a String, not an int 00573 //void setRevision(int rev); 00574 00575 // Problem: When you sync Outlook to a Palm, the conduit splits up 00576 // multi-day events into single-day events WITH ALL THE SAME UID 00577 // Grrrrrrr. 00578 if ( mCalendar ) { 00579 KCal::Event *oldEvent = mCalendar->event( event->uid() ); 00580 if ( oldEvent ) { 00581 kdWarning() << "Already got his event, replace it..." << endl; 00582 mCalendar->deleteEvent( oldEvent ); 00583 } 00584 kdDebug() << "ADD EVENT" << endl; 00585 mCalendar->addEvent( event ); 00586 } else { 00587 kdDebug() << "EMIT gotEvent" << endl; 00588 emit gotEvent( event, static_cast<KIO::DavJob *>( job )->url() ); 00589 // mEvents->append( event ); 00590 } 00591 00592 decreaseDownloads(); 00593 } 00594 00595 void ExchangeDownload::increaseDownloads() 00596 { 00597 mDownloadsBusy++; 00598 emit startDownload(); 00599 } 00600 00601 void ExchangeDownload::decreaseDownloads() 00602 { 00603 mDownloadsBusy--; 00604 // kdDebug() << "Download finished, waiting for " << mDownloadsBusy << " more" << endl; 00605 emit finishDownload(); 00606 if ( mDownloadsBusy == 0 ) { 00607 kdDebug() << "All downloads finished" << endl; 00608 finishUp( ExchangeClient::ResultOK ); 00609 } 00610 } 00611 00612 void ExchangeDownload::finishUp( int result, const QString &moreInfo ) 00613 { 00614 kdDebug() << "ExchangeDownload::finishUp() " << result << " " 00615 << moreInfo << endl; 00616 00617 if ( mCalendar ) mCalendar->setModified( true ); 00618 // Disconnect from progress bar 00619 if ( mProgress ) { 00620 disconnect( this, 0, mProgress, 0 ); 00621 disconnect( mProgress, 0, this, 0 ); 00622 mProgress->delayedDestruct(); 00623 } 00624 00625 // if ( mEvents ) { 00626 // emit finished( this, result, moreInfo, *mEvents ); 00627 // } else { 00628 emit finished( this, result, moreInfo ); 00629 // } 00630 } 00631 00632 void ExchangeDownload::finishUp( int result, KIO::Job *job ) 00633 { 00634 finishUp( result, QString("WebDAV job error code = ") + 00635 QString::number( job->error() ) + ";\n" + "\"" + 00636 job->errorString() + "\"" ); 00637 } 00638 00639 #include "exchangedownload.moc"
KDE Logo
This file is part of the documentation for libkpimexchange Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Thu Oct 21 19:46:38 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003