00001
00002
00003
00004
00005
00006 #include "kaddressbook.h"
00007 #include <kabc/vcardconverter.h>
00008
00009 #include <qkeycode.h>
00010 #include <qregexp.h>
00011 #include <qlayout.h>
00012
00013 #include <klocale.h>
00014 #include <kglobal.h>
00015 #include <kconfig.h>
00016 #include <kdebug.h>
00017 #include <kfiledialog.h>
00018 #include <kmessagebox.h>
00019 #include <kstatusbar.h>
00020 #include <kstandarddirs.h>
00021 #include <kprocess.h>
00022 #include <kapplication.h>
00023 #include <kprotocolinfo.h>
00024 #include <kprinter.h>
00025 #include <kabc/stdaddressbook.h>
00026 #include <kabc/distributionlistdialog.h>
00027 #include <kabc/distributionlist.h>
00028 #include <kabc/field.h>
00029 #include <kabc/resourceselectdialog.h>
00030
00031 #include "undo.h"
00032 #include "undocmds.h"
00033 #include "addresseeeditordialog.h"
00034 #include "filtereditdialog.h"
00035 #include "importdialog.h"
00036 #include "prefsdialog.h"
00037 #include "ldapsearchdialogimpl.h"
00038 #include "viewmanager.h"
00039 #include "printing/printingwizard.h"
00040 #include "filter.h"
00041 #include "incsearchwidget.h"
00042
00043 KAddressBook::KAddressBook( QWidget *parent, const char *name )
00044 : QWidget( parent, name )
00045 {
00046 QBoxLayout *topLayout = new QVBoxLayout( this );
00047
00048 mDocument = KABC::StdAddressBook::self();
00049 KABC::StdAddressBook::setAutomaticSave( false );
00050
00051 connect( mDocument, SIGNAL( addressBookChanged( AddressBook * ) ),
00052 SLOT( slotAddressBookChanged() ) );
00053
00054 mDocument->addCustomField( i18n("Department"), KABC::Field::Organization,
00055 "X-Department", "KADDRESSBOOK" );
00056 mDocument->addCustomField( i18n("Profession"), KABC::Field::Organization,
00057 "X-Profession", "KADDRESSBOOK" );
00058 mDocument->addCustomField( i18n("Assistant's Name"),
00059 KABC::Field::Organization,
00060 "X-AssistantsName", "KADDRESSBOOK" );
00061 mDocument->addCustomField( i18n("Manager's Name"),
00062 KABC::Field::Organization,
00063 "X-ManagersName", "KADDRESSBOOK" );
00064 mDocument->addCustomField( i18n("Spouse's Name"),
00065 KABC::Field::Personal,
00066 "X-SpousesName", "KADDRESSBOOK" );
00067 mDocument->addCustomField( i18n("Office"),
00068 KABC::Field::Personal,
00069 "X-Office", "KADDRESSBOOK" );
00070 mDocument->addCustomField( i18n("IM Address"),
00071 KABC::Field::Personal,
00072 "X-IMAddress", "KADDRESSBOOK" );
00073 mDocument->addCustomField( i18n("Anniversary"),
00074 KABC::Field::Personal,
00075 "X-Anniversary", "KADDRESSBOOK" );
00076
00077
00078 mViewManager = new ViewManager(mDocument, kapp->config(),
00079 this, "mViewManager");
00080 topLayout->addWidget(mViewManager);
00081 connect(mViewManager, SIGNAL(selected(const QString &)),
00082 SLOT(addresseeSelected(const QString &)));
00083 connect(mViewManager, SIGNAL(executed(const QString &)),
00084 SLOT(addresseeExecuted(const QString &)));
00085 connect(mViewManager, SIGNAL(modified()),
00086 SLOT(viewModified()));
00087 connect(mViewManager, SIGNAL(importVCard(const QString &, bool)),
00088 SLOT(importVCard(const QString &, bool)));
00089
00090 mPrefsDialog = 0;
00091 mLdapSearchDialog = 0;
00092 }
00093
00094
00095 void KAddressBook::newContact()
00096 {
00097 newAddressee();
00098 }
00099
00100 void KAddressBook::addEmail( QString aStr )
00101 {
00102
00103 QString fullName, email;
00104
00105 KABC::Addressee::parseEmailAddress(aStr, fullName, email);
00106
00107
00108 bool found = false;
00109 QStringList emailList;
00110 KABC::AddressBook::Iterator iter;
00111 for (iter = mDocument->begin(); !found && (iter != mDocument->end());
00112 ++iter)
00113 {
00114 emailList = (*iter).emails();
00115 if (emailList.contains(email) > 0)
00116 {
00117
00118
00119
00120 found = true;
00121 (*iter).setNameFromString(fullName);
00122 editAddressee((*iter).uid());
00123 }
00124 }
00125
00126 if (!found)
00127 {
00128
00129 KABC::Addressee a;
00130 a.setNameFromString(fullName);
00131 a.insertEmail(email, true);
00132
00133 mDocument->insertAddressee(a);
00134 mViewManager->refresh( a.uid() );
00135 editAddressee(a.uid());
00136 }
00137 }
00138
00139 ASYNC KAddressBook::showContactEditor ( QString uid )
00140 {
00141 editAddressee(uid);
00142 }
00143
00144 void KAddressBook::editAddressee(QString uid)
00145 {
00146 if ( mViewManager->isQuickEditVisible() ) {
00147 return;
00148 }
00149
00150
00151 if (uid == QString::null)
00152 {
00153 QStringList uidList = mViewManager->selectedUids();
00154 if (uidList.count() > 0)
00155 uid = *(uidList.at(0));
00156 }
00157
00158 KABC::Addressee a = mDocument->findByUid(uid);
00159 if (!a.isEmpty())
00160 {
00161 AddresseeEditorDialog *dialog = mEditorDict.find( a.uid() );
00162 if ( !dialog ) {
00163 dialog = createAddresseeEditorDialog( this );
00164
00165 mEditorDict.insert( a.uid(), dialog );
00166
00167 dialog->setAddressee(a);
00168 }
00169
00170 dialog->raise();
00171 dialog->show();
00172 }
00173 }
00174
00175 void KAddressBook::newAddressee()
00176 {
00177 AddresseeEditorDialog *dialog = 0;
00178
00179 KABC::Resource *resource = KABC::ResourceSelectDialog::getResource( mDocument,
00180 this );
00181 if ( resource ) {
00182 KABC::Addressee addr;
00183 addr.setResource( resource );
00184 dialog = createAddresseeEditorDialog( this );
00185 dialog->setAddressee( addr );
00186 } else {
00187 return;
00188 }
00189
00190 mEditorDict.insert( dialog->addressee().uid(), dialog );
00191
00192 dialog->show();
00193 }
00194
00195 AddresseeEditorDialog *KAddressBook::createAddresseeEditorDialog( QWidget *parent,
00196 const char *name )
00197 {
00198 AddresseeEditorDialog *dialog = new AddresseeEditorDialog( parent,
00199 name ? name : "editorDialog" );
00200 connect(dialog, SIGNAL(addresseeModified(const KABC::Addressee &)),
00201 SLOT(addresseeModified(const KABC::Addressee &)));
00202 connect(dialog, SIGNAL( editorDestroyed( const QString & ) ),
00203 SLOT( slotEditorDestroyed( const QString & ) ) );
00204
00205 return dialog;
00206 }
00207
00208 void KAddressBook::slotEditorDestroyed( const QString &uid )
00209 {
00210
00211 mEditorDict.remove( uid );
00212 }
00213
00214 void KAddressBook::save()
00215 {
00216 KABC::StdAddressBook *b = dynamic_cast<KABC::StdAddressBook*>(mDocument);
00217 if (!b || !b->save())
00218 {
00219 QString text = i18n("There was an error while attempting to save the "
00220 "address book. Please check that some other application is "
00221 "not using it. ");
00222
00223 KMessageBox::error(this, text, i18n("Unable to Save"));
00224 return;
00225 }
00226
00227 emit modified(false);
00228 }
00229
00230 void KAddressBook::readConfig()
00231 {
00232 mViewManager->readConfig();
00233 }
00234
00235 void KAddressBook::writeConfig()
00236 {
00237 mViewManager->writeConfig();
00238 }
00239
00240 KAddressBook::~KAddressBook()
00241 {
00242 writeConfig();
00243
00244 delete mDocument;
00245 }
00246
00247 void KAddressBook::undo()
00248 {
00249 UndoStack::instance()->undo();
00250
00251
00252 mViewManager->refresh();
00253 }
00254
00255 void KAddressBook::redo()
00256 {
00257 RedoStack::instance()->redo();
00258
00259
00260 mViewManager->refresh();
00261 }
00262
00263 void KAddressBook::importKDE2()
00264 {
00265 if (!QFile::exists(locateLocal("data", "kabc/std.vcf") )) {
00266 KMessageBox::sorry( this, i18n("Couldn't find a KDE 2 address book.") );
00267 return;
00268 }
00269
00270 int result = KMessageBox::questionYesNoCancel( this,
00271 i18n("Override previously imported entries?"),
00272 i18n("Import KDE 2 Addressbook"));
00273
00274 if ( !result ) return;
00275
00276 KProcess proc;
00277
00278 if ( result == KMessageBox::Yes ) {
00279 proc << "kab2kabc";
00280 proc << "--override";
00281 } else if ( result == KMessageBox::No ) {
00282 proc << "kab2kabc";
00283 } else {
00284 kdDebug() << "KAddressBook::importKDE2(): Unknow return value." << endl;
00285 }
00286
00287 proc.start( KProcess::Block );
00288
00289 mDocument->load();
00290 mViewManager->refresh();
00291 }
00292
00293 void KAddressBook::importCSV()
00294 {
00295
00296 ContactImportDialog *dialog = new ContactImportDialog(mDocument, this);
00297
00298 if ( dialog->exec() )
00299 mViewManager->refresh();
00300 delete dialog;
00301
00302 emit modified( true );
00303 }
00304
00305 void KAddressBook::importVCardSimple()
00306 {
00307 importVCard( QString::null, true );
00308 }
00309
00310 void KAddressBook::importVCard( const QString &file, bool showDialog )
00311 {
00312 QString fileName;
00313
00314 if ( file )
00315 fileName = file;
00316 else
00317 fileName = KFileDialog::getOpenFileName( QString::null,
00318 "*.vcf|vCards", 0,
00319 i18n( "Select vCard to Import" ) );
00320
00321 if ( !fileName.isEmpty() ) {
00322 KABC::VCardConverter converter;
00323 QFile file( fileName );
00324
00325 file.open( IO_ReadOnly );
00326 QByteArray rawData = file.readAll();
00327 file.close();
00328
00329 QString data = QString::fromUtf8( rawData.data(), rawData.size() + 1 );
00330 QStringList dataList = QStringList::split( "\r\n\r\n", data );
00331
00332 QStringList::Iterator it;
00333 for ( it = dataList.begin(); it != dataList.end(); ++it ) {
00334 KABC::Addressee addr;
00335 bool ok = false;
00336 if ( (*it).contains( "VERSION:3.0" ) ) {
00337 ok = converter.vCardToAddressee( *it, addr, KABC::VCardConverter::v3_0 );
00338 } else if ( (*it).contains( "VERSION:2.1" ) ) {
00339 ok = converter.vCardToAddressee( *it, addr, KABC::VCardConverter::v2_1 );
00340 } else {
00341 KMessageBox::sorry( this, i18n( "Not supported vCard version!" ) );
00342 continue;
00343 }
00344
00345 if ( !addr.isEmpty() && ok ) {
00346
00347
00348 PwNewCommand *command = new PwNewCommand( mDocument, addr );
00349 UndoStack::instance()->push( command );
00350 RedoStack::instance()->clear();
00351
00352 mViewManager->refresh();
00353
00354 if ( showDialog )
00355 editAddressee( addr.uid() );
00356
00357 emit modified( true );
00358 } else {
00359 QString text = i18n( "The selected file does not appear to be a valid vCard. "
00360 "Please check the file and try again." );
00361
00362 KMessageBox::sorry( this, text, i18n( "vCard Import Failed" ) );
00363 }
00364 }
00365 }
00366 }
00367
00368 void KAddressBook::exportCSV()
00369 {
00370 QString fileName = KFileDialog::getSaveFileName("addressbook.csv");
00371 if ( fileName.isEmpty())
00372 return;
00373 QFile outFile(fileName);
00374 if ( outFile.open(IO_WriteOnly) )
00375 {
00376 QTextStream t( &outFile );
00377
00378 KABC::AddressBook::Iterator iter;
00379 KABC::Field::List fields = mDocument->fields();
00380 KABC::Field::List::Iterator fieldIter;
00381 bool first = true;
00382
00383
00384 for (fieldIter = fields.begin(); fieldIter != fields.end(); ++fieldIter)
00385 {
00386 if (!first)
00387 t << ",";
00388
00389 t << "\"" << (*fieldIter)->label() << "\"";
00390 first = false;
00391 }
00392 t << "\n";
00393
00394
00395 KABC::Addressee a;
00396 for (iter = mDocument->begin(); iter != mDocument->end(); ++iter)
00397 {
00398 a = *iter;
00399 first = true;
00400
00401 for (fieldIter = fields.begin(); fieldIter != fields.end(); ++fieldIter)
00402 {
00403 if (!first)
00404 t << ",";
00405
00406 t << "\"" << (*fieldIter)->value( a ).replace( QRegExp("\n"), "\\n" ) << "\"";
00407 first = false;
00408 }
00409
00410 t << "\n";
00411 }
00412
00413 outFile.close();
00414 }
00415 }
00416
00417 void KAddressBook::exportVCard30()
00418 {
00419 exportVCard( KABC::VCardConverter::v3_0 );
00420 }
00421
00422 void KAddressBook::exportVCard( KABC::VCardConverter::Version )
00423 {
00424 KABC::Addressee::List addrList;
00425
00426 QStringList uids = viewManager()->selectedUids();
00427 if ( uids.count() == 0 )
00428 return;
00429
00430 for ( uint i = 0; i < uids.count(); ++i ) {
00431 KABC::Addressee addr;
00432 addr = mDocument->findByUid( uids[ i ] );
00433 if ( !addr.isEmpty() )
00434 addrList.append( addr );
00435 }
00436
00437 if ( addrList.count() == 0 )
00438 return;
00439
00440 QString name;
00441 if ( addrList.count() == 1 )
00442 name = addrList[ 0 ].givenName() + "_" + addrList[ 0 ].familyName() + ".vcf";
00443 else
00444 name = "addressbook.vcf";
00445
00446 QString fileName = KFileDialog::getSaveFileName( name );
00447 if ( fileName.isEmpty() )
00448 return;
00449
00450 QFile outFile(fileName);
00451 if ( !outFile.open( IO_WriteOnly ) ) {
00452 QString text = i18n( "<qt>Unable to open file <b>%1</b> for export!</qt>" );
00453 KMessageBox::error( this, text.arg( fileName ) );
00454 return;
00455 }
00456
00457 QTextStream t( &outFile );
00458 t.setEncoding( QTextStream::UnicodeUTF8 );
00459
00460 KABC::Addressee::List::Iterator it;
00461 for ( it = addrList.begin(); it != addrList.end(); ++it )
00462 {
00463 KABC::VCardConverter converter;
00464 QString vcard;
00465
00466 converter.addresseeToVCard( *it, vcard );
00467 t << vcard << "\r\n\r\n";
00468 }
00469
00470 outFile.close();
00471 }
00472
00473 QString KAddressBook::getNameByPhone( QString phone )
00474 {
00475 QRegExp r("[/*/-]");
00476
00477 bool found = false;
00478 QString ownerName = "";
00479 KABC::AddressBook::Iterator iter;
00480 KABC::PhoneNumber::List::Iterator phoneIter;
00481 KABC::PhoneNumber::List phoneList;
00482 for (iter = mDocument->begin(); !found && (iter != mDocument->end()); ++iter)
00483 {
00484 phoneList = (*iter).phoneNumbers();
00485 for (phoneIter = phoneList.begin();
00486 !found && (phoneIter != phoneList.end());
00487 ++phoneIter)
00488 {
00489
00490 if ((*phoneIter).number().replace( r, "" ) == phone.replace( r, "" ))
00491 {
00492 ownerName = (*iter).formattedName();
00493 found = true;
00494 }
00495 }
00496 }
00497
00498 return ownerName;
00499 }
00500
00501 void KAddressBook::addresseeSelected(const QString &uid)
00502 {
00503 emit addresseeSelected(uid != QString::null);
00504 }
00505
00506 void KAddressBook::addresseeExecuted(const QString &uid)
00507 {
00508
00509
00510 if ( uid != QString::null && !mViewManager->isQuickEditVisible() )
00511 editAddressee(uid);
00512 }
00513
00514 void KAddressBook::addresseeModified(const KABC::Addressee &a)
00515 {
00516
00517 Command *command = 0;
00518 QString uid;
00519
00520
00521 KABC::Addressee origA = mDocument->findByUid(a.uid());
00522 if (origA.isEmpty()) {
00523
00524 command = new PwNewCommand(mDocument, a);
00525 } else {
00526
00527 command = new PwEditCommand(mDocument, origA, a);
00528 uid = a.uid();
00529 }
00530 UndoStack::instance()->push(command);
00531 RedoStack::instance()->clear();
00532
00533 mViewManager->refresh(uid);
00534
00535 emit modified(true);
00536 }
00537
00538 void KAddressBook::viewModified()
00539 {
00540 emit modified(true);
00541 }
00542 void KAddressBook::configure()
00543 {
00544 if ( !mPrefsDialog ) {
00545 mPrefsDialog = new PrefsDialog( this );
00546 connect(mPrefsDialog, SIGNAL(configChanged()), SLOT(configChanged()));
00547 }
00548
00549
00550
00551 writeConfig();
00552
00553 mPrefsDialog->show();
00554 mPrefsDialog->raise();
00555 }
00556
00557 void KAddressBook::slotOpenLDAPDialog()
00558 {
00559 if( !mLdapSearchDialog ) {
00560 mLdapSearchDialog = new LDAPSearchDialogImpl( mDocument, this);
00561 connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ),
00562 this, SLOT( slotLDAPRefresh() ) );
00563 } else
00564 mLdapSearchDialog->rereadConfig();
00565
00566 if( mLdapSearchDialog->isOK() )
00567 mLdapSearchDialog->exec();
00568 }
00569
00570
00571 void KAddressBook::slotLDAPRefresh()
00572 {
00573 emit modified(true);
00574 mViewManager->refresh();
00575 }
00576
00577
00578 void KAddressBook::print()
00579 {
00580
00581
00582
00583 KPrinter printer;
00584 if(!printer.setup(this))
00585 {
00586 return;
00587 }
00588
00589 KABPrinting::PrintingWizard *wizard=
00590 KABPrinting::producePrintingWizard(&printer, mDocument,
00591 mViewManager->selectedUids(),
00592 this);
00593
00594
00595
00596
00597 wizard->exec();
00598 delete wizard;
00599 }
00600
00601 void KAddressBook::configChanged()
00602 {
00603 readConfig();
00604 }
00605
00606 void KAddressBook::slotAddressBookChanged()
00607 {
00608
00609 QDictIterator<AddresseeEditorDialog> it( mEditorDict );
00610 while ( it.current() ) {
00611 if ( it.current()->dirty() ) {
00612 QString text = i18n( "Data has been changed externally. Unsaved "
00613 "changes will be lost." );
00614 KMessageBox::information( this, text );
00615 }
00616 it.current()->setAddressee( mDocument->findByUid( it.currentKey() ) );
00617 ++it;
00618 }
00619
00620 mViewManager->refresh();
00621 }
00622
00623 void KAddressBook::configureFilters()
00624 {
00625 FilterDialog dlg( this );
00626
00627 dlg.setFilters( mViewManager->filters() );
00628
00629 if ( dlg.exec() )
00630 mViewManager->filtersChanged( dlg.filters() );
00631 }
00632
00633 void KAddressBook::setIncSearchWidget(IncSearchWidget *w)
00634 {
00635 mIncSearchWidget=w;
00636 connect(w, SIGNAL(incSearch(const QString&, int)),
00637 mViewManager, SLOT(incSearch(const QString&, int)));
00638 connect(mViewManager, SIGNAL(setIncSearchFields(const QStringList&)),
00639 w, SLOT(setFields(const QStringList&)));
00640 }
00641
00642 #include "kaddressbook.moc"