kaddressbook

kabcore.cpp

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