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 #include "options.h"
00032
00033 #include <pi-file.h>
00034 #include <pi-dlp.h>
00035
00036 #include <qlayout.h>
00037 #include <qdir.h>
00038 #include <qregexp.h>
00039 #include <qlistview.h>
00040
00041 #include <klistbox.h>
00042 #include <ktextedit.h>
00043 #include <kpushbutton.h>
00044 #include <kcombobox.h>
00045 #include <kmessagebox.h>
00046
00047 #include "listCat.h"
00048 #include "listItems.h"
00049
00050 #include "dbviewerWidget.h"
00051 #include "pilotLocalDatabase.h"
00052 #include "pilotDatabase.h"
00053 #include "pilotRecord.h"
00054 #include "dbFlagsEditor.h"
00055 #include "dbRecordEditor.h"
00056 #include "dbAppInfoEditor.h"
00057 #include "kpilotConfig.h"
00058
00059
00060 #include "dbviewerWidget.moc"
00061
00062
00063 GenericDBWidget::GenericDBWidget(QWidget *parent, const QString &dbpath) :
00064 PilotComponent(parent,"component_generic",dbpath), fDB(0L)
00065 {
00066 FUNCTIONSETUP;
00067 setupWidget();
00068 fRecList.setAutoDelete(true);
00069 }
00070
00071
00072 void GenericDBWidget::setupWidget()
00073 {
00074 QGridLayout *g = new QGridLayout( this, 1, 1, SPACING);
00075
00076 fDBList = new KListBox( this );
00077 g->addWidget( fDBList, 0, 0 );
00078 fDBType = new KComboBox( FALSE, this );
00079 g->addWidget( fDBType, 1, 0 );
00080 fDBType->insertItem( i18n( "All Databases" ) );
00081 fDBType->insertItem( i18n( "Only Applications (*.prc)" ) );
00082 fDBType->insertItem( i18n( "Only Databases (*.pdb)" ) );
00083
00084 QGridLayout *g1 = new QGridLayout( 0, 1, 1);
00085 fDBInfo = new KTextEdit( this );
00086 fDBInfo->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0, 0, 0, fDBInfo->sizePolicy().hasHeightForWidth() ) );
00087 fDBInfo->setReadOnly( TRUE );
00088 g1->addWidget( fDBInfo, 0, 0 );
00089 fDBInfoButton = new KPushButton( i18n( "General Database &Information..." ), this );
00090 g1->addWidget( fDBInfoButton, 1, 0 );
00091 fAppInfoButton = new KPushButton( i18n( "&Application Info Block (Categories etc.)" ), this );
00092 g1->addWidget( fAppInfoButton, 2, 0 );
00093
00094 QGridLayout *g2 = new QGridLayout( 0, 1, 1);
00095 fRecordList = new KListView( this );
00096 g2->addMultiCellWidget( fRecordList, 0, 0, 0, 2 );
00097 fRecordList->addColumn(i18n("Rec. Nr."));
00098 fRecordList->addColumn(i18n("Length"));
00099 fRecordList->addColumn(i18n("Record ID"));
00100 fRecordList->setAllColumnsShowFocus(true);
00101 fRecordList->setResizeMode( KListView::LastColumn );
00102 fRecordList->setFullWidth( TRUE );
00103 fRecordList->setItemsMovable( FALSE );
00104
00105 fAddRecord = new KPushButton( i18n("&Add..."), this );
00106 g2->addWidget( fAddRecord, 1, 0 );
00107 fEditRecord = new KPushButton( i18n("&Edit"), this );
00108 g2->addWidget( fEditRecord, 1, 1 );
00109 fDeleteRecord = new KPushButton( i18n("&Delete"), this );
00110 g2->addWidget( fDeleteRecord, 1, 2 );
00111
00112 g1->addLayout( g2, 3, 0 );
00113
00114
00115 g->addMultiCellLayout( g1, 0, 1, 1, 1 );
00116 resize( QSize(682, 661).expandedTo(minimumSizeHint()) );
00117
00118 connect(fDBList, SIGNAL(highlighted(const QString &)),
00119 this, SLOT(slotSelected(const QString &)));
00120 connect(fDBType, SIGNAL(activated(int)),
00121 this, SLOT(slotDBType(int)));
00122 connect(fDBInfoButton, SIGNAL(clicked()),
00123 this, SLOT(slotShowDBInfo()));
00124 connect(fAppInfoButton, SIGNAL(clicked()),
00125 this, SLOT(slotShowAppInfo()));
00126 connect(fAddRecord, SIGNAL(clicked()),
00127 this, SLOT(slotAddRecord()));
00128 connect(fEditRecord, SIGNAL(clicked()),
00129 this, SLOT(slotEditRecord()));
00130 connect(fDeleteRecord, SIGNAL(clicked()),
00131 this, SLOT(slotDeleteRecord()));
00132 connect(fRecordList, SIGNAL(executed(QListViewItem*)),
00133 this, SLOT(slotEditRecord(QListViewItem*)));
00134
00135 }
00136
00137 GenericDBWidget::~GenericDBWidget()
00138 {
00139 FUNCTIONSETUP;
00140 if (fDB) KPILOT_DELETE(fDB);
00141 }
00142
00143
00144 void GenericDBWidget::showComponent()
00145 {
00146 FUNCTIONSETUP;
00147 fDBInfo->setText(QString::null);
00148 slotDBType(0);
00149
00150 fDBList->show();
00151 fDBInfo->show();
00152 }
00153
00154 void GenericDBWidget::hideComponent()
00155 {
00156 reset();
00157 }
00158
00159 void GenericDBWidget::slotSelected(const QString &dbname)
00160 {
00161 FUNCTIONSETUP;
00162 #ifdef DEBUG
00163 DEBUGKPILOT << fname << ": Selected DB " << dbname << endl;
00164 #endif
00165 struct DBInfo dbinfo;
00166 QString display("");
00167 fRecList.clear();
00168 fRecordList->clear();
00169
00170 if (fDB) KPILOT_DELETE(fDB);
00171 currentDB=dbname;
00172
00173 if (!shown) return;
00174
00175 if (dbname.endsWith(".pdb") || dbname.endsWith(".PDB"))
00176 {
00177
00178 currentDBtype=eDatabase;
00179
00180 currentDB.remove( QRegExp(".(pdb|PDB)$") );
00181
00182 fDB=new PilotLocalDatabase(dbPath(), currentDB, false);
00183 if (!fDB || !fDB->isDBOpen())
00184 {
00185 fDBInfo->setText(i18n("<B>Warning:</B> Cannot read "
00186 "database file %1.").arg(currentDB));
00187 return;
00188 }
00189 dbinfo=fDB->getDBInfo();
00190 display.append(i18n("<B>Database:</B> %1, %2 records<BR>").arg(dbinfo.name).arg(fDB->recordCount()));
00191 char buff[5];
00192 set_long(buff, dbinfo.type);
00193 buff[4]='\0';
00194 QString tp(buff);
00195 set_long(buff, dbinfo.creator);
00196 buff[4]='\0';
00197 QString cr(buff);
00198 display.append(i18n("<B>Type:</B> %1, <B>Creator:</B> %2<br><br>").arg(tp).arg(cr));
00199
00200 int currentRecord = 0;
00201 PilotRecord *pilotRec;
00202
00203 #ifdef DEBUG
00204 DEBUGKPILOT << fname << ": Reading database "<<dbname<<"..." << endl;
00205 #endif
00206
00207 while ((pilotRec = fDB->readRecordByIndex(currentRecord)) != 0L)
00208 {
00209
00210 {
00211 PilotListViewItem*item=new PilotListViewItem(fRecordList,
00212 QString::number(currentRecord), QString::number(pilotRec->getLen()), QString::number(pilotRec->getID()), QString::null,
00213 pilotRec->getID(), pilotRec);
00214 item->setNumericCol(0, true);
00215 item->setNumericCol(1, true);
00216 item->setNumericCol(2, true);
00217 }
00218 fRecList.append(pilotRec);
00219
00220 currentRecord++;
00221 }
00222
00223 #ifdef DEBUG
00224 DEBUGKPILOT << fname
00225 << ": Total " << currentRecord << " records" << endl;
00226 #endif
00227
00228 }
00229 else
00230 {
00231
00232 currentDBtype=eApplication;
00233
00234 QCString filename = QFile::encodeName(dbPath() + CSL1("/") + dbname);
00235 const char *s = filename;
00236 struct pi_file *pf = pi_file_open(const_cast<char *>(s));
00237 if (!pf)
00238 {
00239 fDBInfo->setText(i18n("<B>Warning:</B> Cannot read "
00240 "application file %1.").arg(dbname));
00241 return;
00242 }
00243 if (pi_file_get_info(pf,&dbinfo))
00244 {
00245 fDBInfo->setText(i18n("<B>Warning:</B> Cannot read "
00246 "application file %1.").arg(dbname));
00247 return;
00248 }
00249 display.append(i18n("<B>Application:</B> %1<BR><BR>").arg(dbname));
00250 }
00251 enableWidgets(currentDBtype==eDatabase);
00252
00253 QDateTime ttime;
00254
00255 ttime.setTime_t(dbinfo.createDate);
00256 display.append(i18n("Created: %1<BR>").arg(ttime.toString()));
00257
00258 ttime.setTime_t(dbinfo.modifyDate);
00259 display.append(i18n("Modified: %1<BR>").arg(ttime.toString()));
00260
00261 ttime.setTime_t(dbinfo.backupDate);
00262 display.append(i18n("Backed up: %1<BR>").arg(ttime.toString()));
00263
00264 fDBInfo->setText(display);
00265 }
00266
00267 void GenericDBWidget::slotDBType(int mode)
00268 {
00269 FUNCTIONSETUP;
00270 if (!shown) return;
00271
00272 reset();
00273
00274 QDir dir(dbPath());
00275 switch (mode)
00276 {
00277 case 1:
00278 dir.setNameFilter(CSL1("*.prc")); break;
00279 case 2:
00280 dir.setNameFilter(CSL1("*.pdb")); break;
00281 case 0:
00282 default:
00283 dir.setNameFilter(CSL1("*.pdb;*.prc")); break;
00284 }
00285 QStringList l = dir.entryList();
00286 fDBList->insertStringList(l);
00287 }
00288
00289 void GenericDBWidget::reset()
00290 {
00291 FUNCTIONSETUP;
00292 fDBList->clear();
00293 fDBInfo->clear();
00294 fRecordList->clear();
00295 if (fDB) KPILOT_DELETE(fDB);
00296 currentDB=QString::null;
00297 }
00298
00299 void GenericDBWidget::slotAddRecord()
00300 {
00301 FUNCTIONSETUP;
00302 PilotRecord*rec=new PilotRecord(0L, 0, 0, 0, 0);
00303 PilotListViewItem*item=new PilotListViewItem(fRecordList,
00304 QString::number(-1), QString::number(rec->getLen()),
00305 QString::number(rec->getID()), QString::null,
00306 rec->getID(), rec);
00307 if (slotEditRecord(item))
00308 {
00309 fRecList.append(rec);
00310 }
00311 else
00312 {
00313 KPILOT_DELETE(item);
00314 KPILOT_DELETE(rec);
00315 }
00316 }
00317
00318 bool GenericDBWidget::slotEditRecord(QListViewItem*item)
00319 {
00320 FUNCTIONSETUP;
00321 PilotListViewItem*currRecItem=dynamic_cast<PilotListViewItem*>(item);
00322 if (currRecItem)
00323 {
00324 PilotRecord*rec=(PilotRecord*)currRecItem->rec();
00325 int nr=currRecItem->text(0).toInt();
00326 DBRecordEditor*dlg=new DBRecordEditor(rec, nr, this);
00327 if (dlg->exec())
00328 {
00329 currRecItem->setText(1, QString::number(rec->getLen()));
00330 currRecItem->setText(2, QString::number(rec->getID()));
00331 fRecordList->triggerUpdate();
00332 writeRecord(rec);
00333 KPILOT_DELETE(dlg);
00334 return true;
00335 }
00336 KPILOT_DELETE(dlg);
00337 }
00338 else
00339 {
00340
00341 KMessageBox::information(this, i18n("You must select a record for editing."), i18n("No record selected"), i18n("Do not show this message again"));
00342 }
00343 return false;
00344 }
00345 void GenericDBWidget::slotEditRecord()
00346 {
00347 slotEditRecord(fRecordList->selectedItem());
00348 }
00349
00350 void GenericDBWidget::slotDeleteRecord()
00351 {
00352 FUNCTIONSETUP;
00353 PilotListViewItem*currRecItem=dynamic_cast<PilotListViewItem*>(fRecordList->selectedItem());
00354 if (currRecItem && (KMessageBox::questionYesNo(this, i18n("<qt>Do you really want to delete the selected record? This cannot be undone.<br><br>Delete record?<qt>"), i18n("Deleting record"))==KMessageBox::Yes) )
00355 {
00356 PilotRecord*rec=(PilotRecord*)currRecItem->rec();
00357 rec->makeDeleted();
00358 writeRecord(rec);
00359
00360 KPILOT_DELETE(currRecItem);
00361 }
00362 }
00363
00364 void GenericDBWidget::slotShowAppInfo()
00365 {
00366 FUNCTIONSETUP;
00367 if (!fDB) return;
00368 char*appBlock=new char[0xFFFF];
00369 int len=fDB->readAppBlock((unsigned char*)appBlock, 0xFFFF);
00370 DBAppInfoEditor*dlg=new DBAppInfoEditor(appBlock, len, this);
00371 if (dlg->exec())
00372 {
00373 fDB->writeAppBlock( (unsigned char*)(dlg->appInfo), dlg->len );
00374
00375 KPilotConfigSettings &c=KPilotConfig::getConfig();
00376 c.setDatabaseGroup().addAppBlockChangedDatabase(getCurrentDB());
00377 c.sync();
00378 }
00379 KPILOT_DELETE(dlg);
00380 delete[] appBlock;
00381 }
00382
00383 void GenericDBWidget::slotShowDBInfo()
00384 {
00385 FUNCTIONSETUP;
00386 if ( !fDB || !shown ) return;
00387 DBInfo db=fDB->getDBInfo();
00388 DBFlagsEditor*dlg=new DBFlagsEditor(&db, this);
00389 if (dlg->exec())
00390 {
00391 #ifdef DEBUG
00392 DEBUGKPILOT<<"OK pressed, assiging DBInfo, flags="<<
00393 db.flags<<", miscFlag="<<db.miscFlags<<endl;
00394 #endif
00395 fDB->setDBInfo(db);
00396
00397 KPilotConfigSettings&c=KPilotConfig::getConfig();
00398 c.setDatabaseGroup().addFlagsChangedDatabase(getCurrentDB());
00399 c.sync();
00400
00401 slotSelected(fDBList->currentText());
00402 }
00403 KPILOT_DELETE(dlg);
00404 }
00405
00406 void GenericDBWidget::enableWidgets(bool enable)
00407 {
00408
00409 fDBInfoButton->setEnabled(enable);
00410 fAppInfoButton->setEnabled(enable);
00411 fRecordList->setEnabled(enable);
00412 fAddRecord->setEnabled(enable);
00413 fEditRecord->setEnabled(enable);
00414 fDeleteRecord->setEnabled(enable);
00415 }
00416
00417 void GenericDBWidget::writeRecord(PilotRecord*r)
00418 {
00419
00420 if (fDB && r)
00421 {
00422 fDB->writeRecord(r);
00423 markDBDirty(getCurrentDB());
00424 }
00425 }
00426
00427
00428
00429
00430