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 #include <options.h>
00029
00030 #include <qtimer.h>
00031 #include <qlayout.h>
00032 #include <qlabel.h>
00033 #include <kmessagebox.h>
00034 #include <kdialog.h>
00035 #include <ktextedit.h>
00036 #include <kdialogbase.h>
00037
00038 #include <pilotRecord.h>
00039 #include <pilotLocalDatabase.h>
00040 #include <pilotDatabase.h>
00041 #include <pilotSerialDatabase.h>
00042 #include "kpilotConfig.h"
00043 #include "internalEditorAction.h"
00044
00045 #include <pilotAddress.h>
00046 #include <pilotMemo.h>
00047 #include <pilotDateEntry.h>
00048 #include <pilotTodoEntry.h>
00049
00050 #include "khexedit/byteseditinterface.h"
00051 using namespace KHE;
00052
00053 InternalEditorAction::InternalEditorAction(KPilotLink * p) :
00054 SyncAction(p, "internalSync")
00055 {
00056 FUNCTIONSETUP;
00057 }
00058
00059 bool InternalEditorAction::exec()
00060 {
00061 FUNCTIONSETUP;
00062 emit logMessage(i18n("[Internal Editors]"));
00063 fInternalEditorSyncStatus=eSyncStarted;
00064 QTimer::singleShot(0, this, SLOT(syncDirtyDB()));
00065 return true;
00066 }
00067
00068 void InternalEditorAction::syncDirtyDB()
00069 {
00070 FUNCTIONSETUP;
00071
00072 if (fInternalEditorSyncStatus!=eSyncDirtyDB)
00073 {
00074 fInternalEditorSyncStatus=eSyncDirtyDB;
00075 dirtyDBs=KPilotSettings::dirtyDatabases();
00076 emit logMessage(i18n("Databases with changed records: %1").arg(dirtyDBs.join(CSL1(", "))));
00077 dbIter=dirtyDBs.begin();
00078 }
00079 else
00080 {
00081 dbIter++;
00082 }
00083 if (dbIter==dirtyDBs.end())
00084 {
00085 KPilotSettings::setDirtyDatabases(QStringList());
00086 KPilotConfig::sync();
00087 QTimer::singleShot(0, this, SLOT(syncFlagsChangedDB()));
00088 return;
00089 }
00090 #ifdef DEBUG
00091 DEBUGKPILOT<<"syncDirtyDB for DB "<<(*dbIter)<<endl;
00092 #endif
00093
00094
00095
00096 PilotRecord*rec=0L;
00097 PilotLocalDatabase*localDB=new PilotLocalDatabase(*dbIter, false);
00098 PilotDatabase *serialDB= deviceLink()->database(*dbIter);
00099 if (!localDB->isOpen() || !serialDB->isOpen())
00100 {
00101 emit logError(i18n("Unable to open the serial or local database for %1. "
00102 "Skipping it.").arg(*dbIter));
00103 goto nextDB;
00104 }
00105 while ( (rec=localDB->readNextModifiedRec()) )
00106 {
00107 int id=rec->id();
00108 #ifdef DEBUG
00109 DEBUGKPILOT<<"ID of modified record is "<<id<<endl;
00110 DEBUGKPILOT<<endl<<endl;
00111 #endif
00112 if (id>0)
00113 {
00114 PilotRecord*serrec=serialDB->readRecordById(id);
00115 if (serrec && (serrec->isModified()) )
00116 {
00117 bool kpilotOverrides=queryUseKPilotChanges(*dbIter, id, rec, serrec, localDB);
00118 if (kpilotOverrides)
00119 serialDB->writeRecord(rec);
00120 else
00121 localDB->writeRecord(serrec);
00122 }
00123 else
00124 serialDB->writeRecord(rec);
00125 }
00126 else
00127 {
00128 #ifdef DEBUG
00129 DEBUGKPILOT<<"Generating ID for Record "<<rec->id()<<" with data "<<endl;
00130 DEBUGKPILOT<<rec->data()<<endl;
00131 DEBUGKPILOT<<"-----------------------------------------"<<endl;
00132 #endif
00133 int id=serialDB->writeRecord(rec);
00134 rec->setID(id);
00135 #ifdef DEBUG
00136 DEBUGKPILOT<<"New ID is "<<id<<endl;
00137 DEBUGKPILOT<<endl<<endl<<endl;
00138 #endif
00139
00140 localDB->updateID(id);
00141 }
00142 KPILOT_DELETE(rec);
00143 }
00144
00145 nextDB:
00146 localDB->resetSyncFlags();
00147 KPILOT_DELETE(localDB);
00148 KPILOT_DELETE(serialDB);
00149 QTimer::singleShot(0, this, SLOT(syncDirtyDB()));
00150 }
00151
00152 bool InternalEditorAction::queryUseKPilotChanges(QString dbName, recordid_t id, PilotRecord*localrec, PilotRecord*serialrec, PilotDatabase*db)
00153 {
00154 FUNCTIONSETUP;
00155 bool knownDB=true;
00156 QString localEntry, serialEntry, recType(i18n("record"));
00157
00158 if (dbName==CSL1("AddressDB") && db)
00159 {
00160 PilotAddressInfo info(db);
00161
00162 PilotAddress localAddr(localrec);
00163 PilotAddress serialAddr(serialrec);
00164 localEntry=localAddr.getTextRepresentation(&info,Qt::RichText);
00165 serialEntry=serialAddr.getTextRepresentation(&info,Qt::RichText);
00166 recType=i18n("address");
00167 }
00168 else
00169 if (dbName==CSL1("ToDoDB") && db)
00170 {
00171 PilotToDoInfo info(db);
00172
00173 PilotTodoEntry localTodo(localrec);
00174 PilotTodoEntry serialTodo(serialrec);
00175 localEntry=localTodo.getTextRepresentation(Qt::RichText);
00176 serialEntry=serialTodo.getTextRepresentation(Qt::RichText);
00177 recType=i18n("to-do entry");
00178 }
00179 else
00180 if (dbName==CSL1("MemoDB"))
00181 {
00182 PilotMemo localMemo(localrec);
00183 PilotMemo serialMemo(serialrec);
00184 localEntry=localMemo.getTextRepresentation(Qt::RichText);
00185 serialEntry=serialMemo.getTextRepresentation(Qt::RichText);
00186 recType=i18n("memo");
00187 }
00188 else
00189 if (dbName==CSL1("DatebookDB"))
00190 {
00191 PilotDateInfo info(db);
00192
00193 PilotDateEntry localEvent(localrec);
00194 PilotDateEntry serialEvent(serialrec);
00195 localEntry=localEvent.getTextRepresentation(Qt::RichText);
00196 serialEntry=serialEvent.getTextRepresentation(Qt::RichText);
00197 recType=i18n("calendar entry");
00198 }
00199 else
00200 {
00201 knownDB=false;
00202 }
00203
00204 QString dialogText(i18n("The %1 with ID %2 of the database \"%3\" was changed "
00205 "on the handheld and in the internal editor. Shall the changes in KPilot be copied to the handheld, and so override the changes there?").
00206 arg(recType).arg(id).arg(dbName));
00207
00208 KDialogBase*resdlg=new KDialogBase(0L, "internalresolutiondialog", true,
00209 i18n("Conflict in database %1").arg(*dbIter),
00210 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok, true,
00211 i18n("Use KPilot"), i18n("Use Handheld") );
00212 resdlg->setButtonText(KDialogBase::Ok, i18n("Use &KPilot"));
00213 resdlg->setButtonText(KDialogBase::Cancel, i18n("Use &Handheld"));
00214
00215 QWidget*page=new QWidget(resdlg);
00216 resdlg->setMainWidget(page);
00217 QGridLayout*layout = new QGridLayout( page, 1, 1);
00218
00219 QLabel *label=new QLabel(dialogText, page);
00220 label->setAlignment( QLabel::WordBreak );
00221 layout->addMultiCellWidget( label, 0,0, 0,1 );
00222
00223 layout->addItem( new QSpacerItem( 20, 10, QSizePolicy::Minimum,
00224 QSizePolicy::Fixed ), 1, 0 );
00225
00226 if (knownDB)
00227 {
00228 label=new QLabel(i18n("Entry in KPilot"), page);
00229 layout->addWidget( label, 2,0);
00230
00231 KTextEdit*textBrowser = new KTextEdit(CSL1("<qt>")+localEntry+CSL1("</qt>"), QString::null, page);
00232 textBrowser->setReadOnly(true);
00233 layout->addWidget( textBrowser, 3,0);
00234
00235 label=new QLabel(i18n("Entry on Handheld"), page);
00236 layout->addWidget( label, 2,1);
00237
00238 textBrowser = new KTextEdit(CSL1("<qt>")+serialEntry+CSL1("</qt>"), QString::null, page);
00239 textBrowser->setReadOnly(true);
00240 layout->addWidget( textBrowser, 3,1);
00241 }
00242 else
00243 {
00244 label=new QLabel(i18n("Entry in KPilot"), page);
00245 layout->addMultiCellWidget( label, 2,2,0,1);
00246
00247
00248 QWidget *hexEdit = KHE::createBytesEditWidget( page, "LocalBufferEdit" );
00249 if( hexEdit )
00250 {
00251 KHE::BytesEditInterface* hexEditIf = KHE::bytesEditInterface( hexEdit );
00252 Q_ASSERT( hexEditIf );
00253 if( hexEditIf )
00254 {
00255 hexEditIf->setData( localrec->data(), localrec->size() );
00256
00257
00258 hexEditIf->setReadOnly( true );
00259 }
00260 }
00261 else
00262 {
00263 QLabel*tmpW = new QLabel( i18n("To view and edit the record data, please install a hex editor (e.g. khexedit from kdeutils)."), page );
00264 tmpW->setBackgroundMode( Qt::PaletteMid );
00265 tmpW->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter | Qt::WordBreak);
00266 tmpW->setFrameShape( QFrame::Panel );
00267 tmpW->setFrameShadow( QFrame::Sunken );
00268 hexEdit = tmpW;
00269 }
00270 layout->addMultiCellWidget( hexEdit, 3,3,0,1);
00271
00272 label=new QLabel(i18n("Entry on Handheld"), page);
00273 layout->addMultiCellWidget( label, 4,4,0,1);
00274
00275
00276 hexEdit = KHE::createBytesEditWidget( page, "SerialBufferEdit" );
00277 if( hexEdit )
00278 {
00279 KHE::BytesEditInterface* hexEditIf = KHE::bytesEditInterface( hexEdit );
00280 Q_ASSERT( hexEditIf );
00281 if( hexEditIf )
00282 {
00283 hexEditIf->setData( serialrec->data(), serialrec->size() );
00284
00285
00286 hexEditIf->setReadOnly( true );
00287 }
00288 }
00289 else
00290 {
00291 QLabel*tmpW = new QLabel( i18n("To view and edit the record data, please install a hex editor (e.g. khexedit from kdeutils)."), page );
00292 tmpW->setBackgroundMode( Qt::PaletteMid );
00293 tmpW->setAlignment( Qt::AlignHCenter | Qt::AlignVCenter | Qt::WordBreak);
00294 tmpW->setFrameShape( QFrame::Panel );
00295 tmpW->setFrameShadow( QFrame::Sunken );
00296 hexEdit = tmpW;
00297 }
00298 layout->addMultiCellWidget( hexEdit, 5,5,0,1);
00299 }
00300
00301 int res=resdlg->exec();
00302 KPILOT_DELETE(resdlg);
00303
00304 return res==KDialogBase::Accepted;
00305 }
00306
00307
00308 void InternalEditorAction::syncFlagsChangedDB()
00309 {
00310 FUNCTIONSETUP;
00311 if (fInternalEditorSyncStatus!=eSyncFlagsChangedDB)
00312 {
00313 fInternalEditorSyncStatus=eSyncFlagsChangedDB;
00314 dirtyDBs=KPilotSettings::flagsChangedDatabases();
00315 emit logMessage(i18n("Databases with changed flags: %1").arg(dirtyDBs.join(CSL1(", "))));
00316 dbIter=dirtyDBs.begin();
00317 }
00318 else
00319 {
00320 dbIter++;
00321 }
00322 if (dbIter==dirtyDBs.end())
00323 {
00324 KPilotSettings::setFlagsChangedDatabases(QStringList());
00325 KPilotConfig::sync();
00326 QTimer::singleShot(0, this, SLOT(syncAppBlockChangedDB()));
00327 return;
00328 }
00329
00330 #ifdef DEBUG
00331 DEBUGKPILOT<<"syncFlagsChangedDB for DB "<<(*dbIter)<<endl;
00332 #endif
00333 emit logError(i18n("Setting the database flags on the handheld is not yet supported."));
00334 QTimer::singleShot(0, this, SLOT(syncAppBlockChangedDB()));
00335 return;
00336
00337 PilotLocalDatabase*localDB=new PilotLocalDatabase(*dbIter, false);
00338 PilotDatabase *serialDB=deviceLink()->database(*dbIter);
00339
00340
00341
00342
00343
00344 KPILOT_DELETE(localDB);
00345 KPILOT_DELETE(serialDB);
00346 QTimer::singleShot(0, this, SLOT(syncAppBlockChangedDB()));
00347 }
00348
00349 void InternalEditorAction::syncAppBlockChangedDB()
00350 {
00351 FUNCTIONSETUP;
00352 if (fInternalEditorSyncStatus!=eSyncAppBlockChangedDB)
00353 {
00354 fInternalEditorSyncStatus=eSyncAppBlockChangedDB;
00355 dirtyDBs=KPilotSettings::appBlockChangedDatabases();
00356 emit logMessage(i18n("Databases with changed AppBlock: %1").arg(dirtyDBs.join(CSL1(", "))));
00357 dbIter=dirtyDBs.begin();
00358 }
00359 else
00360 {
00361 dbIter++;
00362 }
00363 if (dbIter==dirtyDBs.end())
00364 {
00365 KPilotSettings::setAppBlockChangedDatabases(QStringList());
00366 KPilotConfig::sync();
00367 QTimer::singleShot(0, this, SLOT(cleanup()));
00368 return;
00369 }
00370 #ifdef DEBUG
00371 DEBUGKPILOT<<"syncAppBlockChangedDB for DB "<<(*dbIter)<<endl;
00372 #endif
00373
00374 PilotLocalDatabase*localDB=new PilotLocalDatabase(*dbIter, false);
00375 PilotDatabase *serialDB=deviceLink()->database(*dbIter);
00376
00377 unsigned char*appBlock=new unsigned char[0xFFFF];
00378 int len=localDB->readAppBlock(appBlock, 0xFFFF);
00379
00380 serialDB->writeAppBlock(appBlock, len);
00381
00382 KPILOT_DELETE(localDB);
00383 KPILOT_DELETE(serialDB);
00384 QTimer::singleShot(0, this, SLOT(syncAppBlockChangedDB()));
00385 }
00386
00387 void InternalEditorAction::cleanup()
00388 {
00389 FUNCTIONSETUP;
00390 fInternalEditorSyncStatus=eSyncFinished;
00391 emit syncDone(this);
00392 }
00393
00394 #include "internalEditorAction.moc"