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 static const char *addresswidget_id =
00030 "$Id: addressWidget.cc,v 1.64 2003/10/13 13:58:19 kainhofe Exp $";
00031
00032
00033
00034 #ifndef _KPILOT_OPTIONS_H
00035 #include "options.h"
00036 #endif
00037
00038 #include <iostream>
00039 #include <cstring>
00040 #include <cstdlib>
00041
00042 #include <qptrlist.h>
00043 #include <qlistbox.h>
00044 #include <qfile.h>
00045 #include <qpushbutton.h>
00046 #include <qtextstream.h>
00047 #include <qlayout.h>
00048 #include <qlabel.h>
00049 #include <qmultilineedit.h>
00050 #include <qcombobox.h>
00051 #include <qwhatsthis.h>
00052 #include <qtextview.h>
00053 #include <qtextcodec.h>
00054 #include <qregexp.h>
00055
00056 #include <kapplication.h>
00057 #include <kmessagebox.h>
00058 #include <kdebug.h>
00059 #include <kfiledialog.h>
00060
00061 #include "kpilotConfig.h"
00062 #include "listItems.h"
00063 #include "addressEditor.h"
00064 #include "pilotLocalDatabase.h"
00065
00066 #include "addressWidget.moc"
00067
00068
00069
00070
00071
00072
00073 #define BUFFERSIZE (0xffff)
00074
00075 AddressWidget::AddressWidget(QWidget * parent,
00076 const QString & path) :
00077 PilotComponent(parent, "component_address", path),
00078 fAddrInfo(0),
00079 fPendingAddresses(0)
00080 {
00081 FUNCTIONSETUP;
00082
00083 setupWidget();
00084 fAddressList.setAutoDelete(true);
00085
00086
00087 (void) addresswidget_id;
00088 }
00089
00090 AddressWidget::~AddressWidget()
00091 {
00092 FUNCTIONSETUP;
00093 }
00094
00095 int AddressWidget::getAllAddresses(PilotDatabase * addressDB)
00096 {
00097 FUNCTIONSETUP;
00098
00099 int currentRecord = 0;
00100 PilotRecord *pilotRec;
00101 PilotAddress *address;
00102 bool showSecrets = KPilotConfig::getConfig().getShowSecrets();
00103
00104
00105 #ifdef DEBUG
00106 DEBUGKPILOT << fname << ": Reading AddressDB..." << endl;
00107 #endif
00108
00109 while ((pilotRec = addressDB->readRecordByIndex(currentRecord)) != 0L)
00110 {
00111 if (!(pilotRec->isDeleted()) &&
00112 (!(pilotRec->isSecret()) || showSecrets))
00113 {
00114 address = new PilotAddress(fAddressAppInfo, pilotRec);
00115 if (address == 0L)
00116 {
00117 kdWarning() << k_funcinfo
00118 << ": Couldn't allocate record "
00119 << currentRecord++
00120 << endl;
00121 break;
00122 }
00123 fAddressList.append(address);
00124 }
00125 delete pilotRec;
00126
00127 currentRecord++;
00128 }
00129
00130 #ifdef DEBUG
00131 DEBUGKPILOT << fname
00132 << ": Total " << currentRecord << " records" << endl;
00133 #endif
00134
00135 return currentRecord;
00136 }
00137
00138 void AddressWidget::showComponent()
00139 {
00140 FUNCTIONSETUP;
00141 if ( fPendingAddresses>0 ) return;
00142
00143 #ifdef DEBUG
00144 DEBUGKPILOT << fname
00145 << ": Reading from directory " << dbPath() << endl;
00146 #endif
00147
00148 PilotDatabase *addressDB =
00149 new PilotLocalDatabase(dbPath(), CSL1("AddressDB"));
00150 unsigned char buffer[BUFFERSIZE];
00151 int appLen;
00152
00153 fAddressList.clear();
00154
00155 if (addressDB->isDBOpen())
00156 {
00157 appLen = addressDB->readAppBlock(buffer, BUFFERSIZE);
00158 unpack_AddressAppInfo(&fAddressAppInfo, buffer, appLen);
00159
00160 populateCategories(fCatList, &fAddressAppInfo.category);
00161 getAllAddresses(addressDB);
00162
00163 }
00164 else
00165 {
00166 populateCategories(fCatList, 0L);
00167 kdWarning() << k_funcinfo
00168 << ": Could not open local AddressDB" << endl;
00169 }
00170
00171 KPILOT_DELETE( addressDB );
00172
00173 updateWidget();
00174 }
00175
00176 void AddressWidget::hideComponent()
00177 {
00178 FUNCTIONSETUP;
00179 if (fPendingAddresses==0 )
00180 {
00181 fAddressList.clear();
00182 fListBox->clear();
00183
00184 updateWidget();
00185 }
00186 }
00187
00188 bool AddressWidget::preHotSync(QString &s)
00189 {
00190 FUNCTIONSETUP;
00191
00192 if ( fPendingAddresses )
00193 {
00194 #ifdef DEBUG
00195 DEBUGKPILOT << fname
00196 << ": fPendingAddress="
00197 << fPendingAddresses
00198 << endl;
00199 #endif
00200
00201 #if KDE_VERSION<220
00202 s = i18n("There are still %1 address editing windows open.")
00203 .arg(QString::number(fPendingAddresses));
00204 #else
00205 s = i18n("There is still an address editing window open.",
00206 "There are still %n address editing windows open.",
00207 fPendingAddresses);
00208 #endif
00209 return false;
00210 }
00211
00212 return true;
00213 }
00214
00215 void AddressWidget::postHotSync()
00216 {
00217 FUNCTIONSETUP;
00218
00219 if ( shown )
00220 {
00221 fAddressList.clear();
00222 showComponent();
00223 }
00224 }
00225
00226
00227 void AddressWidget::setupWidget()
00228 {
00229 FUNCTIONSETUP;
00230
00231 QLabel *label;
00232 QGridLayout *grid = new QGridLayout(this, 6, 4, SPACING);
00233
00234 fCatList = new QComboBox(this);
00235 grid->addWidget(fCatList, 0, 1);
00236 connect(fCatList, SIGNAL(activated(int)),
00237 this, SLOT(slotSetCategory(int)));
00238 QWhatsThis::add(fCatList,
00239 i18n("<qt>Select the category of addresses to display here.</qt>"));
00240
00241 label = new QLabel(i18n("Category:"), this);
00242 label->setBuddy(fCatList);
00243 grid->addWidget(label, 0, 0);
00244
00245 fListBox = new QListBox(this);
00246 grid->addMultiCellWidget(fListBox, 1, 1, 0, 1);
00247 connect(fListBox, SIGNAL(highlighted(int)),
00248 this, SLOT(slotShowAddress(int)));
00249 connect(fListBox, SIGNAL(selected(int)),
00250 this, SLOT(slotEditRecord()));
00251 QWhatsThis::add(fListBox,
00252 i18n("<qt>This list displays all the addresses "
00253 "in the selected category. Click on "
00254 "one to display it to the right.</qt>"));
00255
00256 label = new QLabel(i18n("Address info:"), this);
00257 grid->addWidget(label, 0, 2);
00258
00259
00260 fAddrInfo = new QTextView(this);
00261 grid->addMultiCellWidget(fAddrInfo, 1, 4, 2, 2);
00262
00263 QPushButton *button;
00264
00265 fEditButton = new QPushButton(i18n("Edit Record..."), this);
00266 grid->addWidget(fEditButton, 2, 0);
00267 connect(fEditButton, SIGNAL(clicked()), this, SLOT(slotEditRecord()));
00268 QWhatsThis::add(fEditButton,
00269 i18n("<qt>You can edit an address when it is selected.</qt>"));
00270
00271 button = new QPushButton(i18n("New Record..."), this);
00272 grid->addWidget(button, 2, 1);
00273 connect(button, SIGNAL(clicked()), this, SLOT(slotCreateNewRecord()));
00274 QWhatsThis::add(button, i18n("<qt>Add a new address to the address book.</qt>"));
00275
00276 fDeleteButton = new QPushButton(i18n("Delete Record"), this);
00277 grid->addWidget(fDeleteButton, 3, 0);
00278 connect(fDeleteButton, SIGNAL(clicked()),
00279 this, SLOT(slotDeleteRecord()));
00280 QWhatsThis::add(fDeleteButton,
00281 i18n("<qt>Delete the selected address from the address book.</qt>"));
00282 }
00283
00284 void AddressWidget::updateWidget()
00285 {
00286 FUNCTIONSETUP;
00287
00288 int addressDisplayMode =
00289 KPilotConfig::getConfig().setAddressGroup().
00290 getAddressDisplayMode();
00291
00292 int listIndex = 0;
00293
00294 #ifdef DEBUG
00295 DEBUGKPILOT << fname
00296 << ": Display Mode=" << addressDisplayMode << endl;
00297 #endif
00298
00299 int currentCatID = findSelectedCategory(fCatList,
00300 &(fAddressAppInfo.category));
00301
00302 fListBox->clear();
00303 fAddressList.first();
00304
00305 #ifdef DEBUG
00306 DEBUGKPILOT << fname << ": Adding records..." << endl;
00307 #endif
00308
00309 while (fAddressList.current())
00310 {
00311 if ((currentCatID == -1) ||
00312 (fAddressList.current()->getCat() == currentCatID))
00313 {
00314 QString title = createTitle(fAddressList.current(),
00315 addressDisplayMode);
00316
00317 if (!title.isEmpty())
00318 {
00319 title.remove(QRegExp("\n.*"));
00320 PilotListItem *p = new PilotListItem(title,
00321 listIndex,
00322 fAddressList.current());
00323
00324 fListBox->insertItem(p);
00325 }
00326 }
00327 listIndex++;
00328 fAddressList.next();
00329 }
00330
00331 #ifdef DEBUG
00332 DEBUGKPILOT << fname << ": " << listIndex << " records" << endl;
00333 #endif
00334
00335 slotUpdateButtons();
00336 }
00337
00338
00339
00340 QString AddressWidget::createTitle(PilotAddress * address, int displayMode)
00341 {
00342
00343
00344 QString title;
00345
00346 switch (displayMode)
00347 {
00348 case 1:
00349 if (!address->getField(entryCompany).isEmpty())
00350 {
00351 title.append(address->getField(entryCompany));
00352 }
00353 if (!address->getField(entryLastname).isEmpty())
00354 {
00355 if (!title.isEmpty())
00356 {
00357 title.append( CSL1(", "));
00358 }
00359
00360 title.append(address->getField(entryLastname));
00361 }
00362 break;
00363 case 0:
00364 default:
00365 if (!address->getField(entryLastname).isEmpty())
00366 {
00367 title.append(address->getField(entryLastname));
00368 }
00369
00370 if (!address->getField(entryFirstname).isEmpty())
00371 {
00372 if (!title.isEmpty())
00373 {
00374 title.append( CSL1(", "));
00375 }
00376 title.append(address->getField(entryFirstname));
00377 }
00378 break;
00379 }
00380
00381 if (title.isEmpty())
00382 {
00383 if (!fAddressList.current()->getField(entryCompany).isEmpty())
00384 {
00385 title.append(fAddressList.current()->
00386 getField(entryCompany));
00387 }
00388 if (title.isEmpty())
00389 {
00390 title = i18n("[unknown]");
00391 }
00392 }
00393
00394 return title;
00395 }
00396
00397
00398 void AddressWidget::slotUpdateButtons()
00399 {
00400 FUNCTIONSETUP;
00401
00402 bool enabled = (fListBox->currentItem() != -1);
00403
00404 fEditButton->setEnabled(enabled);
00405 fDeleteButton->setEnabled(enabled);
00406 }
00407
00408 void AddressWidget::slotSetCategory(int)
00409 {
00410 FUNCTIONSETUP;
00411
00412 updateWidget();
00413 }
00414
00415 void AddressWidget::slotEditRecord()
00416 {
00417 FUNCTIONSETUP;
00418 if ( !shown ) return;
00419
00420 int item = fListBox->currentItem();
00421
00422 if (item == -1)
00423 return;
00424
00425 PilotListItem *p = (PilotListItem *) fListBox->item(item);
00426 PilotAddress *selectedRecord = (PilotAddress *) p->rec();
00427
00428 if (selectedRecord->id() == 0)
00429 {
00430 KMessageBox::error(0L,
00431 i18n("Cannot edit new records until "
00432 "HotSynced with Pilot."),
00433 i18n("HotSync Required"));
00434 return;
00435 }
00436
00437 AddressEditor *editor = new AddressEditor(selectedRecord,
00438 &fAddressAppInfo, this);
00439
00440 connect(editor, SIGNAL(recordChangeComplete(PilotAddress *)),
00441 this, SLOT(slotUpdateRecord(PilotAddress *)));
00442 connect(editor, SIGNAL(cancelClicked()),
00443 this, SLOT(slotEditCancelled()));
00444 editor->show();
00445
00446 fPendingAddresses++;
00447 }
00448
00449 void AddressWidget::slotCreateNewRecord()
00450 {
00451 FUNCTIONSETUP;
00452 if ( !shown ) return;
00453
00454
00455
00456
00457
00458
00459 PilotDatabase *myDB = new PilotLocalDatabase(dbPath(), CSL1("AddressDB"));
00460
00461 if (!myDB || !myDB->isDBOpen())
00462 {
00463 #ifdef DEBUG
00464 DEBUGKPILOT << fname
00465 << ": Tried to open "
00466 << dbPath()
00467 << "/AddressDB"
00468 << " and got pointer @"
00469 << (int) myDB
00470 << " with status "
00471 << ( myDB ? myDB->isDBOpen() : false )
00472 << endl;
00473 #endif
00474
00475 KMessageBox::sorry(this,
00476 i18n("You can't add addresses to the address book "
00477 "until you have done a HotSync at least once "
00478 "to retrieve the database layout from your Pilot."),
00479 i18n("Can't Add New Address"));
00480
00481 if (myDB)
00482 KPILOT_DELETE( myDB );
00483
00484 return;
00485 }
00486
00487 AddressEditor *editor = new AddressEditor(0L,
00488 &fAddressAppInfo, this);
00489
00490 connect(editor, SIGNAL(recordChangeComplete(PilotAddress *)),
00491 this, SLOT(slotAddRecord(PilotAddress *)));
00492 connect(editor, SIGNAL(cancelClicked()),
00493 this, SLOT(slotEditCancelled()));
00494 editor->show();
00495
00496 fPendingAddresses++;
00497 }
00498
00499 void AddressWidget::slotAddRecord(PilotAddress * address)
00500 {
00501 FUNCTIONSETUP;
00502 if ( !shown && fPendingAddresses==0 ) return;
00503
00504 int currentCatID = findSelectedCategory(fCatList,
00505 &(fAddressAppInfo.category), true);
00506
00507
00508 address->setCat(currentCatID);
00509 fAddressList.append(address);
00510 writeAddress(address);
00511
00512 updateWidget();
00513
00514
00515
00516
00517 int k = fListBox->count() - 1;
00518
00519 fListBox->setCurrentItem(k);
00520 fListBox->setBottomItem(k);
00521
00522 fPendingAddresses--;
00523 if ( !shown && fPendingAddresses==0 ) hideComponent();
00524 }
00525
00526 void AddressWidget::slotUpdateRecord(PilotAddress * address)
00527 {
00528 FUNCTIONSETUP;
00529 if ( !shown && fPendingAddresses==0 ) return;
00530
00531 writeAddress(address);
00532 int currentRecord = fListBox->currentItem();
00533
00534
00535 updateWidget();
00536 fListBox->setCurrentItem(currentRecord);
00537
00538 emit(recordChanged(address));
00539
00540 fPendingAddresses--;
00541 if ( !shown && fPendingAddresses==0 ) hideComponent();
00542 }
00543
00544 void AddressWidget::slotEditCancelled()
00545 {
00546 FUNCTIONSETUP;
00547
00548 fPendingAddresses--;
00549 if ( !shown && fPendingAddresses==0 ) hideComponent();
00550 }
00551
00552 void AddressWidget::slotDeleteRecord()
00553 {
00554 FUNCTIONSETUP;
00555 if ( !shown ) return;
00556
00557 int item = fListBox->currentItem();
00558
00559 if (item == -1)
00560 return;
00561
00562 PilotListItem *p = (PilotListItem *) fListBox->item(item);
00563 PilotAddress *selectedRecord = (PilotAddress *) p->rec();
00564
00565 if (selectedRecord->id() == 0)
00566 {
00567 KMessageBox::error(this,
00568 i18n("New records cannot be deleted until "
00569 "HotSynced with pilot."),
00570 i18n("HotSync Required"));
00571 return;
00572 }
00573
00574 if (KMessageBox::questionYesNo(this,
00575 i18n("Delete currently selected record?"),
00576 i18n("Delete Record?")) == KMessageBox::No)
00577 return;
00578
00579 selectedRecord->makeDeleted();
00580 writeAddress(selectedRecord);
00581 emit(recordChanged(selectedRecord));
00582 showComponent();
00583 }
00584
00585
00586
00587 void AddressWidget::slotShowAddress(int which)
00588 {
00589 FUNCTIONSETUP;
00590 if (!shown) return;
00591
00592 PilotListItem *p = (PilotListItem *) fListBox->item(which);
00593 PilotAddress *addr = (PilotAddress *) p->rec();
00594
00595 #ifdef DEBUG
00596 DEBUGKPILOT << fname
00597 << ": Showing "
00598 << addr->getField(entryLastname)
00599 << " "
00600 << addr->getField(entryFirstname)
00601 << endl;
00602 #endif
00603
00604 QString text(CSL1("<qt>"));
00605 text += addr->getTextRepresentation(true);
00606 text += CSL1("</qt>\n");
00607 fAddrInfo->setText(text);
00608
00609 slotUpdateButtons();
00610 }
00611
00612
00613
00614 void AddressWidget::writeAddress(PilotAddress * which,
00615 PilotDatabase * addressDB)
00616 {
00617 FUNCTIONSETUP;
00618
00619
00620
00621
00622
00623
00624 PilotDatabase *myDB = addressDB;
00625 bool usemyDB = false;
00626
00627 if (myDB == 0L || !myDB->isDBOpen())
00628 {
00629 myDB = new PilotLocalDatabase(dbPath(), CSL1("AddressDB"));
00630 usemyDB = true;
00631 }
00632
00633
00634
00635
00636 if (!myDB->isDBOpen())
00637 {
00638 #ifdef DEBUG
00639 DEBUGKPILOT << fname << ": Address database is not open" <<
00640 endl;
00641 #endif
00642 return;
00643 }
00644
00645
00646
00647 PilotRecord *pilotRec = which->pack();
00648
00649 myDB->writeRecord(pilotRec);
00650 markDBDirty("AddressDB");
00651 delete pilotRec;
00652
00653
00654
00655
00656 if (usemyDB)
00657 {
00658 KPILOT_DELETE( myDB );
00659 }
00660 }
00661