kpilot Library API Documentation

vcal-conduitbase.cc

00001 /* vcal-conduitbase.cc                      KPilot
00002 **
00003 ** Copyright (C) 2002 by Reinhold Kainhofer
00004 ** Copyright (C) 2001 by Dan Pilone
00005 ** 
00006 ** Contributions:
00007 **    Copyright (c) 2001 David Jarvie <software@astrojar.org.uk>
00008 **
00009 ** This file defines the vcal-conduit plugin.
00010 */
00011 
00012 /*
00013 ** This program is free software; you can redistribute it and/or modify
00014 ** it under the terms of the GNU General Public License as published by
00015 ** the Free Software Foundation; either version 2 of the License, or
00016 ** (at your option) any later version.
00017 **
00018 ** This program is distributed in the hope that it will be useful,
00019 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00021 ** GNU General Public License for more details.
00022 **
00023 ** You should have received a copy of the GNU General Public License
00024 ** along with this program in a file called COPYING; if not, write to
00025 ** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
00026 ** MA 02111-1307, USA.
00027 */
00028 
00029 /*
00030 ** Bug reports and questions can be sent to kde-pim@kde.org
00031 */
00032 
00033 static const char *vcalconduitbase_id = "$Id: vcal-conduitbase.cc,v 1.22.4.8 2003/03/12 23:25:11 adridg Exp $";
00034 
00035 #include <options.h>
00036 #include <unistd.h>
00037 
00038 // Qt includes
00039 #include <qdatetime.h>
00040 #include <qtimer.h>
00041 
00042 // KDE includes
00043 #include <kconfig.h>
00044 #include <kmessagebox.h>
00045 #include <kstandarddirs.h>
00046 #include <ksimpleconfig.h>
00047 
00048 // libkcal includes
00049 #include "libkcal/calendar.h"
00050 #include "libkcal/calendarlocal.h"
00051 #include "libkcal/incidence.h"
00052 /*
00053 ** KDE 2.2 uses class KORecurrence in a different header file.
00054 */
00055 #ifdef KDE2
00056 #include <korecurrence.h>
00057 #define Recurrence_t KCal::KORecurrence
00058 #define DateList_t QDateList
00059 #define DateListIterator_t QDateListIterator
00060 #else
00061 #include "libkcal/recurrence.h"
00062 #define Recurrence_t KCal::Recurrence
00063 #define DateList_t KCal::DateList
00064 #define DateListIterator_t KCal::DateList::ConstIterator
00065 #endif
00066 
00067 // kpilot includes
00068 #include "pilotSerialDatabase.h"
00069 #include "pilotLocalDatabase.h"
00070 #include "pilotDateEntry.h"
00071 #include "pilotUser.h"
00072 
00073 #include "vcal-factorybase.h"
00074 #include "vcal-conduitbase.moc"
00075 
00076 
00077 
00078 QDateTime readTm(const struct tm &t)
00079 {
00080   QDateTime dt;
00081   dt.setDate(QDate(1900 + t.tm_year, t.tm_mon + 1, t.tm_mday));
00082   dt.setTime(QTime(t.tm_hour, t.tm_min, t.tm_sec));
00083   return dt;
00084 }
00085 
00086 
00087 
00088 struct tm writeTm(const QDateTime &dt)
00089 {
00090   struct tm t;
00091 
00092   t.tm_wday = 0; // unimplemented
00093   t.tm_yday = 0; // unimplemented
00094   t.tm_isdst = 0; // unimplemented
00095 
00096   t.tm_year = dt.date().year() - 1900;
00097   t.tm_mon = dt.date().month() - 1;
00098   t.tm_mday = dt.date().day();
00099   t.tm_hour = dt.time().hour();
00100   t.tm_min = dt.time().minute();
00101   t.tm_sec = dt.time().second();
00102 
00103   return t;
00104 }
00105 
00106 
00107 
00108 struct tm writeTm(const QDate &dt)
00109 {
00110   struct tm t;
00111 
00112   t.tm_wday = 0; // unimplemented
00113   t.tm_yday = 0; // unimplemented
00114   t.tm_isdst = 0; // unimplemented
00115 
00116   t.tm_year = dt.year() - 1900;
00117   t.tm_mon = dt.month() - 1;
00118   t.tm_mday = dt.day();
00119   t.tm_hour = 0;
00120   t.tm_min = 0;
00121   t.tm_sec = 0;
00122 
00123   return t;
00124 }
00125 
00126 
00127 
00128 
00129 /****************************************************************************
00130  *                          VCalConduitBase class                               *
00131  ****************************************************************************/
00132 
00133  
00134 VCalConduitBase::VCalConduitBase(KPilotDeviceLink *d,
00135         const char *n,
00136         const QStringList &a) :
00137         ConduitAction(d,n,a),
00138         fCalendar(0L),
00139         fFullSync(false),
00140         fP(0L)
00141 {
00142         FUNCTIONSETUP;
00143 #ifdef DEBUG
00144         DEBUGCONDUIT<<vcalconduitbase_id<<endl;
00145 #endif
00146 }
00147 
00148 
00149 
00150 VCalConduitBase::~VCalConduitBase()
00151 {
00152         FUNCTIONSETUP;
00153 
00154         KPILOT_DELETE(fP);
00155         KPILOT_DELETE(fCalendar);
00156 }
00157 
00158 
00159 
00160 /* There are several different scenarios for a record on the Palm and its PC counterpart
00161   N means a new record, M flags a modified record, D a deleted and - an unmodified record
00162   first is the Palm record, second the corresponding PC record
00163   (-,-)...unchanged, just sync if first time or full sync
00164   (N,-)...no rec matching the Palm ID in the backupDB/calendar yet => add KCal::Event
00165   (M,-)...record is in backupDB, unchanged in calendar => modify in calendar and in backupDB
00166   (D,-)...deleted on Palm, exists in backupDB and calendar => just delete from calendar and backupDB
00167   (-,N)...no or invalid pilotID set for the KCal::Event => just add to palm and backupDB
00168   (-,M)...valid PilotID set => just modify on Palm
00169   (-,D)...Record in backupDB, but not in calendar => delete from Palm and backupDB
00170   (N,N)...Can't find out (the two records are not correlated in any way, they just have the same data!!
00171   (M,M),(M,L),(L,M)...(Record exists on Palm and the Event has the ID) CONFLICT, ask the user what to do
00172                       or use a config setting
00173   (L,L)...already deleted on both, no need to do anything.
00174 
00175 
00176    The sync process is as follows (for a fast sync):
00177         1) syncPalmRecToPC goes through all records on Palm (just the modified one are necessary), find it
00178            in the backupDB. The following handles ([NMD],*)
00179            a) if it doesn't exist and was not deleted, add it to the calendar and the backupDB
00180            b) if it exists and was not deleted,
00181                         A) if it is unchanged in the calendar, just modify in the calendar
00182                 c) if it exists and was deleted, delete it from the calendar if necessary
00183         2) syncEvent goes through all KCale::Events in the calendar (just modified, this is the modification
00184            time is later than the last sync time). This handles (-,N),(-,M)
00185                 a) if it does not have a pilotID, add it to the palm and backupDB, store the PalmID
00186                 b) if it has a valid pilotID, update the Palm record and the backup
00187         3) finally, dheleteRecord goes through all records (which don't have the deleted flag) of the backup db
00188            and if one does not exist in the Calendar, it was deleted there, so delete it from the Palm, too.
00189                 This handles the last remaining case of (-,D)
00190 
00191 
00192 In addition to the fast sync, where the last sync was done with this very PC and calendar file,
00193 there are two special cases: a full and a first sync.
00194 -) a full sync goes through all records, not just the modified ones. The pilotID setting of the calendar
00195    records is used to determine if the record already exists. if yes, the record is just modified
00196 -) a first sync completely ignores the pilotID setting of the calendar events. All records are added,
00197         so there might be duplicates. The add function for the calendar should check if a similar record already
00198         exists, but this is not done yet.
00199 
00200 
00201 -) a full sync is done if
00202         a) there is a backupdb and a calendar, but the PC id number changed
00203         b) it was explicitely requested by pressing the full sync button in KPilot
00204         c) the setting "always full sync" was selected in the configuration dlg
00205 -) a first sync is done if
00206         a) either the calendar or the backup DB does not exist.
00207         b) the calendar and the backup DB exists, but the sync is done for a different User name
00208         c) it was explicitely requested in KPilot
00209 
00210 */
00211 
00212 /* virtual */ bool VCalConduitBase::exec()
00213 {
00214         FUNCTIONSETUP;
00215         DEBUGCONDUIT << vcalconduitbase_id << endl;
00216 
00217         KPilotUser *usr;
00218 
00219         if (!fConfig)
00220         {
00221                 kdWarning() << k_funcinfo
00222                         << ": No configuration set for vcal-conduit"
00223                         << endl;
00224                 return false;
00225         }
00226 
00227         if (PluginUtility::isRunning("korganizer") ||
00228                 PluginUtility::isRunning("alarmd"))
00229         {
00230                 emit logError(i18n("KOrganizer is running, can't update datebook."));
00231                 return false;
00232         }
00233 
00234         readConfig();
00235 
00236         if (fCalendarFile.isEmpty())
00237         {
00238                 kdWarning() << k_funcinfo
00239                         << ": No calendar file set." << endl;
00240                 return false;
00241         }
00242 
00243 #ifdef DEBUG
00244         if (isTest())
00245         {
00246                 DEBUGCONDUIT << fname
00247                         << ": Running conduit test. Using calendar "
00248                         << fCalendarFile << endl;
00249                 doTest();
00250                 delayDone();
00251                 return true;
00252         }
00253 #endif
00254 
00255         // don't do a first sync by default in any case, only when explicitely requested, or the backup
00256         // database or the alendar are empty.
00257         fFirstTime = (syncAction==SYNC_FIRST || nextSyncAction!=0);
00258         usr=fHandle->getPilotUser();
00259         // changing the PC or using a different Palm Desktop app causes a full sync
00260         // Use gethostid for this, since JPilot uses 1+(2000000000.0*random()/(RAND_MAX+1.0))
00261         // as PC_ID, so using JPilot and KPilot is the same as using two differenc PCs
00262         fFullSync = fFullSync|| (syncAction==SYNC_FULL) ||
00263                 ((usr->getLastSyncPC()!=(unsigned long) gethostid()) && fConfig->readBoolEntry(VCalConduitFactoryBase::fullSyncOnPCChange, true));
00264 
00265         if (!openDatabases(dbname(), &fFullSync) ) goto error;
00266         if (!openCalendar() ) goto error;
00267 
00268         preSync();
00269 
00270 
00271 #ifdef DEBUG
00272         DEBUGCONDUIT<<fname<<": fullsync="<<fFullSync<<", firstSync="<<fFirstTime<<endl;
00273         DEBUGCONDUIT<<fname<<": syncAction="<<syncAction<<", nextSyncAction = "<<nextSyncAction
00274                 <<", conflictResolution = "<<conflictResolution<<", archive = "<<archive<<endl;
00275 #endif
00276 
00277         addSyncLogEntry(i18n("Syncing with file \"%1\"").arg(fCalendarFile));
00278         pilotindex=0;
00279         switch (nextSyncAction)
00280         {
00281         case 2:
00282                 // TODO: Clear the palm and backup database??? Or just add the new items ignore
00283                 // the Palm->PC side and leave the existing items on the palm?
00284                 QTimer::singleShot(0, this, SLOT(syncPCRecToPalm()));
00285                 break;
00286         case 1:
00287                 // TODO: Clear the backup database and the calendar, update fP
00288                 //       or just add the palm items and leave the PC ones there????
00289         default:
00290                 QTimer::singleShot(0, this, SLOT(syncPalmRecToPC()));
00291         }
00292         return true;
00293 
00294 error:
00295 
00296         emit logError(i18n("Couldn't open the calendar databases."));
00297 
00298         KPILOT_DELETE(fCalendar);
00299         KPILOT_DELETE(fP);
00300         return false;
00301 }
00302 
00303 
00304 
00305 /* virtual */ void VCalConduitBase::readConfig()
00306 {
00307         fConfig->setGroup(configGroup());
00308 
00309         fCalendarFile = fConfig->readEntry(VCalConduitFactoryBase::calendarFile);
00310         syncAction = fConfig->readNumEntry(VCalConduitFactoryBase::syncAction);
00311         nextSyncAction = fConfig->readNumEntry(VCalConduitFactoryBase::nextSyncAction);
00312         conflictResolution = fConfig->readNumEntry(VCalConduitFactoryBase::conflictResolution);
00313         archive = fConfig->readBoolEntry(VCalConduitFactoryBase::archive);
00314 }
00315 
00316 
00317 
00318 /* virtual */ bool VCalConduitBase::openCalendar()
00319 {
00320         FUNCTIONSETUP;
00321 
00322         KConfig korgcfg( locate( "config", CSL1("korganizerrc") ) );
00323         // this part taken from adcalendarbase.cpp:
00324         korgcfg.setGroup( "Time & Date" );
00325         QString tz(korgcfg.readEntry( "TimeZoneId" ) );
00326 #ifdef DEBUG
00327         DEBUGCONDUIT << fname<<": KOrganizer's time zone = "<<tz<<endl;
00328 #endif
00329 
00330 
00331 #ifdef DEBUG
00332         DEBUGCONDUIT << fname
00333                 << ": Using calendar file "
00334                 << fCalendarFile
00335                 << endl;
00336 #endif
00337 
00338 //      emit logMessage(i18n("Using calendar file %1.")
00339 //              .arg(fCalendarFile));
00340 
00341         fCalendar = new KCal::CalendarLocal(tz);
00342         if ( !fCalendar)
00343         {
00344 #ifdef DEBUG
00345                 DEBUGCONDUIT << fname << ":Cannot initialize calendar object"<<endl;
00346 #endif
00347                 return false;
00348         }
00349 
00350         // if there is no calendar yet, use a first sync..
00351         // the calendar is initialized, so nothing more to do...
00352         if (!fCalendar->load(fCalendarFile) )
00353         {
00354 #ifdef DEBUG
00355                 DEBUGCONDUIT << "calendar file "<<fCalendarFile<<" could not be opened. Will create a new one"<<endl;
00356 #endif
00357                 fFirstTime=true;
00358         }
00359 
00360         fP = newVCalPrivate(fCalendar);
00361         if (!fP) return false;
00362         fP->updateIncidences();
00363         if (fP->count()<1) //fFullSync=true;
00364                 fFirstTime=true;
00365         
00366         return (fCalendar && fP);
00367 }
00368 
00369 
00370 
00371 void VCalConduitBase::syncPalmRecToPC()
00372 {
00373         FUNCTIONSETUP;
00374 
00375         PilotRecord *r;
00376         if (fFirstTime || fFullSync)
00377         {
00378                 r = fDatabase->readRecordByIndex(pilotindex++);
00379         }
00380         else
00381         {
00382                 r = fDatabase->readNextModifiedRec();
00383         }
00384         PilotRecord *s = 0L;
00385         
00386         if (!r)
00387         {
00388                 fP->updateIncidences();
00389                 if (nextSyncAction==1)
00390                 {
00391                         QTimer::singleShot(0, this, SLOT(cleanup()));
00392                         return;
00393                 }
00394                 else
00395                 {
00396                         QTimer::singleShot(0 ,this,SLOT(syncPCRecToPalm()));
00397                         return;
00398                 }
00399         }
00400 
00401         // let subclasses do something with the record before we try to sync
00402         preRecord(r);
00403 
00404 //      DEBUGCONDUIT<<fname<<": Event: "<<e->dtStart()<<" until "<<e->dtEnd()<<endl;
00405 //      DEBUGCONDUIT<<fname<<": Time: "<<e->dtStart()<<" until "<<e->dtEnd()<<endl;
00406         bool archiveRecord=(r->isArchived());
00407 
00408         s = fLocalDatabase->readRecordById(r->getID());
00409         if (!s || fFirstTime)
00410         {
00411 #ifdef DEBUG
00412                 if (r->getID()>0 && !s)
00413                 {
00414                         DEBUGCONDUIT<<"---------------------------------------------------------------------------"<<endl;
00415                         DEBUGCONDUIT<< fname<<": Could not read palm record with ID "<<r->getID()<<endl;
00416                 }
00417 #endif
00418                 if (!r->isDeleted() || (archive && archiveRecord))
00419                 {
00420                         KCal::Incidence*e=addRecord(r);
00421                         if (archive && archiveRecord)  {
00422                                 e->setSyncStatus(KCal::Incidence::SYNCDEL);
00423                         }
00424                 }
00425         }
00426         else
00427         {
00428                 if (r->isDeleted())
00429                 {
00430                         if (archive && archiveRecord) 
00431                         {
00432                                 changeRecord(r,s);
00433                         }
00434                         else
00435                         {
00436                                 deleteRecord(r,s);
00437                         }
00438                 }
00439                 else
00440                 {
00441                         changeRecord(r,s);
00442                 }
00443         }
00444 
00445         KPILOT_DELETE(r);
00446         KPILOT_DELETE(s);
00447 
00448         QTimer::singleShot(0,this,SLOT(syncPalmRecToPC()));
00449 }
00450 
00451 
00452 void VCalConduitBase::syncPCRecToPalm()
00453 {
00454         FUNCTIONSETUP;
00455         KCal::Incidence*e=0L;
00456         if (fFirstTime || fFullSync) e=fP->getNextIncidence();
00457         else e=fP->getNextModifiedIncidence();
00458 
00459         if (!e)
00460         {
00461                 pilotindex=0;
00462                 if (nextSyncAction!=0) 
00463                 {
00464                         QTimer::singleShot(0, this, SLOT(cleanup()));
00465                         return;
00466                 }
00467                 QTimer::singleShot(0,this,SLOT(syncDeletedIncidence()));
00468                 return;
00469         }
00470         
00471         // let subclasses do something with the event
00472         preIncidence(e);
00473 
00474         // find the corresponding index on the palm and sync. If there is none, create it.
00475         recordid_t ix=e->pilotId();
00476 #ifdef DEBUG
00477                 DEBUGCONDUIT<<fname<<": found PC entry with pilotID "<<ix<<endl;
00478                 DEBUGCONDUIT<<fname<<": Description: "<<e->summary()<<endl;
00479                 DEBUGCONDUIT<<fname<<": Time: "
00480                         << e->dtStart().toString()
00481 #if KDE_VERSION > 0x030180
00482                         << " until "
00483                         << e->dtEnd()
00484 #endif
00485                         << endl;
00486 #endif
00487         PilotRecord *s=0L;
00488         if (ix>0 && (s=fDatabase->readRecordById(ix)))
00489         {
00490                 if (e->syncStatus()==KCal::Incidence::SYNCDEL)
00491                 {
00492                         deletePalmRecord(e, s);
00493                 }
00494                 else
00495                 {
00496                         changePalmRecord(e, s);
00497                 }
00498                 KPILOT_DELETE(s);
00499         } else {
00500 #ifdef DEBUG
00501                 if (ix>0)
00502                 {
00503                         DEBUGCONDUIT<<"---------------------------------------------------------------------------"<<endl;
00504                         DEBUGCONDUIT<< fname<<": Could not read palm record with ID "<<ix<<endl;
00505                 }
00506 #endif
00507                 addPalmRecord(e);
00508         }
00509         QTimer::singleShot(0, this, SLOT(syncPCRecToPalm()));
00510 }
00511 
00512 
00513 void VCalConduitBase::syncDeletedIncidence()
00514 {
00515         FUNCTIONSETUP;
00516 
00517         PilotRecord *r = fLocalDatabase->readRecordByIndex(pilotindex++);
00518         if (!r || fFullSync || fFirstTime)
00519         {
00520                 QTimer::singleShot(0 ,this,SLOT(cleanup()));
00521                 return;
00522         }
00523 
00524         KCal::Incidence *e = fP->findIncidence(r->getID());
00525         if (!e)
00526         {
00527 #ifdef DEBUG
00528                 DEBUGCONDUIT<<"didn't find incidence with id="<<r->getID()<<", deleting it"<<endl;
00529 #endif
00530                 // entry was deleted from Calendar, so delete it from the palm
00531 //              PilotRecord*s=fLocalDatabase->readRecordById(r->getID());
00532 //              if (s)
00533 //              {
00534 //                      // delete the record from the palm
00535 //                      s->makeDeleted();
00537 //                      fDatabase->writeRecord(s);
00538 //                      KPILOT_DELETE(s);
00539 //              }
00540                 deletePalmRecord(NULL, r);
00541 //              r->makeDeleted();
00543 //              fLocalDatabase->writeRecord(r);
00544 //              fDatabase->writeRecord(r);
00545         }
00546 
00547         KPILOT_DELETE(r);
00548         QTimer::singleShot(0,this,SLOT(syncDeletedIncidence()));
00549 }
00550 
00551 
00552 void VCalConduitBase::cleanup()
00553 {
00554         FUNCTIONSETUP;
00555         postSync();
00556 
00557         if (fDatabase) 
00558         {
00559                 fDatabase->resetSyncFlags();
00560                 fDatabase->cleanup();
00561         }
00562         if (fLocalDatabase) 
00563         {
00564                 fLocalDatabase->resetSyncFlags();
00565                 fLocalDatabase->cleanup();
00566         }
00567         KPILOT_DELETE(fDatabase);
00568         KPILOT_DELETE(fLocalDatabase);
00569         if (fCalendar) fCalendar->save(fCalendarFile);
00570         KPILOT_DELETE(fCalendar);
00571         KPILOT_DELETE(fP);
00572 
00573         emit syncDone(this);
00574 }
00575 
00576 
00577 
00578 void VCalConduitBase::postSync()
00579 {
00580         FUNCTIONSETUP;
00581         fConfig->setGroup(configGroup());
00582         fConfig->writeEntry(VCalConduitFactoryBase::nextSyncAction, 0);
00583 }
00584 
00585 
00586 KCal::Incidence* VCalConduitBase::addRecord(PilotRecord *r)
00587 {
00588         FUNCTIONSETUP;
00589 
00590         recordid_t id=fLocalDatabase->writeRecord(r);
00591 #ifdef DEBUG
00592         DEBUGCONDUIT<<fname<<": Pilot Record ID="<<r->getID()<<", backup ID="<<id<<endl;
00593 #endif
00594 
00595         PilotAppCategory *de=newPilotEntry(r);
00596         KCal::Incidence*e =0L;
00597          
00598         if (de) 
00599         {
00600                 e=fP->findIncidence(de);
00601                 if (!e)
00602                 {
00603                         // no corresponding entry found, so create, copy and insert it.
00604                         e=newIncidence();
00605                         incidenceFromRecord(e,de);
00606                         fP->addIncidence(e);
00607                 }
00608                 else
00609                 {
00610                         // similar entry found, so just copy, no need to insert again
00611                         incidenceFromRecord(e,de);
00612                 }
00613 /*      if (e && de)
00614         {
00615                 
00616                 incidenceFromRecord(e,de);
00617                 // TODO: find out if there is already an entry with this data...
00618 
00619                 fP->addIncidence(e);*/
00620         }
00621         KPILOT_DELETE(de);
00622         return e;
00623 }
00624 
00625 // return how to resolve conflicts. for now PalmOverrides=0=false, PCOverrides=1=true, Ask=2-> ask the user using a messagebox
00626 int VCalConduitBase::resolveConflict(KCal::Incidence*e, PilotAppCategory*de) {
00627         if (conflictResolution==RES_ASK)
00628         {
00629                 return KMessageBox::warningYesNo(NULL, 
00630                         i18n("The following item was modified both on the Pilot and on your PC:\nPC entry:\n\t")+e->summary()+i18n("\nPilot entry:\n\t")+getTitle(de)+
00631                                 i18n("\n\nShould the Pilot entry overwrite the PC entry? If you select \"No\", the PC entry will overwrite the Pilot entry."),
00632                         i18n("Conflicting Entries")
00633                 )==KMessageBox::No;
00634         }
00635         return conflictResolution;
00636 }
00637 
00638 KCal::Incidence*VCalConduitBase::changeRecord(PilotRecord *r,PilotRecord *)
00639 {
00640         FUNCTIONSETUP;
00641 
00642         PilotAppCategory*de=newPilotEntry(r);
00643         KCal::Incidence *e = fP->findIncidence(r->getID());
00644 
00645         if (e && de)
00646         {
00647                 // TODO: check for conflict, and if there is one, ask for resolution
00648                 if ( (e->syncStatus()!=KCal::Incidence::SYNCNONE) && (r->getAttrib() &dlpRecAttrDirty) )
00649                 {
00650                         // TODO: I have not yet found a way to complete ignore an item
00651                         if (resolveConflict(e, de))
00652                         {
00653                                 // PC record takes precedence:
00654                                 KPILOT_DELETE(de);
00655                                 return e;
00656                         }
00657                 }
00658                 // no conflict or conflict resolution says, Palm overwrites, so do it:
00659                 incidenceFromRecord(e,de);
00660                 e->setSyncStatus(KCal::Incidence::SYNCNONE);
00661                 fLocalDatabase->writeRecord(r);
00662         }
00663         else
00664         {
00665                 kdWarning() << k_funcinfo << ": While changing record -- not found in iCalendar" << endl;
00666                 addRecord(r);
00667         }
00668         KPILOT_DELETE(de);
00669         return e;
00670 }
00671 
00672 
00673 KCal::Incidence*VCalConduitBase::deleteRecord(PilotRecord *r, PilotRecord *)
00674 {
00675         FUNCTIONSETUP;
00676 
00677         KCal::Incidence *e = fP->findIncidence(r->getID());
00678         if (e)
00679         {
00680                 // RemoveEvent also takes it out of the calendar.
00681                 fP->removeIncidence(e);
00682         }
00683         fLocalDatabase->writeRecord(r);
00684         return NULL;
00685 }
00686 
00687 
00688 void VCalConduitBase::addPalmRecord(KCal::Incidence*e)
00689 {
00690         FUNCTIONSETUP;
00691 
00692         PilotAppCategory*de=newPilotEntry(NULL);
00693         updateIncidenceOnPalm(e, de);
00694         KPILOT_DELETE(de);
00695 }
00696 
00697 
00698 void VCalConduitBase::changePalmRecord(KCal::Incidence*e, PilotRecord*s)
00699 {
00700         PilotAppCategory*de=newPilotEntry(s);
00701         updateIncidenceOnPalm(e, de);
00702         KPILOT_DELETE(de);
00703 }
00704 
00705 
00706 void VCalConduitBase::deletePalmRecord(KCal::Incidence*e, PilotRecord*s)
00707 {
00708         FUNCTIONSETUP;
00709         if (s)
00710         {
00711 #ifdef DEBUG
00712                 DEBUGCONDUIT << fname << ": deleting record " << s->getID() << endl;
00713 #endif
00714                 s->makeDeleted();
00715 //              s->setAttrib(s->getAttrib() & ~dlpRecAttrDeleted);
00716                 fDatabase->writeRecord(s);
00717                 fLocalDatabase->writeRecord(s);
00718         }
00719         else
00720         {
00721 #ifdef DEBUG
00722                 DEBUGCONDUIT << fname << ": could not find record to delete (" << e->pilotId() << ")" << endl;
00723 #endif
00724         }
00725 }
00726 
00727 
00728 /* I have to use a pointer to an existing PilotDateEntry so that I can handle
00729    new records as well (and to prevent some crashes concerning the validity
00730    domain of the PilotRecord*r). In syncEvent this PilotDateEntry is created. */
00731 void VCalConduitBase::updateIncidenceOnPalm(KCal::Incidence*e, PilotAppCategory*de)
00732 {
00733         FUNCTIONSETUP;
00734         if (!de || !e ) {
00735 #ifdef DEBUG
00736                 DEBUGCONDUIT<<fname<<": NULL event given... Skipping it"<<endl;
00737 #endif
00738                 return;
00739         }
00740         if (e->syncStatus()==KCal::Incidence::SYNCDEL)
00741         {
00742 #ifdef DEBUG
00743                 DEBUGCONDUIT<<fname<<": don't write deleted incidence "<<e->summary()<<" to the palm"<<endl;
00744 #endif
00745                 return;
00746         }
00747         PilotRecord*r=recordFromIncidence(de, e);
00748 
00749         // TODO: Check for conflict!
00750         if (r)
00751         {
00752                 recordid_t id=fDatabase->writeRecord(r);
00753                 r->setID(id);
00754 //              r->setAttrib(r->getAttrib() & ~dlpRecAttrDeleted);
00755                 fLocalDatabase->writeRecord(r);
00756 //              fDatabase->writeRecord(r);
00757                 e->setSyncStatus(KCal::Incidence::SYNCNONE);
00758                 e->setPilotId(id);
00759                 KPILOT_DELETE(r);
00760         }
00761 }
00762 
KDE Logo
This file is part of the documentation for kdelibs Version 3.1.5.
Documentation copyright © 1996-2002 the KDE developers.
Generated on Sun Feb 15 11:40:45 2004 by doxygen 1.3.5 written by Dimitri van Heesch, © 1997-2001