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