libkcal Library API Documentation

resourceimap.cpp

00001 /* 00002 This file is part of libkcal. 00003 00004 Copyright (c) 2003 Steffen Hansen <steffen@klaralvdalens-datakonsult.se> 00005 Copyright (c) 2003 - 2004 Bo Thorsen <bo@klaralvdalens-datakonsult.se> 00006 00007 This library is free software; you can redistribute it and/or 00008 modify it under the terms of the GNU Library General Public 00009 License as published by the Free Software Foundation; either 00010 version 2 of the License, or (at your option) any later version. 00011 00012 This library is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 Library General Public License for more details. 00016 00017 You should have received a copy of the GNU Library General Public License 00018 along with this library; see the file COPYING.LIB. If not, write to 00019 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00020 Boston, MA 02111-1307, USA. 00021 */ 00022 00023 #include <kdebug.h> 00024 #include <dcopclient.h> 00025 #include <kapplication.h> 00026 #include <kdcopservicestarter.h> 00027 #include <klocale.h> 00028 00029 #include <libkcal/vcaldrag.h> 00030 #include <libkcal/vcalformat.h> 00031 #include <libkcal/exceptions.h> 00032 #include <libkcal/incidence.h> 00033 #include <libkcal/event.h> 00034 #include <libkcal/todo.h> 00035 #include <libkcal/journal.h> 00036 00037 #include <kabc/locknull.h> 00038 00039 #include <kresources/configwidget.h> 00040 #include <kresources/resource.h> 00041 00042 #include "kmailicalIface_stub.h" 00043 00044 00045 #include "resourceimapconfig.h" 00046 #include "resourceimap.h" 00047 00048 using namespace KCal; 00049 00050 static const QCString dcopObjectId = "KMailICalIface"; 00051 00052 extern "C" 00053 { 00054 void *init_kcal_imap() 00055 { 00056 return new KRES::PluginFactory<ResourceIMAP,ResourceIMAPConfig>(); 00057 } 00058 } 00059 00060 00061 ResourceIMAP::ResourceIMAP( const KConfig* config ) 00062 : DCOPObject("ResourceIMAP"), ResourceCalendar( config ) 00063 { 00064 if ( config ) { 00065 mServer = config->readEntry( "Servername" ); 00066 } 00067 init(); 00068 00069 // Make the connection to KMail ready 00070 mKMailIcalIfaceStub = 0; 00071 kapp->dcopClient()->setNotifications( true ); 00072 connect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString& ) ), 00073 this, SLOT( unregisteredFromDCOP( const QCString& ) ) ); 00074 } 00075 00076 void ResourceIMAP::writeConfig( KConfig* config ) 00077 { 00078 ResourceCalendar::writeConfig( config ); 00079 config->writeEntry( "Servername", mServer ); 00080 } 00081 00082 void ResourceIMAP::init() 00083 { 00084 mSilent = false; 00085 00086 mDCOPClient = new DCOPClient(); 00087 mDCOPClient->attach(); 00088 mDCOPClient->registerAs( "resourceimap", true ); 00089 } 00090 00091 00092 ResourceIMAP::~ResourceIMAP() 00093 { 00094 kapp->dcopClient()->setNotifications( false ); 00095 delete mKMailIcalIfaceStub; 00096 close(); 00097 delete mDCOPClient; 00098 } 00099 00100 bool ResourceIMAP::getIncidenceList( QStringList& lst, const QString& type ) 00101 { 00102 if ( !connectToKMail() ) { 00103 kdError() << "DCOP error during incidences(QString)\n"; 00104 return false; 00105 } 00106 00107 lst = mKMailIcalIfaceStub->incidences( type ); 00108 if ( !mKMailIcalIfaceStub->ok() ) { 00109 kdError() << "Communication problem in ResourceIMAP::getIncidenceList()\n"; 00110 return false; 00111 } 00112 00113 return true; 00114 } 00115 00116 bool ResourceIMAP::doOpen() 00117 { 00118 return true; 00119 } 00120 00121 bool ResourceIMAP::load() 00122 { 00123 // Load each resource. Note: It's intentional to use & instead of && 00124 // so we try all three, even if the first failed 00125 return loadAllEvents() & loadAllTasks() & loadAllJournals(); 00126 } 00127 00128 bool ResourceIMAP::loadAllEvents() 00129 { 00130 // Get the list of events 00131 QStringList lst; 00132 if ( !getIncidenceList( lst, "Calendar" ) ) 00133 // The get failed 00134 return false; 00135 00136 // We got a fresh list of events, so clean out the old ones 00137 mCalendar.deleteAllEvents(); 00138 00139 // Populate the calendar with the new events 00140 for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { 00141 Incidence* i = parseIncidence( *it ); 00142 if ( i ) { 00143 if ( i->type() == "Event" ) { 00144 mCalendar.addEvent(static_cast<Event*>(i)); 00145 i->registerObserver( this ); 00146 } else { 00147 kdDebug() << "Unknown incidence type " << i->type(); 00148 delete i; 00149 } 00150 } 00151 } 00152 00153 return true; 00154 } 00155 00156 bool ResourceIMAP::loadAllTasks() 00157 { 00158 // Get the list of todos 00159 QStringList lst; 00160 if ( !getIncidenceList( lst, "Task" ) ) 00161 // The get failed 00162 return false; 00163 00164 // We got a fresh list of todos, so clean out the old ones 00165 mCalendar.deleteAllTodos(); 00166 00167 // Populate the calendar with the new todos 00168 for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { 00169 Incidence* i = parseIncidence( *it ); 00170 if ( i ) { 00171 if ( i->type() == "Todo" ) { 00172 mCalendar.addTodo(static_cast<Todo*>(i)); 00173 i->registerObserver( this ); 00174 } else { 00175 kdDebug() << "Unknown incidence type " << i->type(); 00176 delete i; 00177 } 00178 } 00179 } 00180 00181 return true; 00182 } 00183 00184 bool ResourceIMAP::loadAllJournals() 00185 { 00186 // Get the list of journals 00187 QStringList lst; 00188 if ( !getIncidenceList( lst, "Journal" ) ) 00189 // The get failed 00190 return false; 00191 00192 // We got a fresh list of journals, so clean out the old ones 00193 mCalendar.deleteAllJournals(); 00194 00195 // Populate the calendar with the new journals 00196 for ( QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) { 00197 Incidence* i = parseIncidence( *it ); 00198 if ( i ) { 00199 if ( i->type() == "Journal" ) { 00200 mCalendar.addJournal(static_cast<Journal*>(i)); 00201 i->registerObserver( this ); 00202 } else { 00203 kdDebug() << "Unknown incidence type " << i->type(); 00204 delete i; 00205 } 00206 } 00207 } 00208 00209 return true; 00210 } 00211 00212 bool ResourceIMAP::save() 00213 { 00214 return false; 00215 } 00216 00217 KABC::Lock *ResourceIMAP::lock() 00218 { 00219 return new KABC::LockNull( true ); 00220 } 00221 00222 /*********************************************** 00223 * Adding and removing Events 00224 */ 00225 00226 bool ResourceIMAP::addEvent(Event *anEvent) 00227 { 00228 mCalendar.addEvent(anEvent); 00229 anEvent->registerObserver( this ); 00230 00231 if ( mSilent ) return true; 00232 00233 // Call kmail ... 00234 if ( !connectToKMail() ) { 00235 kdError() << "DCOP error during addIncidence(QString)\n"; 00236 return false; 00237 } 00238 00239 mCurrentUID = anEvent->uid(); 00240 QString vCal = mFormat.createScheduleMessage( anEvent, Scheduler::Request ); 00241 bool rc = mKMailIcalIfaceStub->addIncidence( "Calendar", mCurrentUID, vCal ); 00242 mCurrentUID = QString::null; 00243 00244 if ( !mKMailIcalIfaceStub->ok() ) { 00245 kdError() << "Communication problem in ResourceIMAP::addEvent()\n"; 00246 return false; 00247 } 00248 00249 return rc; 00250 } 00251 00252 // probably not really efficient, but...it works for now. 00253 void ResourceIMAP::deleteEvent(Event *event) 00254 { 00255 // Call kmail ... 00256 if ( !mSilent ) { 00257 if ( !connectToKMail() ) { 00258 kdError() << "DCOP error during " 00259 << "ResourceIMAP::deleteIncidence(QString)\n"; 00260 } else { 00261 mCurrentUID = event->uid(); 00262 mKMailIcalIfaceStub->deleteIncidence( "Calendar", mCurrentUID ); 00263 } 00264 } 00265 00266 mCalendar.deleteEvent(event); 00267 mCurrentUID = QString::null; 00268 } 00269 00270 00271 /*********************************************** 00272 * Getting Events 00273 */ 00274 00275 Event *ResourceIMAP::event( const QString &uid ) 00276 { 00277 return mCalendar.event(uid); 00278 } 00279 00280 // taking a QDate, this function will look for an eventlist in the dict 00281 // with that date attached - 00282 Event::List ResourceIMAP::rawEventsForDate( const QDate &qd, bool sorted ) 00283 { 00284 return mCalendar.rawEventsForDate( qd, sorted ); 00285 } 00286 00287 00288 Event::List ResourceIMAP::rawEvents( const QDate &start, const QDate &end, 00289 bool inclusive ) 00290 { 00291 return mCalendar.rawEvents( start, end, inclusive ); 00292 } 00293 00294 Event::List ResourceIMAP::rawEventsForDate(const QDateTime &qdt) 00295 { 00296 return mCalendar.rawEventsForDate( qdt ); 00297 } 00298 00299 Event::List ResourceIMAP::rawEvents() 00300 { 00301 return mCalendar.rawEvents(); 00302 } 00303 00304 /*********************************************** 00305 * Adding and removing Todos 00306 */ 00307 00308 bool ResourceIMAP::addTodo(Todo *todo) 00309 { 00310 mCalendar.addTodo(todo); 00311 todo->registerObserver( this ); 00312 00313 if ( mSilent ) return true; 00314 00315 if ( !connectToKMail() ) { 00316 kdError() << "DCOP error during addTodo(QString)\n"; 00317 return false; 00318 } 00319 00320 mCurrentUID = todo->uid(); 00321 QString vCal = mFormat.createScheduleMessage( todo, Scheduler::Request ); 00322 bool rc = mKMailIcalIfaceStub->addIncidence( "Task", mCurrentUID, vCal ); 00323 mCurrentUID = QString::null; 00324 00325 if ( !mKMailIcalIfaceStub->ok() ) { 00326 kdError() << "Communication problem in ResourceIMAP::addTodo()\n"; 00327 return false; 00328 } 00329 00330 return rc; 00331 } 00332 00333 void ResourceIMAP::deleteTodo(Todo *todo) 00334 { 00335 // call kmail ... 00336 if ( !mSilent ) { 00337 if ( !connectToKMail() ) { 00338 kdError() << "DCOP error during ResourceIMAP::deleteTodo(QString)\n"; 00339 } else { 00340 mCurrentUID = todo->uid(); 00341 mKMailIcalIfaceStub->deleteIncidence( "Task", mCurrentUID ); 00342 mCurrentUID = QString::null; 00343 } 00344 } 00345 mCalendar.deleteTodo(todo); 00346 } 00347 00348 /*********************************************** 00349 * Getting Todos 00350 */ 00351 00352 Todo::List ResourceIMAP::rawTodos() 00353 { 00354 return mCalendar.rawTodos(); 00355 } 00356 00357 Todo *ResourceIMAP::todo( const QString &uid ) 00358 { 00359 return mCalendar.todo(uid); 00360 } 00361 00362 Todo::List ResourceIMAP::todos( const QDate &date ) 00363 { 00364 return mCalendar.todos(date); 00365 } 00366 00367 /*********************************************** 00368 * Journal handling 00369 */ 00370 00371 bool ResourceIMAP::addJournal(Journal *journal) 00372 { 00373 mCalendar.addJournal(journal); 00374 journal->registerObserver( this ); 00375 00376 if ( mSilent ) return true; 00377 00378 // call kmail .. 00379 if ( !connectToKMail() ) { 00380 kdError() << "DCOP error during addTodo(QString)\n"; 00381 return false; 00382 } 00383 00384 mCurrentUID = journal->uid(); 00385 QString vCal = mFormat.createScheduleMessage( journal, Scheduler::Request ); 00386 bool rc = mKMailIcalIfaceStub->addIncidence( "Journal", mCurrentUID, vCal ); 00387 mCurrentUID = QString::null; 00388 00389 if ( !mKMailIcalIfaceStub->ok() ) { 00390 kdError() << "Communication problem in ResourceIMAP::addJournal()\n"; 00391 return false; 00392 } 00393 00394 return rc; 00395 } 00396 00397 void ResourceIMAP::deleteJournal(Journal *journal) 00398 { 00399 if( !journal ) 00400 return; 00401 00402 if ( !mSilent ) { 00403 if ( !connectToKMail() ) { 00404 kdError() << "DCOP error during ResourceIMAP::deleteJournal(QString)\n"; 00405 } else { 00406 mCurrentUID = journal->uid(); 00407 mKMailIcalIfaceStub->deleteIncidence( "Journal", mCurrentUID ); 00408 mCurrentUID = QString::null; 00409 } 00410 } 00411 mCalendar.deleteJournal(journal); 00412 } 00413 00414 00415 Journal *ResourceIMAP::journal(const QDate &date) 00416 { 00417 return mCalendar.journal(date); 00418 } 00419 00420 Journal *ResourceIMAP::journal(const QString &uid) 00421 { 00422 return mCalendar.journal(uid); 00423 } 00424 00425 Journal::List ResourceIMAP::journals() 00426 { 00427 return mCalendar.journals(); 00428 } 00429 00430 /*********************************************** 00431 * Alarm handling 00432 */ 00433 00434 Alarm::List ResourceIMAP::alarmsTo( const QDateTime &to ) 00435 { 00436 return mCalendar.alarmsTo(to); 00437 } 00438 00439 Alarm::List ResourceIMAP::alarms( const QDateTime &from, const QDateTime &to ) 00440 { 00441 return mCalendar.alarms( from, to ); 00442 } 00443 00444 /*********************************************** 00445 * update() (kind of slot) 00446 */ 00447 00448 // after changes are made to an event, this should be called. 00449 void ResourceIMAP::update(IncidenceBase *incidencebase) 00450 { 00451 if ( !connectToKMail() ) { 00452 kdError() << "DCOP error during ResourceIMAP::update(QString)\n"; 00453 return; 00454 } 00455 00456 QString type = incidencebase->type(); 00457 if ( type == "Event" ) type = "Calendar"; 00458 else if ( type == "Todo" ) type = "Task"; 00459 else if ( type != "Journal" ) return; 00460 00461 incidencebase->setSyncStatus(Event::SYNCMOD); 00462 incidencebase->setLastModified(QDateTime::currentDateTime()); 00463 // we should probably update the revision number here, 00464 // or internally in the Event itself when certain things change. 00465 // need to verify with ical documentation. 00466 00467 // Delete the old one and add the new version 00468 mCurrentUID = incidencebase->uid(); 00469 QString vCal = mFormat.createScheduleMessage( incidencebase, 00470 Scheduler::Request ); 00471 mKMailIcalIfaceStub->deleteIncidence( type, mCurrentUID ); 00472 mKMailIcalIfaceStub->addIncidence( type, mCurrentUID, vCal ); 00473 mCurrentUID = QString::null; 00474 00475 if ( !mKMailIcalIfaceStub->ok() ) { 00476 kdError() << "Communication problem in ResourceIMAP::addJournal()\n"; 00477 } 00478 } 00479 00480 KCal::Incidence* ResourceIMAP::parseIncidence( const QString& str ) 00481 { 00482 Incidence* i = mFormat.fromString( str ); 00483 return i; 00484 } 00485 00486 bool ResourceIMAP::addIncidence( const QString& type, const QString& ical ) 00487 { 00488 if( type != "Calendar" && type != "Task" && type != "Journal" ) 00489 // Not an ical for us 00490 return false; 00491 00492 Incidence* i = parseIncidence( ical ); 00493 if ( !i ) return false; 00494 // Ignore events that come from us 00495 if ( !mCurrentUID.isNull() && mCurrentUID == i->uid() ) return true; 00496 00497 mSilent = true; 00498 if ( type == "Calendar" && i->type() == "Event" ) { 00499 addEvent( static_cast<Event*>(i) ); 00500 emit resourceChanged( this ); 00501 } else if ( type == "Task" && i->type() == "Todo" ) { 00502 addTodo( static_cast<Todo*>(i) ); 00503 emit resourceChanged( this ); 00504 } else if ( type == "Journal" && i->type() == "Journal" ) { 00505 addJournal( static_cast<Journal*>(i) ); 00506 emit resourceChanged( this ); 00507 } 00508 mSilent = false; 00509 00510 return true; 00511 } 00512 00513 void ResourceIMAP::deleteIncidence( const QString& type, const QString& uid ) 00514 { 00515 if( type != "Calendar" && type != "Task" && type != "Journal" ) 00516 // Not an ical for us 00517 return; 00518 00519 // Ignore events that come from us 00520 if ( !mCurrentUID.isNull() && mCurrentUID == uid ) return; 00521 00522 mSilent = true; 00523 if ( type == "Calendar" ) { 00524 Event* e = event( uid ); 00525 if( e ) { 00526 deleteEvent( e ); 00527 emit resourceChanged( this ); 00528 } 00529 } else if ( type == "Task" ) { 00530 Todo* t = todo( uid ); 00531 if( t ) { 00532 deleteTodo( t ); 00533 emit resourceChanged( this ); 00534 } 00535 } else if ( type == "Journal" ) { 00536 Journal* j = journal( uid ); 00537 if( j ) { 00538 deleteJournal( j ); 00539 emit resourceChanged( this ); 00540 } 00541 } 00542 mSilent = false; 00543 } 00544 00545 void ResourceIMAP::slotRefresh( const QString& type ) 00546 { 00547 if ( type == "Calendar" ) 00548 loadAllEvents(); 00549 else if ( type == "Task" ) 00550 loadAllTasks(); 00551 else if ( type == "Journal" ) 00552 loadAllJournals(); 00553 } 00554 00555 bool ResourceIMAP::connectToKMail() const 00556 { 00557 if ( !mKMailIcalIfaceStub ) { 00558 QString error; 00559 QCString dcopService; 00560 int result = KDCOPServiceStarter::self()-> 00561 findServiceFor( "DCOP/ResourceBackend/IMAP", QString::null, 00562 QString::null, &error, &dcopService ); 00563 if ( result != 0 ) { 00564 kdDebug(5800) << "Couldn't connect to the IMAP resource backend\n"; 00565 // TODO: You might want to show "error" (if not empty) here, using e.g. KMessageBox 00566 return false; 00567 } 00568 00569 mKMailIcalIfaceStub = new KMailICalIface_stub( kapp->dcopClient(), 00570 dcopService, dcopObjectId ); 00571 00572 // Attach to the KMail signals 00573 if ( !connectKMailSignal( "incidenceAdded(QString,QString)", 00574 "addIncidence(QString,QString)" ) ) { 00575 kdError() << "DCOP connection to incidenceAdded failed" << endl; 00576 } 00577 if ( !connectKMailSignal( "incidenceDeleted(QString,QString)", 00578 "deleteIncidence(QString,QString)" ) ) { 00579 kdError() << "DCOP connection to incidenceDeleted failed" << endl; 00580 } 00581 if ( !connectKMailSignal( "signalRefresh(QString)", 00582 "slotRefresh(QString)" ) ) { 00583 kdError() << "DCOP connection to signalRefresh failed" << endl; 00584 } 00585 } 00586 00587 return ( mKMailIcalIfaceStub != 0 ); 00588 } 00589 00590 bool ResourceIMAP::connectKMailSignal( const QCString& signal, 00591 const QCString& method ) const 00592 { 00593 ResourceIMAP* _this = const_cast<ResourceIMAP*>( this ); 00594 return _this->connectDCOPSignal( "kmail", dcopObjectId, signal, method, 00595 false ); 00596 } 00597 00598 void ResourceIMAP::unregisteredFromDCOP( const QCString& appId ) 00599 { 00600 if ( mKMailIcalIfaceStub && mKMailIcalIfaceStub->app() == appId ) { 00601 // Delete the stub so that the next time we need the addressbook, 00602 // we'll know that we need to start a new one. 00603 delete mKMailIcalIfaceStub; 00604 mKMailIcalIfaceStub = 0; 00605 } 00606 } 00607 00608 00609 void ResourceIMAP::setTimeZoneId( const QString& tzid ) 00610 { 00611 mCalendar.setTimeZoneId( tzid ); 00612 } 00613 00614 #include "resourceimap.moc" 00615
KDE Logo
This file is part of the documentation for libkcal Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:57:44 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003