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
00022
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
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 void OrganizerPart::sync( const SynceeList &in,
00116 SynceeList &out )
00117 {
00118
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
00125 Profile prof = core()->currentProfile();
00126 KonnectorProfile kon = core()->currentKonnectorProfile();
00127
00128
00129 QString path = prof.path( "OrganizerPart" );
00130 QString meta = kon.uid()+"/"+prof.uid() + "organizer.rc";
00131 bool met = kon.kapabilities().isMetaSyncingEnabled();
00132
00133
00134 EventSyncee *evSyncee = in.eventSyncee();
00135 TodoSyncee *toSyncee = in.todoSyncee();
00136 if (!evSyncee && !toSyncee) {
00137 done();
00138 return;
00139 }
00140
00141
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
00150 if ( met )
00151 doMeta( events, todos, meta );
00152
00153
00154
00155
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
00189 if ( met )
00190 writeMeta( events, todos, meta );
00191
00192
00193 save( events, todos, path, timeZoneId );
00194
00195
00196
00197
00198 if (events)
00199 out.append( events );
00200
00201 if (todos)
00202 out.append( todos );
00203 done();
00204 }
00205
00206
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
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
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
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
00289 for ( entry = syncee->firstEntry(); entry; entry = syncee->nextEntry() ) {
00290 ids << entry->id();
00291
00292 if ( conf->hasGroup( key + entry->id() ) ) {
00293 conf->setGroup( key + entry->id() );
00294 timestmp = conf->readEntry( "time");
00295
00296
00297 if ( timestmp != entry->timestamp() )
00298 entry->setState(SyncEntry::Modified );
00299
00300 }else {
00301 entry->setState( SyncEntry::Added );
00302 }
00303
00304 }
00305
00306 QStringList groups = conf->groupList();
00307 QStringList::Iterator it;
00308
00309 for ( it = groups.begin(); it != groups.end(); ++it ) {
00310
00311 if ( (*it).startsWith(key ) ) {
00312 QString id = (*it).mid( key.length() );
00313 kdDebug(5222) << "OrganizerPart Meta Gathering: "
00314 << id << endl;
00315
00316
00317
00318
00319
00320
00321
00322
00323
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 {
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
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
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
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 delete loc;
00436 }
00437
00438
00439
00440
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"