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