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 #include <unistd.h>
00026 #include <qeventloop.h>
00027
00028 #include <qclipboard.h>
00029 #include <qdir.h>
00030 #include <qfile.h>
00031 #include <qlabel.h>
00032 #include <qlayout.h>
00033 #include <qptrlist.h>
00034 #include <qwidgetstack.h>
00035 #include <qregexp.h>
00036 #include <qvbox.h>
00037 #include <qtooltip.h>
00038 #include <qwhatsthis.h>
00039
00040 #include <kabc/addresseelist.h>
00041 #include <kabc/errorhandler.h>
00042 #include <kabc/resource.h>
00043 #include <kabc/stdaddressbook.h>
00044 #include <kabc/vcardconverter.h>
00045 #include <kabc/resourcefile.h>
00046 #include <kaboutdata.h>
00047 #include <kaccelmanager.h>
00048 #include <kapplication.h>
00049 #include <dcopclient.h>
00050 #include <kactionclasses.h>
00051 #include <kcmdlineargs.h>
00052 #include <kcmultidialog.h>
00053 #include <kdebug.h>
00054 #include <kdeversion.h>
00055 #include <kimproxy.h>
00056 #include <klocale.h>
00057 #include <kmessagebox.h>
00058 #include <kprinter.h>
00059 #include <kprotocolinfo.h>
00060 #include <kpushbutton.h>
00061 #include <kresources/selectdialog.h>
00062 #include <kstandarddirs.h>
00063 #include <kstatusbar.h>
00064 #include <kstdguiitem.h>
00065 #include <kxmlguiclient.h>
00066 #include <ktoolbar.h>
00067 #include <libkdepim/addresseeview.h>
00068 #include <libkdepim/categoryeditdialog.h>
00069 #include <libkdepim/categoryselectdialog.h>
00070 #include <libkdepim/resourceabc.h>
00071 #include "distributionlisteditor.h"
00072
00073 #include "addresseeutil.h"
00074 #include "addresseeeditordialog.h"
00075 #include "distributionlistentryview.h"
00076 #include "extensionmanager.h"
00077 #include "filterselectionwidget.h"
00078 #include "incsearchwidget.h"
00079 #include "jumpbuttonbar.h"
00080 #include "kablock.h"
00081 #include "kabprefs.h"
00082 #include "kabtools.h"
00083 #include "kaddressbookservice.h"
00084 #include "kaddressbookiface.h"
00085 #include "ldapsearchdialog.h"
00086 #include "locationmap.h"
00087 #include "printing/printingwizard.h"
00088 #include "searchmanager.h"
00089 #include "undocmds.h"
00090 #include "viewmanager.h"
00091 #include "xxportmanager.h"
00092
00093 #include "kabcore.h"
00094
00095 KABCore::KABCore( KXMLGUIClient *client, bool readWrite, QWidget *parent,
00096 const QString &file, const char *name )
00097 : KAB::Core( client, parent, name ), mStatusBar( 0 ), mViewManager( 0 ),
00098 mExtensionManager( 0 ), mJumpButtonBar( 0 ), mCategorySelectDialog( 0 ),
00099 mCategoryEditDialog( 0 ), mLdapSearchDialog( 0 ), mReadWrite( readWrite ),
00100 mModified( false )
00101 {
00102 mWidget = new QWidget( parent, name );
00103
00104 mIsPart = !parent->isA( "KAddressBookMain" );
00105
00106 mAddressBookChangedTimer = new QTimer( this );
00107 connect( mAddressBookChangedTimer, SIGNAL( timeout() ),
00108 this, SLOT( addressBookChanged() ) );
00109
00110 if ( file.isEmpty() ) {
00111 mAddressBook = KABC::StdAddressBook::self( true );
00112 } else {
00113 kdDebug(5720) << "KABCore(): document '" << file << "'" << endl;
00114 mAddressBook = new KABC::AddressBook;
00115 mAddressBook->addResource( new KABC::ResourceFile( file ) );
00116 if ( !mAddressBook->load() ) {
00117 KMessageBox::error( parent, i18n("Unable to load '%1'.").arg( file ) );
00118 }
00119 }
00120 mAddressBook->setErrorHandler( new KABC::GuiErrorHandler( mWidget ) );
00121
00122 #if ! KDE_IS_VERSION(3,5,8)
00123 mAddressBook->addCustomField( i18n( "Department" ), KABC::Field::Organization,
00124 "X-Department", "KADDRESSBOOK" );
00125 #endif
00126 mAddressBook->addCustomField( i18n( "Profession" ), KABC::Field::Organization,
00127 "X-Profession", "KADDRESSBOOK" );
00128 mAddressBook->addCustomField( i18n( "Assistant's Name" ), KABC::Field::Organization,
00129 "X-AssistantsName", "KADDRESSBOOK" );
00130 mAddressBook->addCustomField( i18n( "Manager's Name" ), KABC::Field::Organization,
00131 "X-ManagersName", "KADDRESSBOOK" );
00132 mAddressBook->addCustomField( i18n( "Partner's Name" ), KABC::Field::Personal,
00133 "X-SpousesName", "KADDRESSBOOK" );
00134 mAddressBook->addCustomField( i18n( "Office" ), KABC::Field::Personal,
00135 "X-Office", "KADDRESSBOOK" );
00136 mAddressBook->addCustomField( i18n( "IM Address" ), KABC::Field::Personal,
00137 "X-IMAddress", "KADDRESSBOOK" );
00138 mAddressBook->addCustomField( i18n( "Anniversary" ), KABC::Field::Personal,
00139 "X-Anniversary", "KADDRESSBOOK" );
00140 mAddressBook->addCustomField( i18n( "Blog" ), KABC::Field::Personal,
00141 "BlogFeed", "KADDRESSBOOK" );
00142
00143 mSearchManager = new KAB::SearchManager( mAddressBook, parent );
00144
00145 connect( mSearchManager, SIGNAL( contactsUpdated() ),
00146 this, SLOT( slotContactsUpdated() ) );
00147
00148 initGUI();
00149
00150 connect( mAddressBook, SIGNAL( addressBookChanged( AddressBook* ) ),
00151 SLOT( delayedAddressBookChanged() ) );
00152 connect( mAddressBook, SIGNAL( loadingFinished( Resource* ) ),
00153 SLOT( delayedAddressBookChanged() ) );
00154
00155 mIncSearchWidget->setFocus();
00156
00157 connect( mViewManager, SIGNAL( selected( const QString& ) ),
00158 SLOT( setContactSelected( const QString& ) ) );
00159 connect( mViewManager, SIGNAL( executed( const QString& ) ),
00160 SLOT( editContact( const QString& ) ) );
00161 connect( mViewManager, SIGNAL( modified() ),
00162 SLOT( setModified() ) );
00163 connect( mViewManager, SIGNAL( urlDropped( const KURL& ) ),
00164 mXXPortManager, SLOT( importVCard( const KURL& ) ) );
00165 connect( mViewManager, SIGNAL( viewFieldsChanged() ),
00166 SLOT( updateIncSearchWidget() ) );
00167 connect( mExtensionManager, SIGNAL( modified( const KABC::Addressee::List& ) ),
00168 this, SLOT( extensionModified( const KABC::Addressee::List& ) ) );
00169 connect( mExtensionManager, SIGNAL( deleted( const QStringList& ) ),
00170 this, SLOT( extensionDeleted( const QStringList& ) ) );
00171
00172 connect( mXXPortManager, SIGNAL( modified() ),
00173 SLOT( setModified() ) );
00174
00175 connect( mDetailsViewer, SIGNAL( highlightedMessage( const QString& ) ),
00176 SLOT( detailsHighlighted( const QString& ) ) );
00177
00178 connect( mIncSearchWidget, SIGNAL( scrollUp() ),
00179 mViewManager, SLOT( scrollUp() ) );
00180 connect( mIncSearchWidget, SIGNAL( scrollDown() ),
00181 mViewManager, SLOT( scrollDown() ) );
00182
00183 mAddressBookService = new KAddressBookService( this );
00184
00185 mCommandHistory = new KCommandHistory( actionCollection(), true );
00186 connect( mCommandHistory, SIGNAL( commandExecuted() ),
00187 mSearchManager, SLOT( reload() ) );
00188
00189 mSearchManager->reload();
00190
00191 setModified( false );
00192
00193 KAcceleratorManager::manage( mWidget );
00194
00195 mKIMProxy = ::KIMProxy::instance( kapp->dcopClient() );
00196 }
00197
00198 KABCore::~KABCore()
00199 {
00200 mAddressBook->disconnect();
00201
00202 mAddressBook = 0;
00203 KABC::StdAddressBook::close();
00204 mKIMProxy = 0;
00205 }
00206
00207 void KABCore::restoreSettings()
00208 {
00209 bool state = KABPrefs::instance()->jumpButtonBarVisible();
00210 mActionJumpBar->setChecked( state );
00211 setJumpButtonBarVisible( state );
00212
00213 state = KABPrefs::instance()->detailsPageVisible();
00214 mActionDetails->setChecked( state );
00215 setDetailsVisible( state );
00216
00217 mViewManager->restoreSettings();
00218 mExtensionManager->restoreSettings();
00219
00220 updateIncSearchWidget();
00221 mIncSearchWidget->setCurrentItem( KABPrefs::instance()->currentIncSearchField() );
00222
00223 QValueList<int> splitterSize = KABPrefs::instance()->detailsSplitter();
00224 if ( splitterSize.count() == 0 ) {
00225 splitterSize.append( 360 );
00226 splitterSize.append( 260 );
00227 }
00228 mDetailsSplitter->setSizes( splitterSize );
00229
00230 const QValueList<int> leftSplitterSizes = KABPrefs::instance()->leftSplitter();
00231 if ( !leftSplitterSizes.isEmpty() )
00232 mLeftSplitter->setSizes( leftSplitterSizes );
00233 }
00234
00235 void KABCore::saveSettings()
00236 {
00237 KABPrefs::instance()->setJumpButtonBarVisible( mActionJumpBar->isChecked() );
00238 KABPrefs::instance()->setDetailsPageVisible( mActionDetails->isChecked() );
00239 KABPrefs::instance()->setDetailsSplitter( mDetailsSplitter->sizes() );
00240 KABPrefs::instance()->setLeftSplitter( mLeftSplitter->sizes() );
00241
00242 mExtensionManager->saveSettings();
00243 mViewManager->saveSettings();
00244
00245 KABPrefs::instance()->setCurrentIncSearchField( mIncSearchWidget->currentItem() );
00246 }
00247
00248 KABC::AddressBook *KABCore::addressBook() const
00249 {
00250 return mAddressBook;
00251 }
00252
00253 KConfig *KABCore::config() const
00254 {
00255 return KABPrefs::instance()->config();
00256 }
00257
00258 KActionCollection *KABCore::actionCollection() const
00259 {
00260 return guiClient()->actionCollection();
00261 }
00262
00263 KABC::Field *KABCore::currentSortField() const
00264 {
00265 return mViewManager->currentSortField();
00266 }
00267
00268 QStringList KABCore::selectedUIDs() const
00269 {
00270 return mViewManager->selectedUids();
00271 }
00272
00273 KABC::Resource *KABCore::requestResource( QWidget *parent )
00274 {
00275 QPtrList<KABC::Resource> kabcResources = addressBook()->resources();
00276
00277 QPtrList<KRES::Resource> kresResources;
00278 QPtrListIterator<KABC::Resource> resIt( kabcResources );
00279 KABC::Resource *resource;
00280 while ( ( resource = resIt.current() ) != 0 ) {
00281 ++resIt;
00282 if ( !resource->readOnly() ) {
00283 KRES::Resource *res = resource;
00284 kresResources.append( res );
00285 }
00286 }
00287
00288 KRES::Resource *res = KRES::SelectDialog::getResource( kresResources, parent );
00289 return static_cast<KABC::Resource*>( res );
00290 }
00291
00292 QWidget *KABCore::widget() const
00293 {
00294 return mWidget;
00295 }
00296
00297 KAboutData *KABCore::createAboutData()
00298 {
00299 KAboutData *about = new KAboutData( "kaddressbook", I18N_NOOP( "KAddressBook" ),
00300 "3.5.10", I18N_NOOP( "The KDE Address Book" ),
00301 KAboutData::License_GPL_V2,
00302 I18N_NOOP( "(c) 1997-2005, The KDE PIM Team" ) );
00303 about->addAuthor( "Tobias Koenig", I18N_NOOP( "Current maintainer" ), "tokoe@kde.org" );
00304 about->addAuthor( "Don Sanders", I18N_NOOP( "Original author" ) );
00305 about->addAuthor( "Cornelius Schumacher",
00306 I18N_NOOP( "Co-maintainer, libkabc port, CSV import/export" ),
00307 "schumacher@kde.org" );
00308 about->addAuthor( "Mike Pilone", I18N_NOOP( "GUI and framework redesign" ),
00309 "mpilone@slac.com" );
00310 about->addAuthor( "Greg Stern", I18N_NOOP( "DCOP interface" ) );
00311 about->addAuthor( "Mark Westcott", I18N_NOOP( "Contact pinning" ) );
00312 about->addAuthor( "Mischel Boyer de la Giroday", I18N_NOOP( "LDAP Lookup" ),
00313 "michel@klaralvdalens-datakonsult.se" );
00314 about->addAuthor( "Steffen Hansen", I18N_NOOP( "LDAP Lookup" ),
00315 "hansen@kde.org" );
00316
00317 return about;
00318 }
00319
00320 void KABCore::setStatusBar( KStatusBar *statusBar )
00321 {
00322 mStatusBar = statusBar;
00323 }
00324
00325 KStatusBar *KABCore::statusBar() const
00326 {
00327 return mStatusBar;
00328 }
00329
00330 void KABCore::setContactSelected( const QString &uid )
00331 {
00332 KABC::Addressee addr = mAddressBook->findByUid( uid );
00333 if ( !mDetailsViewer->isHidden() )
00334 mDetailsViewer->setAddressee( addr );
00335 #ifdef KDEPIM_NEW_DISTRLISTS
00336 if ( !mSelectedDistributionList.isNull() && mDistListEntryView->isShown() ) {
00337 showDistributionListEntry( uid );
00338 }
00339 #endif
00340 mExtensionManager->setSelectionChanged();
00341
00342 KABC::Addressee::List list = mViewManager->selectedAddressees();
00343 const bool someSelected = list.size() > 0;
00344 const bool singleSelected = list.size() == 1;
00345 bool writable = mReadWrite;
00346
00347 if ( writable ) {
00348
00349
00350
00351
00352 KABC::Addressee::List::ConstIterator addrIt = list.constBegin();
00353 for ( ; addrIt != list.constEnd(); ++addrIt ) {
00354 KABC::Resource *res = ( *addrIt ).resource();
00355 if ( !res ) {
00356 kdDebug() << "KABCore::setContactSelected: this addressee has no resource!" << endl;
00357 writable = false;
00358 break;
00359 }
00360 if ( res->readOnly() ) {
00361 writable = false;
00362 break;
00363 }
00364
00365 if ( res->inherits( "KPIM::ResourceABC" ) ) {
00366 KPIM::ResourceABC *resAbc = static_cast<KPIM::ResourceABC *>( res );
00367
00368 QString subresource = resAbc->uidToResourceMap()[ ( *addrIt ).uid() ];
00369 if ( !subresource.isEmpty() && !resAbc->subresourceWritable( subresource ) ) {
00370 writable = false;
00371 break;
00372 }
00373 }
00374 }
00375 }
00376
00377 bool moreThanOneResource = mAddressBook->resources().count() > 1;
00378 if ( !moreThanOneResource && !mAddressBook->resources().isEmpty() ) {
00379 KABC::Resource *res = mAddressBook->resources().first();
00380 if ( res->inherits( "KPIM::ResourceABC" ) ) {
00381 KPIM::ResourceABC *resAbc = static_cast<KPIM::ResourceABC *>( res );
00382 const QStringList subresources = resAbc->subresources();
00383 int writeables = 0;
00384 for ( QStringList::ConstIterator it = subresources.begin(); it != subresources.end(); ++it ) {
00385 if ( resAbc->subresourceActive(*it) && resAbc->subresourceWritable(*it) ) {
00386 writeables++;
00387 }
00388 }
00389 moreThanOneResource = ( writeables >= 2 );
00390 }
00391 }
00392
00393
00394
00395 mActionCopy->setEnabled( someSelected );
00396 mActionCut->setEnabled( someSelected && writable );
00397 mActionDelete->setEnabled( someSelected && writable );
00398
00399
00400 mActionEditAddressee->setEnabled( singleSelected && !mExtensionManager->isQuickEditVisible());
00401 mActionCopyAddresseeTo->setEnabled( someSelected && moreThanOneResource );
00402 mActionMoveAddresseeTo->setEnabled( someSelected && moreThanOneResource && writable );
00403 mActionMail->setEnabled( someSelected );
00404 mActionMailVCard->setEnabled( someSelected );
00405 mActionChat->setEnabled( singleSelected && mKIMProxy && mKIMProxy->initialize() );
00406 mActionWhoAmI->setEnabled( singleSelected );
00407 mActionCategories->setEnabled( someSelected && writable );
00408 mActionMerge->setEnabled( ( list.size() == 2 ) && writable );
00409
00410 if ( mReadWrite ) {
00411 QClipboard *cb = QApplication::clipboard();
00412 #if defined(KABC_VCARD_ENCODING_FIX)
00413 const QMimeSource *data = cb->data( QClipboard::Clipboard );
00414 list = AddresseeUtil::clipboardToAddressees( data->encodedData( "text/x-vcard" ) );
00415 #else
00416 list = AddresseeUtil::clipboardToAddressees( cb->text() );
00417 #endif
00418 mActionPaste->setEnabled( !list.isEmpty() );
00419 }
00420 #ifdef KDEPIM_NEW_DISTRLISTS
00421 mAddDistListButton->setEnabled( writable );
00422 mRemoveDistListButton->setEnabled( someSelected && writable );
00423 #endif
00424 }
00425
00426 void KABCore::sendMail()
00427 {
00428
00429 sendMail( mViewManager->selectedEmails().join( ", " ) );
00430 }
00431
00432 void KABCore::sendMail( const QString& email )
00433 {
00434 kapp->invokeMailer( email, "" );
00435 }
00436
00437 void KABCore::mailVCard()
00438 {
00439 QStringList uids = mViewManager->selectedUids();
00440 if ( !uids.isEmpty() )
00441 mailVCard( uids );
00442 }
00443
00444 void KABCore::mailVCard( const QStringList &uids )
00445 {
00446 KABTools::mailVCards( uids, mAddressBook );
00447 }
00448
00449 void KABCore::startChat()
00450 {
00451 QStringList uids = mViewManager->selectedUids();
00452 if ( !uids.isEmpty() )
00453 mKIMProxy->chatWithContact( uids.first() );
00454 }
00455
00456 void KABCore::browse( const QString& url )
00457 {
00458 kapp->invokeBrowser( url );
00459 }
00460
00461 void KABCore::selectAllContacts()
00462 {
00463 mViewManager->setSelected( QString::null, true );
00464 }
00465
00466 void KABCore::deleteContacts()
00467 {
00468 QStringList uidList = mViewManager->selectedUids();
00469
00470 deleteContacts( uidList );
00471 }
00472
00473 void KABCore::deleteDistributionLists( const QStringList & names )
00474 {
00475 if ( names.isEmpty() )
00476 return;
00477 if ( KMessageBox::warningContinueCancelList( mWidget, i18n( "Do you really want to delete this distribution list?",
00478 "Do you really want to delete these %n distribution lists?", names.count() ),
00479 names, QString::null, KStdGuiItem::del() ) == KMessageBox::Cancel )
00480 return;
00481
00482 QStringList uids;
00483 for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it ) {
00484 uids.append( KPIM::DistributionList::findByName( mAddressBook, *it ).uid() );
00485 }
00486 DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
00487 mCommandHistory->addCommand( command );
00488 setModified( true );
00489 }
00490
00491 void KABCore::deleteContacts( const QStringList &uids )
00492 {
00493 if ( uids.count() > 0 ) {
00494 QStringList names;
00495 QStringList::ConstIterator it = uids.begin();
00496 const QStringList::ConstIterator endIt( uids.end() );
00497 while ( it != endIt ) {
00498 KABC::Addressee addr = mAddressBook->findByUid( *it );
00499 names.append( addr.realName().isEmpty() ? addr.preferredEmail() : addr.realName() );
00500 ++it;
00501 }
00502
00503 if ( KMessageBox::warningContinueCancelList(
00504 mWidget,
00505 i18n( "<qt>"
00506 "Do you really want to delete this contact from your addressbook?<br>"
00507 "<b>Note:</b>The contact will be also removed from all distribution lists."
00508 "</qt>",
00509 "<qt>"
00510 "Do you really want to delete these %n contacts from your addressbook?<br>"
00511 "<b>Note:</b>The contacts will be also removed from all distribution lists."
00512 "</qt>",
00513 uids.count() ),
00514 names, QString::null, KStdGuiItem::del() ) == KMessageBox::Cancel ) {
00515 return;
00516 }
00517
00518 DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
00519 mCommandHistory->addCommand( command );
00520
00521
00522 setContactSelected( QString::null );
00523 setModified( true );
00524 }
00525 }
00526
00527 void KABCore::copyContacts()
00528 {
00529 KABC::Addressee::List addrList = mViewManager->selectedAddressees();
00530
00531 #if defined(KABC_VCARD_ENCODING_FIX)
00532 QByteArray clipText = AddresseeUtil::addresseesToClipboard( addrList );
00533 QClipboard *cb = QApplication::clipboard();
00534 cb->setText( QString::fromUtf8( clipText.data() ) );
00535 #else
00536 QString clipText = AddresseeUtil::addresseesToClipboard( addrList );
00537 QClipboard *cb = QApplication::clipboard();
00538 cb->setText( clipText );
00539 #endif
00540 }
00541
00542 void KABCore::cutContacts()
00543 {
00544 QStringList uidList = mViewManager->selectedUids();
00545
00546 if ( uidList.size() > 0 ) {
00547 CutCommand *command = new CutCommand( mAddressBook, uidList );
00548 mCommandHistory->addCommand( command );
00549
00550 setModified( true );
00551 }
00552 }
00553
00554 void KABCore::pasteContacts()
00555 {
00556 QClipboard *cb = QApplication::clipboard();
00557 #if defined(KABC_VCARD_ENCODING_FIX)
00558 const QMimeSource *data = cb->data( QClipboard::Clipboard );
00559 KABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( data->encodedData( "text/x-vcard" ) );
00560 #else
00561 KABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( cb->text() );
00562 #endif
00563 pasteContacts( list );
00564 }
00565
00566 void KABCore::pasteContacts( KABC::Addressee::List &list )
00567 {
00568 KABC::Resource *resource = requestResource( mWidget );
00569 if ( !resource )
00570 return;
00571
00572 KABC::Addressee::List::Iterator it;
00573 const KABC::Addressee::List::Iterator endIt( list.end() );
00574 for ( it = list.begin(); it != endIt; ++it )
00575 (*it).setResource( resource );
00576
00577 PasteCommand *command = new PasteCommand( this, list );
00578 mCommandHistory->addCommand( command );
00579
00580 setModified( true );
00581 }
00582
00583 void KABCore::mergeContacts()
00584 {
00585 KABC::Addressee::List list = mViewManager->selectedAddressees();
00586 if ( list.count() < 2 )
00587 return;
00588
00589 KABC::Addressee addr = KABTools::mergeContacts( list );
00590
00591 KABC::Addressee::List::Iterator it = list.begin();
00592 const KABC::Addressee::List::Iterator endIt( list.end() );
00593 KABC::Addressee origAddr = *it;
00594 QStringList uids;
00595 ++it;
00596 while ( it != endIt ) {
00597 uids.append( (*it).uid() );
00598 ++it;
00599 }
00600
00601 DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
00602 mCommandHistory->addCommand( command );
00603
00604 EditCommand *editCommand = new EditCommand( mAddressBook, origAddr, addr );
00605 mCommandHistory->addCommand( editCommand );
00606
00607 mSearchManager->reload();
00608 }
00609
00610 void KABCore::setWhoAmI()
00611 {
00612 KABC::Addressee::List addrList = mViewManager->selectedAddressees();
00613
00614 if ( addrList.count() > 1 ) {
00615
00616 KMessageBox::sorry( mWidget, i18n( "Please select only one contact." ) );
00617 return;
00618 }
00619
00620 QString text( i18n( "<qt>Do you really want to use <b>%1</b> as your new personal contact?</qt>" ) );
00621 if ( KMessageBox::questionYesNo( mWidget, text.arg( addrList[ 0 ].assembledName() ), QString::null, i18n("Use"), i18n("Do Not Use") ) == KMessageBox::Yes )
00622 static_cast<KABC::StdAddressBook*>( KABC::StdAddressBook::self( true ) )->setWhoAmI( addrList[ 0 ] );
00623 }
00624
00625 void KABCore::incrementalTextSearch( const QString& text )
00626 {
00627 setContactSelected( QString::null );
00628 mSearchManager->search( text, mIncSearchWidget->currentFields() );
00629 }
00630
00631 void KABCore::incrementalJumpButtonSearch( const QString& character )
00632 {
00633 mViewManager->setSelected( QString::null, false );
00634
00635 KABC::AddresseeList list = mSearchManager->contacts();
00636 KABC::Field *field = mViewManager->currentSortField();
00637 if ( field ) {
00638 list.sortByField( field );
00639 KABC::AddresseeList::ConstIterator it;
00640 const KABC::AddresseeList::ConstIterator endIt( list.end() );
00641 for ( it = list.begin(); it != endIt; ++it ) {
00642 if ( field->value( *it ).startsWith( character, false ) ) {
00643 mViewManager->setSelected( (*it).uid(), true );
00644 return;
00645 }
00646 }
00647 }
00648 }
00649
00650 void KABCore::setModified()
00651 {
00652 setModified( true );
00653 }
00654
00655 void KABCore::setModified( bool modified )
00656 {
00657 mModified = modified;
00658 mActionSave->setEnabled( mModified );
00659
00660 mSearchManager->reload();
00661 }
00662
00663 bool KABCore::modified() const
00664 {
00665 return mModified;
00666 }
00667
00668 void KABCore::contactModified( const KABC::Addressee &addr )
00669 {
00670 Command *command = 0;
00671
00672
00673 KABC::Addressee origAddr = mAddressBook->findByUid( addr.uid() );
00674 if ( origAddr.isEmpty() ) {
00675 KABC::Addressee::List addressees;
00676 addressees.append( addr );
00677 command = new NewCommand( mAddressBook, addressees );
00678 } else {
00679 command = new EditCommand( mAddressBook, origAddr, addr );
00680 }
00681
00682 mCommandHistory->addCommand( command );
00683
00684 setContactSelected( addr.uid() );
00685 setModified( true );
00686 }
00687
00688 void KABCore::newDistributionList()
00689 {
00690 #ifdef KDEPIM_NEW_DISTRLISTS
00691 KABC::Resource *resource = requestResource( mWidget );
00692 if ( !resource )
00693 return;
00694
00695 QString name = i18n( "New Distribution List" );
00696 const KPIM::DistributionList distList = KPIM::DistributionList::findByName( addressBook(), name );
00697 if ( !distList.isEmpty() ) {
00698 bool foundUnused = false;
00699 int i = 1;
00700 while ( !foundUnused ) {
00701 name = i18n( "New Distribution List (%1)" ).arg( i++ );
00702 foundUnused = KPIM::DistributionList::findByName( addressBook(), name ).isEmpty();
00703 }
00704 }
00705 KPIM::DistributionList list;
00706 list.setUid( KApplication::randomString( 10 ) );
00707 list.setName( name );
00708 list.setResource( resource );
00709 editDistributionList( list );
00710 #endif
00711 }
00712
00713 void KABCore::newContact()
00714 {
00715 AddresseeEditorDialog *dialog = 0;
00716
00717 KABC::Resource* resource = requestResource( mWidget );
00718
00719 if ( resource ) {
00720 KABC::Addressee addr;
00721 addr.setResource( resource );
00722
00723 if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) )
00724 return;
00725
00726 dialog = createAddresseeEditorDialog( mWidget );
00727 dialog->setAddressee( addr );
00728 } else
00729 return;
00730
00731 mEditorDict.insert( dialog->addressee().uid(), dialog );
00732
00733 dialog->show();
00734 }
00735
00736 void KABCore::addEmail( const QString &aStr )
00737 {
00738 QString fullName, email;
00739
00740 KABC::Addressee::parseEmailAddress( aStr, fullName, email );
00741
00742 #if KDE_IS_VERSION(3,4,89)
00743
00744
00745 while ( !mAddressBook->loadingHasFinished() ) {
00746 QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00747
00748 usleep( 100 );
00749 }
00750 #endif
00751
00752
00753 bool found = false;
00754 QStringList emailList;
00755 KABC::AddressBook::Iterator it;
00756 const KABC::AddressBook::Iterator endIt( mAddressBook->end() );
00757 for ( it = mAddressBook->begin(); !found && (it != endIt); ++it ) {
00758 emailList = (*it).emails();
00759 if ( emailList.contains( email ) > 0 ) {
00760 found = true;
00761 (*it).setNameFromString( fullName );
00762 editContact( (*it).uid() );
00763 }
00764 }
00765
00766 if ( !found ) {
00767 KABC::Addressee addr;
00768 addr.setNameFromString( fullName );
00769 addr.insertEmail( email, true );
00770
00771 mAddressBook->insertAddressee( addr );
00772 mViewManager->refreshView( addr.uid() );
00773 editContact( addr.uid() );
00774 }
00775 }
00776
00777 void KABCore::importVCard( const KURL &url )
00778 {
00779 mXXPortManager->importVCard( url );
00780 }
00781
00782 void KABCore::importVCardFromData( const QString &vCard )
00783 {
00784 mXXPortManager->importVCardFromData( vCard );
00785 }
00786
00787 void KABCore::editContact( const QString &uid )
00788 {
00789 if ( mExtensionManager->isQuickEditVisible() )
00790 return;
00791
00792
00793 QString localUID = uid;
00794 if ( localUID.isNull() ) {
00795 QStringList uidList = mViewManager->selectedUids();
00796 if ( uidList.count() > 0 )
00797 localUID = *( uidList.at( 0 ) );
00798 }
00799 #if KDE_IS_VERSION(3,4,89)
00800
00801
00802
00803 else while ( !mAddressBook->loadingHasFinished() ) {
00804 QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00805
00806 usleep( 100 );
00807 }
00808 #endif
00809
00810 KABC::Addressee addr = mAddressBook->findByUid( localUID );
00811 if ( !addr.isEmpty() ) {
00812 AddresseeEditorDialog *dialog = mEditorDict.find( addr.uid() );
00813 if ( !dialog ) {
00814
00815 if ( !addr.resource()->readOnly() )
00816 if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) ) {
00817 return;
00818 }
00819
00820 dialog = createAddresseeEditorDialog( mWidget );
00821
00822 mEditorDict.insert( addr.uid(), dialog );
00823
00824 dialog->setAddressee( addr );
00825 }
00826
00827 dialog->raise();
00828 dialog->show();
00829 }
00830 }
00831
00832
00833 void KABCore::copySelectedContactToResource()
00834 {
00835 storeContactIn( QString(), true );
00836 }
00837
00838 void KABCore::moveSelectedContactToResource()
00839 {
00840 storeContactIn( QString(), false );
00841 }
00842
00843 void KABCore::storeContactIn( const QString &uid, bool copy )
00844 {
00845
00846 QStringList uidList;
00847 if ( uid.isNull() ) {
00848 uidList = mViewManager->selectedUids();
00849 } else {
00850 uidList << uid;
00851 }
00852 KABC::Resource *resource = requestResource( mWidget );
00853 if ( !resource )
00854 return;
00855
00856 if ( copy ) {
00857 CopyToCommand *command = new CopyToCommand( mAddressBook, uidList, resource );
00858 mCommandHistory->addCommand( command );
00859 }
00860 else {
00861 MoveToCommand *command = new MoveToCommand( this, uidList, resource );
00862 mCommandHistory->addCommand( command );
00863 }
00864
00865 addressBookChanged();
00866 setModified( true );
00867 }
00868
00869 void KABCore::save()
00870 {
00871 QPtrList<KABC::Resource> resources = mAddressBook->resources();
00872 QPtrListIterator<KABC::Resource> it( resources );
00873 while ( it.current() && !it.current()->readOnly() ) {
00874 KABC::Ticket *ticket = mAddressBook->requestSaveTicket( it.current() );
00875 if ( ticket ) {
00876 if ( !mAddressBook->save( ticket ) ) {
00877 KMessageBox::error( mWidget,
00878 i18n( "<qt>Unable to save address book <b>%1</b>.</qt>" ).arg( it.current()->resourceName() ) );
00879 mAddressBook->releaseSaveTicket( ticket );
00880 } else {
00881 setModified( false );
00882 }
00883 } else {
00884 KMessageBox::error( mWidget,
00885 i18n( "<qt>Unable to get access for saving the address book <b>%1</b>.</qt>" )
00886 .arg( it.current()->resourceName() ) );
00887 }
00888
00889 ++it;
00890 }
00891 }
00892
00893 void KABCore::setJumpButtonBarVisible( bool visible )
00894 {
00895 if ( visible ) {
00896 if ( !mJumpButtonBar )
00897 createJumpButtonBar();
00898 mJumpButtonBar->show();
00899 } else
00900 if ( mJumpButtonBar )
00901 mJumpButtonBar->hide();
00902 }
00903
00904 void KABCore::setDetailsVisible( bool visible )
00905 {
00906 if ( visible )
00907 mDetailsPage->show();
00908 else
00909 mDetailsPage->hide();
00910 }
00911
00912 void KABCore::extensionModified( const KABC::Addressee::List &list )
00913 {
00914 if ( list.count() != 0 ) {
00915 KABC::Addressee::List::ConstIterator it;
00916 const KABC::Addressee::List::ConstIterator endIt( list.end() );
00917 for ( it = list.begin(); it != endIt; ++it ) {
00918 Command *command = 0;
00919
00920
00921 KABC::Addressee origAddr = mAddressBook->findByUid( (*it).uid() );
00922 if ( origAddr.isEmpty() ) {
00923 KABC::Addressee::List addressees;
00924 addressees.append( *it );
00925 command = new NewCommand( mAddressBook, addressees );
00926 } else
00927 command = new EditCommand( mAddressBook, origAddr, *it );
00928
00929 mCommandHistory->blockSignals( true );
00930 mCommandHistory->addCommand( command );
00931 mCommandHistory->blockSignals( false );
00932 }
00933
00934 setModified(true);
00935 }
00936 }
00937
00938 void KABCore::extensionDeleted( const QStringList &uidList )
00939 {
00940 DeleteCommand *command = new DeleteCommand( mAddressBook, uidList );
00941 mCommandHistory->addCommand( command );
00942
00943
00944 setContactSelected( QString::null );
00945 setModified( true );
00946 }
00947
00948 QString KABCore::getNameByPhone( const QString &phone )
00949 {
00950 #if KDE_IS_VERSION(3,4,89)
00951
00952
00953 while ( !mAddressBook->loadingHasFinished() ) {
00954 QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00955
00956 usleep( 100 );
00957 }
00958 #endif
00959
00960 QRegExp r( "[/*/-/ ]" );
00961 QString localPhone( phone );
00962
00963 bool found = false;
00964 QString ownerName = "";
00965 KABC::PhoneNumber::List phoneList;
00966
00967 KABC::AddressBook::ConstIterator iter;
00968 const KABC::AddressBook::ConstIterator endIter( mAddressBook->end() );
00969
00970 for ( iter = mAddressBook->begin(); !found && ( iter != endIter ); ++iter ) {
00971 phoneList = (*iter).phoneNumbers();
00972 KABC::PhoneNumber::List::Iterator phoneIter( phoneList.begin() );
00973 const KABC::PhoneNumber::List::Iterator phoneEndIter( phoneList.end() );
00974 for ( ; !found && ( phoneIter != phoneEndIter ); ++phoneIter) {
00975
00976 if ( (*phoneIter).number().replace( r, "" ) == localPhone.replace( r, "" ) ) {
00977 ownerName = (*iter).realName();
00978 found = true;
00979 }
00980 }
00981 }
00982
00983 return ownerName;
00984 }
00985
00986 void KABCore::openLDAPDialog()
00987 {
00988 if ( !KProtocolInfo::isKnownProtocol( KURL( "ldap://localhost" ) ) ) {
00989 KMessageBox::error( mWidget, i18n( "Your KDE installation is missing LDAP "
00990 "support, please ask your administrator or distributor for more information." ),
00991 i18n( "No LDAP IO Slave Available" ) );
00992 return;
00993 }
00994
00995 if ( !mLdapSearchDialog ) {
00996 mLdapSearchDialog = new LDAPSearchDialog( mAddressBook, this, mWidget );
00997 connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ),
00998 SLOT( addressBookChanged() ) );
00999 connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ),
01000 SLOT( setModified() ) );
01001 } else
01002 mLdapSearchDialog->restoreSettings();
01003
01004 if ( mLdapSearchDialog->isOK() )
01005 mLdapSearchDialog->exec();
01006 }
01007
01008 void KABCore::configure()
01009 {
01010
01011 saveSettings();
01012
01013 KCMultiDialog dlg( mWidget, "", true );
01014 connect( &dlg, SIGNAL( configCommitted() ),
01015 this, SLOT( configurationChanged() ) );
01016
01017 dlg.addModule( "kabconfig.desktop" );
01018 dlg.addModule( "kabldapconfig.desktop" );
01019 dlg.addModule( "kabcustomfields.desktop" );
01020
01021 dlg.exec();
01022 }
01023
01024 void KABCore::print()
01025 {
01026 KPrinter printer;
01027 printer.setDocName( i18n( "Address Book" ) );
01028 printer.setDocFileName( "addressbook" );
01029
01030 if ( !printer.setup( mWidget, i18n("Print Addresses") ) )
01031 return;
01032
01033 KABPrinting::PrintingWizard wizard( &printer, mAddressBook,
01034 mViewManager->selectedUids(), mWidget );
01035
01036 wizard.exec();
01037 }
01038
01039 void KABCore::detailsHighlighted( const QString &msg )
01040 {
01041 if ( mStatusBar ) {
01042 if ( !mStatusBar->hasItem( 2 ) )
01043 mStatusBar->insertItem( msg, 2 );
01044 else
01045 mStatusBar->changeItem( msg, 2 );
01046 }
01047 }
01048
01049 void KABCore::showContactsAddress( const QString &addrUid )
01050 {
01051 QStringList uidList = mViewManager->selectedUids();
01052 if ( uidList.isEmpty() )
01053 return;
01054
01055 KABC::Addressee addr = mAddressBook->findByUid( uidList.first() );
01056 if ( addr.isEmpty() )
01057 return;
01058
01059 const KABC::Address::List list = addr.addresses();
01060 KABC::Address::List::ConstIterator it;
01061 const KABC::Address::List::ConstIterator endIt( list.end() );
01062 for ( it = list.begin(); it != endIt; ++it )
01063 if ( (*it).id() == addrUid ) {
01064 LocationMap::instance()->showAddress( *it );
01065 break;
01066 }
01067 }
01068
01069 void KABCore::configurationChanged()
01070 {
01071 mExtensionManager->reconfigure();
01072 mViewManager->refreshView();
01073 }
01074
01075 bool KABCore::queryClose()
01076 {
01077 saveSettings();
01078 KABPrefs::instance()->writeConfig();
01079
01080 QPtrList<KABC::Resource> resources = mAddressBook->resources();
01081 QPtrListIterator<KABC::Resource> it( resources );
01082 while ( it.current() ) {
01083 it.current()->close();
01084 ++it;
01085 }
01086
01087 return true;
01088 }
01089
01090 void KABCore::reinitXMLGUI()
01091 {
01092 mExtensionManager->createActions();
01093 }
01094 void KABCore::delayedAddressBookChanged()
01095 {
01096 mAddressBookChangedTimer->start( 1000 );
01097 }
01098
01099 void KABCore::addressBookChanged()
01100 {
01101 const QStringList selectedUids = mViewManager->selectedUids();
01102
01103 mAddressBookChangedTimer->stop();
01104
01105 if ( mJumpButtonBar )
01106 mJumpButtonBar->updateButtons();
01107
01108 mSearchManager->reload();
01109
01110 mViewManager->setSelected( QString::null, false );
01111
01112 QString uid = QString::null;
01113 if ( !selectedUids.isEmpty() ) {
01114 uid = selectedUids.first();
01115 mViewManager->setSelected( uid, true );
01116 }
01117
01118 setContactSelected( uid );
01119
01120 updateCategories();
01121 }
01122
01123 AddresseeEditorDialog *KABCore::createAddresseeEditorDialog( QWidget *parent,
01124 const char *name )
01125 {
01126 AddresseeEditorDialog *dialog = new AddresseeEditorDialog( this, parent,
01127 name ? name : "editorDialog" );
01128 connect( dialog, SIGNAL( contactModified( const KABC::Addressee& ) ),
01129 SLOT( contactModified( const KABC::Addressee& ) ) );
01130 connect( dialog, SIGNAL( editorDestroyed( const QString& ) ),
01131 SLOT( slotEditorDestroyed( const QString& ) ) );
01132
01133 return dialog;
01134 }
01135
01136 void KABCore::activateDetailsWidget( QWidget *widget )
01137 {
01138 if ( mDetailsStack->visibleWidget() == widget )
01139 return;
01140 mDetailsStack->raiseWidget( widget );
01141 }
01142
01143 void KABCore::deactivateDetailsWidget( QWidget *widget )
01144 {
01145 if ( mDetailsStack->visibleWidget() != widget )
01146 return;
01147 mDetailsStack->raiseWidget( mDetailsWidget );
01148 }
01149
01150 void KABCore::slotEditorDestroyed( const QString &uid )
01151 {
01152 AddresseeEditorDialog *dialog = mEditorDict.take( uid );
01153
01154 KABC::Addressee addr = dialog->addressee();
01155
01156 if ( !addr.resource()->readOnly() ) {
01157 QApplication::setOverrideCursor( Qt::waitCursor );
01158 KABLock::self( mAddressBook )->unlock( addr.resource() );
01159 QApplication::restoreOverrideCursor();
01160 }
01161 }
01162
01163 void KABCore::initGUI()
01164 {
01165 QVBoxLayout *topLayout = new QVBoxLayout( mWidget, 0, 0 );
01166 KToolBar* searchTB = new KToolBar( mWidget, "search toolbar");
01167 searchTB->boxLayout()->setSpacing( KDialog::spacingHint() );
01168 mIncSearchWidget = new IncSearchWidget( searchTB, "kde toolbar widget");
01169 searchTB->setStretchableWidget( mIncSearchWidget );
01170 connect( mIncSearchWidget, SIGNAL( doSearch( const QString& ) ),
01171 SLOT( incrementalTextSearch( const QString& ) ) );
01172
01173 mDetailsSplitter = new QSplitter( mWidget );
01174
01175 mLeftSplitter = new QSplitter( mDetailsSplitter );
01176 mLeftSplitter->setOrientation( KABPrefs::instance()->contactListAboveExtensions() ? Qt::Vertical : Qt::Horizontal );
01177
01178 topLayout->addWidget( searchTB );
01179 topLayout->addWidget( mDetailsSplitter );
01180
01181 mDetailsStack = new QWidgetStack( mDetailsSplitter );
01182 mExtensionManager = new ExtensionManager( new QWidget( mLeftSplitter ), mDetailsStack, this, this );
01183 connect( mExtensionManager, SIGNAL( detailsWidgetDeactivated( QWidget* ) ),
01184 this, SLOT( deactivateDetailsWidget( QWidget* ) ) );
01185 connect( mExtensionManager, SIGNAL( detailsWidgetActivated( QWidget* ) ),
01186 this, SLOT( activateDetailsWidget( QWidget* ) ) );
01187
01188 QWidget *viewWidget = new QWidget( mLeftSplitter );
01189 if ( KABPrefs::instance()->contactListAboveExtensions() )
01190 mLeftSplitter->moveToFirst( viewWidget );
01191 QVBoxLayout *viewLayout = new QVBoxLayout( viewWidget );
01192 viewLayout->setSpacing( KDialog::spacingHint() );
01193
01194 mViewHeaderLabel = new QLabel( viewWidget );
01195
01196 mViewHeaderLabel->setText( i18n( "Contacts" ) );
01197 viewLayout->addWidget( mViewHeaderLabel );
01198 mViewManager = new ViewManager( this, viewWidget );
01199 viewLayout->addWidget( mViewManager, 1 );
01200
01201 #ifdef KDEPIM_NEW_DISTRLISTS
01202 mDistListButtonWidget = new QWidget( viewWidget );
01203 QHBoxLayout *buttonLayout = new QHBoxLayout( mDistListButtonWidget );
01204 buttonLayout->setSpacing( KDialog::spacingHint() );
01205 buttonLayout->addStretch( 1 );
01206
01207 mAddDistListButton = new KPushButton( mDistListButtonWidget );
01208 mAddDistListButton->setEnabled( false );
01209 mAddDistListButton->setText( i18n( "Add" ) );
01210 QToolTip::add( mAddDistListButton, i18n( "Add contacts to the distribution list" ) );
01211 QWhatsThis::add( mAddDistListButton,
01212 i18n( "Click this button if you want to add more contacts to "
01213 "the current distribution list. You will be shown a dialog that allows "
01214 "to enter a list of existing contacts to this distribution list." ) );
01215 connect( mAddDistListButton, SIGNAL( clicked() ),
01216 this, SLOT( editSelectedDistributionList() ) );
01217 buttonLayout->addWidget( mAddDistListButton );
01218 mDistListButtonWidget->setShown( false );
01219 viewLayout->addWidget( mDistListButtonWidget );
01220
01221 mRemoveDistListButton = new KPushButton( mDistListButtonWidget );
01222 mRemoveDistListButton->setEnabled( false );
01223 mRemoveDistListButton->setText( i18n( "Remove" ) );
01224 QToolTip::add( mRemoveDistListButton, i18n( "Remove contacts from the distribution list" ) );
01225 QWhatsThis::add( mRemoveDistListButton,
01226 i18n( "Click this button if you want to remove the selected contacts from "
01227 "the current distribution list." ) );
01228 connect( mRemoveDistListButton, SIGNAL( clicked() ),
01229 this, SLOT( removeSelectedContactsFromDistList() ) );
01230 buttonLayout->addWidget( mRemoveDistListButton );
01231 #endif
01232
01233 mFilterSelectionWidget = new FilterSelectionWidget( searchTB , "kde toolbar widget" );
01234 mViewManager->setFilterSelectionWidget( mFilterSelectionWidget );
01235
01236 connect( mFilterSelectionWidget, SIGNAL( filterActivated( int ) ),
01237 mViewManager, SLOT( setActiveFilter( int ) ) );
01238
01239 mDetailsWidget = new QWidget( mDetailsSplitter );
01240 mDetailsLayout = new QHBoxLayout( mDetailsWidget );
01241
01242 mDetailsPage = new QWidget( mDetailsWidget );
01243 mDetailsLayout->addWidget( mDetailsPage );
01244
01245 QHBoxLayout *detailsPageLayout = new QHBoxLayout( mDetailsPage, 0, 0 );
01246 mDetailsViewer = new KPIM::AddresseeView( mDetailsPage );
01247 mDetailsViewer->setVScrollBarMode( QScrollView::Auto );
01248 detailsPageLayout->addWidget( mDetailsViewer );
01249
01250 mDistListEntryView = new KAB::DistributionListEntryView( this, mWidget );
01251 connect( mDistListEntryView, SIGNAL( distributionListClicked( const QString& ) ),
01252 this, SLOT( sendMailToDistributionList( const QString& ) ) );
01253 mDetailsStack->addWidget( mDistListEntryView );
01254 mDetailsStack->addWidget( mDetailsWidget );
01255 mDetailsStack->raiseWidget( mDetailsWidget );
01256 mDetailsSplitter->moveToLast( mDetailsStack );
01257
01258 connect( mDetailsViewer, SIGNAL( addressClicked( const QString&) ),
01259 this, SLOT( showContactsAddress( const QString& ) ) );
01260
01261 topLayout->setStretchFactor( mDetailsSplitter, 1 );
01262
01263 mXXPortManager = new XXPortManager( this, mWidget );
01264
01265 initActions();
01266 }
01267
01268 void KABCore::createJumpButtonBar()
01269 {
01270 mJumpButtonBar = new JumpButtonBar( this, mDetailsWidget );
01271 mDetailsLayout->addWidget( mJumpButtonBar );
01272 mDetailsLayout->setStretchFactor( mJumpButtonBar, 1 );
01273
01274 connect( mJumpButtonBar, SIGNAL( jumpToLetter( const QString& ) ),
01275 SLOT( incrementalJumpButtonSearch( const QString& ) ) );
01276 connect( mViewManager, SIGNAL( sortFieldChanged() ),
01277 mJumpButtonBar, SLOT( updateButtons() ) );
01278 }
01279
01280 void KABCore::initActions()
01281 {
01282 connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
01283 SLOT( clipboardDataChanged() ) );
01284
01285 KAction *action;
01286
01287
01288 mActionMail = new KAction( i18n( "&Send Email to Contact..." ), "mail_send", 0,
01289 this, SLOT( sendMail() ), actionCollection(), "file_mail" );
01290 action = KStdAction::print( this, SLOT( print() ), actionCollection() );
01291 mActionMail->setWhatsThis( i18n( "Send a mail to all selected contacts." ) );
01292 action->setWhatsThis( i18n( "Print a special number of contacts." ) );
01293
01294 mActionSave = KStdAction::save( this,
01295 SLOT( save() ), actionCollection(), "file_sync" );
01296 mActionSave->setWhatsThis( i18n( "Save all changes of the address book to the storage backend." ) );
01297
01298 action = new KAction( i18n( "&New Contact..." ), "identity", CTRL+Key_N, this,
01299 SLOT( newContact() ), actionCollection(), "file_new_contact" );
01300 action->setWhatsThis( i18n( "Create a new contact<p>You will be presented with a dialog where you can add all data about a person, including addresses and phone numbers." ) );
01301
01302 action = new KAction( i18n( "&New Distribution List..." ), "kontact_contacts", 0, this,
01303 SLOT( newDistributionList() ), actionCollection(), "file_new_distributionlist" );
01304 action->setWhatsThis( i18n( "Create a new distribution list<p>You will be presented with a dialog where you can create a new distribution list." ) );
01305
01306 mActionMailVCard = new KAction( i18n("Send &Contact..."), "mail_post_to", 0,
01307 this, SLOT( mailVCard() ),
01308 actionCollection(), "file_mail_vcard" );
01309 mActionMailVCard->setWhatsThis( i18n( "Send a mail with the selected contact as attachment." ) );
01310
01311 mActionChat = new KAction( i18n("Chat &With..."), 0,
01312 this, SLOT( startChat() ),
01313 actionCollection(), "file_chat" );
01314 mActionChat->setWhatsThis( i18n( "Start a chat with the selected contact." ) );
01315
01316 mActionEditAddressee = new KAction( i18n( "&Edit Contact..." ), "edit", 0,
01317 this, SLOT( editContact() ),
01318 actionCollection(), "file_properties" );
01319 mActionEditAddressee->setWhatsThis( i18n( "Edit a contact<p>You will be presented with a dialog where you can change all data about a person, including addresses and phone numbers." ) );
01320
01321 mActionMerge = new KAction( i18n( "&Merge Contacts" ), "", 0,
01322 this, SLOT( mergeContacts() ),
01323 actionCollection(), "edit_merge" );
01324
01325
01326 mActionCopy = KStdAction::copy( this, SLOT( copyContacts() ), actionCollection() );
01327 mActionCut = KStdAction::cut( this, SLOT( cutContacts() ), actionCollection() );
01328 mActionPaste = KStdAction::paste( this, SLOT( pasteContacts() ), actionCollection() );
01329 action = KStdAction::selectAll( this, SLOT( selectAllContacts() ), actionCollection() );
01330 mActionCopy->setWhatsThis( i18n( "Copy the currently selected contact(s) to system clipboard in vCard format." ) );
01331 mActionCut->setWhatsThis( i18n( "Cuts the currently selected contact(s) to system clipboard in vCard format." ) );
01332 mActionPaste->setWhatsThis( i18n( "Paste the previously cut or copied contacts from clipboard." ) );
01333 action->setWhatsThis( i18n( "Selects all visible contacts from current view." ) );
01334
01335
01336
01337 mActionDelete = new KAction( i18n( "&Delete Contact" ), "editdelete",
01338 Key_Delete, this, SLOT( deleteContacts() ),
01339 actionCollection(), "edit_delete" );
01340 mActionDelete->setWhatsThis( i18n( "Delete all selected contacts." ) );
01341
01342
01343 mActionCopyAddresseeTo = new KAction( i18n( "&Copy Contact To..." ), "", 0,
01344 this, SLOT( copySelectedContactToResource() ),
01345 actionCollection(), "copy_contact_to" );
01346 const QString copyMoveWhatsThis = i18n( "Store a contact in a different Addressbook<p>You will be presented with a dialog where you can select a new storage place for this contact." );
01347 mActionCopyAddresseeTo->setWhatsThis( copyMoveWhatsThis );
01348
01349 mActionMoveAddresseeTo = new KAction( i18n( "M&ove Contact To..." ), "", 0,
01350 this, SLOT( moveSelectedContactToResource() ),
01351 actionCollection(), "move_contact_to" );
01352 mActionMoveAddresseeTo->setWhatsThis( copyMoveWhatsThis );
01353
01354
01355 mActionJumpBar = new KToggleAction( i18n( "Show Jump Bar" ), "next", 0,
01356 actionCollection(), "options_show_jump_bar" );
01357 mActionJumpBar->setWhatsThis( i18n( "Toggle whether the jump button bar shall be visible." ) );
01358 mActionJumpBar->setCheckedState( i18n( "Hide Jump Bar") );
01359 connect( mActionJumpBar, SIGNAL( toggled( bool ) ), SLOT( setJumpButtonBarVisible( bool ) ) );
01360
01361 mActionDetails = new KToggleAction( i18n( "Show Details" ), 0, 0,
01362 actionCollection(), "options_show_details" );
01363 mActionDetails->setWhatsThis( i18n( "Toggle whether the details page shall be visible." ) );
01364 mActionDetails->setCheckedState( i18n( "Hide Details") );
01365 connect( mActionDetails, SIGNAL( toggled( bool ) ), SLOT( setDetailsVisible( bool ) ) );
01366
01367 if ( mIsPart )
01368 action = new KAction( i18n( "&Configure Address Book..." ), "configure", 0,
01369 this, SLOT( configure() ), actionCollection(),
01370 "kaddressbook_configure" );
01371 else
01372 action = KStdAction::preferences( this, SLOT( configure() ), actionCollection() );
01373
01374 action->setWhatsThis( i18n( "You will be presented with a dialog, that offers you all possibilities to configure KAddressBook." ) );
01375
01376
01377 action = new KAction( i18n( "&Lookup Addresses in LDAP Directory..." ), "find", 0,
01378 this, SLOT( openLDAPDialog() ), actionCollection(), "ldap_lookup" );
01379 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." ) );
01380
01381 mActionWhoAmI = new KAction( i18n( "Set as Personal Contact Data" ), "personal", 0, this,
01382 SLOT( setWhoAmI() ), actionCollection(),
01383 "edit_set_personal" );
01384 mActionWhoAmI->setWhatsThis( i18n( "Set the personal contact<p>The data of this contact will be used in many other KDE applications, so you do not have to input your personal data several times." ) );
01385
01386 mActionCategories = new KAction( i18n( "Select Categories..." ), 0, this,
01387 SLOT( setCategories() ), actionCollection(),
01388 "edit_set_categories" );
01389 mActionCategories->setWhatsThis( i18n( "Set the categories for all selected contacts." ) );
01390
01391 KAction *clearLocation = new KAction( i18n( "Clear Search Bar" ),
01392 QApplication::reverseLayout() ? "clear_left" : "locationbar_erase",
01393 CTRL+Key_L, this, SLOT( slotClearSearchBar() ), actionCollection(), "clear_search" );
01394 clearLocation->setWhatsThis( i18n( "Clear Search Bar<p>"
01395 "Clears the content of the quick search bar." ) );
01396
01397 clipboardDataChanged();
01398 }
01399
01400 void KABCore::clipboardDataChanged()
01401 {
01402 if ( mReadWrite )
01403 mActionPaste->setEnabled( !QApplication::clipboard()->text().isEmpty() );
01404 }
01405
01406 void KABCore::updateIncSearchWidget()
01407 {
01408 mIncSearchWidget->setViewFields( mViewManager->viewFields() );
01409 }
01410
01411 void KABCore::updateCategories()
01412 {
01413 QStringList categories( allCategories() );
01414 categories.sort();
01415
01416 const QStringList customCategories( KABPrefs::instance()->customCategories() );
01417 QStringList::ConstIterator it;
01418 const QStringList::ConstIterator endIt( customCategories.end() );
01419 for ( it = customCategories.begin(); it != endIt; ++it ) {
01420 if ( categories.find( *it ) == categories.end() ) {
01421 categories.append( *it );
01422 }
01423 }
01424
01425 KABPrefs::instance()->mCustomCategories = categories;
01426 KABPrefs::instance()->writeConfig();
01427
01428 if ( mCategoryEditDialog )
01429 mCategoryEditDialog->reload();
01430 }
01431
01432 QStringList KABCore::allCategories() const
01433 {
01434 QStringList categories, allCategories;
01435 QStringList::ConstIterator catIt;
01436
01437 KABC::AddressBook::ConstIterator it;
01438 const KABC::AddressBook::ConstIterator endIt( mAddressBook->end() );
01439 for ( it = mAddressBook->begin(); it != endIt; ++it ) {
01440 categories = (*it).categories();
01441 const QStringList::ConstIterator catEndIt( categories.end() );
01442 for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) {
01443 if ( !allCategories.contains( *catIt ) )
01444 allCategories.append( *catIt );
01445 }
01446 }
01447
01448 return allCategories;
01449 }
01450
01451 void KABCore::setCategories()
01452 {
01453
01454 if ( mCategorySelectDialog == 0 ) {
01455 mCategorySelectDialog = new KPIM::CategorySelectDialog( KABPrefs::instance(), mWidget );
01456 connect( mCategorySelectDialog, SIGNAL( categoriesSelected( const QStringList& ) ),
01457 SLOT( categoriesSelected( const QStringList& ) ) );
01458 connect( mCategorySelectDialog, SIGNAL( editCategories() ), SLOT( editCategories() ) );
01459 }
01460
01461 mCategorySelectDialog->show();
01462 mCategorySelectDialog->raise();
01463 }
01464
01465 void KABCore::categoriesSelected( const QStringList &categories )
01466 {
01467 bool merge = false;
01468 QString msg = i18n( "Merge with existing categories?" );
01469 if ( KMessageBox::questionYesNo( mWidget, msg, QString::null, i18n( "Merge" ), i18n( "Do Not Merge" ) ) == KMessageBox::Yes )
01470 merge = true;
01471
01472 QStringList uids = mViewManager->selectedUids();
01473 QStringList::ConstIterator it;
01474 const QStringList::ConstIterator endIt( uids.end() );
01475 for ( it = uids.begin(); it != endIt; ++it ) {
01476 KABC::Addressee addr = mAddressBook->findByUid( *it );
01477 if ( !addr.isEmpty() ) {
01478 if ( !merge )
01479 addr.setCategories( categories );
01480 else {
01481 QStringList addrCategories = addr.categories();
01482 QStringList::ConstIterator catIt;
01483 const QStringList::ConstIterator catEndIt( categories.end() );
01484 for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) {
01485 if ( !addrCategories.contains( *catIt ) )
01486 addrCategories.append( *catIt );
01487 }
01488 addr.setCategories( addrCategories );
01489 }
01490
01491 mAddressBook->insertAddressee( addr );
01492 }
01493 }
01494
01495 if ( uids.count() > 0 )
01496 setModified( true );
01497 }
01498
01499 void KABCore::editCategories()
01500 {
01501 if ( mCategoryEditDialog == 0 ) {
01502 mCategoryEditDialog = new KPIM::CategoryEditDialog( KABPrefs::instance(), mWidget );
01503 connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ),
01504 mCategorySelectDialog, SLOT( updateCategoryConfig() ) );
01505 }
01506
01507 mCategoryEditDialog->show();
01508 mCategoryEditDialog->raise();
01509 }
01510
01511 void KABCore::slotClearSearchBar()
01512 {
01513 mIncSearchWidget->clear();
01514 mIncSearchWidget->setFocus();
01515 }
01516
01517 void KABCore::slotContactsUpdated()
01518 {
01519 if ( mStatusBar ) {
01520 QString msg( i18n( "%n contact matches", "%n contacts matching", mSearchManager->contacts().count() ) );
01521 if ( !mStatusBar->hasItem( 1 ) )
01522 mStatusBar->insertItem( msg, 1 );
01523 else
01524 mStatusBar->changeItem( msg, 1 );
01525 }
01526
01527 emit contactsUpdated();
01528 }
01529
01530 bool KABCore::handleCommandLine( KAddressBookIface* iface )
01531 {
01532 KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
01533 QCString addrStr = args->getOption( "addr" );
01534 QCString uidStr = args->getOption( "uid" );
01535
01536 QString addr, uid, vcard;
01537 if ( !addrStr.isEmpty() )
01538 addr = QString::fromLocal8Bit( addrStr );
01539 if ( !uidStr.isEmpty() )
01540 uid = QString::fromLocal8Bit( uidStr );
01541
01542 bool doneSomething = false;
01543
01544
01545 if ( !addr.isEmpty() ) {
01546 iface->addEmail( addr );
01547 doneSomething = true;
01548 }
01549
01550 if ( !uid.isEmpty() ) {
01551 iface->showContactEditor( uid );
01552 doneSomething = true;
01553 }
01554
01555 if ( args->isSet( "new-contact" ) ) {
01556 iface->newContact();
01557 doneSomething = true;
01558 }
01559
01560 if ( args->count() >= 1 ) {
01561 for ( int i = 0; i < args->count(); ++i )
01562 iface->importVCard( args->url( i ).url() );
01563 doneSomething = true;
01564 }
01565 return doneSomething;
01566 }
01567
01568 void KABCore::removeSelectedContactsFromDistList()
01569 {
01570 #ifdef KDEPIM_NEW_DISTRLISTS
01571
01572 KPIM::DistributionList dist = KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList );
01573 if ( dist.isEmpty() )
01574 return;
01575 const QStringList uids = selectedUIDs();
01576 if ( uids.isEmpty() )
01577 return;
01578
01579 QStringList names;
01580 QStringList::ConstIterator it = uids.begin();
01581 const QStringList::ConstIterator endIt( uids.end() );
01582 while ( it != endIt ) {
01583 KABC::Addressee addr = mAddressBook->findByUid( *it );
01584 names.append( addr.realName().isEmpty() ? addr.preferredEmail() : addr.realName() );
01585 ++it;
01586 }
01587
01588 if ( KMessageBox::warningContinueCancelList(
01589 mWidget,
01590 i18n( "<qt>"
01591 "Do you really want to remove this contact from the %1 distribution list?<br>"
01592 "<b>Note:</b>The contact will be not be removed from your addressbook nor from "
01593 "any other distribution list."
01594 "</qt>",
01595 "<qt>"
01596 "Do you really want to remove these %n contacts from the %1 distribution list?<br>"
01597 "<b>Note:</b>The contacts will be not be removed from your addressbook nor from "
01598 "any other distribution list."
01599 "</qt>",
01600 uids.count() ).arg( mSelectedDistributionList ),
01601 names, QString::null, KStdGuiItem::del() ) == KMessageBox::Cancel ) {
01602 return;
01603 }
01604
01605 for ( QStringList::ConstIterator uidIt = uids.begin(); uidIt != uids.end(); ++uidIt ) {
01606 typedef KPIM::DistributionList::Entry::List EntryList;
01607 const EntryList entries = dist.entries( addressBook() );
01608 for ( EntryList::ConstIterator it = entries.begin(); it != entries.end(); ++it ) {
01609 if ( (*it).addressee.uid() == (*uidIt) ) {
01610 dist.removeEntry( (*it).addressee, (*it).email );
01611 break;
01612 }
01613 }
01614 }
01615 addressBook()->insertAddressee( dist );
01616 setModified();
01617 #endif
01618 }
01619
01620 void KABCore::sendMailToDistributionList( const QString &name )
01621 {
01622 #ifdef KDEPIM_NEW_DISTRLISTS
01623 KPIM::DistributionList dist = KPIM::DistributionList::findByName( addressBook(), name );
01624 if ( dist.isEmpty() )
01625 return;
01626 typedef KPIM::DistributionList::Entry::List EntryList;
01627 QStringList mails;
01628 const EntryList entries = dist.entries( addressBook() );
01629 for ( EntryList::ConstIterator it = entries.begin(); it != entries.end(); ++it )
01630 mails += (*it).addressee.fullEmail( (*it).email );
01631 sendMail( mails.join( ", " ) );
01632 #endif
01633 }
01634
01635 void KABCore::editSelectedDistributionList()
01636 {
01637 #ifdef KDEPIM_NEW_DISTRLISTS
01638 editDistributionList( KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList ) );
01639 #endif
01640 }
01641
01642
01643 void KABCore::editDistributionList( const QString &name )
01644 {
01645 #ifdef KDEPIM_NEW_DISTRLISTS
01646 editDistributionList( KPIM::DistributionList::findByName( addressBook(), name ) );
01647 #endif
01648 }
01649
01650 #ifdef KDEPIM_NEW_DISTRLISTS
01651
01652 void KABCore::showDistributionListEntry( const QString& uid )
01653 {
01654 KPIM::DistributionList dist = KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList );
01655 if ( !dist.isEmpty() ) {
01656 mDistListEntryView->clear();
01657 typedef KPIM::DistributionList::Entry::List EntryList;
01658 const EntryList entries = dist.entries( addressBook() );
01659 for (EntryList::ConstIterator it = entries.begin(); it != entries.end(); ++it ) {
01660 if ( (*it).addressee.uid() == uid ) {
01661 mDistListEntryView->setEntry( dist, *it );
01662 break;
01663 }
01664 }
01665 }
01666 }
01667
01668 void KABCore::editDistributionList( const KPIM::DistributionList &dist )
01669 {
01670 if ( dist.isEmpty() )
01671 return;
01672 QGuardedPtr<KPIM::DistributionListEditor::EditorWidget> dlg = new KPIM::DistributionListEditor::EditorWidget( addressBook(), widget() );
01673 dlg->setDistributionList( dist );
01674 if ( dlg->exec() == QDialog::Accepted && dlg ) {
01675 const KPIM::DistributionList newDist = dlg->distributionList();
01676 if ( newDist != dist ) {
01677 setModified();
01678 }
01679 }
01680 delete dlg;
01681 }
01682
01683
01684 KPIM::DistributionList::List KABCore::distributionLists() const
01685 {
01686 return mSearchManager->distributionLists();
01687 }
01688
01689 void KABCore::setSelectedDistributionList( const QString &name )
01690 {
01691 mSelectedDistributionList = name;
01692 mSearchManager->setSelectedDistributionList( name );
01693 mViewHeaderLabel->setText( name.isNull() ?
01694 i18n( "Contacts" ) :
01695 i18n( "Distribution List: %1" ).arg( name ) );
01696 mDistListButtonWidget->setShown( !mSelectedDistributionList.isNull() );
01697 if ( !name.isNull() ) {
01698 mDetailsStack->raiseWidget( mDistListEntryView );
01699 if ( selectedUIDs().isEmpty() ) {
01700 mViewManager->setFirstSelected( true );
01701 }
01702 const QStringList selectedUids = selectedUIDs();
01703 showDistributionListEntry( selectedUids.isEmpty() ? QString() : selectedUids.first() );
01704 } else {
01705 mDetailsStack->raiseWidget( mExtensionManager->activeDetailsWidget() ?
01706 mExtensionManager->activeDetailsWidget() : mDetailsWidget );
01707 }
01708 }
01709
01710 QStringList KABCore::distributionListNames() const
01711 {
01712 return mSearchManager->distributionListNames();
01713 }
01714 #endif
01715
01716 #include "kabcore.moc"