kpilot Library API Documentation

addressWidget.cc

00001 /* addressWidget.cc KPilot 00002 ** 00003 ** Copyright (C) 1998-2001 by Dan Pilone 00004 ** 00005 ** This file defines the addressWidget, that part of KPilot that 00006 ** displays address records from the Pilot. 00007 */ 00008 00009 /* 00010 ** This program is free software; you can redistribute it and/or modify 00011 ** it under the terms of the GNU General Public License as published by 00012 ** the Free Software Foundation; either version 2 of the License, or 00013 ** (at your option) any later version. 00014 ** 00015 ** This program is distributed in the hope that it will be useful, 00016 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00017 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00018 ** GNU General Public License for more details. 00019 ** 00020 ** You should have received a copy of the GNU General Public License 00021 ** along with this program in a file called COPYING; if not, write to 00022 ** the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 00023 ** MA 02111-1307, USA. 00024 */ 00025 00026 /* 00027 ** Bug reports and questions can be sent to kde-pim@kde.org 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 // This is the size of several (automatic) buffers, 00069 // used to retrieve data from the database. 00070 // I have no idea if 0xffff is some magic number or not. 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 /* NOTREACHED */ 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 /* virtual */ 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 // address info text view 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 // FUNCTIONSETUP; 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()) // One last try 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 /* slot */ 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 // Response to bug 18072: Don't even try to 00455 // add records to an empty or unopened database, 00456 // since we don't have the DBInfo stuff to deal with it. 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 // TODO: Just add the new record to the lists 00512 updateWidget(); 00513 00514 // k holds the item number of the address just added. 00515 // 00516 // 00517 int k = fListBox->count() - 1; 00518 00519 fListBox->setCurrentItem(k); // Show the newest one 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 // TODO: Just change the record 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 // Open a database (myDB) only if needed, 00620 // i.e. only if the passed-in addressDB 00621 // isn't valid. 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 // Still no valid address database... 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 // Do the actual work. 00647 PilotRecord *pilotRec = which->pack(); 00648 00649 myDB->writeRecord(pilotRec); 00650 markDBDirty("AddressDB"); 00651 delete pilotRec; 00652 00653 // Clean up in the case that we allocated our own DB. 00654 // 00655 // 00656 if (usemyDB) 00657 { 00658 KPILOT_DELETE( myDB ); 00659 } 00660 } 00661
KDE Logo
This file is part of the documentation for kpilot Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:57:48 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003