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
00032
00033
00034
00035
static const char *TodoConduit_id =
"$Id: todo-conduit.cc,v 1.41 2004/01/15 09:58:49 kainhofe Exp $";
00036
00037
#include <options.h>
00038
#include <unistd.h>
00039
00040
#include <qdatetime.h>
00041
#include <qtimer.h>
00042
#include <qtextcodec.h>
00043
00044
#include <pilotUser.h>
00045
#include <kconfig.h>
00046
00047
#include <libkcal/calendar.h>
00048
#include <libkcal/todo.h>
00049
00050
00051
00052
00053
00054
#ifdef KDE2
00055
#define DateList_t QDateList
00056
#define DateListIterator_t QDateListIterator
00057
#else
00058
#define DateList_t KCal::DateList
00059
#define DateListIterator_t KCal::DateList::ConstIterator
00060
#endif
00061
00062
#include <pilotSerialDatabase.h>
00063
#include <pilotLocalDatabase.h>
00064
00065
#include "todo-conduit.moc"
00066
00067
00068
#define CONDUIT_VERSION_CATEGORYSYNC 10
00069
#define CONDUIT_VERSION 10
00070
00071
00072
00073 TodoConduitPrivate::TodoConduitPrivate(KCal::Calendar *b) :
00074 VCalConduitPrivateBase(b)
00075 {
00076 fAllTodos.setAutoDelete(
false);
00077 }
00078
00079
void TodoConduitPrivate::addIncidence(KCal::Incidence*e)
00080 {
00081 fAllTodos.append(static_cast<KCal::Todo*>(e));
00082 fCalendar->addTodo(static_cast<KCal::Todo*>(e));
00083 }
00084
00085
int TodoConduitPrivate::updateIncidences()
00086 {
00087 fAllTodos = fCalendar->todos();
00088 fAllTodos.setAutoDelete(
false);
00089
return fAllTodos.count();
00090 }
00091
00092
00093
void TodoConduitPrivate::removeIncidence(KCal::Incidence *e)
00094 {
00095 fAllTodos.remove(static_cast<KCal::Todo*>(e));
00096 fCalendar->deleteTodo(static_cast<KCal::Todo*>(e));
00097 }
00098
00099
00100
00101 KCal::Incidence *TodoConduitPrivate::findIncidence(recordid_t
id)
00102 {
00103 KCal::Todo::List::ConstIterator it;
00104
for( it = fAllTodos.begin(); it != fAllTodos.end(); ++it ) {
00105 KCal::Todo *todo = *it;
00106
if ((recordid_t)(todo->pilotId()) ==
id)
return todo;
00107 }
00108
00109
return 0L;
00110 }
00111
00112
00113
00114 KCal::Incidence *TodoConduitPrivate::findIncidence(PilotAppCategory*tosearch)
00115 {
00116 PilotTodoEntry*entry=dynamic_cast<PilotTodoEntry*>(tosearch);
00117
if (!entry)
return 0L;
00118
00119 QString title=entry->getDescription();
00120 QDateTime dt=readTm( entry->getDueDate() );
00121
00122 KCal::Todo::List::ConstIterator it;
00123
for( it = fAllTodos.begin(); it != fAllTodos.end(); ++it ) {
00124 KCal::Todo *event = *it;
00125
if ( (event->dtDue().date() == dt.date()) && (event->summary() == title) )
return event;
00126 }
00127
return 0L;
00128 }
00129
00130
00131
00132 KCal::Incidence *TodoConduitPrivate::getNextIncidence()
00133 {
00134
if (reading) {
00135 ++fAllTodosIterator;
00136
if ( fAllTodosIterator == fAllTodos.end() )
return 0;
00137 }
else {
00138 reading=
true;
00139 fAllTodosIterator = fAllTodos.begin();
00140 }
00141
return *fAllTodosIterator;
00142 }
00143
00144
00145
00146 KCal::Incidence *TodoConduitPrivate::getNextModifiedIncidence()
00147 {
00148 FUNCTIONSETUP;
00149 KCal::Todo*e=0L;
00150
if (!reading)
00151 {
00152 reading=
true;
00153 fAllTodosIterator = fAllTodos.begin();
00154
if ( fAllTodosIterator != fAllTodos.end() ) e=*fAllTodosIterator;
00155 }
00156
else
00157 {
00158 ++fAllTodosIterator;
00159 }
00160
while (fAllTodosIterator != fAllTodos.end() &&
00161 e && e->syncStatus()!=KCal::Incidence::SYNCMOD)
00162 {
00163 ++fAllTodosIterator;
00164 e=*fAllTodosIterator;
00165
#ifdef DEBUG
00166
if (e)
00167 DEBUGCONDUIT<< e->summary()<<
" had SyncStatus="<<e->syncStatus()<<endl;
00168
#endif
00169
}
00170
if ( fAllTodosIterator == fAllTodos.end() )
return 0;
00171
else return *fAllTodosIterator;
00172 }
00173
00174
00175
00176
00177
00178
00179
00180 TodoConduit::TodoConduit(KPilotDeviceLink *d,
00181
const char *n,
00182
const QStringList &a) : VCalConduitBase(d,n,a)
00183 {
00184 FUNCTIONSETUP;
00185
#ifdef DEBUG
00186
DEBUGCONDUIT << TodoConduit_id << endl;
00187
#endif
00188
fConduitName=i18n(
"To-do");
00189
00190 (
void) TodoConduit_id;
00191 }
00192
00193
00194
00195 TodoConduit::~TodoConduit()
00196 {
00197
00198 }
00199
00200
00201
00202
void TodoConduit::_setAppInfo()
00203 {
00204 FUNCTIONSETUP;
00205
00206
int appLen = pack_ToDoAppInfo(&fTodoAppInfo, 0, 0);
00207
unsigned char *buffer =
new unsigned char[appLen];
00208 pack_ToDoAppInfo(&fTodoAppInfo, buffer, appLen);
00209
if (fDatabase) fDatabase->
writeAppBlock(buffer, appLen);
00210
if (fLocalDatabase) fLocalDatabase->
writeAppBlock(buffer, appLen);
00211
delete[] buffer;
00212 }
00213
void TodoConduit::_getAppInfo()
00214 {
00215 FUNCTIONSETUP;
00216
00217
unsigned char *buffer =
00218
new unsigned char[PilotTodoEntry::APP_BUFFER_SIZE];
00219
int appLen = fDatabase->
readAppBlock(buffer,PilotTodoEntry::APP_BUFFER_SIZE);
00220
00221 unpack_ToDoAppInfo(&fTodoAppInfo, buffer, appLen);
00222
delete[]buffer;
00223 buffer = NULL;
00224
00225
#ifdef DEBUG
00226
DEBUGCONDUIT << fname <<
" lastUniqueId"
00227 << fTodoAppInfo.category.lastUniqueID << endl;
00228
#endif
00229
for (
int i = 0; i < 16; i++)
00230 {
00231
#ifdef DEBUG
00232
DEBUGCONDUIT << fname <<
" cat " << i <<
" =" <<
00233 fTodoAppInfo.category.name[i] << endl;
00234
#endif
00235
}
00236
00237 }
00238
00239
00240
00241
const QString TodoConduit::getTitle(PilotAppCategory*de)
00242 {
00243 PilotTodoEntry*d=dynamic_cast<PilotTodoEntry*>(de);
00244
if (d)
return QString(d->getDescription());
00245
return QString::null;
00246 }
00247
00248
00249
00250
void TodoConduit::readConfig()
00251 {
00252 FUNCTIONSETUP;
00253 VCalConduitBase::readConfig();
00254
00255
00256 categoriesSynced = fConfig->readNumEntry(
"ConduitVersion", 0)>=CONDUIT_VERSION_CATEGORYSYNC;
00257
if (!categoriesSynced & !
isFullSync() ) fSyncDirection=SyncAction::eFullSync;
00258
#ifdef DEBUG
00259
DEBUGCONDUIT<<
"categoriesSynced="<<categoriesSynced<<endl;
00260
#endif
00261
}
00262
00263
00264
00265
void TodoConduit::postSync()
00266 {
00267 FUNCTIONSETUP;
00268 VCalConduitBase::postSync();
00269 fConfig->setGroup(configGroup());
00270
00271 fConfig->writeEntry(
"ConduitVersion", CONDUIT_VERSION);
00272 _setAppInfo();
00273 }
00274
00275
00276
00277 PilotRecord*TodoConduit::recordFromIncidence(PilotAppCategory*de,
const KCal::Incidence*e)
00278 {
00279
00280 PilotTodoEntry *tde = dynamic_cast<PilotTodoEntry*>(de);
00281
const KCal::Todo *te = dynamic_cast<const KCal::Todo*>(e);
00282
00283
return recordFromTodo(tde, te);
00284 }
00285
00286
00287
00288 PilotRecord*TodoConduit::recordFromTodo(PilotTodoEntry*de,
const KCal::Todo*todo)
00289 {
00290 FUNCTIONSETUP;
00291
if (!de || !todo) {
00292
#ifdef DEBUG
00293
DEBUGCONDUIT<<fname<<
": NULL todo given... Skipping it"<<endl;
00294
#endif
00295
return NULL;
00296 }
00297
00298
00299
if (todo->secrecy()!=KCal::Todo::SecrecyPublic) de->makeSecret();
00300
00301
00302
00303
if (todo->hasDueDate()) {
00304
struct tm t = writeTm(todo->dtDue());
00305 de->setDueDate(t);
00306 de->setIndefinite(0);
00307 }
else {
00308 de->setIndefinite(1);
00309 }
00310
00311
00312
00313 setCategory(de, todo);
00314
00315
00316 de->setPriority(todo->priority());
00317
00318 de->setComplete(todo->isCompleted());
00319
00320
00321 de->setDescription(todo->summary());
00322
00323
00324 de->setNote(todo->description());
00325
00326
#ifdef DEBUG
00327
DEBUGCONDUIT<<
"-------- "<<todo->summary()<<endl;
00328
#endif
00329
return de->pack();
00330 }
00331
00332
00333
00334
void TodoConduit::preRecord(PilotRecord*r)
00335 {
00336 FUNCTIONSETUP;
00337
if (!categoriesSynced && r)
00338 {
00339
const PilotAppCategory*de=newPilotEntry(r);
00340 KCal::Incidence *e = fP->findIncidence(r->getID());
00341 setCategory(dynamic_cast<KCal::Todo*>(e), dynamic_cast<const PilotTodoEntry*>(de));
00342 }
00343 }
00344
00345
00346
00347
void TodoConduit::setCategory(PilotTodoEntry*de,
const KCal::Todo*todo)
00348 {
00349
if (!de || !todo)
return;
00350 de->setCategory(_getCat(todo->categories(), de->getCategoryLabel()));
00351 }
00352
00353
00354
00359 QString TodoConduit::_getCat(
const QStringList cats,
const QString curr)
const
00360
{
00361
int j;
00362
if (cats.size()<1)
return QString::null;
00363
if (cats.contains(curr))
return curr;
00364
for ( QStringList::ConstIterator it = cats.begin(); it != cats.end(); ++it ) {
00365
for (j=1; j<=15; j++)
00366 {
00367 QString catName = PilotAppCategory::codec()->
00368 toUnicode(fTodoAppInfo.category.name[j]);
00369
if (!(*it).isEmpty() && !(*it).compare( catName ) )
00370 {
00371
return catName;
00372 }
00373 }
00374 }
00375
00376 QString lastName(fTodoAppInfo.category.name[15]);
00377
if (lastName.isEmpty())
return cats.first();
00378
return QString::null;
00379 }
00380
00381
00382
00383 KCal::Incidence *TodoConduit::incidenceFromRecord(KCal::Incidence *e,
const PilotAppCategory *de)
00384 {
00385
return dynamic_cast<KCal::Incidence*>(incidenceFromRecord(dynamic_cast<KCal::Todo*>(e), dynamic_cast<const PilotTodoEntry*>(de)));
00386 }
00387
00388
00389
00390 KCal::Todo *TodoConduit::incidenceFromRecord(KCal::Todo *e,
const PilotTodoEntry *de)
00391 {
00392 FUNCTIONSETUP;
00393
00394 KCal::Todo*vtodo=e;
00395
if (!vtodo)
00396 {
00397
#ifdef DEBUG
00398
DEBUGCONDUIT<<fname<<
": null todo entry given. skipping..."<<endl;
00399
#endif
00400
return NULL;
00401 }
00402
00403 e->setOrganizer(fCalendar->getEmail());
00404 e->setPilotId(de->getID());
00405 e->setSyncStatus(KCal::Incidence::SYNCNONE);
00406 e->setSecrecy(de->isSecret() ? KCal::Todo::SecrecyPrivate : KCal::Todo::SecrecyPublic);
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
if (de->getIndefinite()) {
00417 e->setHasDueDate(
false);
00418 }
else {
00419 e->setDtDue(readTm(de->getDueDate()));
00420 e->setHasDueDate(
true);
00421 }
00422
00423
00424
00425
00426 setCategory(e, de);
00427
00428
00429 e->setPriority(de->getPriority());
00430
00431
00432 e->setCompleted(de->getComplete());
00433
00434 e->setSummary(de->getDescription());
00435 e->setDescription(de->getNote());
00436
00437 e->setSyncStatus(KCal::Incidence::SYNCNONE);
00438
00439
return e;
00440 }
00441
00442
00443
00444
void TodoConduit::setCategory(KCal::Todo *e,
const PilotTodoEntry *de)
00445 {
00446
if (!e || !de)
return;
00447 QStringList cats=e->categories();
00448
int cat=de->getCat();
00449
if (0<cat && cat<=15)
00450 {
00451 QString newcat=PilotAppCategory::codec()->toUnicode(fTodoAppInfo.category.name[cat]);
00452
if (!cats.contains(newcat))
00453 {
00454 cats.append( newcat );
00455 e->setCategories(cats);
00456 }
00457 }
00458 }