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