00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qclipboard.h>
00025 #include <qdir.h>
00026 #include <qfile.h>
00027 #include <qlayout.h>
00028 #include <qregexp.h>
00029 #include <qstatusbar.h>
00030 #include <qvbox.h>
00031
00032 #include <kabc/addresseelist.h>
00033 #include <kabc/errorhandler.h>
00034 #include <kabc/resource.h>
00035 #include <kabc/stdaddressbook.h>
00036 #include <kabc/vcardconverter.h>
00037 #include <kaboutdata.h>
00038 #include <kaccelmanager.h>
00039 #include <kapplication.h>
00040 #include <kactionclasses.h>
00041 #include <kcmdlineargs.h>
00042 #include <kcmultidialog.h>
00043 #include <kdebug.h>
00044 #include <kdeversion.h>
00045 #include <klocale.h>
00046 #include <kmessagebox.h>
00047 #include <kprinter.h>
00048 #include <kprotocolinfo.h>
00049 #include <kresources/selectdialog.h>
00050 #include <kstandarddirs.h>
00051 #include <kstdguiitem.h>
00052 #include <ktempfile.h>
00053 #include <kxmlguiclient.h>
00054 #include <libkdepim/addresseeview.h>
00055 #include <libkdepim/categoryeditdialog.h>
00056 #include <libkdepim/categoryselectdialog.h>
00057
00058 #include "addresseeutil.h"
00059 #include "addresseeeditordialog.h"
00060 #include "extensionmanager.h"
00061 #include "filterselectionwidget.h"
00062 #include "incsearchwidget.h"
00063 #include "jumpbuttonbar.h"
00064 #include "kablock.h"
00065 #include "kabprefs.h"
00066 #include "kaddressbookservice.h"
00067 #include "kaddressbookiface.h"
00068 #include "ldapsearchdialog.h"
00069 #include "printing/printingwizard.h"
00070 #include "undocmds.h"
00071 #include "viewmanager.h"
00072 #include "xxportmanager.h"
00073
00074 #include "kabcore.h"
00075
00076 KABCore::KABCore( KXMLGUIClient *client, bool readWrite, QWidget *parent,
00077 const char *name )
00078 : KAB::Core( client, parent, name ), mStatusBar( 0 ), mViewManager( 0 ),
00079 mExtensionManager( 0 ), mCategorySelectDialog( 0 ), mCategoryEditDialog( 0 ),
00080 mLdapSearchDialog( 0 ), mReadWrite( readWrite ), mModified( false )
00081 {
00082 mWidget = new QWidget( parent, name );
00083
00084 mIsPart = !parent->isA( "KAddressBookMain" );
00085
00086 mAddressBook = KABC::StdAddressBook::self( true );
00087 mAddressBook->setErrorHandler( new KABC::GuiErrorHandler( mWidget ) );
00088
00089 mAddressBook->addCustomField( i18n( "Department" ), KABC::Field::Organization,
00090 "X-Department", "KADDRESSBOOK" );
00091 mAddressBook->addCustomField( i18n( "Profession" ), KABC::Field::Organization,
00092 "X-Profession", "KADDRESSBOOK" );
00093 mAddressBook->addCustomField( i18n( "Assistant's Name" ), KABC::Field::Organization,
00094 "X-AssistantsName", "KADDRESSBOOK" );
00095 mAddressBook->addCustomField( i18n( "Manager's Name" ), KABC::Field::Organization,
00096 "X-ManagersName", "KADDRESSBOOK" );
00097 mAddressBook->addCustomField( i18n( "Spouse's Name" ), KABC::Field::Personal,
00098 "X-SpousesName", "KADDRESSBOOK" );
00099 mAddressBook->addCustomField( i18n( "Office" ), KABC::Field::Personal,
00100 "X-Office", "KADDRESSBOOK" );
00101 mAddressBook->addCustomField( i18n( "IM Address" ), KABC::Field::Personal,
00102 "X-IMAddress", "KADDRESSBOOK" );
00103 mAddressBook->addCustomField( i18n( "Anniversary" ), KABC::Field::Personal,
00104 "X-Anniversary", "KADDRESSBOOK" );
00105
00106 initGUI();
00107
00108 connect( mAddressBook, SIGNAL( addressBookChanged( AddressBook* ) ),
00109 SLOT( addressBookChanged() ) );
00110 connect( mAddressBook, SIGNAL( loadingFinished( Resource* ) ),
00111 SLOT( addressBookChanged() ) );
00112
00113 mIncSearchWidget->setFocus();
00114
00115 connect( mViewManager, SIGNAL( selected( const QString& ) ),
00116 SLOT( setContactSelected( const QString& ) ) );
00117 connect( mViewManager, SIGNAL( executed( const QString& ) ),
00118 SLOT( editContact( const QString& ) ) );
00119 connect( mViewManager, SIGNAL( modified() ),
00120 SLOT( setModified() ) );
00121 connect( mViewManager, SIGNAL( urlDropped( const KURL& ) ),
00122 mXXPortManager, SLOT( importVCard( const KURL& ) ) );
00123 connect( mExtensionManager, SIGNAL( modified( const KABC::Addressee::List& ) ),
00124 this, SLOT( extensionModified( const KABC::Addressee::List& ) ) );
00125
00126 connect( mXXPortManager, SIGNAL( modified() ),
00127 SLOT( setModified() ) );
00128
00129 connect( mJumpButtonBar, SIGNAL( jumpToLetter( const QString& ) ),
00130 SLOT( incrementalJumpButtonSearch( const QString& ) ) );
00131 connect( mViewManager, SIGNAL( sortFieldChanged() ),
00132 mJumpButtonBar, SLOT( updateButtons() ) );
00133
00134 connect( mDetails, SIGNAL( highlightedMessage( const QString& ) ),
00135 SLOT( detailsHighlighted( const QString& ) ) );
00136
00137 mAddressBookService = new KAddressBookService( this );
00138
00139 setModified( false );
00140
00141 KAcceleratorManager::manage( mWidget );
00142 }
00143
00144 KABCore::~KABCore()
00145 {
00146 saveSettings();
00147 KABPrefs::instance()->writeConfig();
00148
00149 mAddressBook = 0;
00150 KABC::StdAddressBook::close();
00151 }
00152
00153 void KABCore::restoreSettings()
00154 {
00155 bool state = KABPrefs::instance()->mJumpButtonBarVisible;
00156 mActionJumpBar->setChecked( state );
00157 setJumpButtonBarVisible( state );
00158
00159 state = KABPrefs::instance()->mDetailsPageVisible;
00160 mActionDetails->setChecked( state );
00161 setDetailsVisible( state );
00162
00163 QValueList<int> splitterSize = KABPrefs::instance()->mExtensionsSplitter;
00164 if ( splitterSize.count() == 0 ) {
00165 splitterSize.append( mWidget->width() / 2 );
00166 splitterSize.append( mWidget->width() / 2 );
00167 }
00168 mExtensionBarSplitter->setSizes( splitterSize );
00169
00170 splitterSize = KABPrefs::instance()->mDetailsSplitter;
00171 if ( splitterSize.count() == 0 ) {
00172 splitterSize.append( mWidget->height() / 2 );
00173 splitterSize.append( mWidget->height() / 2 );
00174 }
00175 mDetailsSplitter->setSizes( splitterSize );
00176
00177 mViewManager->restoreSettings();
00178 mExtensionManager->restoreSettings();
00179
00180 mIncSearchWidget->setCurrentItem( KABPrefs::instance()->mCurrentIncSearchField );
00181 }
00182
00183 void KABCore::saveSettings()
00184 {
00185 KABPrefs::instance()->mJumpButtonBarVisible = mActionJumpBar->isChecked();
00186 KABPrefs::instance()->mDetailsPageVisible = mActionDetails->isChecked();
00187
00188 KABPrefs::instance()->mExtensionsSplitter = mExtensionBarSplitter->sizes();
00189 KABPrefs::instance()->mDetailsSplitter = mDetailsSplitter->sizes();
00190
00191 mExtensionManager->saveSettings();
00192 mViewManager->saveSettings();
00193
00194 KABPrefs::instance()->mCurrentIncSearchField = mIncSearchWidget->currentItem();
00195 }
00196
00197 KABC::AddressBook *KABCore::addressBook() const
00198 {
00199 return mAddressBook;
00200 }
00201
00202 KConfig *KABCore::config() const
00203 {
00204 return KABPrefs::instance()->config();
00205 }
00206
00207 KActionCollection *KABCore::actionCollection() const
00208 {
00209 return guiClient()->actionCollection();
00210 }
00211
00212 KABC::Field *KABCore::currentSearchField() const
00213 {
00214 return mIncSearchWidget->currentField();
00215 }
00216
00217 KABC::Field *KABCore::currentSortField() const
00218 {
00219 return mViewManager->currentSortField();
00220 }
00221
00222 QStringList KABCore::selectedUIDs() const
00223 {
00224 return mViewManager->selectedUids();
00225 }
00226
00227 KABC::Resource *KABCore::requestResource( QWidget *parent )
00228 {
00229 QPtrList<KABC::Resource> kabcResources = addressBook()->resources();
00230
00231 QPtrList<KRES::Resource> kresResources;
00232 QPtrListIterator<KABC::Resource> resIt( kabcResources );
00233 KABC::Resource *resource;
00234 while ( ( resource = resIt.current() ) != 0 ) {
00235 ++resIt;
00236 if ( !resource->readOnly() ) {
00237 KRES::Resource *res = static_cast<KRES::Resource*>( resource );
00238 if ( res )
00239 kresResources.append( res );
00240 }
00241 }
00242
00243 KRES::Resource *res = KRES::SelectDialog::getResource( kresResources, parent );
00244 return static_cast<KABC::Resource*>( res );
00245 }
00246
00247 QWidget *KABCore::widget() const
00248 {
00249 return mWidget;
00250 }
00251
00252 KAboutData *KABCore::createAboutData()
00253 {
00254 KAboutData *about = new KAboutData( "kaddressbook", I18N_NOOP( "KAddressBook" ),
00255 "3.2.1", I18N_NOOP( "The KDE Address Book" ),
00256 KAboutData::License_GPL_V2,
00257 I18N_NOOP( "(c) 1997-2003, The KDE PIM Team" ) );
00258 about->addAuthor( "Tobias Koenig", I18N_NOOP( "Current maintainer" ), "tokoe@kde.org" );
00259 about->addAuthor( "Don Sanders", I18N_NOOP( "Original author" ) );
00260 about->addAuthor( "Cornelius Schumacher",
00261 I18N_NOOP( "Co-maintainer, libkabc port, CSV import/export" ),
00262 "schumacher@kde.org" );
00263 about->addAuthor( "Mike Pilone", I18N_NOOP( "GUI and framework redesign" ),
00264 "mpilone@slac.com" );
00265 about->addAuthor( "Greg Stern", I18N_NOOP( "DCOP interface" ) );
00266 about->addAuthor( "Mark Westcott", I18N_NOOP( "Contact pinning" ) );
00267 about->addAuthor( "Mischel Boyer de la Giroday", I18N_NOOP( "LDAP Lookup" ),
00268 "michel@klaralvdalens-datakonsult.se" );
00269 about->addAuthor( "Steffen Hansen", I18N_NOOP( "LDAP Lookup" ),
00270 "hansen@kde.org" );
00271
00272 return about;
00273 }
00274
00275 void KABCore::setStatusBar( QStatusBar *statusBar )
00276 {
00277 mStatusBar = statusBar;
00278 }
00279
00280 QStatusBar *KABCore::statusBar() const
00281 {
00282 return mStatusBar;
00283 }
00284
00285 void KABCore::setContactSelected( const QString &uid )
00286 {
00287 KABC::Addressee addr = mAddressBook->findByUid( uid );
00288 if ( !mDetails->isHidden() )
00289 mDetails->setAddressee( addr );
00290
00291 if ( !addr.isEmpty() ) {
00292 emit contactSelected( addr.formattedName() );
00293 KABC::Picture pic = addr.photo();
00294 if ( pic.isIntern() )
00295 emit contactSelected( pic.data() );
00296 }
00297
00298 mExtensionManager->setSelectionChanged();
00299
00300
00301 bool selected = !uid.isEmpty();
00302
00303 if ( mReadWrite ) {
00304 mActionCut->setEnabled( selected );
00305 mActionPaste->setEnabled( selected );
00306 }
00307
00308 mActionCopy->setEnabled( selected );
00309 mActionDelete->setEnabled( selected );
00310 mActionEditAddressee->setEnabled( selected );
00311 mActionMail->setEnabled( selected );
00312 mActionMailVCard->setEnabled( selected );
00313 mActionWhoAmI->setEnabled( selected );
00314 mActionCategories->setEnabled( selected );
00315 }
00316
00317 void KABCore::sendMail()
00318 {
00319 sendMail( mViewManager->selectedEmails().join( ", " ) );
00320 }
00321
00322 void KABCore::sendMail( const QString& email )
00323 {
00324 kapp->invokeMailer( email, "" );
00325 }
00326
00327 void KABCore::mailVCard()
00328 {
00329 QStringList uids = mViewManager->selectedUids();
00330 if ( !uids.isEmpty() )
00331 mailVCard( uids );
00332 }
00333
00334 void KABCore::mailVCard( const QStringList& uids )
00335 {
00336 QStringList urls;
00337
00338
00339 KTempFile tempDir;
00340 if ( tempDir.status() != 0 ) {
00341 kdWarning() << strerror( tempDir.status() ) << endl;
00342 return;
00343 }
00344
00345 QString dirName = tempDir.name();
00346 tempDir.unlink();
00347 QDir().mkdir( dirName, true );
00348
00349 for( QStringList::ConstIterator it = uids.begin(); it != uids.end(); ++it ) {
00350 KABC::Addressee a = mAddressBook->findByUid( *it );
00351
00352 if ( a.isEmpty() )
00353 continue;
00354
00355 QString name = a.givenName().utf8() + "_" + a.familyName().utf8() + ".vcf";
00356
00357 QString fileName = dirName + "/" + name;
00358
00359 QFile outFile(fileName);
00360 if ( outFile.open( IO_WriteOnly ) ) {
00361 KABC::VCardConverter converter;
00362 KABC::Addressee::List list;
00363 list.append( a );
00364 QString vcard = converter.createVCards( list, KABC::VCardConverter::v3_0 );
00365
00366 QTextStream t( &outFile );
00367 t.setEncoding( QTextStream::UnicodeUTF8 );
00368 t << vcard;
00369
00370 outFile.close();
00371
00372 urls.append( fileName );
00373 }
00374 }
00375
00376 kapp->invokeMailer( QString::null, QString::null, QString::null,
00377 QString::null,
00378 QString::null,
00379 QString::null,
00380 urls );
00381 }
00382
00383 void KABCore::browse( const QString& url )
00384 {
00385 kapp->invokeBrowser( url );
00386 }
00387
00388 void KABCore::selectAllContacts()
00389 {
00390 mViewManager->setSelected( QString::null, true );
00391 }
00392
00393 void KABCore::deleteContacts()
00394 {
00395 QStringList uidList = mViewManager->selectedUids();
00396
00397 deleteContacts( uidList );
00398 }
00399
00400 void KABCore::deleteContacts( const QStringList &uids )
00401 {
00402 if ( uids.count() > 0 ) {
00403 PwDeleteCommand *command = new PwDeleteCommand( mAddressBook, uids );
00404 UndoStack::instance()->push( command );
00405 RedoStack::instance()->clear();
00406
00407
00408 setContactSelected( QString::null );
00409 setModified( true );
00410 }
00411 }
00412
00413 void KABCore::copyContacts()
00414 {
00415 KABC::Addressee::List addrList = mViewManager->selectedAddressees();
00416
00417 QString clipText = AddresseeUtil::addresseesToClipboard( addrList );
00418
00419 kdDebug(5720) << "KABCore::copyContacts: " << clipText << endl;
00420
00421 QClipboard *cb = QApplication::clipboard();
00422 cb->setText( clipText );
00423 }
00424
00425 void KABCore::cutContacts()
00426 {
00427 QStringList uidList = mViewManager->selectedUids();
00428
00429 if ( uidList.size() > 0 ) {
00430 PwCutCommand *command = new PwCutCommand( mAddressBook, uidList );
00431 UndoStack::instance()->push( command );
00432 RedoStack::instance()->clear();
00433
00434 setModified( true );
00435 }
00436 }
00437
00438 void KABCore::pasteContacts()
00439 {
00440 QClipboard *cb = QApplication::clipboard();
00441
00442 KABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( cb->text() );
00443
00444 pasteContacts( list );
00445 }
00446
00447 void KABCore::pasteContacts( KABC::Addressee::List &list )
00448 {
00449 KABC::Resource *resource = requestResource( mWidget );
00450 KABC::Addressee::List::Iterator it;
00451 for ( it = list.begin(); it != list.end(); ++it )
00452 (*it).setResource( resource );
00453
00454 PwPasteCommand *command = new PwPasteCommand( this, list );
00455 UndoStack::instance()->push( command );
00456 RedoStack::instance()->clear();
00457
00458 setModified( true );
00459 }
00460
00461 void KABCore::setWhoAmI()
00462 {
00463 KABC::Addressee::List addrList = mViewManager->selectedAddressees();
00464
00465 if ( addrList.count() > 1 ) {
00466 KMessageBox::sorry( mWidget, i18n( "Please select only one contact." ) );
00467 return;
00468 }
00469
00470 QString text( i18n( "<qt>Do you really want to use <b>%1</b> as your new personal contact?</qt>" ) );
00471 if ( KMessageBox::questionYesNo( mWidget, text.arg( addrList[ 0 ].assembledName() ) ) == KMessageBox::Yes )
00472 static_cast<KABC::StdAddressBook*>( KABC::StdAddressBook::self( true ) )->setWhoAmI( addrList[ 0 ] );
00473 }
00474
00475 void KABCore::setSearchFields( const KABC::Field::List &fields )
00476 {
00477 mIncSearchWidget->setFields( fields );
00478 }
00479
00480 void KABCore::incrementalTextSearch( const QString& text )
00481 {
00482 incrementalSearch( text, true );
00483 }
00484
00485 void KABCore::incrementalJumpButtonSearch( const QString& text )
00486 {
00487 incrementalSearch( text, false );
00488 }
00489
00490 void KABCore::incrementalSearch( const QString& text, bool search )
00491 {
00492 mViewManager->setSelected( QString::null, false );
00493
00494 if ( !text.isEmpty() ) {
00495 KABC::Field *field = ( search ? mIncSearchWidget->currentField() :
00496 mViewManager->currentSortField() );
00497
00498 #if KDE_VERSION >= 319
00499 KABC::AddresseeList list( mAddressBook->allAddressees() );
00500 if ( field ) {
00501 list.sortByField( field );
00502 KABC::AddresseeList::Iterator it;
00503 for ( it = list.begin(); it != list.end(); ++it ) {
00504 if ( (search && field->value( *it ).find( text, 0, false ) != -1) ||
00505 (!search && field->value( *it).startsWith( text, false)) ) {
00506 mViewManager->setSelected( (*it).uid(), true );
00507 return;
00508 }
00509 }
00510 } else {
00511 KABC::AddresseeList::Iterator it;
00512 for ( it = list.begin(); it != list.end(); ++it ) {
00513 KABC::Field::List fieldList = KABC::Field::allFields();
00514 KABC::Field::List::ConstIterator fieldIt;
00515 for ( fieldIt = fieldList.begin(); fieldIt != fieldList.end(); ++fieldIt ) {
00516 if ( (*fieldIt)->value( *it ).find( text, 0, false ) != -1 ) {
00517 mViewManager->setSelected( (*it).uid(), true );
00518 return;
00519 }
00520 }
00521 }
00522 }
00523 #else
00524 KABC::AddressBook::Iterator it;
00525 for ( it = mAddressBook->begin(); it != mAddressBook->end(); ++it ) {
00526 if ( field ) {
00527 if ( field->value( *it ).startsWith( text, false ) ) {
00528 mViewManager->setSelected( (*it).uid(), true );
00529 return;
00530 }
00531 } else {
00532 KABC::Field::List fieldList = mIncSearchWidget->fields();
00533 KABC::Field::List::ConstIterator fieldIt;
00534 for ( fieldIt = fieldList.begin(); fieldIt != fieldList.end(); ++fieldIt ) {
00535 if ( (*fieldIt)->value( *it ).startsWith( text, false ) ) {
00536 mViewManager->setSelected( (*it).uid(), true );
00537 return;
00538 }
00539 }
00540 }
00541 }
00542 #endif
00543 }
00544 }
00545
00546 void KABCore::setModified()
00547 {
00548 setModified( true );
00549 }
00550
00551 void KABCore::setModified( bool modified )
00552 {
00553 mModified = modified;
00554 mActionSave->setEnabled( mModified );
00555
00556 mViewManager->refreshView();
00557 }
00558
00559 bool KABCore::modified() const
00560 {
00561 return mModified;
00562 }
00563
00564 void KABCore::contactModified( const KABC::Addressee &addr )
00565 {
00566 Command *command = 0;
00567 QString uid;
00568
00569
00570 KABC::Addressee origAddr = mAddressBook->findByUid( addr.uid() );
00571 if ( origAddr.isEmpty() )
00572 command = new PwNewCommand( mAddressBook, addr );
00573 else {
00574 command = new PwEditCommand( mAddressBook, origAddr, addr );
00575 uid = addr.uid();
00576 }
00577
00578 UndoStack::instance()->push( command );
00579 RedoStack::instance()->clear();
00580
00581 setContactSelected( addr.uid() );
00582 setModified( true );
00583 }
00584
00585 void KABCore::newContact()
00586 {
00587 AddresseeEditorDialog *dialog = 0;
00588
00589 QPtrList<KABC::Resource> kabcResources = mAddressBook->resources();
00590
00591 QPtrList<KRES::Resource> kresResources;
00592 QPtrListIterator<KABC::Resource> it( kabcResources );
00593 KABC::Resource *resource;
00594 while ( ( resource = it.current() ) != 0 ) {
00595 ++it;
00596 if ( !resource->readOnly() ) {
00597 KRES::Resource *res = static_cast<KRES::Resource*>( resource );
00598 if ( res )
00599 kresResources.append( res );
00600 }
00601 }
00602
00603 KRES::Resource *res = KRES::SelectDialog::getResource( kresResources, mWidget );
00604 resource = static_cast<KABC::Resource*>( res );
00605
00606 if ( resource ) {
00607 KABC::Addressee addr;
00608 addr.setResource( resource );
00609
00610 if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) )
00611 return;
00612
00613 dialog = createAddresseeEditorDialog( mWidget );
00614 dialog->setAddressee( addr );
00615 } else
00616 return;
00617
00618 mEditorDict.insert( dialog->addressee().uid(), dialog );
00619
00620 dialog->show();
00621 }
00622
00623 void KABCore::addEmail( const QString &aStr )
00624 {
00625 QString fullName, email;
00626
00627 KABC::Addressee::parseEmailAddress( aStr, fullName, email );
00628
00629
00630 bool found = false;
00631 QStringList emailList;
00632 KABC::AddressBook::Iterator it;
00633 for ( it = mAddressBook->begin(); !found && (it != mAddressBook->end()); ++it ) {
00634 emailList = (*it).emails();
00635 if ( emailList.contains( email ) > 0 ) {
00636 found = true;
00637 (*it).setNameFromString( fullName );
00638 editContact( (*it).uid() );
00639 }
00640 }
00641
00642 if ( !found ) {
00643 KABC::Addressee addr;
00644 addr.setNameFromString( fullName );
00645 addr.insertEmail( email, true );
00646
00647 mAddressBook->insertAddressee( addr );
00648 mViewManager->refreshView( addr.uid() );
00649 editContact( addr.uid() );
00650 }
00651 }
00652
00653 void KABCore::importVCard( const KURL &url )
00654 {
00655 mXXPortManager->importVCard( url );
00656 }
00657
00658 void KABCore::importVCard( const QString &vCardURL )
00659 {
00660 mXXPortManager->importVCard( vCardURL );
00661 }
00662
00663 void KABCore::editContact( const QString &uid )
00664 {
00665 if ( mExtensionManager->isQuickEditVisible() )
00666 return;
00667
00668
00669 QString localUID = uid;
00670 if ( localUID.isNull() ) {
00671 QStringList uidList = mViewManager->selectedUids();
00672 if ( uidList.count() > 0 )
00673 localUID = *( uidList.at( 0 ) );
00674 }
00675
00676 KABC::Addressee addr = mAddressBook->findByUid( localUID );
00677 if ( !addr.isEmpty() ) {
00678 AddresseeEditorDialog *dialog = mEditorDict.find( addr.uid() );
00679 if ( !dialog ) {
00680
00681 if ( !addr.resource()->readOnly() )
00682 if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) )
00683 return;
00684
00685 dialog = createAddresseeEditorDialog( mWidget );
00686
00687 mEditorDict.insert( addr.uid(), dialog );
00688
00689 dialog->setAddressee( addr );
00690 }
00691
00692 dialog->raise();
00693 dialog->show();
00694 }
00695 }
00696
00697 void KABCore::save()
00698 {
00699 KABC::StdAddressBook *b = dynamic_cast<KABC::StdAddressBook*>( mAddressBook );
00700 if ( !b || !b->save() ) {
00701 QString text = i18n( "There was an error while attempting to save the "
00702 "address book. Please check that some other application is "
00703 "not using it. " );
00704
00705 KMessageBox::error( mWidget, text, i18n( "Unable to Save" ) );
00706 }
00707
00708 setModified( false );
00709 }
00710
00711 void KABCore::undo()
00712 {
00713 UndoStack::instance()->undo();
00714
00715
00716 mViewManager->refreshView();
00717 }
00718
00719 void KABCore::redo()
00720 {
00721 RedoStack::instance()->redo();
00722
00723
00724 mViewManager->refreshView();
00725 }
00726
00727 void KABCore::setJumpButtonBarVisible( bool visible )
00728 {
00729 if ( visible )
00730 mJumpButtonBar->show();
00731 else
00732 mJumpButtonBar->hide();
00733 }
00734
00735 void KABCore::setDetailsVisible( bool visible )
00736 {
00737 if ( visible )
00738 mDetailsPage->show();
00739 else
00740 mDetailsPage->hide();
00741 }
00742
00743 void KABCore::extensionModified( const KABC::Addressee::List &list )
00744 {
00745 if ( list.count() != 0 ) {
00746 KABC::Addressee::List::ConstIterator it;
00747 for ( it = list.begin(); it != list.end(); ++it ) {
00748 Command *command = 0;
00749
00750
00751 KABC::Addressee origAddr = mAddressBook->findByUid( (*it).uid() );
00752 if ( origAddr.isEmpty() )
00753 command = new PwNewCommand( mAddressBook, *it );
00754 else
00755 command = new PwEditCommand( mAddressBook, origAddr, *it );
00756
00757 UndoStack::instance()->push( command );
00758 RedoStack::instance()->clear();
00759 }
00760
00761 setModified( true );
00762 }
00763
00764 if ( list.count() == 0 )
00765 mViewManager->refreshView();
00766 else
00767 mViewManager->refreshView( list[ 0 ].uid() );
00768 }
00769
00770 QString KABCore::getNameByPhone( const QString &phone )
00771 {
00772 QRegExp r( "[/*/-/ ]" );
00773 QString localPhone( phone );
00774
00775 bool found = false;
00776 QString ownerName = "";
00777 KABC::AddressBook::Iterator iter;
00778 KABC::PhoneNumber::List::Iterator phoneIter;
00779 KABC::PhoneNumber::List phoneList;
00780 for ( iter = mAddressBook->begin(); !found && ( iter != mAddressBook->end() ); ++iter ) {
00781 phoneList = (*iter).phoneNumbers();
00782 for ( phoneIter = phoneList.begin(); !found && ( phoneIter != phoneList.end() );
00783 ++phoneIter) {
00784
00785 if ( (*phoneIter).number().replace( r, "" ) == localPhone.replace( r, "" ) ) {
00786 ownerName = (*iter).formattedName();
00787 found = true;
00788 }
00789 }
00790 }
00791
00792 return ownerName;
00793 }
00794
00795 void KABCore::openLDAPDialog()
00796 {
00797 if ( !KProtocolInfo::isKnownProtocol( KURL( "ldap://localhost" ) ) ) {
00798 KMessageBox::error( mWidget, i18n( "Your KDE installation is missing LDAP "
00799 "support, please ask your administrator or distributor for more information!" ),
00800 i18n( "No LDAP IO slave available" ) );
00801 return;
00802 }
00803
00804 if ( !mLdapSearchDialog ) {
00805 mLdapSearchDialog = new LDAPSearchDialog( mAddressBook, mWidget );
00806 connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ), mViewManager,
00807 SLOT( refreshView() ) );
00808 connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ), this,
00809 SLOT( setModified() ) );
00810 } else
00811 mLdapSearchDialog->restoreSettings();
00812
00813 if ( mLdapSearchDialog->isOK() )
00814 mLdapSearchDialog->exec();
00815 }
00816
00817 void KABCore::configure()
00818 {
00819
00820 saveSettings();
00821
00822 KCMultiDialog dlg( mWidget, "", true );
00823 connect( &dlg, SIGNAL( configCommitted() ),
00824 this, SLOT( configurationChanged() ) );
00825
00826 dlg.addModule( "kabconfig.desktop" );
00827 dlg.addModule( "kabldapconfig.desktop" );
00828
00829 dlg.exec();
00830 }
00831
00832 void KABCore::print()
00833 {
00834 KPrinter printer;
00835 if ( !printer.setup( mWidget, i18n("Print Addresses") ) )
00836 return;
00837
00838 KABPrinting::PrintingWizard wizard( &printer, mAddressBook,
00839 mViewManager->selectedUids(), mWidget );
00840
00841 wizard.exec();
00842 }
00843
00844 void KABCore::detailsHighlighted( const QString &msg )
00845 {
00846 if ( statusBar() )
00847 statusBar()->message( msg );
00848 }
00849
00850 void KABCore::configurationChanged()
00851 {
00852 mExtensionManager->reconfigure();
00853 }
00854
00855 void KABCore::addressBookChanged()
00856 {
00857 mViewManager->refreshView();
00858 }
00859
00860 AddresseeEditorDialog *KABCore::createAddresseeEditorDialog( QWidget *parent,
00861 const char *name )
00862 {
00863 AddresseeEditorDialog *dialog = new AddresseeEditorDialog( this, parent,
00864 name ? name : "editorDialog" );
00865 connect( dialog, SIGNAL( contactModified( const KABC::Addressee& ) ),
00866 SLOT( contactModified( const KABC::Addressee& ) ) );
00867 connect( dialog, SIGNAL( editorDestroyed( const QString& ) ),
00868 SLOT( slotEditorDestroyed( const QString& ) ) );
00869
00870 return dialog;
00871 }
00872
00873 void KABCore::slotEditorDestroyed( const QString &uid )
00874 {
00875 mEditorDict.remove( uid );
00876
00877 KABC::Addressee addr = mAddressBook->findByUid( uid );
00878
00879 KABLock::self( mAddressBook )->unlock( addr.resource() );
00880 }
00881
00882 void KABCore::initGUI()
00883 {
00884 QVBoxLayout *topLayout = new QVBoxLayout( mWidget, KDialog::marginHint(),
00885 KDialog::spacingHint() );
00886 QHBoxLayout *hbox = new QHBoxLayout( topLayout, KDialog::spacingHint() );
00887
00888 mIncSearchWidget = new IncSearchWidget( mWidget );
00889 connect( mIncSearchWidget, SIGNAL( doSearch( const QString& ) ),
00890 SLOT( incrementalTextSearch( const QString& ) ) );
00891
00892 mFilterSelectionWidget = new FilterSelectionWidget( mWidget );
00893 hbox->addWidget( mIncSearchWidget );
00894 hbox->addWidget( mFilterSelectionWidget );
00895
00896 hbox = new QHBoxLayout( topLayout, KDialog::spacingHint() );
00897
00898 mDetailsSplitter = new QSplitter( mWidget );
00899 hbox->addWidget( mDetailsSplitter );
00900
00901 mExtensionBarSplitter = new QSplitter( mDetailsSplitter );
00902 mExtensionBarSplitter->setOrientation( Qt::Vertical );
00903
00904 QWidget *detailsWidget = new QWidget( mDetailsSplitter );
00905 QHBoxLayout *detailsLayout = new QHBoxLayout( detailsWidget );
00906
00907 mDetailsPage = new QWidget( detailsWidget );
00908 detailsLayout->addWidget( mDetailsPage );
00909
00910 QHBoxLayout *detailsPageLayout = new QHBoxLayout( mDetailsPage,
00911 KDialog::marginHint(),
00912 KDialog::spacingHint() );
00913 mDetails = new KPIM::AddresseeView( mDetailsPage );
00914 detailsPageLayout->addWidget( mDetails );
00915
00916 mViewManager = new ViewManager( this, mExtensionBarSplitter );
00917 mViewManager->setFilterSelectionWidget( mFilterSelectionWidget );
00918
00919 connect( mFilterSelectionWidget, SIGNAL( filterActivated( int ) ),
00920 mViewManager, SLOT( setActiveFilter( int ) ) );
00921
00922 mExtensionManager = new ExtensionManager( this, mExtensionBarSplitter );
00923
00924 mJumpButtonBar = new JumpButtonBar( this, detailsWidget );
00925 detailsLayout->addWidget( mJumpButtonBar );
00926 detailsLayout->setStretchFactor( mJumpButtonBar, 1 );
00927
00928 topLayout->setStretchFactor( hbox, 1 );
00929
00930 mXXPortManager = new XXPortManager( this, mWidget );
00931
00932 initActions();
00933 }
00934
00935 void KABCore::initActions()
00936 {
00937 connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
00938 SLOT( clipboardDataChanged() ) );
00939
00940 KAction *action;
00941
00942
00943 mActionMail = KStdAction::mail( this, SLOT( sendMail() ), actionCollection() );
00944 action = KStdAction::print( this, SLOT( print() ), actionCollection() );
00945 mActionMail->setWhatsThis( i18n( "Send a mail to all selected contacts." ) );
00946 action->setWhatsThis( i18n( "Print a special number of contacts." ) );
00947
00948 mActionSave = new KAction( KStdGuiItem::save().text(), "filesave", CTRL+Key_S, this,
00949 SLOT( save() ), actionCollection(), "file_sync" );
00950 mActionSave->setWhatsThis( i18n( "Save all changes of the address book to the storage backend." ) );
00951
00952 action = new KAction( i18n( "&New Contact..." ), "filenew", CTRL+Key_N, this,
00953 SLOT( newContact() ), actionCollection(), "file_new_contact" );
00954 action->setWhatsThis( i18n( "Create a new contact<p>You will be presented with a dialog where you can add all data of a person, including addresses and phonenumbers." ) );
00955
00956 mActionMailVCard = new KAction( i18n("Send &Contact..."), "mail_post_to", 0,
00957 this, SLOT( mailVCard() ),
00958 actionCollection(), "file_mail_vcard" );
00959 mActionMailVCard->setWhatsThis( i18n( "Send a mail with the selected contact as attachment." ) );
00960
00961 mActionEditAddressee = new KAction( i18n( "&Edit Contact..." ), "edit", 0,
00962 this, SLOT( editContact() ),
00963 actionCollection(), "file_properties" );
00964 mActionEditAddressee->setWhatsThis( i18n( "Edit a contact<p>You will be presented with a dialog where you can change all data of a person, including addresses and phonenumbers." ) );
00965
00966
00967 mActionCopy = KStdAction::copy( this, SLOT( copyContacts() ), actionCollection() );
00968 mActionCut = KStdAction::cut( this, SLOT( cutContacts() ), actionCollection() );
00969 mActionPaste = KStdAction::paste( this, SLOT( pasteContacts() ), actionCollection() );
00970 action = KStdAction::selectAll( this, SLOT( selectAllContacts() ), actionCollection() );
00971 mActionUndo = KStdAction::undo( this, SLOT( undo() ), actionCollection() );
00972 mActionRedo = KStdAction::redo( this, SLOT( redo() ), actionCollection() );
00973 mActionCopy->setWhatsThis( i18n( "Copy the currently selected contact(s) to system clipboard in vCard format." ) );
00974 mActionCut->setWhatsThis( i18n( "Cuts the currently selected contact(s) to system clipboard in vCard format." ) );
00975 mActionPaste->setWhatsThis( i18n( "Paste the previously cut or copied contacts from clipboard." ) );
00976 action->setWhatsThis( i18n( "Selects all visible contacts from current view." ) );
00977 mActionUndo->setWhatsThis( i18n( "Undoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) );
00978 mActionRedo->setWhatsThis( i18n( "Redoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) );
00979
00980 mActionDelete = new KAction( i18n( "&Delete Contact" ), "editdelete",
00981 Key_Delete, this, SLOT( deleteContacts() ),
00982 actionCollection(), "edit_delete" );
00983 mActionDelete->setWhatsThis( i18n( "Delete all selected contacts." ) );
00984
00985 mActionUndo->setEnabled( false );
00986 mActionRedo->setEnabled( false );
00987
00988
00989 mActionJumpBar = new KToggleAction( i18n( "Show Jump Bar" ), "next", 0,
00990 actionCollection(), "options_show_jump_bar" );
00991 mActionJumpBar->setWhatsThis( i18n( "Toggle whether the jump button bar shall be visible." ) );
00992 connect( mActionJumpBar, SIGNAL( toggled( bool ) ), SLOT( setJumpButtonBarVisible( bool ) ) );
00993
00994 mActionDetails = new KToggleAction( i18n( "Show Details" ), 0, 0,
00995 actionCollection(), "options_show_details" );
00996 mActionDetails->setWhatsThis( i18n( "Toggle whether the details page shall be visible." ) );
00997 connect( mActionDetails, SIGNAL( toggled( bool ) ), SLOT( setDetailsVisible( bool ) ) );
00998
00999 if ( mIsPart )
01000 action = new KAction( i18n( "&Configure KAddressBook..." ), "configure", 0,
01001 this, SLOT( configure() ), actionCollection(),
01002 "kaddressbook_configure" );
01003 else
01004 action = KStdAction::preferences( this, SLOT( configure() ), actionCollection() );
01005
01006 action->setWhatsThis( i18n( "You will be presented with a dialog, that offers you all possibilities to configure KAddressBook." ) );
01007
01008
01009 action = new KAction( i18n( "&Lookup Addresses in LDAP Directory..." ), "find", 0,
01010 this, SLOT( openLDAPDialog() ), actionCollection(), "ldap_lookup" );
01011 action->setWhatsThis( i18n( "Search for contacts on a LDAP server<p>You will be presented with a dialog, where you can search for contacts and select the ones you want to add to your local address book." ) );
01012
01013 mActionWhoAmI = new KAction( i18n( "Set 'Who Am I'" ), "personal", 0, this,
01014 SLOT( setWhoAmI() ), actionCollection(),
01015 "edit_set_personal" );
01016 mActionWhoAmI->setWhatsThis( i18n( "Set the personal contact<p>The data of this contact will be used in many other KDE applications, so you don't have to input your personal data several times." ) );
01017
01018 mActionCategories = new KAction( i18n( "Select Categories..." ), 0, this,
01019 SLOT( setCategories() ), actionCollection(),
01020 "edit_set_categories" );
01021 mActionCategories->setWhatsThis( i18n( "Set the categories for all selected contacts." ) );
01022
01023 clipboardDataChanged();
01024
01025 connect( UndoStack::instance(), SIGNAL( changed() ), SLOT( updateActionMenu() ) );
01026 connect( RedoStack::instance(), SIGNAL( changed() ), SLOT( updateActionMenu() ) );
01027 }
01028
01029 void KABCore::clipboardDataChanged()
01030 {
01031 if ( mReadWrite )
01032 mActionPaste->setEnabled( !QApplication::clipboard()->text().isEmpty() );
01033 }
01034
01035 void KABCore::updateActionMenu()
01036 {
01037 UndoStack *undo = UndoStack::instance();
01038 RedoStack *redo = RedoStack::instance();
01039
01040 if ( undo->isEmpty() )
01041 mActionUndo->setText( i18n( "Undo" ) );
01042 else
01043 mActionUndo->setText( i18n( "Undo %1" ).arg( undo->top()->name() ) );
01044
01045 mActionUndo->setEnabled( !undo->isEmpty() );
01046
01047 if ( !redo->top() )
01048 mActionRedo->setText( i18n( "Redo" ) );
01049 else
01050 mActionRedo->setText( i18n( "Redo %1" ).arg( redo->top()->name() ) );
01051
01052 mActionRedo->setEnabled( !redo->isEmpty() );
01053 }
01054
01055 void KABCore::setCategories()
01056 {
01057
01058 if ( mCategorySelectDialog == 0 ) {
01059 mCategorySelectDialog = new KPIM::CategorySelectDialog( KABPrefs::instance(), mWidget );
01060 connect( mCategorySelectDialog, SIGNAL( categoriesSelected( const QStringList& ) ),
01061 SLOT( categoriesSelected( const QStringList& ) ) );
01062 connect( mCategorySelectDialog, SIGNAL( editCategories() ), SLOT( editCategories() ) );
01063 }
01064
01065 QStringList selected = mCategorySelectDialog->selectedCategories();
01066 mCategorySelectDialog->setCategories();
01067 mCategorySelectDialog->setSelected( selected );
01068 mCategorySelectDialog->show();
01069 mCategorySelectDialog->raise();
01070 }
01071
01072 void KABCore::categoriesSelected( const QStringList &categories )
01073 {
01074 bool merge = false;
01075 QString msg = i18n( "Merge with existing categories?" );
01076 if ( KMessageBox::questionYesNo( mWidget, msg ) == KMessageBox::Yes )
01077 merge = true;
01078
01079 QStringList uids = mViewManager->selectedUids();
01080 QStringList::ConstIterator it;
01081 for ( it = uids.begin(); it != uids.end(); ++it ) {
01082 KABC::Addressee addr = mAddressBook->findByUid( *it );
01083 if ( !addr.isEmpty() ) {
01084 if ( !merge )
01085 addr.setCategories( categories );
01086 else {
01087 QStringList addrCategories = addr.categories();
01088 QStringList::ConstIterator catIt;
01089 for ( catIt = categories.begin(); catIt != categories.end(); ++catIt ) {
01090 if ( !addrCategories.contains( *catIt ) )
01091 addrCategories.append( *catIt );
01092 }
01093 addr.setCategories( addrCategories );
01094 }
01095
01096 mAddressBook->insertAddressee( addr );
01097 }
01098 }
01099
01100 if ( uids.count() > 0 )
01101 setModified( true );
01102 }
01103
01104 void KABCore::editCategories()
01105 {
01106 if ( mCategoryEditDialog == 0 ) {
01107 mCategoryEditDialog = new KPIM::CategoryEditDialog( KABPrefs::instance(), mWidget );
01108 connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ),
01109 SLOT( setCategories() ) );
01110 }
01111
01112 mCategoryEditDialog->show();
01113 mCategoryEditDialog->raise();
01114 }
01115
01116 bool KABCore::handleCommandLine( KAddressBookIface* iface )
01117 {
01118 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
01119 QCString addrStr = args->getOption( "addr" );
01120 QCString uidStr = args->getOption( "uid" );
01121
01122 QString addr, uid, vcard;
01123 if ( !addrStr.isEmpty() )
01124 addr = QString::fromLocal8Bit( addrStr );
01125 if ( !uidStr.isEmpty() )
01126 uid = QString::fromLocal8Bit( uidStr );
01127
01128 bool doneSomething = false;
01129
01130
01131 if ( !addr.isEmpty() ) {
01132 iface->addEmail( addr );
01133 doneSomething = true;
01134 }
01135
01136 if ( !uid.isEmpty() ) {
01137 iface->showContactEditor( uid );
01138 doneSomething = true;
01139 }
01140
01141 if ( args->isSet( "new-contact" ) ) {
01142 iface->newContact();
01143 doneSomething = true;
01144 }
01145
01146 if ( args->count() >= 1 ) {
01147 for ( int i = 0; i < args->count(); ++i )
01148 iface->importVCard( args->url( i ).url() );
01149 doneSomething = true;
01150 }
01151 return doneSomething;
01152 }
01153
01154 #include "kabcore.moc"