kitchensync Library API Documentation

organizerpart.cpp

00001 00002 #include <qcheckbox.h> 00003 00004 #include <ksimpleconfig.h> 00005 #include <kdebug.h> 00006 #include <kiconloader.h> 00007 #include <kmessagebox.h> 00008 #include <kparts/genericfactory.h> 00009 00010 #include <libkcal/icalformat.h> 00011 #include <libkcal/calendarlocal.h> 00012 00013 #include <eventsyncee.h> 00014 #include <todosyncee.h> 00015 #include <syncer.h> 00016 00017 #include <mainwindow.h> 00018 00019 #include "organizerpart.h" 00020 00021 //#include "return.h" 00022 //#include "sync.h" 00023 00024 typedef KParts::GenericFactory< KSync::OrganizerPart> OrganizerPartFactory; 00025 K_EXPORT_COMPONENT_FACTORY( liborganizerpart, OrganizerPartFactory ) 00026 00027 using namespace KSync ; 00028 00029 OrganizerPart::OrganizerPart(QWidget *parent, const char *name, 00030 QObject *, const char *, const QStringList & ) 00031 : ManipulatorPart( parent, name ) 00032 { 00033 setInstance(OrganizerPartFactory::instance() ); 00034 m_pixmap = KGlobal::iconLoader()->loadIcon("korganizer", KIcon::Desktop, 48 ); 00035 00036 kdDebug() << "OragnizerPart" << endl; 00037 } 00038 OrganizerPart::~OrganizerPart() 00039 { 00040 } 00041 QString OrganizerPart::iconName()const { 00042 return QString::fromLatin1("korganizer"); 00043 } 00044 QPixmap* OrganizerPart::pixmap() 00045 { 00046 return &m_pixmap; 00047 } 00048 QString OrganizerPart::type()const { 00049 return QString::fromLatin1("Organizer"); 00050 } 00051 QString OrganizerPart::name()const { 00052 return i18n("Organizer"); 00053 } 00054 QString OrganizerPart::description()const { 00055 return i18n("This part is responsible for syncing your Calendar."); 00056 } 00057 bool OrganizerPart::hasGui()const { 00058 return false; 00059 } 00060 bool OrganizerPart::configIsVisible()const { 00061 return true; 00062 } 00063 QWidget* OrganizerPart::configWidget() 00064 { 00065 m_config = new OrganizerDialogBase(); 00066 00067 if ( isEvolutionSync() ) 00068 m_config->ckbEvo->setChecked( true ); 00069 else{ 00070 m_config->urlReq->setURL( core()->currentProfile().path("OrganizerPart") ); 00071 } 00072 00073 return (QWidget*) m_config; 00074 } 00075 00076 bool OrganizerPart::isEvolutionSync()const { 00077 QString path; 00078 path = core()->currentProfile().path( "OrganizerPart" ); 00079 00080 return ( path == QString::fromLatin1("evolution" ) ) ; 00081 } 00082 00083 KAboutData *OrganizerPart::createAboutData() 00084 { 00085 return new KAboutData("KSyncOrganizerPart", I18N_NOOP("Sync organizer part"), "0.0" ); 00086 } 00087 00088 void OrganizerPart::slotConfigOk() 00089 { 00090 Profile prof = core()->currentProfile(); 00091 if ( m_config->ckbEvo->isChecked() ) 00092 prof.setPath("OrganizerPart", "evolution"); 00093 else 00094 prof.setPath("OrganizerPart", m_config->urlReq->url() ); 00095 00096 core()->profileManager()->replaceProfile( prof ); 00097 core()->profileManager()->setCurrentProfile( prof ); 00098 } 00099 /* Do it for Events + Todos 00100 * The 10 Stages to synced data 00101 * 0. get the time zone id 00102 * 1. get the currentProfile and currentKonnector 00103 * 2. get the paths + the information about using meta data 00104 * from the Konnector 00105 * 3. search our Syncees 00106 * 4. load the File from currentProfile 00107 * 5. If meta data collect it currentProfile.uid() + currentKonnectorProf.uid() 00108 * + name for the MetaInformation filename 00109 * 6. SYNC using our own algorithm 00110 * 7. write back meta data if necessary 00111 * 8. write back file 00112 * 9. append the Syncee to the out list 00113 * 10. have a party and get drunk 00114 */ 00115 void OrganizerPart::sync( const SynceeList &in, 00116 SynceeList &out ) 00117 { 00118 /* 0. */ 00119 KConfig conf("korganizerrc"); 00120 conf.setGroup("Time & Date"); 00121 QString timeZoneId = conf.readEntry("TimeZoneId", QString::fromLatin1("UTC") ); 00122 kdDebug(5222) << " Time & Date " << timeZoneId << endl; 00123 00124 /* 1. is fairly easy */ 00125 Profile prof = core()->currentProfile(); 00126 KonnectorProfile kon = core()->currentKonnectorProfile(); 00127 00128 /* 2. too */ 00129 QString path = prof.path( "OrganizerPart" ); 00130 QString meta = kon.uid()+"/"+prof.uid() + "organizer.rc"; 00131 bool met = kon.kapabilities().isMetaSyncingEnabled(); 00132 00133 /* 3. */ 00134 EventSyncee *evSyncee = in.eventSyncee(); 00135 TodoSyncee *toSyncee = in.todoSyncee(); 00136 if (!evSyncee && !toSyncee) { 00137 done(); 00138 return; // did not find both of them 00139 } 00140 00141 /* 4. load */ 00142 EventSyncee* events =0l; 00143 TodoSyncee* todos = 0l; 00144 if (evSyncee ) 00145 events = loadEvents( path, timeZoneId ); 00146 if (toSyncee ) 00147 todos = loadTodos( path, timeZoneId ); 00148 00149 /* 5. meta data */ 00150 if ( met ) 00151 doMeta( events, todos, meta ); 00152 //else { 00153 // set the sync MODE FIXME 00154 //} 00155 /* 6. sync */ 00156 Syncer sync( core()->syncUi(), core()->syncAlgorithm() ); 00157 if (evSyncee ) { 00158 events->setSource( i18n("Organizer") ); 00159 sync.addSyncee(evSyncee); 00160 sync.addSyncee(events); 00161 sync.sync(); 00162 sync.clear(); 00163 } 00164 if (toSyncee ) { 00165 todos->setSource( i18n("Todolist") ); 00166 sync.addSyncee( toSyncee ); 00167 sync.addSyncee( todos ); 00168 sync.sync(); 00169 sync.clear(); 00170 } 00171 00172 if ( confirmBeforeWriting() ) { 00173 switch ( KMessageBox::questionYesNo(0, i18n("Do you want to write back todolist and calendar?"), i18n("Save"), 00174 KStdGuiItem::save(), KStdGuiItem::dontSave() ) ) { 00175 case KMessageBox::No:{ 00176 delete todos; 00177 delete events; 00178 done(); 00179 return; 00180 00181 break; 00182 } 00183 default: 00184 break; 00185 } 00186 } 00187 00188 /* 7. write back meta */ 00189 if ( met ) 00190 writeMeta( events, todos, meta ); 00191 00192 /* 8. write back data */ 00193 save( events, todos, path, timeZoneId ); 00194 00195 /* 8.1 take care of the IdHelpers.... */ 00196 00197 /* 9. */ 00198 if (events) 00199 out.append( events ); 00200 00201 if (todos) 00202 out.append( todos ); 00203 done(); 00204 } 00205 00206 //AddressBookSyncee* ANY 00207 TodoSyncee* OrganizerPart::loadTodos( const QString& pa, const QString& timeZoneId ) { 00208 TodoSyncee* syncee = new TodoSyncee(); 00209 KCal::CalendarLocal cal(timeZoneId); 00210 cal.load(path( Todo, pa ) ); 00211 KCal::Todo::List todos = cal.rawTodos(); 00212 if ( todos.isEmpty() ) { 00213 return syncee; 00214 } 00215 00216 KCal::Todo::List::ConstIterator it; 00217 TodoSyncEntry* entry =0 ; 00218 for ( it = todos.begin(); it != todos.end(); ++it ) { 00219 entry = new TodoSyncEntry( (*it)->clone() ) ; 00220 syncee->addEntry( entry ); 00221 } 00222 return syncee; 00223 } 00224 EventSyncee* OrganizerPart::loadEvents(const QString& pa, const QString& timeZoneId) { 00225 EventSyncee* syncee = new EventSyncee(); 00226 KCal::CalendarLocal cal(timeZoneId); 00227 cal.load( path(Calendar, pa) ); 00228 KCal::Event::List events = cal.rawEvents(); 00229 if ( events.isEmpty() ) { 00230 return syncee; 00231 } 00232 00233 KCal::Event::List::ConstIterator it; 00234 EventSyncEntry* entry; 00235 for ( it = events.begin(); it != events.end(); ++it ) { 00236 entry = new EventSyncEntry( (*it)->clone() ); 00237 syncee->addEntry( entry ); 00238 kdDebug(5222) << "Start Date of loaded " << entry->incidence()->dtStart().toString() << " " << entry->incidence()->uid() << endl; 00239 } 00240 return syncee; 00241 } 00242 /* 00243 * For meta informations we're using a KConfig file 00244 * we've one Group for each id 00245 * and we save the timestamp 00246 * First we try to find modified 00247 * then added and removed 00248 * Modified is quite easy to find 00249 * if there hasGroup(uid) and timestamp differs it was 00250 * modified. 00251 * added: if not hasGroup(uid) added 00252 * removed: if it's inside the Config file but not in 00253 * the current set of data 00254 */ 00255 void OrganizerPart::doMeta( EventSyncee* evSyncee, 00256 TodoSyncee* toSyncee, 00257 const QString& path ) { 00258 QString str = QDir::homeDirPath(); 00259 str += "/.kitchensync/meta/konnector-" + path; 00260 if (!QFile::exists( str ) ) { 00261 if (evSyncee ) { 00262 evSyncee->setFirstSync( true ); 00263 evSyncee->setSyncMode( Syncee::MetaMode ); 00264 } 00265 if (toSyncee) { 00266 toSyncee->setFirstSync( true ); 00267 toSyncee->setSyncMode( Syncee::MetaMode ); 00268 } 00269 return; 00270 } 00271 KSimpleConfig conf( str ); 00272 00273 /* check if event and or todosyncee are valid */ 00274 if (evSyncee ) 00275 doMetaIntern(evSyncee, &conf, "events-" ); 00276 00277 if (toSyncee ) 00278 doMetaIntern(toSyncee, &conf, "todos-" ); 00279 } 00280 void OrganizerPart::doMetaIntern( Syncee* syncee, 00281 KSimpleConfig* conf, 00282 const QString& key) { 00283 syncee->setSyncMode( Syncee::MetaMode ); 00284 SyncEntry* entry; 00285 QStringList ids; 00286 QString timestmp; 00287 00288 /* mod + added */ 00289 for ( entry = syncee->firstEntry(); entry; entry = syncee->nextEntry() ) { 00290 ids << entry->id(); 00291 /* has group see if modified */ 00292 if ( conf->hasGroup( key + entry->id() ) ) { 00293 conf->setGroup( key + entry->id() ); 00294 timestmp = conf->readEntry( "time"); 00295 00296 /* timestamp mismatch */ 00297 if ( timestmp != entry->timestamp() ) 00298 entry->setState(SyncEntry::Modified ); 00299 00300 }else { // added 00301 entry->setState( SyncEntry::Added ); 00302 } 00303 00304 } 00305 /* now let's find the removed items */ 00306 QStringList groups = conf->groupList(); 00307 QStringList::Iterator it; 00308 // first find the groups for our key 00309 for ( it = groups.begin(); it != groups.end(); ++it ) { 00310 /* if group starts with the key */ 00311 if ( (*it).startsWith(key ) ) { // right group 00312 QString id = (*it).mid( key.length() ); 00313 kdDebug(5222) << "OrganizerPart Meta Gathering: " 00314 << id << endl; 00315 00316 /* 00317 * the previous saved list of ids 00318 * does not contain this id 00319 * ->REMOVED 00320 * items were removed we need to create an item 00321 * with just a uid...... 00322 * let's find out which item to create or have 00323 * 2 methods sharing 95% of code 00324 */ 00325 if (!ids.contains( id )) { 00326 if ( syncee->type() == "TodoSyncee" ) { 00327 KCal::Todo *todo = new KCal::Todo(); 00328 todo->setUid( id ); 00329 TodoSyncEntry* entry = new TodoSyncEntry( todo ); 00330 syncee->addEntry( entry ); 00331 entry->setState( SyncEntry::Removed ); 00332 00333 }else { // organizer 00334 KCal::Event* ev = new KCal::Event(); 00335 ev->setUid( id ); 00336 EventSyncEntry* entry = new EventSyncEntry( ev ); 00337 syncee->addEntry( entry ); 00338 entry->setState( SyncEntry::Removed ); 00339 kdDebug(5222) << "Removed " << entry->id() << endl; 00340 } 00341 } 00342 } 00343 } 00344 } 00345 00349 void OrganizerPart::writeMeta( EventSyncee* evSyncee, 00350 TodoSyncee* toSyncee, 00351 const QString& path) { 00352 QString str = QDir::homeDirPath(); 00353 str += "/.kitchensync/meta/konnector-" + path; 00354 if (!QFile::exists( str ) ) { 00355 KonnectorProfile kon = core()->currentKonnectorProfile(); 00356 QDir dir; 00357 dir.mkdir( QDir::homeDirPath() + "/.kitchensync"); 00358 dir.mkdir( QDir::homeDirPath() + "/.kitchensync/meta"); 00359 dir.mkdir( QDir::homeDirPath() + "/.kitchensync/meta/konnector-" + kon.uid() ); 00360 } 00361 KSimpleConfig conf( str ); 00362 /* clear config before */ 00363 QStringList groups = conf.groupList(); 00364 QStringList::Iterator it; 00365 for (it = groups.begin(); it != groups.end(); ++it ) { 00366 conf.deleteGroup( (*it) ); 00367 } 00368 if (evSyncee ) 00369 writeMetaIntern( evSyncee, &conf, "events-"); 00370 if (toSyncee) 00371 writeMetaIntern( toSyncee, &conf, "todos-"); 00372 } 00373 void OrganizerPart::writeMetaIntern( Syncee* syncee, 00374 KSimpleConfig* conf, 00375 const QString& key ) { 00376 SyncEntry* entry; 00377 for (entry = syncee->firstEntry(); entry; entry= syncee->nextEntry() ) { 00378 if (entry->state() == SyncEntry::Removed ) 00379 continue; 00380 00381 conf->setGroup( key + entry->id() ); 00382 conf->writeEntry( "time", entry->timestamp() ); 00383 } 00384 } 00385 void OrganizerPart::save( EventSyncee* evSyncee, 00386 TodoSyncee* toSyncee, 00387 const QString& pa, 00388 const QString& timeZoneId) { 00389 KCal::CalendarLocal* loc = new KCal::CalendarLocal(timeZoneId); 00390 EventSyncEntry* evEntry=0l; 00391 TodoSyncEntry* toEntry=0l; 00392 if (evSyncee) { 00393 for ( evEntry = (EventSyncEntry*)evSyncee->firstEntry(); 00394 evEntry; 00395 evEntry = (EventSyncEntry*)evSyncee->nextEntry() ) 00396 { 00397 if (evEntry->state() != SyncEntry::Removed ) 00398 loc->addEvent((KCal::Event*)evEntry->incidence()->clone() ); 00399 } 00400 } 00401 00402 /* 00403 * For Evolution we will save here 00404 */ 00405 if (isEvolutionSync() ) { 00406 loc->save( path( Calendar, pa ) ); 00407 delete loc; 00408 loc = new KCal::CalendarLocal( timeZoneId ); 00409 } 00410 00411 if (toSyncee){ 00412 for ( toEntry = (TodoSyncEntry*)toSyncee->firstEntry(); 00413 toEntry; 00414 toEntry = (TodoSyncEntry*)toSyncee->nextEntry() ) 00415 { 00416 if (toEntry->state() != SyncEntry::Removed ) 00417 loc->addTodo((KCal::Todo*)toEntry->todo()->clone() ); 00418 } 00419 } 00420 00421 loc->save( path( Todo, pa) ); 00422 00423 /* WE NEED TO LEAK HERE CAUSE CLONE SEAMS TO FAIL 00424 * I'll INVESTIGATE THIS FURTHER 00425 * FIXME let the libkonnector be more verbose 00426 * let us tell us if it synced successfully or not 00427 * there we could also delete the calendar then.... 00428 * More Info now: 00429 * We add these incidence to the calendar and it want to take ownership 00430 * the CalendarLocals internal QPtrList is set to AutoDelete 00431 * which will delete even our todos.. 00432 * so we need to clone before adding it. 00433 * FIXED 00434 */ 00435 delete loc; 00436 } 00437 00438 /* 00439 * we will return the right path 00440 * for the right calendar system! 00441 */ 00442 QString OrganizerPart::path( Data d, const QString& path ) { 00443 if ( !isEvolutionSync() ) { 00444 kdDebug(5222) << "Syncing with KDE and not Evolution " << endl; 00445 return path; 00446 } 00447 00448 QString str; 00449 switch(d) { 00450 case Calendar: 00451 str = QDir::homeDirPath() + "/evolution/local/Calendar/calendar.ics"; 00452 break; 00453 case Todo: 00454 default: 00455 str = QDir::homeDirPath()+ "/evolution/local/Tasks/tasks.ics"; 00456 break; 00457 } 00458 return str; 00459 } 00460 00461 #include "organizerpart.moc"
KDE Logo
This file is part of the documentation for kitchensync Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 27 12:50:49 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003