00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "options.h"
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034
00035 #if QT_VERSION < 300
00036 #include <qmsgbox.h>
00037 #else
00038 #include <qmessagebox.h>
00039 #endif
00040
00041 #include <qtimer.h>
00042 #include <kconfig.h>
00043 #include <kmessagebox.h>
00044 #include <kstandarddirs.h>
00045 #include <pilotSerialDatabase.h>
00046 #include <calendarlocal.h>
00047 #include "Organizer-conduit.h"
00048 #include "DatabaseAction.h"
00049
00050 using namespace KCal;
00051
00052 static const char *Organizer_conduit_id = "$Id: Organizer-conduit.cc,v 1.4.4.1 2003/03/12 23:31:10 adridg Exp $";
00053
00054
00055
00056
00057
00058
00059 class OrganizerConduit::VCalPrivate {
00060 private:
00061 bool reading;
00062 KCal::Calendar*fCalendar;
00063 public:
00064 VCalPrivate(KCal::Calendar *buddy);
00065 #ifdef KDE2
00066 QList<KCal::Todo> fAllTodos;
00067 #else
00068 QPtrList<KCal::Todo> fAllTodos;
00069 #endif
00070 int updateTodos();
00071 int count() {return fAllTodos.count();};
00072 void addTodo(KCal::Todo*);
00073 void removeTodo(KCal::Todo*);
00074 void insertTodo(KCal::Todo*);
00075 KCal::Todo *findTodo(recordid_t);
00076 KCal::Todo *getNextTodo();
00077 KCal::Todo *getNextModifiedTodo();
00078 };
00079
00080
00081
00082 OrganizerConduit::VCalPrivate::VCalPrivate(KCal::Calendar *b) : fCalendar(b) {
00083 fAllTodos.setAutoDelete(false);
00084 }
00085
00086 void OrganizerConduit::VCalPrivate::addTodo(KCal::Todo*e)
00087 {
00088 fAllTodos.append(e);
00089 fCalendar->addTodo(e);
00090 }
00091
00092 int OrganizerConduit::VCalPrivate::updateTodos() {
00093 fAllTodos=fCalendar->getTodoList();
00094 fAllTodos.setAutoDelete(false);
00095 return fAllTodos.count();
00096 }
00097
00098 void OrganizerConduit::VCalPrivate::removeTodo(KCal::Todo*e) {
00099 fAllTodos.remove(e);
00100 fCalendar->deleteTodo(e);
00101 }
00102
00103 void OrganizerConduit::VCalPrivate::insertTodo(KCal::Todo*e) {
00104 fAllTodos.append(e);
00105 }
00106
00107 KCal::Todo*OrganizerConduit::VCalPrivate::findTodo(recordid_t id) {
00108 KCal::Todo *todo = fAllTodos.first();
00109 while (todo) {
00110 if ((recordid_t)todo->pilotId()==id) return todo;
00111 todo=fAllTodos.next();
00112 }
00113 return 0L;
00114 }
00115
00116 KCal::Todo *OrganizerConduit::VCalPrivate::getNextTodo()
00117 {
00118 if (reading) return fAllTodos.next();
00119 reading=true;
00120 return fAllTodos.first();
00121 }
00122
00123 KCal::Todo *OrganizerConduit::VCalPrivate::getNextModifiedTodo()
00124 {
00125 KCal::Todo*e=0L;
00126 if (!reading) {
00127 reading=true;
00128 e=fAllTodos.first();
00129 } else {
00130 e=fAllTodos.next();
00131 }
00132 while (e && e->syncStatus()==KCal::Todo::SYNCNONE) {
00133 e=fAllTodos.next();
00134 }
00135 return e;
00136 }
00137
00138
00139
00140
00141
00142 OrganizerConduit::OrganizerConduit(KPilotDeviceLink *d, const char *n, const QStringList &l, SyncTypeList_t *tps) :
00143 MultiDBConduit(d,n,l,tps), fCalendar(0L), fP(0L) {
00144 FUNCTIONSETUP;
00145 for (int i=0; i<7; i++) { levelparent[i]=0;}
00146 previd=0;
00147 (void)Organizer_conduit_id;
00148 }
00149
00150
00151 OrganizerConduit::~OrganizerConduit() {
00152 FUNCTIONSETUP;
00153 cleanup();
00154 }
00155
00156 bool OrganizerConduit::exec() {
00157 FUNCTIONSETUP;
00158 KConfig korgcfg( locate( "config", "korganizerrc" ) );
00159 QString tz;
00160
00161 korgcfg.setGroup( "Time & Date" );
00162 tz = korgcfg.readEntry( "TimeZoneId" );
00163 #ifdef DEBUG
00164 DEBUGCONDUIT << fname<<": KOrganizer's time zone = "<<tz<<endl;
00165 #endif
00166
00167 return MultiDBConduit::exec();
00168 }
00169
00170 void OrganizerConduit::cleanup() {
00171 FUNCTIONSETUP;
00172 MultiDBConduit::cleanup();
00173 KPILOT_DELETE(fP);
00174 }
00175
00176 void OrganizerConduit::cleanupDB() {
00177 FUNCTIONSETUP;
00178 MultiDBConduit::cleanupDB();
00179 KPILOT_DELETE(fCalendar);
00180 }
00181
00182
00183 void OrganizerConduit::syncNextRecord() {
00184 PilotRecord*rec=fCurrentDatabase->readRecordByIndex(Palmix);
00185 KCal::Todo*todo=fP->fAllTodos.at(PCix);
00186
00187
00188 if (!rec) {
00189 while ( (todo=fP->fAllTodos.at(PCix++)) ) {
00190 insertRecordToPalm(Palmix++, todo);
00191 }
00192 QTimer::singleShot(0, this, SLOT(finishedDB()));
00193 return;
00194 }
00195 if (!todo) {
00196 while ( (rec=fCurrentDatabase->readRecordByIndex(Palmix++)) ) {
00197 insertRecordToPC(PCix++, rec);
00198 }
00199 QTimer::singleShot(0, this, SLOT(finishedDB()));
00200 return;
00201 }
00202
00203
00204
00205 if ((recordid_t)rec->getID()==(recordid_t)todo->pilotId()) {
00206
00207
00208
00209
00210
00211
00212 if ( !(todo->syncStatus()==Incidence::SYNCNONE) ||
00213 (rec->getAttrib() & dlpRecAttrDirty) ||
00214 (inserted && (flags()&FLG_NUMBERED)) ) {
00215 updateRecords(Palmix, rec, PCix, todo);
00216 }
00217 PCix++; Palmix++;
00218 QTimer::singleShot(0, this, SLOT(syncNextRecord()));
00219 return;
00220 }
00221
00222
00223
00224 KCal::Todo*t=fP->findTodo(rec->getID());
00225 if (!t) {
00226 insertRecordToPC(PCix++, rec);
00227 QTimer::singleShot(0, this, SLOT(syncNextRecord()));
00228 return;
00229 }
00230
00231
00232 if ((recordid_t)todo->pilotId()==0)
00233 while ((recordid_t)todo->pilotId() ==0) {
00234 insertRecordToPalm(Palmix++, todo);
00235 if (!(todo=fP->fAllTodos.at(PCix++))) {
00236 QTimer::singleShot(0, this, SLOT(syncNextRecord()));
00237 return;
00238 }
00239 }
00240
00241
00242 PilotRecord*rec1=fCurrentDatabase->readRecordById(todo->pilotId());
00243 if (!rec1) {
00244 fP->removeTodo(todo);
00245 QTimer::singleShot(0, this, SLOT(syncNextRecord()));
00246 return;
00247 }
00248 if ((t->syncStatus()==Incidence::SYNCNONE) || (rec->getAttrib() & dlpRecAttrDirty)) {
00249
00250 movePCRecord(fP->fAllTodos.find(t), PCix);
00251 updateRecords(Palmix, rec, PCix, t);
00252 Palmix++; PCix++;
00253 QTimer::singleShot(0, this, SLOT(syncNextRecord()));
00254 return;
00255 }
00256
00257 movePalmRecord(Palmix, Palmix + (fP->fAllTodos.find(t)-Palmix));
00258 QTimer::singleShot(0, this, SLOT(syncNextRecord()));
00259 return;
00260 }
00261
00262 void OrganizerConduit::updateRecords(int pid, PilotRecord*rec, int pcid, KCal::Todo*todo) {
00263
00264 }
00265
00266 void OrganizerConduit::insertRecordToPC(int pos, PilotRecord*rec) {
00267 PilotOrganizerEntry*poe=createOrganizerEntry(rec);
00268 KCal::Todo*todo=poe->getTodo();
00269 fP->fAllTodos.insert(pos, todo);
00270 delete poe;
00271 }
00272 void OrganizerConduit::insertRecordToPalm(int pos, KCal::Todo*todo) {
00273 PilotOrganizerEntry*poe=createOrganizerEntry(todo);
00274 poe->setNumber(pos);
00275 PilotRecord*rec=poe->pack();
00276
00277
00278 KPILOT_DELETE(rec);
00279 }
00280
00281 void OrganizerConduit::movePCRecord(int frompos, int topos) {
00282
00283 if (frompos>topos) {
00284
00285 } else {
00286
00287 }
00288 }
00289 void OrganizerConduit::movePalmRecord(int frompos, int topos) {
00290
00291 if (frompos>topos) {
00292
00293 } else {
00294
00295 }
00296 }
00297
00298
00299
00300
00301
00302 bool OrganizerConduit::preSyncAction(DBSyncInfo*dbinfo) {
00303 FUNCTIONSETUP;
00304 PCix=0;
00305 Palmix=0;
00306 inserted=false;
00307 switch (syncinfo.syncaction) {
00308 case st_vcal:
00309 fCalendar=new KCal::CalendarLocal(timezone);
00310 if (!fCalendar) return false;
00311
00312
00313
00314 if (!fCalendar->load(dbinfo->filename) ) {
00315 #ifdef DEBUG
00316 DEBUGCONDUIT << "calendar file "<<fCalendarFile<<" could not be opened. Will create a new one"<<endl;
00317 #endif
00318 fFullSync=true;
00319 }
00320
00321 fP = new VCalPrivate(fCalendar);
00322 if (!fP) {
00323 emit logError(i18n("Could not load the calendar "+dbinfo->filename));
00324 kdWarning() << k_funcinfo << ": Couldn't load calendar "<<dbinfo->filename<<" from local harddrive" << endl;
00325 return false;
00326 }
00327 fP->updateTodos();
00328 if (fP->count()<1) fFullSync=true;
00329
00330 return true;
00331 break;
00332 case st_pdb:
00333 #ifdef DEBUG
00334 DEBUGCONDUIT<<" skipping database "<<dbinfo->filename<<". PDB not yet implemented." <<endl;
00335 #endif
00336
00337 return false;
00338 break;
00339 default:
00340 return MultiDBConduit::preSyncAction(dbinfo);
00341 break;
00342 }
00343 return MultiDBConduit::preSyncAction(dbinfo);
00344 }
00345
00346
00347
00348
00349
00350
00351 void OrganizerConduit::updateLocalEntry(PilotRecord *rec, bool force) {
00352 FUNCTIONSETUP;
00353
00354 PilotOrganizerEntry*entry=createOrganizerEntry(rec);
00355
00356 #ifdef DEBUG
00357 DEBUGCONDUIT << fname
00358 << ": Using rec @" << (int) rec
00359 << " with ID " << ( rec ? rec->getID() : 0xffffffff)
00360 << endl;
00361 #endif
00362
00363 #ifdef DEBUG
00364 if (entry->getLevel()>hierlevel+1) {
00365 DEBUGCONDUIT<<fname << ": skipped one hierarchy level. Jumped from "<<hierlevel<<" to "<<entry->getLevel()<<endl;
00366 }
00367 #endif
00368
00369
00370
00371 if (hierlevel<entry->getLevel() && levelparent[hierlevel]==0) {
00372 levelparent[hierlevel]=fP->findTodo(previd);
00373 }
00374 hierlevel=entry->getLevel();
00375 previd=rec->getID();
00376
00377
00378 if ( (rec->getAttrib() & dlpRecAttrDirty) || force ) {
00379 KCal::Todo *vtodo=fP->findTodo(rec->getID());
00380 if (!vtodo) {
00381
00382 vtodo = new KCal::Todo;
00383 fP->insertTodo(vtodo);
00384
00385 vtodo->setPilotId(entry->getID());
00386 vtodo->setSyncStatus(Incidence::SYNCNONE);
00387 }
00388 levelparent[hierlevel]=vtodo;
00389
00390 if (hierlevel>0 && levelparent[hierlevel-1] ) {
00391 vtodo->setRelatedTo(levelparent[hierlevel-1]);
00392 if (! levelparent[hierlevel-1]->relations().containsRef(vtodo)) {
00393 levelparent[hierlevel-1]->addRelation(vtodo);
00394 }
00395 }
00396
00397
00398
00399
00400
00401
00402
00403
00404 if (entry->hasDate(DATE_CREATED)) vtodo->setCreated(entry->getDate(DATE_CREATED));
00405
00406 if (entry->hasDate(DATE_STARTED)) vtodo->setDtStart(entry->getDate(DATE_STARTED));
00407 else vtodo->setHasStartDate(false);
00408
00409 if (entry->hasDate(DATE_FINISHED)) vtodo->setCompleted(entry->getDate(DATE_FINISHED));
00410 else vtodo->setCompleted(false);
00411
00412 if (entry->hasDate(DATE_DUE)) vtodo->setDtDue(entry->getDate(DATE_DUE));
00413 else vtodo->setHasDueDate(false);
00414
00415
00416 vtodo->setPercentComplete(entry->getProgress());
00417 vtodo->setCompleted(entry->getFlag(IS_CHECKED));
00418
00419
00420
00421
00422 vtodo->setPriority(entry->getPriority());
00423
00424
00425
00426
00427 vtodo->setSummary(entry->getDescription());
00428 vtodo->setDescription(entry->getNote());
00429
00430
00431 setCustomFields(vtodo, entry);
00432
00433 vtodo->setSyncStatus(Incidence::SYNCNONE);
00434 }
00435 delete(entry);
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495