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 mAccount = account; 00068 mDownloadsBusy = 0; 00069 mProgress = 0L; 00070 mCalendar = 0L; 00071 mFormat = new KCal::ICalFormat(); 00072 } 00073 00074 ExchangeDownload::~ExchangeDownload() 00075 { 00076 kdDebug() << "ExchangeDownload destructor" << endl; 00077 delete mFormat; 00078 if ( mEvents ) delete mEvents; 00079 } 00080 00081 void ExchangeDownload::download(KCal::Calendar* calendar, const QDate& start, const QDate& end, bool showProgress) 00082 { 00083 mCalendar = calendar; 00084 mEvents = 0; 00085 00086 if( showProgress ) { 00087 //kdDebug() << "Creating progress dialog" << endl; 00088 mProgress = new ExchangeProgress(); 00089 mProgress->show(); 00090 00091 connect( this, SIGNAL(startDownload()), mProgress, SLOT(slotTransferStarted()) ); 00092 connect( this, SIGNAL(finishDownload()), mProgress, SLOT(slotTransferFinished()) ); 00093 } 00094 00095 QString sql = dateSelectQuery( start, end.addDays( 1 ) ); 00096 00097 // kdDebug() << "Exchange download query: " << endl << sql << endl; 00098 00099 increaseDownloads(); 00100 00101 KIO::DavJob *job = KIO::davSearch( mAccount->calendarURL(), "DAV:", "sql", sql, false ); 00102 KIO::Scheduler::scheduleJob(job); 00103 job->setWindow( mWindow ); 00104 connect(job, SIGNAL(result( KIO::Job * )), this, SLOT(slotSearchResult(KIO::Job *))); 00105 } 00106 00107 void ExchangeDownload::download( const QDate& start, const QDate& end, bool showProgress ) 00108 { 00109 mCalendar = 0; 00110 mEvents = new QPtrList<KCal::Event>; 00111 00112 if( showProgress ) { 00113 //kdDebug() << "Creating progress dialog" << endl; 00114 mProgress = new ExchangeProgress(); 00115 mProgress->show(); 00116 00117 connect( this, SIGNAL(startDownload()), mProgress, SLOT(slotTransferStarted()) ); 00118 connect( this, SIGNAL(finishDownload()), mProgress, SLOT(slotTransferFinished()) ); 00119 } 00120 00121 QString sql = dateSelectQuery( start, end.addDays( 1 ) ); 00122 00123 increaseDownloads(); 00124 00125 KIO::DavJob *job = KIO::davSearch( mAccount->calendarURL(), "DAV:", "sql", sql, false ); 00126 KIO::Scheduler::scheduleJob(job); 00127 job->setWindow( mWindow ); 00128 connect(job, SIGNAL(result( KIO::Job * )), this, SLOT(slotSearchResult(KIO::Job *))); 00129 } 00130 00131 QString ExchangeDownload::dateSelectQuery( const QDate& start, const QDate& end ) 00132 { 00133 QString startString; 00134 startString.sprintf("%04i/%02i/%02i",start.year(),start.month(),start.day()); 00135 QString endString; 00136 endString.sprintf("%04i/%02i/%02i",end.year(),end.month(),end.day()); 00137 QString sql = 00138 "SELECT \"DAV:href\", \"urn:schemas:calendar:instancetype\", \"urn:schemas:calendar:uid\"\r\n" 00139 "FROM Scope('shallow traversal of \"\"')\r\n" 00140 "WHERE \"urn:schemas:calendar:dtend\" > '" + startString + "'\r\n" 00141 "AND \"urn:schemas:calendar:dtstart\" < '" + endString + "'"; 00142 return sql; 00143 } 00144 00145 00146 void ExchangeDownload::slotSearchResult( KIO::Job *job ) 00147 { 00148 if ( job->error() ) { 00149 kdError() << "Error result for search: " << job->error() << endl; 00150 job->showErrorDialog( 0L ); 00151 finishUp( ExchangeClient::CommunicationError, job ); 00152 return; 00153 } 00154 QDomDocument& response = static_cast<KIO::DavJob *>( job )->response(); 00155 00156 // kdDebug() << "Search result: " << endl << response.toString() << endl; 00157 00158 handleAppointments( response, true ); 00159 00160 decreaseDownloads(); 00161 } 00162 00163 void ExchangeDownload::slotMasterResult( KIO::Job *job ) 00164 { 00165 if ( job->error() ) { 00166 kdError() << "Error result for Master search: " << job->error() << endl; 00167 job->showErrorDialog( 0L ); 00168 finishUp( ExchangeClient::CommunicationError, job ); 00169 return; 00170 } 00171 QDomDocument& response = static_cast<KIO::DavJob *>( job )->response(); 00172 00173 kdDebug() << "Search (master) result: " << endl << response.toString() << endl; 00174 00175 handleAppointments( response, false ); 00176 00177 decreaseDownloads(); 00178 } 00179 00180 void ExchangeDownload::handleAppointments( const QDomDocument& response, bool recurrence ) { 00181 // kdDebug() << "Entering handleAppointments" << endl; 00182 int successCount = 0; 00183 00184 if ( response.documentElement().firstChild().toElement().isNull() ) { 00185 // Got an empty response, but no error. This would mean there are 00186 // no appointments in this time period. 00187 return; 00188 } 00189 00190 for( QDomElement item = response.documentElement().firstChild().toElement(); 00191 !item.isNull(); 00192 item = item.nextSibling().toElement() ) 00193 { 00194 //kdDebug() << "Current item:" << item.tagName() << endl; 00195 QDomNodeList propstats = item.elementsByTagNameNS( "DAV:", "propstat" ); 00196 // kdDebug() << "Item has " << propstats.count() << " propstat children" << endl; 00197 for( uint i=0; i < propstats.count(); i++ ) 00198 { 00199 QDomElement propstat = propstats.item(i).toElement(); 00200 QDomElement prop = propstat.namedItem( "prop" ).toElement(); 00201 if ( prop.isNull() ) 00202 { 00203 kdError() << "Error: no <prop> in response" << endl; 00204 continue; 00205 } 00206 00207 QDomElement instancetypeElement = prop.namedItem( "instancetype" ).toElement(); 00208 if ( instancetypeElement.isNull() ) { 00209 kdError() << "Error: no instance type in Exchange server reply" << endl; 00210 continue; 00211 } 00212 int instanceType = instancetypeElement.text().toInt(); 00213 //kdDebug() << "Instance type: " << instanceType << endl; 00214 00215 if ( recurrence && instanceType > 0 ) { 00216 QDomElement uidElement = prop.namedItem( "uid" ).toElement(); 00217 if ( uidElement.isNull() ) { 00218 kdError() << "Error: no uid in Exchange server reply" << endl; 00219 continue; 00220 } 00221 QString uid = uidElement.text(); 00222 if ( ! m_uids.contains( uid ) ) { 00223 m_uids[uid] = 1; 00224 handleRecurrence(uid); 00225 successCount++; 00226 } 00227 continue; 00228 } 00229 00230 QDomElement hrefElement = prop.namedItem( "href" ).toElement(); 00231 if ( hrefElement.isNull() ) { 00232 kdError() << "Error: no href in Exchange server reply" << endl; 00233 continue; 00234 } 00235 QString href = hrefElement.text(); 00236 KURL url(href); 00237 00238 kdDebug() << "Getting appointment from url: " << url.prettyURL() << endl; 00239 00240 readAppointment( toDAV( url ) ); 00241 successCount++; 00242 } 00243 } 00244 if ( !successCount ) { 00245 finishUp( ExchangeClient::ServerResponseError, "WebDAV SEARCH response:\n" + response.toString() ); 00246 } 00247 } 00248 00249 void ExchangeDownload::handleRecurrence(QString uid) { 00250 // kdDebug() << "Handling recurrence info for uid=" << uid << endl; 00251 QString query = 00252 "SELECT \"DAV:href\", \"urn:schemas:calendar:instancetype\"\r\n" 00253 "FROM Scope('shallow traversal of \"\"')\r\n" 00254 "WHERE \"urn:schemas:calendar:uid\" = '" + uid + "'\r\n" 00255 " AND (\"urn:schemas:calendar:instancetype\" = 1)\r\n"; 00256 // " OR \"urn:schemas:calendar:instancetype\" = 3)\r\n" // FIXME: exception are not handled 00257 00258 // kdDebug() << "Exchange master query: " << endl << query << endl; 00259 00260 increaseDownloads(); 00261 00262 KIO::DavJob* job = KIO::davSearch( mAccount->calendarURL(), "DAV:", "sql", query, false ); 00263 KIO::Scheduler::scheduleJob(job); 00264 job->setWindow( mWindow ); 00265 connect(job, SIGNAL(result( KIO::Job * )), this, SLOT(slotMasterResult(KIO::Job *))); 00266 } 00267 00268 void ExchangeDownload::readAppointment( const KURL& url ) 00269 { 00270 QDomDocument doc; 00271 QDomElement root = addElement( doc, doc, "DAV:", "propfind" ); 00272 QDomElement prop = addElement( doc, root, "DAV:", "prop" ); 00273 addElement( doc, prop, "urn:schemas:calendar:", "uid" ); 00274 addElement( doc, prop, "urn:schemas:calendar:", "timezoneid" ); 00275 addElement( doc, prop, "urn:schemas:calendar:", "timezone" ); 00276 addElement( doc, prop, "urn:schemas:calendar:", "lastmodified" ); 00277 addElement( doc, prop, "urn:schemas:calendar:", "organizer" ); 00278 addElement( doc, prop, "urn:schemas:calendar:", "contact" ); 00279 addElement( doc, prop, "urn:schemas:httpmail:", "to" ); 00280 addElement( doc, prop, "urn:schemas:calendar:", "attendeestatus" ); 00281 addElement( doc, prop, "urn:schemas:calendar:", "attendeerole" ); 00282 addElement( doc, prop, "DAV:", "isreadonly" ); 00283 addElement( doc, prop, "urn:schemas:calendar:", "instancetype" ); 00284 addElement( doc, prop, "urn:schemas:calendar:", "created" ); 00285 addElement( doc, prop, "urn:schemas:calendar:", "dtstart" ); 00286 addElement( doc, prop, "urn:schemas:calendar:", "dtend" ); 00287 addElement( doc, prop, "urn:schemas:calendar:", "alldayevent" ); 00288 addElement( doc, prop, "urn:schemas:calendar:", "transparent" ); 00289 addElement( doc, prop, "urn:schemas:httpmail:", "textdescription" ); 00290 addElement( doc, prop, "urn:schemas:httpmail:", "subject" ); 00291 addElement( doc, prop, "urn:schemas:calendar:", "location" ); 00292 addElement( doc, prop, "urn:schemas:calendar:", "rrule" ); 00293 addElement( doc, prop, "urn:schemas:calendar:", "exdate" ); 00294 addElement( doc, prop, "urn:schemas:mailheader:", "sensitivity" ); 00295 addElement( doc, prop, "urn:schemas:calendar:", "reminderoffset" ); 00296 00297 addElement( doc, prop, "urn:schemas-microsoft-com:office:office", "Keywords" ); 00298 00299 // addElement( doc, prop, "", "" ); 00300 // addElement( doc, prop, "DAV:", "" ); 00301 // addElement( doc, prop, "urn:schemas:calendar:", "" ); 00302 // addElement( doc, prop, "urn:content-classes:appointment", "" ); 00303 // addElement( doc, prop, "urn:schemas:httpmail:", "" ); 00304 00305 increaseDownloads(); 00306 00307 KIO::DavJob* job = KIO::davPropFind( url, doc, "0", false ); 00308 KIO::Scheduler::scheduleJob(job); 00309 job->setWindow( mWindow ); 00310 job->addMetaData( "errorPage", "false" ); 00311 connect( job, SIGNAL( result( KIO::Job * ) ), this, SLOT( slotPropFindResult( KIO::Job * ) ) ); 00312 } 00313 00314 void ExchangeDownload::slotPropFindResult( KIO::Job * job ) 00315 { 00316 // kdDebug() << "slotPropFindResult" << endl; 00317 00318 int error = job->error(); 00319 if ( error ) 00320 { 00321 job->showErrorDialog( 0L ); 00322 finishUp( ExchangeClient::CommunicationError, job ); 00323 return; 00324 } 00325 00326 QDomDocument response = static_cast<KIO::DavJob *>( job )->response(); 00327 // kdDebug() << "Response: " << endl; 00328 // kdDebug() << response.toString() << endl; 00329 00330 QDomElement prop = response.documentElement().namedItem( "response" ).namedItem( "propstat" ).namedItem( "prop" ).toElement(); 00331 00332 KCal::Event* event = new KCal::Event(); 00333 00334 QDomElement uidElement = prop.namedItem( "uid" ).toElement(); 00335 if ( uidElement.isNull() ) { 00336 kdError() << "Error: no uid in Exchange server reply" << endl; 00337 finishUp( ExchangeClient::IllegalAppointmentError, "WebDAV server response:\n" + response.toString() ); 00338 return; 00339 } 00340 event->setUid( uidElement.text() ); 00341 // kdDebug() << "Got UID: " << uidElement.text() << endl; 00342 00343 QString timezoneid = prop.namedItem( "timezoneid" ).toElement().text(); 00344 // kdDebug() << "DEBUG: timezoneid = " << timezoneid << endl; 00345 00346 QString timezone = prop.namedItem( "timezone" ).toElement().text(); 00347 // kdDebug() << "DEBUG: timezone = " << timezone << endl; 00348 00349 // mFormat is used for parsing recurrence rules. 00350 QString localTimeZoneId; 00351 if ( mCalendar ) { 00352 mFormat->setTimeZone( mCalendar->timeZoneId(), !mCalendar->isLocalTime() ); 00353 localTimeZoneId = mCalendar->timeZoneId(); 00354 } else { 00355 localTimeZoneId = "UTC"; 00356 // If no mCalendar, stay in UTC 00357 } 00358 00359 QString lastModified = prop.namedItem( "lastmodified" ).toElement().text(); 00360 QDateTime dt = utcAsZone( QDateTime::fromString( lastModified, Qt::ISODate ), localTimeZoneId ); 00361 event->setLastModified( dt ); 00362 // kdDebug() << "Got lastModified:" << lastModified << ", " << dt.toString() << endl; 00363 00364 QString organizer = prop.namedItem( "organizer" ).toElement().text(); 00365 event->setOrganizer( organizer ); 00366 // kdDebug() << "Got organizer: " << organizer << endl; 00367 00368 // Trying to find attendees, not working yet 00369 QString contact = prop.namedItem( "contact" ).toElement().text(); 00370 // event->setOrganizer( organizer ); 00371 // kdDebug() << "DEBUG: Got contact: " << contact << endl; 00372 00373 // This looks promising for finding attendees 00374 // FIXME: get this to work 00375 QString to = prop.namedItem( "to" ).toElement().text(); 00376 // kdDebug() << "DEBUG: Got to: " << to << endl; 00377 QStringList attn = QStringList::split( ",", to ); // This doesn't work: there can be commas between "" 00378 QStringList::iterator it; 00379 for ( it = attn.begin(); it != attn.end(); ++it ) { 00380 // kdDebug() << " attendee: " << (*it) << endl; 00381 QString name = ""; 00382 // KCal::Attendee* a = new KCal::Attendee( name, email ); 00383 00384 // event->addAttendee( a ); 00385 } 00386 00387 QString readonly = prop.namedItem( "isreadonly" ).toElement().text(); 00388 event->setReadOnly( readonly != "0" ); 00389 // kdDebug() << "Got readonly: " << readonly << ":" << (readonly != "0") << endl; 00390 00391 QString created = prop.namedItem( "created" ).toElement().text(); 00392 dt = utcAsZone( QDateTime::fromString( created, Qt::ISODate ), localTimeZoneId ); 00393 event->setCreated( dt ); 00394 // kdDebug() << "got created: " << dt.toString() << endl; 00395 00396 QString dtstart = prop.namedItem( "dtstart" ).toElement().text(); 00397 dt = utcAsZone( QDateTime::fromString( dtstart, Qt::ISODate ), localTimeZoneId ); 00398 event->setDtStart( dt ); 00399 // kdDebug() << "got dtstart: " << dtstart << " becomes in timezone " << dt.toString() << endl; 00400 00401 QString alldayevent = prop.namedItem( "alldayevent" ).toElement().text(); 00402 bool floats = alldayevent.toInt() != 0; 00403 event->setFloats( floats ); 00404 // kdDebug() << "Got alldayevent: \"" << alldayevent << "\":" << floats << endl; 00405 00406 QString dtend = prop.namedItem( "dtend" ).toElement().text(); 00407 dt = utcAsZone( QDateTime::fromString( dtend, Qt::ISODate ), localTimeZoneId ); 00408 // Outlook thinks differently about floating event timing than libkcal 00409 if ( floats ) dt = dt.addDays( -1 ); 00410 event->setDtEnd( dt ); 00411 // kdDebug() << "got dtstart: " << dtend << " becomes in timezone " << dt.toString() << endl; 00412 00413 QString transparent = prop.namedItem( "transparent" ).toElement().text(); 00414 event->setTransparency( transparent.toInt() > 0 ? KCal::Event::Transparent 00415 : KCal::Event::Opaque ); 00416 // kdDebug() << "Got transparent: " << transparent << endl; 00417 00418 QString description = prop.namedItem( "textdescription" ).toElement().text(); 00419 event->setDescription( description ); 00420 // kdDebug() << "Got description: " << description << endl; 00421 00422 QString subject = prop.namedItem( "subject" ).toElement().text(); 00423 event->setSummary( subject ); 00424 // kdDebug() << "Got summary: " << subject << endl; 00425 00426 QString location = prop.namedItem( "location" ).toElement().text(); 00427 event->setLocation( location ); 00428 // kdDebug() << "Got location: " << location << endl; 00429 00430 QString rrule = prop.namedItem( "rrule" ).toElement().text(); 00431 // kdDebug() << "Got rrule: " << rrule << endl; 00432 if ( ! rrule.isNull() ) { 00433 // Timezone should be handled automatically 00434 // because we used mFormat->setTimeZone() earlier 00435 if ( ! mFormat->fromString( event->recurrence(), rrule ) ) { 00436 kdError() << "ERROR parsing rrule " << rrule << endl; 00437 } 00438 } 00439 00440 QDomElement keywords = prop.namedItem( "Keywords" ).toElement(); 00441 QStringList categories; 00442 QDomNodeList list = keywords.elementsByTagNameNS( "xml:", "v" ); 00443 for( uint i=0; i < list.count(); i++ ) { 00444 QDomElement item = list.item(i).toElement(); 00445 categories.append( item.text() ); 00446 } 00447 event->setCategories( categories ); 00448 // kdDebug() << "Got categories: " << categories.join( ", " ) << endl; 00449 00450 00451 QDomElement exdate = prop.namedItem( "exdate" ).toElement(); 00452 KCal::DateList exdates; 00453 list = exdate.elementsByTagNameNS( "xml:", "v" ); 00454 for( uint i=0; i < list.count(); i++ ) { 00455 QDomElement item = list.item(i).toElement(); 00456 QDate date = utcAsZone( QDateTime::fromString( item.text(), Qt::ISODate ), localTimeZoneId ).date(); 00457 exdates.append( date ); 00458 // kdDebug() << "Got exdate: " << date.toString() << endl; 00459 } 00460 event->setExDates( exdates ); 00461 00462 // Exchange sentitivity values: 00463 // 0 None 00464 // 1 Personal 00465 // 2 Private 00466 // 3 Company Confidential 00467 QString sensitivity = prop.namedItem( "sensitivity" ).toElement().text(); 00468 if ( ! sensitivity.isNull() ) 00469 switch( sensitivity.toInt() ) { 00470 case 0: event->setSecrecy( KCal::Incidence::SecrecyPublic ); break; 00471 case 1: event->setSecrecy( KCal::Incidence::SecrecyPrivate ); break; 00472 case 2: event->setSecrecy( KCal::Incidence::SecrecyPrivate ); break; 00473 case 3: event->setSecrecy( KCal::Incidence::SecrecyConfidential ); break; 00474 default: kdWarning() << "Unknown sensitivity: " << sensitivity << endl; 00475 } 00476 // kdDebug() << "Got sensitivity: " << sensitivity << endl; 00477 00478 00479 QString reminder = prop.namedItem( "reminderoffset" ).toElement().text(); 00480 // kdDebug() << "Reminder offset: " << reminder << endl; 00481 if ( ! reminder.isNull() ) { 00482 // Duration before event in seconds 00483 KCal::Duration offset( - reminder.toInt() ); 00484 KCal::Alarm* alarm = event->newAlarm(); 00485 alarm->setStartOffset( offset ); 00486 alarm->setEnabled( true ); 00487 // TODO: multiple alarms; alarm->setType( KCal::Alarm::xxxx ); 00488 } 00490 //Alarm* newAlarm(); 00492 //void addAlarm(Alarm*); 00493 00495 //void setRelatedTo(Incidence *relatedTo); 00497 //void addRelation(Incidence *); 00498 00500 //void setAttachments(const QStringList &attachments); 00501 00503 //void setResources(const QStringList &resources); 00504 00506 //void setPriority(int priority); 00507 00513 //void addAttendee(Attendee *a, bool doupdate=true ); 00514 00515 // THE FOLLOWING EVENT PROPERTIES ARE NOT READ 00516 00517 // Revision ID in webdav is a String, not an int 00519 //void setRevision(int rev); 00520 00521 // Problem: When you sync Outlook to a Palm, the conduit splits up 00522 // multi-day events into single-day events WITH ALL THE SAME UID 00523 // Grrrrrrr. 00524 if ( mCalendar ) { 00525 KCal::Event* oldEvent = mCalendar->event( event->uid() ); 00526 if ( oldEvent ) { 00527 kdWarning() << "Already got his event, keeping old version..." << endl; 00528 // This doesn't work 00529 // *oldEvent = *event; 00530 } else { 00531 mCalendar->addEvent( event ); 00532 } 00533 } else { 00534 emit gotEvent( event, static_cast<KIO::DavJob *>( job )->url() ); 00535 // mEvents->append( event ); 00536 } 00537 00538 decreaseDownloads(); 00539 } 00540 00541 void ExchangeDownload::increaseDownloads() 00542 { 00543 mDownloadsBusy++; 00544 emit startDownload(); 00545 } 00546 00547 void ExchangeDownload::decreaseDownloads() 00548 { 00549 mDownloadsBusy--; 00550 // kdDebug() << "Download finished, waiting for " << mDownloadsBusy << " more" << endl; 00551 emit finishDownload(); 00552 if ( mDownloadsBusy == 0 ) { 00553 kdDebug() << "All downloads finished" << endl; 00554 finishUp( ExchangeClient::ResultOK ); 00555 } 00556 } 00557 00558 void ExchangeDownload::finishUp( int result, const QString& moreInfo ) 00559 { 00560 if ( mCalendar ) mCalendar->setModified( true ); 00561 // Disconnect from progress bar 00562 if ( mProgress ) { 00563 disconnect( this, 0, mProgress, 0 ); 00564 disconnect( mProgress, 0, this, 0 ); 00565 mProgress->delayedDestruct(); 00566 } 00567 00568 // if ( mEvents ) { 00569 // emit finished( this, result, moreInfo, *mEvents ); 00570 // } else { 00571 emit finished( this, result, moreInfo ); 00572 // } 00573 } 00574 00575 void ExchangeDownload::finishUp( int result, KIO::Job* job ) 00576 { 00577 finishUp( result, QString("WebDAV job error code = ") + QString::number( job->error() ) + ";\n" + "\"" + job->errorString() + "\"" ); 00578 } 00579 00580 #include "exchangedownload.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