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