kpilot

dbviewerWidget.cc

Go to the documentation of this file.
00001 /* dbViewerWidget.cc        KPilot
00002 **
00003 ** Copyright (C) 2003 by Dan Pilone.
00004 ** Copyright (C) 2003 Reinhold Kainhofer <reinhold@kainhofer.com>
00005 **  Written 2003 by Reinhold Kainhofer and Adriaan de Groot
00006 **
00007 ** This is the generic DB viewer widget.
00008 */
00009 
00010 /*
00011 ** This program is free software; you can redistribute it and/or modify
00012 ** it under the terms of the GNU General Public License as published by
00013 ** the Free Software Foundation; either version 2 of the License, or
00014 ** (at your option) any later version.
00015 **
00016 ** This program is distributed in the hope that it will be useful,
00017 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 ** GNU General Public License for more details.
00020 **
00021 ** You should have received a copy of the GNU General Public License
00022 ** along with this program in a file called COPYING; if not, write to
00023 ** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
00024 ** MA 02110-1301, USA.
00025 */
00026 
00027 /*
00028 ** Bug reports and questions can be sent to kde-pim@kde.org
00029 */
00030 
00031 
00032 #include "options.h"
00033 
00034 #include <unistd.h>
00035 #include <stdio.h>
00036 
00037 #include <pi-file.h>
00038 #include <pi-dlp.h>
00039 
00040 #include <qlayout.h>
00041 #include <qdir.h>
00042 #include <qregexp.h>
00043 #include <qlistview.h>
00044 
00045 #include <klistbox.h>
00046 #include <ktextedit.h>
00047 #include <kpushbutton.h>
00048 #include <kcombobox.h>
00049 #include <kmessagebox.h>
00050 
00051 #include "listCat.h"
00052 #include "listItems.h"
00053 
00054 #include "dbviewerWidget.h"
00055 #include "pilotLocalDatabase.h"
00056 #include "pilotDatabase.h"
00057 #include "pilotRecord.h"
00058 #include "dbFlagsEditor.h"
00059 #include "dbRecordEditor.h"
00060 #include "dbAppInfoEditor.h"
00061 #include "kpilotConfig.h"
00062 
00063 
00064 #include "dbviewerWidget.moc"
00065 
00066 
00067 GenericDBWidget::GenericDBWidget(QWidget *parent, const QString &dbpath) :
00068     PilotComponent(parent,"component_generic",dbpath), fDB(0L)
00069 {
00070     FUNCTIONSETUP;
00071     setupWidget();
00072     fRecList.setAutoDelete(true);
00073 }
00074 
00075 
00076 void GenericDBWidget::setupWidget()
00077 {
00078     QGridLayout *g = new QGridLayout( this, 1, 1, SPACING);
00079 
00080     fDBList = new KListBox( this );
00081     g->addWidget( fDBList, 0, 0 );
00082     fDBType = new KComboBox( FALSE, this );
00083     g->addWidget( fDBType, 1, 0 );
00084     fDBType->insertItem( i18n( "All Databases" ) );
00085     fDBType->insertItem( i18n( "Only Applications (*.prc)" ) );
00086     fDBType->insertItem( i18n( "Only Databases (*.pdb)" ) );
00087 
00088     QGridLayout *g1 = new QGridLayout( 0, 1, 1);
00089     fDBInfo = new KTextEdit( this );
00090     fDBInfo->setSizePolicy( QSizePolicy( (QSizePolicy::SizeType)3, (QSizePolicy::SizeType)0, 0, 0, fDBInfo->sizePolicy().hasHeightForWidth() ) );
00091     fDBInfo->setReadOnly( TRUE );
00092     g1->addWidget( fDBInfo, 0, 0 );
00093     fDBInfoButton = new KPushButton( i18n( "General Database &Information" ), this );
00094     g1->addWidget( fDBInfoButton, 1, 0 );
00095     fAppInfoButton = new KPushButton( i18n( "&Application Info Block (Categories etc.)" ), this );
00096     g1->addWidget( fAppInfoButton, 2, 0 );
00097 
00098     QGridLayout *g2 = new QGridLayout( 0, 1, 1);
00099     fRecordList = new KListView( this );
00100     g2->addMultiCellWidget( fRecordList, 0, 0, 0, 2 );
00101     fRecordList->addColumn(i18n("Rec. Nr."));
00102     fRecordList->addColumn(i18n("Length"));
00103     fRecordList->addColumn(i18n("Record ID"));
00104     fRecordList->setAllColumnsShowFocus(true);
00105     fRecordList->setResizeMode( KListView::LastColumn );
00106     fRecordList->setFullWidth( TRUE );
00107     fRecordList->setItemsMovable( FALSE );
00108 
00109     fAddRecord = new KPushButton( i18n("&Add..."), this );
00110     g2->addWidget( fAddRecord, 1, 0 );
00111     fEditRecord = new KPushButton( i18n("&Edit..."), this );
00112     g2->addWidget( fEditRecord, 1, 1 );
00113     fDeleteRecord = new KPushButton( i18n("&Delete"), this );
00114     g2->addWidget( fDeleteRecord, 1, 2 );
00115 
00116     g1->addLayout( g2, 3, 0 );
00117 
00118 
00119     g->addMultiCellLayout( g1, 0, 1, 1, 1 );
00120     resize( QSize(682, 661).expandedTo(minimumSizeHint()) );
00121 
00122     connect(fDBList, SIGNAL(highlighted(const QString &)),
00123         this, SLOT(slotSelected(const QString &)));
00124     connect(fDBType, SIGNAL(activated(int)),
00125         this, SLOT(slotDBType(int)));
00126     connect(fDBInfoButton,  SIGNAL(clicked()),
00127         this, SLOT(slotShowDBInfo()));
00128     connect(fAppInfoButton,  SIGNAL(clicked()),
00129         this, SLOT(slotShowAppInfo()));
00130     connect(fAddRecord,  SIGNAL(clicked()),
00131         this, SLOT(slotAddRecord()));
00132     connect(fEditRecord,  SIGNAL(clicked()),
00133         this, SLOT(slotEditRecord()));
00134     connect(fDeleteRecord,  SIGNAL(clicked()),
00135         this, SLOT(slotDeleteRecord()));
00136     connect(fRecordList, SIGNAL(executed(QListViewItem*)),
00137         this, SLOT(slotEditRecord(QListViewItem*)));
00138 
00139 }
00140 
00141 GenericDBWidget::~GenericDBWidget()
00142 {
00143     FUNCTIONSETUP;
00144     if (fDB) KPILOT_DELETE(fDB);
00145 }
00146 
00147 
00148 void GenericDBWidget::showComponent()
00149 {
00150     FUNCTIONSETUP;
00151     fDBInfo->setText(QString::null);
00152     slotDBType(0);
00153 
00154     fDBList->show();
00155     fDBInfo->show();
00156 }
00157 
00158 void GenericDBWidget::hideComponent()
00159 {
00160     reset();
00161 }
00162 
00163 void GenericDBWidget::slotSelected(const QString &dbname)
00164 {
00165     FUNCTIONSETUP;
00166 #ifdef DEBUG
00167     DEBUGKPILOT << fname << ": Selected DB " << dbname << endl;
00168 #endif
00169     struct DBInfo dbinfo;
00170     QString display;
00171     fRecList.clear();
00172     fRecordList->clear();
00173 
00174     if (fDB) KPILOT_DELETE(fDB);
00175     currentDB=dbname;
00176 
00177     if (!shown) return;
00178 
00179     if (dbname.endsWith(CSL1(".pdb")) || dbname.endsWith(CSL1(".PDB")))
00180     {
00181         // We are dealing with a database
00182         currentDBtype=eDatabase;
00183 
00184         currentDB.remove( QRegExp(CSL1(".(pdb|PDB)$")) );
00185 
00186         fDB=new PilotLocalDatabase(dbPath(), currentDB, false);
00187         if (!fDB || !fDB->isOpen())
00188         {
00189             fDBInfo->setText(i18n("<B>Warning:</B> Cannot read "
00190                 "database file %1.").arg(currentDB));
00191             return;
00192         }
00193         dbinfo=fDB->getDBInfo();
00194         display.append(i18n("<B>Database:</B> %1, %2 records<BR>")
00195             .arg(QString::fromLatin1(dbinfo.name)).arg(fDB->recordCount()));
00196         char buff[5];
00197         set_long(buff, dbinfo.type);
00198         buff[4]='\0';
00199         QString tp = QString::fromLatin1(buff);
00200         set_long(buff, dbinfo.creator);
00201         buff[4]='\0';
00202         QString cr = QString::fromLatin1(buff);
00203         display.append(i18n("<B>Type:</B> %1, <B>Creator:</B> %2<br><br>").arg(tp).arg(cr));
00204 
00205         int currentRecord = 0;
00206         PilotRecord *pilotRec;
00207 
00208 #ifdef DEBUG
00209         DEBUGKPILOT << fname << ": Reading database "<<dbname<<"..." << endl;
00210 #endif
00211 
00212         while ((pilotRec = fDB->readRecordByIndex(currentRecord)) != 0L)
00213         {
00214 //          if (!(pilotRec->isDeleted()) )
00215             {
00216                 PilotListViewItem*item=new PilotListViewItem(fRecordList,
00217                     QString::number(currentRecord), QString::number(pilotRec->size()),
00218                     QString::number(pilotRec->id()),
00219                     QString::null,
00220                     pilotRec->id(), pilotRec);
00221                 item->setNumericCol(0, true);
00222                 item->setNumericCol(1, true);
00223                 item->setNumericCol(2, true);
00224             }
00225             fRecList.append(pilotRec);
00226 
00227             currentRecord++;
00228         }
00229 
00230 #ifdef DEBUG
00231         DEBUGKPILOT << fname
00232             << ": Total " << currentRecord << " records" << endl;
00233 #endif
00234 
00235     }
00236     else
00237     {
00238         // we are dealing with an application
00239         currentDBtype=eApplication;
00240 
00241         QCString filename = QFile::encodeName(dbPath() + CSL1("/") + dbname);
00242         const char *s = filename;
00243         struct pi_file *pf = pi_file_open(const_cast<char *>(s));
00244         if (!pf)
00245         {
00246             fDBInfo->setText(i18n("<B>Warning:</B> Cannot read "
00247                 "application file %1.").arg(dbname));
00248             return;
00249         }
00250 #if PILOT_LINK_NUMBER < PILOT_LINK_0_12_0
00251         if (pi_file_get_info(pf,&dbinfo))
00252         {
00253             fDBInfo->setText(i18n("<B>Warning:</B> Cannot read "
00254                 "application file %1.").arg(dbname));
00255             return;
00256         }
00257 #else
00258         pi_file_get_info(pf,&dbinfo);
00259 #endif
00260         display.append(i18n("<B>Application:</B> %1<BR><BR>").arg(dbname));
00261     }
00262     enableWidgets(currentDBtype==eDatabase);
00263 
00264     QDateTime ttime;
00265 
00266     ttime.setTime_t(dbinfo.createDate);
00267     display.append(i18n("Created: %1<BR>").arg(ttime.toString()));
00268 
00269     ttime.setTime_t(dbinfo.modifyDate);
00270     display.append(i18n("Modified: %1<BR>").arg(ttime.toString()));
00271 
00272     ttime.setTime_t(dbinfo.backupDate);
00273     display.append(i18n("Backed up: %1<BR>").arg(ttime.toString()));
00274 
00275     fDBInfo->setText(display);
00276 }
00277 
00278 void GenericDBWidget::slotDBType(int mode)
00279 {
00280     FUNCTIONSETUP;
00281     if (!shown) return;
00282 
00283     reset();
00284 
00285     QDir dir(dbPath());
00286     switch (mode)
00287     {
00288         case 1:
00289             dir.setNameFilter(CSL1("*.prc")); break;
00290         case 2:
00291             dir.setNameFilter(CSL1("*.pdb")); break;
00292         case 0:
00293         default:
00294             dir.setNameFilter(CSL1("*.pdb;*.prc")); break;
00295     }
00296     QStringList l = dir.entryList();
00297     fDBList->insertStringList(l);
00298 }
00299 
00300 void GenericDBWidget::reset()
00301 {
00302     FUNCTIONSETUP;
00303     fDBList->clear();
00304     fDBInfo->clear();
00305     fRecordList->clear();
00306     if (fDB)  KPILOT_DELETE(fDB);
00307     currentDB=QString::null;
00308 }
00309 
00310 void GenericDBWidget::slotAddRecord()
00311 {
00312     FUNCTIONSETUP;
00313     pi_buffer_t *b = pi_buffer_new(0);
00314     PilotRecord *rec=new PilotRecord(b, 0, 0, 0);
00315     PilotListViewItem*item=new PilotListViewItem(fRecordList,
00316         QString::number(-1), QString::number(rec->size()),
00317         QString::number(rec->id()), QString::null,
00318         rec->id(), rec);
00319     if (slotEditRecord(item))
00320     {
00321         fRecList.append(rec);
00322     }
00323     else
00324     {
00325         KPILOT_DELETE(item);
00326         KPILOT_DELETE(rec);
00327     }
00328 }
00329 
00330 bool GenericDBWidget::slotEditRecord(QListViewItem*item)
00331 {
00332     FUNCTIONSETUP;
00333     PilotListViewItem*currRecItem=dynamic_cast<PilotListViewItem*>(item);
00334     if (currRecItem)
00335     {
00336         PilotRecord*rec=(PilotRecord*)currRecItem->rec();
00337         int nr=currRecItem->text(0).toInt();
00338         DBRecordEditor*dlg=new DBRecordEditor(rec, nr, this);
00339         if (dlg->exec())
00340         {
00341             currRecItem->setText(1, QString::number(rec->size()));
00342             currRecItem->setText(2, QString::number(rec->id()));
00343             fRecordList->triggerUpdate();
00344             writeRecord(rec);
00345             KPILOT_DELETE(dlg);
00346             return true;
00347         }
00348         KPILOT_DELETE(dlg);
00349     }
00350     else
00351     {
00352         // Either nothing selected, or some error occurred...
00353         KMessageBox::information(this, i18n("You must select a record for editing."), i18n("No Record Selected"), CSL1("norecordselected"));
00354     }
00355     return false;
00356 }
00357 void GenericDBWidget::slotEditRecord()
00358 {
00359     slotEditRecord(fRecordList->selectedItem());
00360 }
00361 
00362 void GenericDBWidget::slotDeleteRecord()
00363 {
00364     FUNCTIONSETUP;
00365     PilotListViewItem*currRecItem=dynamic_cast<PilotListViewItem*>(fRecordList->selectedItem());
00366     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"), KStdGuiItem::del(), KStdGuiItem::cancel())==KMessageBox::Yes) )
00367     {
00368         PilotRecord*rec=(PilotRecord*)currRecItem->rec();
00369         rec->setDeleted();
00370         writeRecord(rec);
00371         // fRecordList->triggerUpdate();
00372         KPILOT_DELETE(currRecItem);
00373     }
00374 }
00375 
00376 void GenericDBWidget::slotShowAppInfo()
00377 {
00378     FUNCTIONSETUP;
00379     if (!fDB) return;
00380     char*appBlock=new char[0xFFFF];
00381     int len=fDB->readAppBlock((unsigned char*)appBlock, 0xFFFF);
00382     DBAppInfoEditor*dlg=new DBAppInfoEditor(appBlock, len, this);
00383     if (dlg->exec())
00384     {
00385         fDB->writeAppBlock( (unsigned char*)(dlg->appInfo), dlg->len );
00386 
00387         KPilotConfig::addAppBlockChangedDatabase(getCurrentDB());
00388         KPilotSettings::writeConfig();
00389     }
00390     KPILOT_DELETE(dlg);
00391     delete[] appBlock;
00392 }
00393 
00394 void GenericDBWidget::slotShowDBInfo()
00395 {
00396     FUNCTIONSETUP;
00397     if ( !fDB || !shown ) return;
00398     DBInfo db=fDB->getDBInfo();
00399     DBFlagsEditor*dlg=new DBFlagsEditor(&db, this);
00400     if (dlg->exec())
00401     {
00402 #ifdef DEBUG
00403         DEBUGKPILOT<<"OK pressed, assiging DBInfo, flags="<<
00404             db.flags<<",  miscFlag="<<db.miscFlags<<endl;
00405 #endif
00406         fDB->setDBInfo(db);
00407 
00408         KPilotConfig::addFlagsChangedDatabase(getCurrentDB());
00409         KPilotSettings::writeConfig();
00410 
00411         slotSelected(fDBList->currentText());
00412     }
00413     KPILOT_DELETE(dlg);
00414 }
00415 
00416 void GenericDBWidget::enableWidgets(bool enable)
00417 {
00418     //FUNCTIONSETUP;
00419     fDBInfoButton->setEnabled(enable);
00420     fAppInfoButton->setEnabled(enable);
00421     fRecordList->setEnabled(enable);
00422     fAddRecord->setEnabled(enable);
00423     fEditRecord->setEnabled(enable);
00424     fDeleteRecord->setEnabled(enable);
00425 }
00426 
00427 void GenericDBWidget::writeRecord(PilotRecord*r)
00428 {
00429     // FUNCTIONSETUP;
00430     if (fDB && r)
00431     {
00432         fDB->writeRecord(r);
00433         markDBDirty(getCurrentDB());
00434     }
00435 }
00436 
00437 
00438 
00439 
00440