kpilot Library API Documentation

vcal-conduitbase.cc

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