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
00036
#include "options.h"
00037
#include "doc-conduit.moc"
00038
00039
#include <qtimer.h>
00040
#include <qdir.h>
00041
00042
#include <kconfig.h>
00043
#include <kmdcodec.h>
00044
00045
#include <pilotLocalDatabase.h>
00046
#include <pilotSerialDatabase.h>
00047
00048
#include "doc-factory.h"
00049
#include "doc-conflictdialog.h"
00050
#include "DOC-converter.h"
00051
#include "pilotDOCHead.h"
00052
00053
00054
00055
00056
const char *doc_conduit_id =
"$Id: doc-conduit.cc,v 1.20 2003/09/20 17:37:35 binner Exp $";
00057
00058 QString dirToString(eSyncDirectionEnum dir) {
00059
switch(dir) {
00060
00061
case eSyncPDAToPC:
return CSL1(
"eSyncPDAToPC");
00062
case eSyncPCToPDA:
return CSL1(
"eSyncPCToPDA");
00063
case eSyncNone:
return CSL1(
"eSyncNone");
00064
case eSyncConflict:
return CSL1(
"eSyncConflict");
00065
case eSyncDelete:
return CSL1(
"eSyncDelete");
00066
default:
return CSL1(
"ERROR");
00067 }
00068 }
00069
00070
00071
00072
00073
00074
00075
00076 DOCConduit::DOCConduit(KPilotDeviceLink * o,
00077
const char *n,
const QStringList & a):
ConduitAction(o, n, a)
00078 {
00079 FUNCTIONSETUP;
00080
#ifdef DEBUG
00081
DEBUGCONDUIT<<doc_conduit_id<<endl;
00082
#endif
00083
fConduitName=i18n(
"DOC");
00084 }
00085
00086
00087
00088 DOCConduit::~DOCConduit()
00089 {
00090 FUNCTIONSETUP;
00091 }
00092
00093
00094
bool DOCConduit::isCorrectDBTypeCreator(DBInfo dbinfo) {
00095
return dbinfo.type == dbtype() && dbinfo.creator == dbcreator();
00096 }
00097
const unsigned long DOCConduit::dbtype() {
00098
return get_long(DOCConduitFactory::dbDOCtype);
00099 }
00100
const unsigned long DOCConduit::dbcreator() {
00101
return get_long(DOCConduitFactory::dbDOCcreator);
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
void DOCConduit::readConfig()
00113 {
00114 FUNCTIONSETUP;
00115
00116 KConfigGroupSaver g(fConfig, DOCConduitFactory::fGroup);
00117
00118 fTXTDir = fConfig->readEntry(DOCConduitFactory::fTXTDir);
00119 fPDBDir = fConfig->readEntry(DOCConduitFactory::fPDBDir);
00120 fKeepPDBLocally =
00121 fConfig->readBoolEntry(DOCConduitFactory::fKeepPDBLocally,
true);
00122 eConflictResolution =
00123 (
enum eSyncDirectionEnum) (fConfig->
00124 readNumEntry(DOCConduitFactory::fConflictResolution, 0));
00125 fTXTBookmarks = DOCConverter::eBmkNone;
00126
if (fConfig->readBoolEntry(DOCConduitFactory::fConvertBookmarks,
true))
00127 {
00128
if (fConfig->readBoolEntry(DOCConduitFactory::fBookmarksBmk,
true))
00129 fTXTBookmarks |= DOCConverter::eBmkFile;
00130
if (fConfig->readBoolEntry(DOCConduitFactory::fBookmarksInline,
true))
00131 fTXTBookmarks |= DOCConverter::eBmkInline;
00132
if (fConfig->readBoolEntry(DOCConduitFactory::fBookmarksEndtags,
true))
00133 fTXTBookmarks |= DOCConverter::eBmkEndtags;
00134 }
00135 fPDBBookmarks = fConfig->readNumEntry(DOCConduitFactory::fPCBookmarks, DOCConverter::eBmkNone);
00136
00137
00138 fCompress = fConfig->readBoolEntry(DOCConduitFactory::fCompress,
true);
00139 eSyncDirection =
00140 (
enum eSyncDirectionEnum) (fConfig->
00141 readNumEntry(DOCConduitFactory::fSyncDirection, 1));
00142
00143 fIgnoreBmkChangesOnly = fConfig->readBoolEntry(DOCConduitFactory::fIgnoreBmkChanges,
false);
00144 fLocalSync = fConfig->readBoolEntry(DOCConduitFactory::fLocalSync,
false);
00145 fAlwaysUseResolution = fConfig->readBoolEntry(DOCConduitFactory::fAlwaysUseResolution,
false);
00146
00147 fDBListSynced=fConfig->readListEntry(DOCConduitFactory::fDOCList);
00148
00149
#ifdef DEBUG
00150
DEBUGCONDUIT << fname
00151 <<
": Settings "
00152 <<
" fTXTDir=" << fTXTDir
00153 <<
" fPDBDir=" << fPDBDir
00154 <<
" fkeepPDBLocally=" << fKeepPDBLocally
00155 <<
" eConflictResolution=" << eConflictResolution
00156 <<
" fTXTBookmarks=" << fTXTBookmarks
00157 <<
" fPDBBookmarks=" << fPDBBookmarks
00158 <<
" fCompress=" << fCompress
00159 <<
" eSyncDirection=" << eSyncDirection << endl;
00160
#endif
00161
}
00162
00163
00164
00165
bool DOCConduit::pcTextChanged(QString txtfn)
00166 {
00167 KConfigGroupSaver g(fConfig, DOCConduitFactory::fGroup);
00168
00169
00170
00171
00172 QString oldDigest=fConfig->readEntry(txtfn);
00173
if (oldDigest.length()<=0)
00174 {
00175
return true;
00176 }
00177
#ifdef DEBUG
00178
DEBUGCONDUIT<<
"Old digest is "<<oldDigest<<endl;
00179
#endif
00180
00181 KMD5 docmd5;
00182 QFile txtfile(txtfn);
00183
if (txtfile.open(IO_ReadOnly)){
00184 docmd5.update(txtfile);
00185 QString thisDigest(docmd5.hexDigest() );
00186
#ifdef DEBUG
00187
DEBUGCONDUIT<<
"New digest is "<<thisDigest<<endl;
00188
#endif
00189
return (thisDigest.length()<=0) || (thisDigest!=oldDigest);
00190 }
else {
00191
00192
00193
return true;
00194 }
00195
return false;
00196 }
00197
00198
00199
00200
bool DOCConduit::hhTextChanged(
PilotDatabase*docdb)
00201 {
00202
if (!docdb)
return false;
00203
00204 PilotRecord *firstRec = docdb->
readRecordByIndex(0);
00205 PilotDOCHead docHeader(firstRec);
00206 KPILOT_DELETE(firstRec);
00207
00208
int storyRecs = docHeader.numRecords;
00209
00210
00211
00212
int modRecInd=-1;
00213 PilotRecord*modRec=docdb->
readNextModifiedRec(&modRecInd);
00214
#ifdef DEBUG
00215
DEBUGCONDUIT<<
"Index of first changed record: "<<modRecInd<<endl;
00216
#endif
00217
00218 KPILOT_DELETE(modRec);
00219
00220
00221
if (modRecInd==0) {
00222 modRec=docdb->
readNextModifiedRec(&modRecInd);
00223
#ifdef DEBUG
00224
DEBUGCONDUIT<<
"Reread Index of first changed records: "<<modRecInd<<endl;
00225
#endif
00226
KPILOT_DELETE(modRec);
00227 }
00228
00229
00230
00231
if (modRecInd >= 0) {
00232
#ifdef DEBUG
00233
DEBUGCONDUIT<<
"Handheld side has changed, condition="<<
00234 ((!fIgnoreBmkChangesOnly) || (modRecInd <= storyRecs))<<endl;
00235
#endif
00236
if ((!fIgnoreBmkChangesOnly) || (modRecInd <= storyRecs))
00237
return true;
00238 }
else {
00239
#ifdef DEBUG
00240
DEBUGCONDUIT<<
"Handheld side has NOT changed!"<<endl;
00241
#endif
00242
return false;
00243 }
00244
return false;
00245 }
00246
00247
00248
00249
00250
00251
00252
00253 QString DOCConduit::constructPDBFileName(QString name) {
00254 FUNCTIONSETUP;
00255 QString fn;
00256 QDir dr(fPDBDir);
00257 QFileInfo pth(dr, name);
00258
if (!name.isEmpty()) fn=pth.absFilePath()+CSL1(
".pdb");
00259
return fn;
00260 }
00261 QString DOCConduit::constructTXTFileName(QString name) {
00262 FUNCTIONSETUP;
00263 QString fn;
00264 QDir dr(fTXTDir);
00265 QFileInfo pth(dr, name);
00266
if (!name.isEmpty()) fn=pth.absFilePath()+CSL1(
".txt");
00267
return fn;
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
bool DOCConduit::exec()
00283 {
00284 FUNCTIONSETUP;
00285
#ifdef DEBUG
00286
DEBUGCONDUIT<<
"Conduit version: "<<doc_conduit_id<<endl;
00287
#endif
00288
00289
if (!fConfig) {
00290 kdWarning() << k_funcinfo <<
": No config file was set!" << endl;
00291
return false;
00292 }
00293 readConfig();
00294 dbnr=0;
00295
00296 emit logMessage(i18n(
"Searching for texts and databases to synchronize"));
00297
00298 QTimer::singleShot(0,
this, SLOT(syncNextDB()));
00299
return true;
00300 }
00301
00302
00303
00304
bool DOCConduit::doSync(docSyncInfo &sinfo) {
00305
bool res=
false;
00306
00307
if (sinfo.direction==eSyncDelete) {
00308
if (!sinfo.txtfilename.isEmpty()) {
00309
if (!QFile::remove(sinfo.txtfilename)) {
00310 kdWarning()<<
"Unable to delete the text file "<<sinfo.txtfilename<<
" on the PC"<<endl;
00311 }
00312 QString bmkfilename = sinfo.txtfilename;
00313
if (bmkfilename.endsWith(CSL1(
".txt"))){
00314 bmkfilename.remove(bmkfilename.length()-4, 4);
00315 }
00316 bmkfilename+=CSL1(PDBBMK_SUFFIX);
00317
if (!QFile::remove(bmkfilename)) {
00318
#ifdef DEBUG
00319
DEBUGCONDUIT<<
"Could not remove bookmarks file "<<bmkfilename<<
" for database "<<sinfo.handheldDB<<endl;
00320
#endif
00321
}
00322 }
00323
if (!sinfo.pdbfilename.isEmpty() && fKeepPDBLocally) {
00324 PilotLocalDatabase*database=
new PilotLocalDatabase(fPDBDir,
00325 QString::fromLatin1(sinfo.dbinfo.name),
false);
00326
if (database) {
00327
if ( database->deleteDatabase() !=0 ) {
00328 kdWarning()<<
"Unable to delete database "<<sinfo.dbinfo.name<<
" on the PC"<<endl;
00329 }
00330 KPILOT_DELETE(database);
00331 }
00332 }
00333
if (!fLocalSync) {
00334
PilotDatabase *database=
new PilotSerialDatabase(pilotSocket(),
00335 QString::fromLatin1(sinfo.dbinfo.name));
00336
if ( database->
deleteDatabase() !=0 ) {
00337 kdWarning()<<
"Unable to delete database "<<sinfo.dbinfo.name<<
" from the handheld"<<endl;
00338 }
00339 KPILOT_DELETE(database);
00340 }
00341
return true;
00342 }
00343
00344
00345
00346
PilotDatabase *database = preSyncAction(sinfo);
00347
00348
if (database && ( !database->
isDBOpen() ) ) {
00349
#ifdef DEBUG
00350
DEBUGCONDUIT<<
"Database "<<sinfo.dbinfo.name<<
" does not yet exist. Creating it:"<<endl;
00351
#endif
00352
if (!database->
createDatabase(dbcreator(), dbtype()) ) {
00353
#ifdef DEBUG
00354
DEBUGCONDUIT<<
"Failed"<<endl;
00355
#endif
00356
}
00357 }
00358
00359
if (database && database->
isDBOpen()) {
00360 DOCConverter docconverter;
00361 connect(&docconverter, SIGNAL(logError(
const QString &)), SIGNAL(logError(
const QString &)));
00362 connect(&docconverter, SIGNAL(logMessage(
const QString &)), SIGNAL(logMessage(
const QString &)));
00363
00364 docconverter.setTXTpath(fTXTDir, sinfo.txtfilename);
00365 docconverter.setPDB(database);
00366 docconverter.setCompress(fCompress);
00367
00368
switch (sinfo.direction) {
00369
case eSyncPDAToPC:
00370 docconverter.setBookmarkTypes(fPDBBookmarks);
00371 res = docconverter.convertPDBtoTXT();
00372
break;
00373
case eSyncPCToPDA:
00374 docconverter.setBookmarkTypes(fTXTBookmarks);
00375 res = docconverter.convertTXTtoPDB();
00376
break;
00377
default:
00378
break;
00379 }
00380
00381
00382 {
00383 KConfigGroupSaver g(fConfig, DOCConduitFactory::fGroup);
00384 KMD5 docmd5;
00385 QFile txtfile(docconverter.txtFilename());
00386
if (txtfile.open(IO_ReadOnly)) {
00387 docmd5.update(txtfile);
00388 QString thisDigest(docmd5.hexDigest() );
00389 fConfig->writeEntry(docconverter.txtFilename(), thisDigest);
00390 fConfig->sync();
00391
#ifdef DEBUG
00392
DEBUGCONDUIT<<
"MD5 Checksum of the text "<<sinfo.txtfilename<<
" is "<<thisDigest<<endl;
00393
#endif
00394
}
else {
00395
#ifdef DEBUG
00396
DEBUGCONDUIT<<
"couldn't open file "<<docconverter.txtFilename()<<
" for reading!!!"<<endl;
00397
#endif
00398
}
00399 }
00400
00401
if (!postSyncAction(database, sinfo, res))
00402 emit logError(i18n(
"Unable to install the locally created PalmDOC %1 to the handheld.")
00403 .arg(QString::fromLatin1(sinfo.dbinfo.name)));
00404
if (!res)
00405 emit logError(i18n(
"Conversion of PalmDOC \"%1\" failed.")
00406 .arg(QString::fromLatin1(sinfo.dbinfo.name)));
00407
00408
00409
00410 }
00411
else
00412 {
00413 emit logError(i18n(
"Unable to open or create the database %1")
00414 .arg(QString::fromLatin1(sinfo.dbinfo.name)));
00415 }
00416
return res;
00417 }
00418
00419
00422
void DOCConduit::syncNextDB() {
00423 FUNCTIONSETUP;
00424 DBInfo dbinfo;
00425
00426
if (eSyncDirection==eSyncPCToPDA || fHandle->findDatabase(NULL, &dbinfo, dbnr, dbtype(), dbcreator() ) < 0)
00427 {
00428
00429 QTimer::singleShot(0,
this, SLOT(syncNextTXT()));
00430
return;
00431 }
00432 dbnr=dbinfo.index+1;
00433
#ifdef DEBUG
00434
DEBUGCONDUIT<<
"Next Palm database to sync: "<<dbinfo.name<<
", Index="<<dbinfo.index<<endl;
00435
#endif
00436
00437
00438
if (!isCorrectDBTypeCreator(dbinfo) ||
00439 fDBNames.contains(QString::fromLatin1(dbinfo.name)))
00440 {
00441 QTimer::singleShot(0,
this, SLOT(syncNextDB()));
00442
return;
00443 }
00444
00445 QString txtfilename=constructTXTFileName(QString::fromLatin1(dbinfo.name));
00446 QString pdbfilename=constructPDBFileName(QString::fromLatin1(dbinfo.name));
00447
00448 docSyncInfo syncInfo(QString::fromLatin1(dbinfo.name),
00449 txtfilename, pdbfilename, eSyncNone);
00450 syncInfo.dbinfo=dbinfo;
00451 needsSync(syncInfo);
00452 fSyncInfoList.append(syncInfo);
00453 fDBNames.append(QString::fromLatin1(dbinfo.name));
00454
00455 QTimer::singleShot(0,
this, SLOT(syncNextDB()));
00456
return;
00457 }
00458
00459
00460
00461
void DOCConduit::syncNextTXT()
00462 {
00463 FUNCTIONSETUP;
00464
00465
if (eSyncDirection==eSyncPDAToPC )
00466 {
00467
00468 docnames.clear();
00469 QTimer::singleShot(0,
this, SLOT(checkPDBFiles()));
00470
return;
00471 }
00472
00473
00474
if (docnames.isEmpty()) {
00475 docnames=QDir(fTXTDir, CSL1(
"*.txt")).entryList() ;
00476 dociterator=docnames.begin();
00477 }
00478
if (dociterator==docnames.end()) {
00479
00480 docnames.clear();
00481 QTimer::singleShot(0,
this, SLOT(checkPDBFiles()));
00482
return;
00483 }
00484
00485 QString fn=(*dociterator);
00486
00487 QDir dr(fTXTDir);
00488 QFileInfo fl(dr, fn );
00489 QString txtfilename=fl.absFilePath();
00490 QString pdbfilename;
00491 dociterator++;
00492
00493 DBInfo dbinfo;
00494
00495
00496 memset(&dbinfo.name[0], 0, 33);
00497 strncpy(&dbinfo.name[0], fl.baseName(TRUE).latin1(), 30);
00498
00499
bool alreadySynced=fDBNames.contains(fl.baseName(TRUE));
00500
if (!alreadySynced) {
00501 docSyncInfo syncInfo(QString::fromLatin1(dbinfo.name),
00502 txtfilename, pdbfilename, eSyncNone);
00503 syncInfo.dbinfo=dbinfo;
00504 needsSync(syncInfo);
00505 fSyncInfoList.append(syncInfo);
00506 fDBNames.append(QString::fromLatin1(dbinfo.name));
00507 }
else {
00508
#ifdef DEBUG
00509
DEBUGCONDUIT<<txtfilename<<
" has already been synced, skipping it."<<endl;
00510
#endif
00511
}
00512
00513 QTimer::singleShot(0,
this, SLOT(syncNextTXT()));
00514
return;
00515 }
00516
00517
00518
00521
void DOCConduit::checkPDBFiles() {
00522 FUNCTIONSETUP;
00523
00524
if (fLocalSync || !fKeepPDBLocally || eSyncDirection==eSyncPCToPDA )
00525 {
00526
00527 QTimer::singleShot(0,
this, SLOT(checkDeletedDocs()));
00528
return;
00529 }
00530
00531
00532
00533
if (docnames.isEmpty()) {
00534 docnames=QDir(fPDBDir, CSL1(
"*.pdb")).entryList() ;
00535 dociterator=docnames.begin();
00536 }
00537
if (dociterator==docnames.end()) {
00538
00539 docnames.clear();
00540 QTimer::singleShot(0,
this, SLOT(checkDeletedDocs()));
00541
return;
00542 }
00543
00544 QString fn=(*dociterator);
00545
00546 QDir dr(fPDBDir);
00547 QFileInfo fl(dr, fn );
00548 QString pdbfilename=fl.absFilePath();
00549 dociterator++;
00550
00551
00552
00553 QString dbname=fl.baseName(TRUE).left(30);
00554
if (!fDBNames.contains(dbname) && !fDBListSynced.contains(dbname)) {
00555
if (fHandle->installFiles(pdbfilename,
false)) {
00556 DBInfo dbinfo;
00557
00558
00559 memset(&dbinfo.name[0], 0, 33);
00560 strncpy(&dbinfo.name[0], dbname.latin1(), 30);
00561
00562 docSyncInfo syncInfo(dbname, constructTXTFileName(dbname), pdbfilename, eSyncNone);
00563 syncInfo.dbinfo=dbinfo;
00564 needsSync(syncInfo);
00565 fSyncInfoList.append(syncInfo);
00566 fDBNames.append(dbname);
00567 }
else {
00568
#ifdef DEBUG
00569
DEBUGCONDUIT<<
"Could not install database "<<dbname<<
" ("<<pdbfilename<<
") to the handheld"<<endl;
00570
#endif
00571
}
00572 }
00573
00574 QTimer::singleShot(0,
this, SLOT(checkPDBFiles()));
00575 }
00576
00577
00578
00579
void DOCConduit::checkDeletedDocs()
00580 {
00581 FUNCTIONSETUP;
00582
00583
for (QStringList::Iterator it=fDBListSynced.begin(); it!=fDBListSynced.end(); ++it ) {
00584
if (!fDBNames.contains(*it)) {
00585
00586 QString dbname(*it);
00587 QString txtfilename=constructTXTFileName(dbname);
00588 QString pdbfilename=constructPDBFileName(dbname);
00589 docSyncInfo syncInfo(dbname, txtfilename, pdbfilename, eSyncDelete);
00590
00591 DBInfo dbinfo;
00592 memset(&dbinfo.name[0], 0, 33);
00593 strncpy(&dbinfo.name[0], dbname.latin1(), 30);
00594 syncInfo.dbinfo=dbinfo;
00595
00596 fSyncInfoList.append(syncInfo);
00597 }
00598 }
00599 QTimer::singleShot(0,
this, SLOT(resolve()));
00600
return;
00601 }
00602
00603
00604
00605
void DOCConduit::resolve() {
00606 FUNCTIONSETUP;
00607
00608
for (fSyncInfoListIterator=fSyncInfoList.begin(); fSyncInfoListIterator!=fSyncInfoList.end(); fSyncInfoListIterator++) {
00609
00610
00611
if ((*fSyncInfoListIterator).direction==eSyncConflict){
00612
#ifdef DEBUG
00613
DEBUGCONDUIT<<
"We have a conflict for "<<(*fSyncInfoListIterator).handheldDB<<
", default="<<eConflictResolution<<endl;
00614
#endif
00615
switch (eConflictResolution)
00616 {
00617
case eSyncPDAToPC:
00618
#ifdef DEBUG
00619
DEBUGCONDUIT<<
"PDA overrides for database "<<(*fSyncInfoListIterator).handheldDB<<endl;
00620
#endif
00621
(*fSyncInfoListIterator).direction = eSyncPDAToPC;
00622
break;
00623
case eSyncPCToPDA:
00624
#ifdef DEBUG
00625
DEBUGCONDUIT<<
"PC overrides for database "<<(*fSyncInfoListIterator).handheldDB<<endl;
00626
#endif
00627
(*fSyncInfoListIterator).direction = eSyncPCToPDA;
00628
break;
00629
case eSyncNone:
00630
#ifdef DEBUG
00631
DEBUGCONDUIT<<
"No sync for database "<<(*fSyncInfoListIterator).handheldDB<<endl;
00632
#endif
00633
(*fSyncInfoListIterator).direction = eSyncNone;
00634
break;
00635
case eSyncDelete:
00636
case eSyncConflict:
00637
default:
00638
#ifdef DEBUG
00639
DEBUGCONDUIT<<
"Conflict remains due to default resolution setting for database "<<(*fSyncInfoListIterator).handheldDB<<endl;
00640
#endif
00641
break;
00642 }
00643 }
00644 }
00645
00646
00647 ResolutionDialog*dlg=
new ResolutionDialog( 0, i18n(
"Conflict Resolution"), &fSyncInfoList , fHandle);
00648
bool show=fAlwaysUseResolution || (dlg && dlg->hasConflicts);
00649
if (show) {
00650
if (!dlg || !dlg->exec() ) {
00651 KPILOT_DELETE(dlg)
00652 emit logMessage(i18n("Sync aborted by user."));
00653 QTimer::singleShot(0, this, SLOT(cleanup()));
00654 return;
00655 }
00656 }
00657 KPILOT_DELETE(dlg)
00658
00659
00660
00661 fDBNames.clear();
00662 fSyncInfoListIterator=fSyncInfoList.begin();
00663 QTimer::singleShot(0,this, SLOT(syncDatabases()));
00664 return;
00665 }
00666
00667
00668
00669
void DOCConduit::syncDatabases() {
00670 FUNCTIONSETUP;
00671
if (fSyncInfoListIterator==fSyncInfoList.end()) {
00672
00673 QTimer::singleShot(0,
this, SLOT(cleanup()));
00674
return;
00675 }
00676
00677 docSyncInfo sinfo=(*fSyncInfoListIterator);
00678 fSyncInfoListIterator++;
00679
00680
switch (sinfo.direction) {
00681
case eSyncConflict:
00682
#ifdef DEBUG
00683
DEBUGCONDUIT<<
"Entry "<<sinfo.handheldDB<<
"( txtfilename: "<<sinfo.txtfilename<<
00684
", pdbfilename: "<<sinfo.pdbfilename<<
") had sync direction eSyncConflict!!!"<<endl;
00685
#endif
00686
break;
00687
case eSyncDelete:
00688
case eSyncPDAToPC:
00689
case eSyncPCToPDA:
00690 emit logMessage(i18n(
"Synchronizing text \"%1\"").arg(sinfo.handheldDB));
00691
if (!doSync(sinfo)) {
00692
00693
#ifdef DEBUG
00694
DEBUGCONDUIT<<
"There was some error syncing the text \""<<sinfo.handheldDB<<
"\" with the file "<<sinfo.txtfilename<<endl;
00695
#endif
00696
}
00697
break;
00698
case eSyncNone:
00699
00700
break;
00701 }
00702
if (sinfo.direction != eSyncDelete) fDBNames.append(sinfo.handheldDB);
00703
00704 QTimer::singleShot(0,
this, SLOT(syncDatabases()));
00705
return;
00706 }
00707
00708
00709
PilotDatabase*DOCConduit::openDOCDatabase(QString dbname) {
00710
if (fLocalSync)
return new PilotLocalDatabase(fPDBDir, dbname,
false);
00711
else return new PilotSerialDatabase(pilotSocket(), dbname);
00712 }
00713
00714
00715
bool DOCConduit::needsSync(docSyncInfo &sinfo)
00716 {
00717 FUNCTIONSETUP;
00718 sinfo.direction = eSyncNone;
00719
00720
PilotDatabase*docdb=openDOCDatabase(QString::fromLatin1(sinfo.dbinfo.name));
00721
if (!fDBListSynced.contains(sinfo.handheldDB)) {
00722
00723
#ifdef DEBUG
00724
DEBUGCONDUIT<<
"Database "<<sinfo.dbinfo.name<<
" wasn't included in the previous sync!"<<endl;
00725
#endif
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
if (QFile::exists(sinfo.txtfilename)) sinfo.fPCStatus=eStatNew;
00736
else sinfo.fPCStatus=eStatDoesntExist;
00737
if (docdb && docdb->
isDBOpen()) sinfo.fPalmStatus=eStatNew;
00738
else sinfo.fPalmStatus=eStatDoesntExist;
00739 KPILOT_DELETE(docdb);
00740
00741
switch (eSyncDirection) {
00742
case eSyncPDAToPC:
00743
if (sinfo.fPalmStatus==eStatDoesntExist)
00744 sinfo.direction=eSyncDelete;
00745
else sinfo.direction=eSyncPDAToPC;
00746
break;
00747
case eSyncPCToPDA:
00748
if (sinfo.fPCStatus==eStatDoesntExist)
00749 sinfo.direction=eSyncDelete;
00750
else sinfo.direction=eSyncPCToPDA;
00751
break;
00752
case eSyncNone:
00753
if (sinfo.fPCStatus==eStatNew) {
00754
if (sinfo.fPalmStatus==eStatNew) sinfo.direction=eSyncConflict;
00755
else sinfo.direction=eSyncPCToPDA;
00756 }
else {
00757
if (sinfo.fPalmStatus==eStatNew) sinfo.direction=eSyncPDAToPC;
00758
else {
00759 sinfo.direction=eSyncNone;
00760
#ifdef DEBUG
00761
DEBUGCONDUIT<<
"I'm supposed to find a sync direction, but the "<<
00762
" text "<<sinfo.dbinfo.name<<
" doesn't exist on either "<<
00763
" the handheld or the PC"<<endl;
00764
#endif
00765
}
00766 }
00767
break;
00768
default:
00769
break;
00770 }
00771
return true;
00772 }
00773
00774
00775
if (!QFile::exists(sinfo.txtfilename)) sinfo.fPCStatus=eStatDeleted;
00776
else if(pcTextChanged(sinfo.txtfilename)) {
00777 sinfo.fPCStatus=eStatChanged;
00778
#ifdef DEBUG
00779
DEBUGCONDUIT<<
"PC side has changed!"<<endl;
00780
#endif
00781
00782
#ifdef DEBUG
00783
}
else {
00784 DEBUGCONDUIT<<
"PC side has NOT changed!"<<endl;
00785
#endif
00786
}
00787
00788
if (!docdb || !docdb->
isDBOpen()) sinfo.fPalmStatus=eStatDeleted;
00789
else if (hhTextChanged(docdb)) {
00790
#ifdef DEBUG
00791
DEBUGCONDUIT<<
"Handheld side has changed!"<<endl;
00792
#endif
00793
sinfo.fPalmStatus=eStatChanged;
00794
#ifdef DEBUG
00795
}
else {
00796 DEBUGCONDUIT<<
"Handheld side has NOT changed!"<<endl;
00797
#endif
00798
}
00799 KPILOT_DELETE(docdb);
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
if (sinfo.fPCStatus == eStatNone && sinfo.fPalmStatus==eStatNone) {
00820
#ifdef DEBUG
00821
DEBUGCONDUIT<<
"Nothing has changed, not need for a sync."<<endl;
00822
#endif
00823
sinfo.direction=eSyncNone;
00824
return false;
00825 }
00826
00827
00828
00829
00830
00831
if (eSyncDirection==eSyncPCToPDA) {
00832
if (sinfo.fPCStatus==eStatDeleted) sinfo.direction=eSyncDelete;
00833
else sinfo.direction=eSyncPCToPDA;
00834
return true;
00835 }
00836
if (eSyncDirection==eSyncPDAToPC) {
00837
if (sinfo.fPalmStatus==eStatDeleted) sinfo.direction=eSyncDelete;
00838
else sinfo.direction=eSyncPDAToPC;
00839
return true;
00840 }
00841
00842
00843
00844
00845
00846
00847
00848
00849
if ( ((sinfo.fPCStatus==eStatDeleted) && (sinfo.fPalmStatus!=eStatChanged)) ||
00850 ((sinfo.fPalmStatus==eStatDeleted) && (sinfo.fPCStatus!=eStatChanged)) )
00851 {
00852
#ifdef DEBUG
00853
DEBUGCONDUIT<<
"DB was deleted on one side and not changed on "
00854
"the other -> Delete it."<<endl;
00855
#endif
00856
sinfo.direction=eSyncDelete;
00857
return true;
00858 }
00859
00860
00861
00862
if (sinfo.fPCStatus==eStatNone) {
00863
#ifdef DEBUG
00864
DEBUGCONDUIT<<
"PC side has changed!"<<endl;
00865
#endif
00866
sinfo.direction=eSyncPDAToPC;
00867
return true;
00868 }
00869
00870
if (sinfo.fPalmStatus==eStatNone) {
00871 sinfo.direction=eSyncPCToPDA;
00872
return true;
00873 }
00874
00875
00876
00877
00878 sinfo.direction=eSyncConflict;
00879
return true;
00880 }
00881
00882
00883
00884
PilotDatabase *DOCConduit::preSyncAction(docSyncInfo &sinfo)
const
00885
{
00886 FUNCTIONSETUP;
00887
00888 {
00889
00890 QDir dir(fTXTDir);
00891
if (!dir.exists())
00892 {
00893 dir.mkdir(dir.absPath());
00894 }
00895 }
00896
00897 DBInfo dbinfo=sinfo.dbinfo;
00898
switch (sinfo.direction)
00899 {
00900
case eSyncPDAToPC:
00901
if (fKeepPDBLocally)
00902 {
00903
00904 QDir dir(fPDBDir);
00905
00906
if (!dir.exists())
00907 {
00908 dir.mkdir(dir.absPath());
00909 }
00910
#ifdef DEBUG
00911
DEBUGCONDUIT<<
"Need to fetch database "<<dbinfo.name<<
00912
" to the directory "<<dir.absPath()<<endl;
00913
#endif
00914
dbinfo.flags &= ~dlpDBFlagOpen;
00915
00916
if (!fHandle->retrieveDatabase(sinfo.pdbfilename, &dbinfo) )
00917 {
00918 kdWarning(0)<<
"Unable to retrieve database "<<dbinfo.name<<
00919
" from the handheld into "<<sinfo.pdbfilename<<
"."<<endl;
00920
return 0L;
00921 }
00922 }
00923
break;
00924
case eSyncPCToPDA:
00925
if (fKeepPDBLocally)
00926 {
00927
00928 QDir dir(fPDBDir);
00929
if (!dir.exists())
00930 {
00931 dir.mkdir(dir.absPath());
00932 }
00933 }
00934
break;
00935
default:
00936
break;
00937 }
00938
if (fKeepPDBLocally)
00939 {
00940
return new PilotLocalDatabase(fPDBDir,
00941 QString::fromLatin1(dbinfo.name),
false);
00942 }
00943
else
00944 {
00945
return new PilotSerialDatabase(pilotSocket(),
00946 QString::fromLatin1(dbinfo.name));
00947 }
00948 }
00949
00950
00951
00952
00953
bool DOCConduit::postSyncAction(
PilotDatabase * database,
00954 docSyncInfo &sinfo,
bool res)
00955 {
00956 FUNCTIONSETUP;
00957
bool rs =
true;
00958
00959
switch (sinfo.direction)
00960 {
00961
case eSyncPDAToPC:
00962
00963
#ifdef DEBUG
00964
DEBUGCONDUIT<<
"Resetting sync flags for database "
00965 <<sinfo.dbinfo.name<<endl;
00966
#endif
00967
if (fKeepPDBLocally && !fLocalSync) {
00968 PilotSerialDatabase*db=
new PilotSerialDatabase(pilotSocket(),
00969 QString::fromLatin1(sinfo.dbinfo.name));
00970
#ifdef DEBUG
00971
DEBUGCONDUIT<<
"Middle 1 Resetting sync flags for database "
00972 <<sinfo.dbinfo.name<<endl;
00973
#endif
00974
if (db) {
00975 db->resetSyncFlags();
00976 KPILOT_DELETE(db);
00977 }
00978
#ifdef DEBUG
00979
DEBUGCONDUIT<<
"Middle2 Resetting sync flags for database "
00980 <<sinfo.dbinfo.name<<endl;
00981
#endif
00982
}
00983
#ifdef DEBUG
00984
DEBUGCONDUIT<<
"End Resetting sync flags for database "
00985 <<sinfo.dbinfo.name<<endl;
00986
#endif
00987
break;
00988
case eSyncPCToPDA:
00989
if (fKeepPDBLocally && !fLocalSync && res)
00990 {
00991
00992 PilotLocalDatabase*localdb=dynamic_cast<PilotLocalDatabase*>(database);
00993
if (localdb)
00994 {
00995
#ifdef DEBUG
00996
DEBUGCONDUIT<<
"Installing file "<<localdb->dbPathName()<<
" ("
00997 <<sinfo.handheldDB<<
") to the handheld"<<endl;
00998
#endif
00999
QString dbpathname=localdb->dbPathName();
01000
01001 KPILOT_DELETE(database);
01002
if (!fHandle->installFiles(dbpathname,
false))
01003 {
01004 rs =
false;
01005
#ifdef DEBUG
01006
DEBUGCONDUIT<<
"Could not install the database "<<dbpathname<<
" ("
01007 <<sinfo.handheldDB<<
")"<<endl;
01008
#endif
01009
}
01010 }
01011 }
01012
default:
01013
break;
01014 }
01015
01016
#ifdef DEBUG
01017
DEBUGCONDUIT<<
"Vor KPILOT_DELETE(database)"<<endl;
01018
#endif
01019
01020 KPILOT_DELETE(database);
01021
#ifdef DEBUG
01022
DEBUGCONDUIT<<
"End postSyncAction"<<endl;
01023
#endif
01024
return rs;
01025 }
01026
01027
01028
01029
void DOCConduit::cleanup()
01030 {
01031 FUNCTIONSETUP;
01032
01033 KConfigGroupSaver g(fConfig, DOCConduitFactory::fGroup);
01034 fConfig->writeEntry(DOCConduitFactory::fDOCList, fDBNames);
01035 fConfig->sync();
01036
01037 emit syncDone(
this);
01038 }
01039