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 Qt, and distribute the resulting executable,
00021     without including the source code for Qt 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 <qeventloop.h>
00027 
00028 #include <qclipboard.h>
00029 #include <qdir.h>
00030 #include <qfile.h>
00031 #include <qlayout.h>
00032 #include <qptrlist.h>
00033 #include <qregexp.h>
00034 #include <qvbox.h>
00035 
00036 #include <kabc/addresseelist.h>
00037 #include <kabc/errorhandler.h>
00038 #include <kabc/resource.h>
00039 #include <kabc/stdaddressbook.h>
00040 #include <kabc/vcardconverter.h>
00041 #include <kabc/resourcefile.h>
00042 #include <kaboutdata.h>
00043 #include <kaccelmanager.h>
00044 #include <kapplication.h>
00045 #include <dcopclient.h>
00046 #include <kactionclasses.h>
00047 #include <kcmdlineargs.h>
00048 #include <kcmultidialog.h>
00049 #include <kdebug.h>
00050 #include <kdeversion.h>
00051 #include <kimproxy.h>
00052 #include <klocale.h>
00053 #include <kmessagebox.h>
00054 #include <kprinter.h>
00055 #include <kprotocolinfo.h>
00056 #include <kresources/selectdialog.h>
00057 #include <kstandarddirs.h>
00058 #include <kstatusbar.h>
00059 #include <kstdguiitem.h>
00060 #include <kxmlguiclient.h>
00061 #include <ktoolbar.h>
00062 #include <libkdepim/addresseeview.h>
00063 #include <libkdepim/categoryeditdialog.h>
00064 #include <libkdepim/categoryselectdialog.h>
00065 
00066 #include "addresseeutil.h"
00067 #include "addresseeeditordialog.h"
00068 #include "extensionmanager.h"
00069 #include "filterselectionwidget.h"
00070 #include "incsearchwidget.h"
00071 #include "jumpbuttonbar.h"
00072 #include "kablock.h"
00073 #include "kabprefs.h"
00074 #include "kabtools.h"
00075 #include "kaddressbookservice.h"
00076 #include "kaddressbookiface.h"
00077 #include "ldapsearchdialog.h"
00078 #include "locationmap.h"
00079 #include "printing/printingwizard.h"
00080 #include "searchmanager.h"
00081 #include "undocmds.h"
00082 #include "viewmanager.h"
00083 #include "xxportmanager.h"
00084 
00085 #include "kabcore.h"
00086 
00087 KABCore::KABCore( KXMLGUIClient *client, bool readWrite, QWidget *parent,
00088                   const QString &file, const char *name )
00089   : KAB::Core( client, parent, name ), mStatusBar( 0 ), mViewManager( 0 ),
00090     mExtensionManager( 0 ), mJumpButtonBar( 0 ), mCategorySelectDialog( 0 ),
00091     mCategoryEditDialog( 0 ), mLdapSearchDialog( 0 ), mReadWrite( readWrite ),
00092     mModified( false )
00093 {
00094   mWidget = new QWidget( parent, name );
00095 
00096   mIsPart = !parent->isA( "KAddressBookMain" );
00097 
00098   mAddressBookChangedTimer = new QTimer( this );
00099   connect( mAddressBookChangedTimer, SIGNAL( timeout() ),
00100            this, SLOT( addressBookChanged() ) );
00101 
00102   if ( file.isEmpty() ) {
00103     mAddressBook = KABC::StdAddressBook::self( true );
00104   } else {
00105     kdDebug(5720) << "KABCore(): document '" << file << "'" << endl;
00106     mAddressBook = new KABC::AddressBook;
00107     mAddressBook->addResource( new KABC::ResourceFile( file ) );
00108     if ( !mAddressBook->load() ) {
00109       KMessageBox::error( parent, i18n("Unable to load '%1'.").arg( file ) );
00110     }
00111   }
00112   mAddressBook->setErrorHandler( new KABC::GuiErrorHandler( mWidget ) );
00113 
00114   mAddressBook->addCustomField( i18n( "Department" ), KABC::Field::Organization,
00115                                 "X-Department", "KADDRESSBOOK" );
00116   mAddressBook->addCustomField( i18n( "Profession" ), KABC::Field::Organization,
00117                                 "X-Profession", "KADDRESSBOOK" );
00118   mAddressBook->addCustomField( i18n( "Assistant's Name" ), KABC::Field::Organization,
00119                                 "X-AssistantsName", "KADDRESSBOOK" );
00120   mAddressBook->addCustomField( i18n( "Manager's Name" ), KABC::Field::Organization,
00121                                 "X-ManagersName", "KADDRESSBOOK" );
00122   mAddressBook->addCustomField( i18n( "Partner's Name" ), KABC::Field::Personal,
00123                                 "X-SpousesName", "KADDRESSBOOK" );
00124   mAddressBook->addCustomField( i18n( "Office" ), KABC::Field::Personal,
00125                                 "X-Office", "KADDRESSBOOK" );
00126   mAddressBook->addCustomField( i18n( "IM Address" ), KABC::Field::Personal,
00127                                 "X-IMAddress", "KADDRESSBOOK" );
00128   mAddressBook->addCustomField( i18n( "Anniversary" ), KABC::Field::Personal,
00129                                 "X-Anniversary", "KADDRESSBOOK" );
00130   mAddressBook->addCustomField( i18n( "Blog" ), KABC::Field::Personal,
00131                                 "BlogFeed", "KADDRESSBOOK" );
00132 
00133   mSearchManager = new KAB::SearchManager( mAddressBook, parent );
00134 
00135   connect( mSearchManager, SIGNAL( contactsUpdated() ),
00136            this, SLOT( slotContactsUpdated() ) );
00137 
00138   initGUI();
00139 
00140   connect( mAddressBook, SIGNAL( addressBookChanged( AddressBook* ) ),
00141            SLOT( delayedAddressBookChanged() ) );
00142   connect( mAddressBook, SIGNAL( loadingFinished( Resource* ) ),
00143            SLOT( delayedAddressBookChanged() ) );
00144 
00145   mIncSearchWidget->setFocus();
00146 
00147   connect( mViewManager, SIGNAL( selected( const QString& ) ),
00148            SLOT( setContactSelected( const QString& ) ) );
00149   connect( mViewManager, SIGNAL( executed( const QString& ) ),
00150            SLOT( editContact( const QString& ) ) );
00151   connect( mViewManager, SIGNAL( modified() ),
00152            SLOT( setModified() ) );
00153   connect( mViewManager, SIGNAL( urlDropped( const KURL& ) ),
00154            mXXPortManager, SLOT( importVCard( const KURL& ) ) );
00155   connect( mViewManager, SIGNAL( viewFieldsChanged() ),
00156            SLOT( updateIncSearchWidget() ) );
00157   connect( mExtensionManager, SIGNAL( modified( const KABC::Addressee::List& ) ),
00158            this, SLOT( extensionModified( const KABC::Addressee::List& ) ) );
00159   connect( mExtensionManager, SIGNAL( deleted( const QStringList& ) ),
00160            this, SLOT( extensionDeleted( const QStringList& ) ) );
00161 
00162   connect( mXXPortManager, SIGNAL( modified() ),
00163            SLOT( setModified() ) );
00164 
00165   connect( mDetails, SIGNAL( highlightedMessage( const QString& ) ),
00166            SLOT( detailsHighlighted( const QString& ) ) );
00167 
00168   connect( mIncSearchWidget, SIGNAL( scrollUp() ),
00169            mViewManager, SLOT( scrollUp() ) );
00170   connect( mIncSearchWidget, SIGNAL( scrollDown() ),
00171            mViewManager, SLOT( scrollDown() ) );
00172 
00173   mAddressBookService = new KAddressBookService( this );
00174 
00175   mCommandHistory = new KCommandHistory( actionCollection(), true );
00176   connect( mCommandHistory, SIGNAL( commandExecuted() ),
00177            mSearchManager, SLOT( reload() ) );
00178 
00179   mSearchManager->reload();
00180 
00181   setModified( false );
00182 
00183   KAcceleratorManager::manage( mWidget );
00184 
00185   mKIMProxy = ::KIMProxy::instance( kapp->dcopClient() );
00186 }
00187 
00188 KABCore::~KABCore()
00189 {
00190   mAddressBook->disconnect();
00191 
00192   mAddressBook = 0;
00193   KABC::StdAddressBook::close();
00194   mKIMProxy = 0;
00195 }
00196 
00197 void KABCore::restoreSettings()
00198 {
00199   bool state = KABPrefs::instance()->jumpButtonBarVisible();
00200   mActionJumpBar->setChecked( state );
00201   setJumpButtonBarVisible( state );
00202 
00203   state = KABPrefs::instance()->detailsPageVisible();
00204   mActionDetails->setChecked( state );
00205   setDetailsVisible( state );
00206 
00207   mViewManager->restoreSettings();
00208   mExtensionManager->restoreSettings();
00209 
00210   updateIncSearchWidget();
00211   mIncSearchWidget->setCurrentItem( KABPrefs::instance()->currentIncSearchField() );
00212 
00213   QValueList<int> splitterSize = KABPrefs::instance()->extensionsSplitter();
00214   if ( splitterSize.count() == 0 ) {
00215     splitterSize.append( mDetailsSplitter->height() / 2 );
00216     splitterSize.append( mDetailsSplitter->height() / 2 );
00217   }
00218   mExtensionBarSplitter->setSizes( splitterSize );
00219 
00220   splitterSize = KABPrefs::instance()->detailsSplitter();
00221   if ( splitterSize.count() == 0 ) {
00222     splitterSize.append( 360 );
00223     splitterSize.append( 260 );
00224   }
00225   mDetailsSplitter->setSizes( splitterSize );
00226 
00227 }
00228 
00229 void KABCore::saveSettings()
00230 {
00231   KABPrefs::instance()->setJumpButtonBarVisible( mActionJumpBar->isChecked() );
00232   KABPrefs::instance()->setDetailsPageVisible( mActionDetails->isChecked() );
00233 
00234   KABPrefs::instance()->setExtensionsSplitter( mExtensionBarSplitter->sizes() );
00235   KABPrefs::instance()->setDetailsSplitter( mDetailsSplitter->sizes() );
00236 
00237   mExtensionManager->saveSettings();
00238   mViewManager->saveSettings();
00239 
00240   KABPrefs::instance()->setCurrentIncSearchField( mIncSearchWidget->currentItem() );
00241 }
00242 
00243 KABC::AddressBook *KABCore::addressBook() const
00244 {
00245   return mAddressBook;
00246 }
00247 
00248 KConfig *KABCore::config() const
00249 {
00250   return KABPrefs::instance()->config();
00251 }
00252 
00253 KActionCollection *KABCore::actionCollection() const
00254 {
00255   return guiClient()->actionCollection();
00256 }
00257 
00258 KABC::Field *KABCore::currentSortField() const
00259 {
00260   return mViewManager->currentSortField();
00261 }
00262 
00263 QStringList KABCore::selectedUIDs() const
00264 {
00265   return mViewManager->selectedUids();
00266 }
00267 
00268 KABC::Resource *KABCore::requestResource( QWidget *parent )
00269 {
00270   QPtrList<KABC::Resource> kabcResources = addressBook()->resources();
00271 
00272   QPtrList<KRES::Resource> kresResources;
00273   QPtrListIterator<KABC::Resource> resIt( kabcResources );
00274   KABC::Resource *resource;
00275   while ( ( resource = resIt.current() ) != 0 ) {
00276     ++resIt;
00277     if ( !resource->readOnly() ) {
00278       KRES::Resource *res = static_cast<KRES::Resource*>( resource );
00279       if ( res )
00280         kresResources.append( res );
00281     }
00282   }
00283 
00284   KRES::Resource *res = KRES::SelectDialog::getResource( kresResources, parent );
00285   return static_cast<KABC::Resource*>( res );
00286 }
00287 
00288 QWidget *KABCore::widget() const
00289 {
00290   return mWidget;
00291 }
00292 
00293 KAboutData *KABCore::createAboutData()
00294 {
00295   KAboutData *about = new KAboutData( "kaddressbook", I18N_NOOP( "KAddressBook" ),
00296                                       "3.5", I18N_NOOP( "The KDE Address Book" ),
00297                                       KAboutData::License_GPL_V2,
00298                                       I18N_NOOP( "(c) 1997-2005, The KDE PIM Team" ) );
00299   about->addAuthor( "Tobias Koenig", I18N_NOOP( "Current maintainer" ), "tokoe@kde.org" );
00300   about->addAuthor( "Don Sanders", I18N_NOOP( "Original author" ) );
00301   about->addAuthor( "Cornelius Schumacher",
00302                     I18N_NOOP( "Co-maintainer, libkabc port, CSV import/export" ),
00303                     "schumacher@kde.org" );
00304   about->addAuthor( "Mike Pilone", I18N_NOOP( "GUI and framework redesign" ),
00305                     "mpilone@slac.com" );
00306   about->addAuthor( "Greg Stern", I18N_NOOP( "DCOP interface" ) );
00307   about->addAuthor( "Mark Westcott", I18N_NOOP( "Contact pinning" ) );
00308   about->addAuthor( "Mischel Boyer de la Giroday", I18N_NOOP( "LDAP Lookup" ),
00309                     "michel@klaralvdalens-datakonsult.se" );
00310   about->addAuthor( "Steffen Hansen", I18N_NOOP( "LDAP Lookup" ),
00311                     "hansen@kde.org" );
00312 
00313   return about;
00314 }
00315 
00316 void KABCore::setStatusBar( KStatusBar *statusBar )
00317 {
00318   mStatusBar = statusBar;
00319 }
00320 
00321 KStatusBar *KABCore::statusBar() const
00322 {
00323   return mStatusBar;
00324 }
00325 
00326 void KABCore::setContactSelected( const QString &uid )
00327 {
00328   KABC::Addressee addr = mAddressBook->findByUid( uid );
00329   if ( !mDetails->isHidden() )
00330     mDetails->setAddressee( addr );
00331 
00332   mExtensionManager->setSelectionChanged();
00333 
00334   // update the actions
00335   bool selected = !uid.isEmpty();
00336 
00337   if ( mReadWrite ) {
00338     mActionCut->setEnabled( selected );
00339 
00340     QClipboard *cb = QApplication::clipboard();
00341     KABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( cb->text() );
00342     mActionPaste->setEnabled( !list.isEmpty() );
00343   }
00344 
00345   mActionCopy->setEnabled( selected );
00346   mActionDelete->setEnabled( selected );
00347   mActionEditAddressee->setEnabled( selected );
00348   mActionStoreAddresseeIn->setEnabled( selected );
00349   mActionMail->setEnabled( selected );
00350   mActionMailVCard->setEnabled( selected );
00351   mActionChat->setEnabled( selected && mKIMProxy && mKIMProxy->initialize() );
00352   mActionWhoAmI->setEnabled( selected );
00353   mActionCategories->setEnabled( selected );
00354   mActionMerge->setEnabled( selected );
00355 }
00356 
00357 void KABCore::sendMail()
00358 {
00359   sendMail( mViewManager->selectedEmails().join( ", " ) );
00360 }
00361 
00362 void KABCore::sendMail( const QString& email )
00363 {
00364   kapp->invokeMailer( email, "" );
00365 }
00366 
00367 void KABCore::mailVCard()
00368 {
00369   QStringList uids = mViewManager->selectedUids();
00370   if ( !uids.isEmpty() )
00371     mailVCard( uids );
00372 }
00373 
00374 void KABCore::mailVCard( const QStringList &uids )
00375 {
00376   KABTools::mailVCards( uids, mAddressBook );
00377 }
00378 
00379 void KABCore::startChat()
00380 {
00381   QStringList uids = mViewManager->selectedUids();
00382   if ( !uids.isEmpty() )
00383     mKIMProxy->chatWithContact( uids.first() );
00384 }
00385 
00386 void KABCore::browse( const QString& url )
00387 {
00388   kapp->invokeBrowser( url );
00389 }
00390 
00391 void KABCore::selectAllContacts()
00392 {
00393   mViewManager->setSelected( QString::null, true );
00394 }
00395 
00396 void KABCore::deleteContacts()
00397 {
00398   QStringList uidList = mViewManager->selectedUids();
00399 
00400   deleteContacts( uidList );
00401 }
00402 
00403 void KABCore::deleteContacts( const QStringList &uids )
00404 {
00405   if ( uids.count() > 0 ) {
00406     QStringList names;
00407     QStringList::ConstIterator it = uids.begin();
00408     const QStringList::ConstIterator endIt( uids.end() );
00409     while ( it != endIt ) {
00410       KABC::Addressee addr = mAddressBook->findByUid( *it );
00411       names.append( addr.realName().isEmpty() ? addr.preferredEmail() : addr.realName() );
00412       ++it;
00413     }
00414 
00415     if ( KMessageBox::warningContinueCancelList( mWidget, i18n( "Do you really want to delete this contact?",
00416                                                  "Do you really want to delete these %n contacts?", uids.count() ),
00417                                                  names, QString::null, KStdGuiItem::del() ) == KMessageBox::Cancel )
00418       return;
00419 
00420     DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
00421     mCommandHistory->addCommand( command );
00422 
00423     // now if we deleted anything, refresh
00424     setContactSelected( QString::null );
00425     setModified( true );
00426   }
00427 }
00428 
00429 void KABCore::copyContacts()
00430 {
00431   KABC::Addressee::List addrList = mViewManager->selectedAddressees();
00432 
00433   QString clipText = AddresseeUtil::addresseesToClipboard( addrList );
00434 
00435   kdDebug(5720) << "KABCore::copyContacts: " << clipText << endl;
00436 
00437   QClipboard *cb = QApplication::clipboard();
00438   cb->setText( clipText );
00439 }
00440 
00441 void KABCore::cutContacts()
00442 {
00443   QStringList uidList = mViewManager->selectedUids();
00444 
00445   if ( uidList.size() > 0 ) {
00446     CutCommand *command = new CutCommand( mAddressBook, uidList );
00447     mCommandHistory->addCommand( command );
00448 
00449     setModified( true );
00450   }
00451 }
00452 
00453 void KABCore::pasteContacts()
00454 {
00455   QClipboard *cb = QApplication::clipboard();
00456 
00457   KABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( cb->text() );
00458 
00459   pasteContacts( list );
00460 }
00461 
00462 void KABCore::pasteContacts( KABC::Addressee::List &list )
00463 {
00464   KABC::Resource *resource = requestResource( mWidget );
00465   if ( !resource )
00466     return;
00467 
00468   KABC::Addressee::List::Iterator it;
00469   const KABC::Addressee::List::Iterator endIt( list.end() );
00470   for ( it = list.begin(); it != endIt; ++it )
00471     (*it).setResource( resource );
00472 
00473   PasteCommand *command = new PasteCommand( this, list );
00474   mCommandHistory->addCommand( command );
00475 
00476   setModified( true );
00477 }
00478 
00479 void KABCore::mergeContacts()
00480 {
00481   KABC::Addressee::List list = mViewManager->selectedAddressees();
00482   if ( list.count() < 2 )
00483     return;
00484 
00485   KABC::Addressee addr = KABTools::mergeContacts( list );
00486 
00487   KABC::Addressee::List::Iterator it = list.begin();
00488   const KABC::Addressee::List::Iterator endIt( list.end() );
00489   KABC::Addressee origAddr = *it;
00490   QStringList uids;
00491   ++it;
00492   while ( it != endIt ) {
00493     uids.append( (*it).uid() );
00494     ++it;
00495   }
00496 
00497   DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
00498   mCommandHistory->addCommand( command );
00499 
00500   EditCommand *editCommand = new EditCommand( mAddressBook, origAddr, addr );
00501   mCommandHistory->addCommand( editCommand );
00502 
00503   mSearchManager->reload();
00504 }
00505 
00506 void KABCore::setWhoAmI()
00507 {
00508   KABC::Addressee::List addrList = mViewManager->selectedAddressees();
00509 
00510   if ( addrList.count() > 1 ) {
00511     KMessageBox::sorry( mWidget, i18n( "Please select only one contact." ) );
00512     return;
00513   }
00514 
00515   QString text( i18n( "<qt>Do you really want to use <b>%1</b> as your new personal contact?</qt>" ) );
00516   if ( KMessageBox::questionYesNo( mWidget, text.arg( addrList[ 0 ].assembledName() ), QString::null, i18n("Use"), i18n("Do Not Use") ) == KMessageBox::Yes )
00517     static_cast<KABC::StdAddressBook*>( KABC::StdAddressBook::self( true ) )->setWhoAmI( addrList[ 0 ] );
00518 }
00519 
00520 void KABCore::incrementalTextSearch( const QString& text )
00521 {
00522   setContactSelected( QString::null );
00523   mSearchManager->search( text, mIncSearchWidget->currentFields() );
00524 }
00525 
00526 void KABCore::incrementalJumpButtonSearch( const QString& character )
00527 {
00528   mViewManager->setSelected( QString::null, false );
00529 
00530   KABC::AddresseeList list = mSearchManager->contacts();
00531   KABC::Field *field = mViewManager->currentSortField();
00532   if ( field ) {
00533     list.sortByField( field );
00534     KABC::AddresseeList::ConstIterator it;
00535     const KABC::AddresseeList::ConstIterator endIt( list.end() );
00536     for ( it = list.begin(); it != endIt; ++it ) {
00537       if ( field->value( *it ).startsWith( character, false ) ) {
00538         mViewManager->setSelected( (*it).uid(), true );
00539         return;
00540       }
00541     }
00542   }
00543 }
00544 
00545 void KABCore::setModified()
00546 {
00547   setModified( true );
00548 }
00549 
00550 void KABCore::setModified( bool modified )
00551 {
00552   mModified = modified;
00553   mActionSave->setEnabled( mModified );
00554 
00555   mSearchManager->reload();
00556 }
00557 
00558 bool KABCore::modified() const
00559 {
00560   return mModified;
00561 }
00562 
00563 void KABCore::contactModified( const KABC::Addressee &addr )
00564 {
00565   Command *command = 0;
00566 
00567   // check if it exists already
00568   KABC::Addressee origAddr = mAddressBook->findByUid( addr.uid() );
00569   if ( origAddr.isEmpty() ) {
00570     KABC::Addressee::List addressees;
00571     addressees.append( addr );
00572     command = new NewCommand( mAddressBook, addressees );
00573   } else {
00574     command = new EditCommand( mAddressBook, origAddr, addr );
00575   }
00576 
00577   mCommandHistory->addCommand( command );
00578 
00579   setContactSelected( addr.uid() );
00580   setModified( true );
00581 }
00582 
00583 void KABCore::newContact()
00584 {
00585   AddresseeEditorDialog *dialog = 0;
00586 
00587   KABC::Resource* resource = requestResource( mWidget );
00588 
00589   if ( resource ) {
00590     KABC::Addressee addr;
00591     addr.setResource( resource );
00592 
00593     if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) )
00594       return;
00595 
00596     dialog = createAddresseeEditorDialog( mWidget );
00597     dialog->setAddressee( addr );
00598   } else
00599     return;
00600 
00601   mEditorDict.insert( dialog->addressee().uid(), dialog );
00602 
00603   dialog->show();
00604 }
00605 
00606 void KABCore::addEmail( const QString &aStr )
00607 {
00608   QString fullName, email;
00609 
00610   KABC::Addressee::parseEmailAddress( aStr, fullName, email );
00611 
00612 #if KDE_IS_VERSION(3,4,89)
00613   // This ugly hack will be removed in 4.0
00614   // addressbook may not be reloaded yet, as done asynchronously sometimes, so wait
00615   while ( !mAddressBook->loadingHasFinished() ) {
00616     QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00617     // use sleep here to reduce cpu usage
00618     usleep( 100 );
00619   }
00620 #endif
00621 
00622   // Try to lookup the addressee matching the email address
00623   bool found = false;
00624   QStringList emailList;
00625   KABC::AddressBook::Iterator it;
00626   const KABC::AddressBook::Iterator endIt( mAddressBook->end() );
00627   for ( it = mAddressBook->begin(); !found && (it != endIt); ++it ) {
00628     emailList = (*it).emails();
00629     if ( emailList.contains( email ) > 0 ) {
00630       found = true;
00631       (*it).setNameFromString( fullName );
00632       editContact( (*it).uid() );
00633     }
00634   }
00635 
00636   if ( !found ) {
00637     KABC::Addressee addr;
00638     addr.setNameFromString( fullName );
00639     addr.insertEmail( email, true );
00640 
00641     mAddressBook->insertAddressee( addr );
00642     mViewManager->refreshView( addr.uid() );
00643     editContact( addr.uid() );
00644   }
00645 }
00646 
00647 void KABCore::importVCard( const KURL &url )
00648 {
00649   mXXPortManager->importVCard( url );
00650 }
00651 
00652 void KABCore::importVCard( const QString &vCardURL )
00653 {
00654   mXXPortManager->importVCard( vCardURL );
00655 }
00656 
00657 void KABCore::editContact( const QString &uid )
00658 {
00659   if ( mExtensionManager->isQuickEditVisible() )
00660     return;
00661 
00662   // First, locate the contact entry
00663   QString localUID = uid;
00664   if ( localUID.isNull() ) {
00665     QStringList uidList = mViewManager->selectedUids();
00666     if ( uidList.count() > 0 )
00667       localUID = *( uidList.at( 0 ) );
00668   }
00669 #if KDE_IS_VERSION(3,4,89)
00670   // This ugly hack will be removed in 4.0
00671   // for calls with given uid, as done from commandline and DCOP
00672   // addressbook may not be reloaded yet, as done asynchronously, so wait
00673   else while ( !mAddressBook->loadingHasFinished() ) {
00674     QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00675     // use sleep here to reduce cpu usage
00676     usleep( 100 );
00677   }
00678 #endif
00679 
00680   KABC::Addressee addr = mAddressBook->findByUid( localUID );
00681   if ( !addr.isEmpty() ) {
00682     AddresseeEditorDialog *dialog = mEditorDict.find( addr.uid() );
00683     if ( !dialog ) {
00684 
00685       if ( !addr.resource()->readOnly() )
00686         if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) ) {
00687           return;
00688         }
00689 
00690       dialog = createAddresseeEditorDialog( mWidget );
00691 
00692       mEditorDict.insert( addr.uid(), dialog );
00693 
00694       dialog->setAddressee( addr );
00695     }
00696 
00697     dialog->raise();
00698     dialog->show();
00699   }
00700 }
00701 
00702 void KABCore::storeContactIn( const QString &uid )
00703 {
00704   // First, locate the contact entry
00705   QStringList uidList;
00706   if ( uid.isNull() ) {
00707     uidList = mViewManager->selectedUids();
00708   } else {
00709     uidList << uid;
00710   }
00711   KABC::Resource *resource = requestResource( mWidget );
00712   if ( !resource )
00713     return;
00714 
00715   KABLock::self( mAddressBook )->lock( resource );
00716   QStringList::Iterator it( uidList.begin() );
00717   const QStringList::Iterator endIt( uidList.end() );
00718   while ( it != endIt ) {
00719     KABC::Addressee addr = mAddressBook->findByUid( *it++ );
00720     if ( !addr.isEmpty() ) {
00721       KABC::Addressee newAddr( addr );
00722       // We need to set a new uid, otherwise the insert below is
00723       // ignored. This is bad for syncing, but unavoidable, afaiks
00724       newAddr.setUid( KApplication::randomString( 10 ) );
00725       newAddr.setResource( resource );
00726       addressBook()->insertAddressee( newAddr );
00727       KABLock::self( mAddressBook )->lock( addr.resource() );
00728       addressBook()->removeAddressee( addr );
00729       KABLock::self( mAddressBook )->unlock( addr.resource() );
00730     }
00731   }
00732   KABLock::self( mAddressBook )->unlock( resource );
00733 }
00734 
00735 void KABCore::save()
00736 {
00737   QPtrList<KABC::Resource> resources = mAddressBook->resources();
00738   QPtrListIterator<KABC::Resource> it( resources );
00739   while ( it.current() && !it.current()->readOnly() ) {
00740     KABC::Ticket *ticket = mAddressBook->requestSaveTicket( it.current() );
00741     if ( ticket ) {
00742       if ( !mAddressBook->save( ticket ) ) {
00743         KMessageBox::error( mWidget,
00744                             i18n( "<qt>Unable to save address book <b>%1</b>.</qt>" ).arg( it.current()->resourceName() ) );
00745         mAddressBook->releaseSaveTicket( ticket );
00746       } else {
00747         setModified( false );
00748       }
00749     } else {
00750       KMessageBox::error( mWidget,
00751                           i18n( "<qt>Unable to get access for saving the address book <b>%1</b>.</qt>" )
00752                           .arg( it.current()->resourceName() ) );
00753     }
00754 
00755     ++it;
00756   }
00757 }
00758 
00759 void KABCore::setJumpButtonBarVisible( bool visible )
00760 {
00761   if ( visible ) {
00762     if ( !mJumpButtonBar )
00763       createJumpButtonBar();
00764     mJumpButtonBar->show();
00765   } else
00766     if ( mJumpButtonBar )
00767       mJumpButtonBar->hide();
00768 }
00769 
00770 void KABCore::setDetailsVisible( bool visible )
00771 {
00772   if ( visible )
00773     mDetailsPage->show();
00774   else
00775     mDetailsPage->hide();
00776 }
00777 
00778 void KABCore::extensionModified( const KABC::Addressee::List &list )
00779 {
00780   if ( list.count() != 0 ) {
00781     KABC::Addressee::List::ConstIterator it;
00782     const KABC::Addressee::List::ConstIterator endIt( list.end() );
00783     for ( it = list.begin(); it != endIt; ++it ) {
00784       Command *command = 0;
00785 
00786       // check if it exists already
00787       KABC::Addressee origAddr = mAddressBook->findByUid( (*it).uid() );
00788       if ( origAddr.isEmpty() ) {
00789         KABC::Addressee::List addressees;
00790         addressees.append( *it );
00791         command = new NewCommand( mAddressBook, addressees );
00792       } else
00793         command = new EditCommand( mAddressBook, origAddr, *it );
00794 
00795       mCommandHistory->blockSignals( true );
00796       mCommandHistory->addCommand( command );
00797       mCommandHistory->blockSignals( false );
00798     }
00799 
00800     mModified = true;
00801     mActionSave->setEnabled( true );
00802   }
00803 }
00804 
00805 void KABCore::extensionDeleted( const QStringList &uidList )
00806 {
00807   DeleteCommand *command = new DeleteCommand( mAddressBook, uidList );
00808   mCommandHistory->addCommand( command );
00809 
00810   // now if we deleted anything, refresh
00811   setContactSelected( QString::null );
00812   setModified( true );
00813 }
00814 
00815 QString KABCore::getNameByPhone( const QString &phone )
00816 {
00817 #if KDE_IS_VERSION(3,4,89)
00818   // This ugly hack will be removed in 4.0
00819   // addressbook may not be reloaded yet, as done asynchronously, so wait
00820   while ( !mAddressBook->loadingHasFinished() ) {
00821     QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00822     // use sleep here to reduce cpu usage
00823     usleep( 100 );
00824   }
00825 #endif
00826 
00827   QRegExp r( "[/*/-/ ]" );
00828   QString localPhone( phone );
00829 
00830   bool found = false;
00831   QString ownerName = "";
00832   KABC::PhoneNumber::List phoneList;
00833 
00834   KABC::AddressBook::ConstIterator iter;
00835   const KABC::AddressBook::ConstIterator endIter( mAddressBook->end() );
00836 
00837   for ( iter = mAddressBook->begin(); !found && ( iter != endIter ); ++iter ) {
00838     phoneList = (*iter).phoneNumbers();
00839     KABC::PhoneNumber::List::Iterator phoneIter( phoneList.begin() );
00840     const KABC::PhoneNumber::List::Iterator phoneEndIter( phoneList.end() );
00841     for ( ; !found && ( phoneIter != phoneEndIter ); ++phoneIter) {
00842       // Get rid of separator chars so just the numbers are compared.
00843       if ( (*phoneIter).number().replace( r, "" ) == localPhone.replace( r, "" ) ) {
00844         ownerName = (*iter).realName();
00845         found = true;
00846       }
00847     }
00848   }
00849 
00850   return ownerName;
00851 }
00852 
00853 void KABCore::openLDAPDialog()
00854 {
00855   if ( !KProtocolInfo::isKnownProtocol( KURL( "ldap://localhost" ) ) ) {
00856     KMessageBox::error( mWidget, i18n( "Your KDE installation is missing LDAP "
00857                                        "support, please ask your administrator or distributor for more information." ),
00858                         i18n( "No LDAP IO Slave Available" ) );
00859     return;
00860   }
00861 
00862   if ( !mLdapSearchDialog ) {
00863     mLdapSearchDialog = new LDAPSearchDialog( mAddressBook, this, mWidget );
00864     connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ),
00865             SLOT( addressBookChanged() ) );
00866     connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ),
00867             SLOT( setModified() ) );
00868   } else
00869     mLdapSearchDialog->restoreSettings();
00870 
00871   if ( mLdapSearchDialog->isOK() )
00872     mLdapSearchDialog->exec();
00873 }
00874 
00875 void KABCore::configure()
00876 {
00877   // Save the current config so we do not loose anything if the user accepts
00878   saveSettings();
00879 
00880   KCMultiDialog dlg( mWidget, "", true );
00881   connect( &dlg, SIGNAL( configCommitted() ),
00882            this, SLOT( configurationChanged() ) );
00883 
00884   dlg.addModule( "kabconfig.desktop" );
00885   dlg.addModule( "kabldapconfig.desktop" );
00886   dlg.addModule( "kabcustomfields.desktop" );
00887 
00888   dlg.exec();
00889 }
00890 
00891 void KABCore::print()
00892 {
00893   KPrinter printer;
00894   printer.setDocName( i18n( "Address Book" ) );
00895   printer.setDocFileName( "addressbook" );
00896 
00897   if ( !printer.setup( mWidget, i18n("Print Addresses") ) )
00898     return;
00899 
00900   KABPrinting::PrintingWizard wizard( &printer, mAddressBook,
00901                                       mViewManager->selectedUids(), mWidget );
00902 
00903   wizard.exec();
00904 }
00905 
00906 void KABCore::detailsHighlighted( const QString &msg )
00907 {
00908   if ( mStatusBar ) {
00909     if ( !mStatusBar->hasItem( 2 ) )
00910       mStatusBar->insertItem( msg, 2 );
00911     else
00912       mStatusBar->changeItem( msg, 2 );
00913   }
00914 }
00915 
00916 void KABCore::showContactsAddress( const QString &addrUid )
00917 {
00918   QStringList uidList = mViewManager->selectedUids();
00919   if ( uidList.isEmpty() )
00920     return;
00921 
00922   KABC::Addressee addr = mAddressBook->findByUid( uidList.first() );
00923   if ( addr.isEmpty() )
00924     return;
00925 
00926   const KABC::Address::List list = addr.addresses();
00927   KABC::Address::List::ConstIterator it;
00928   const KABC::Address::List::ConstIterator endIt( list.end() );
00929   for ( it = list.begin(); it != endIt; ++it )
00930     if ( (*it).id() == addrUid ) {
00931       LocationMap::instance()->showAddress( *it );
00932       break;
00933     }
00934 }
00935 
00936 void KABCore::configurationChanged()
00937 {
00938   mExtensionManager->reconfigure();
00939   mViewManager->refreshView();
00940 }
00941 
00942 bool KABCore::queryClose()
00943 {
00944   saveSettings();
00945   KABPrefs::instance()->writeConfig();
00946 
00947   QPtrList<KABC::Resource> resources = mAddressBook->resources();
00948   QPtrListIterator<KABC::Resource> it( resources );
00949   while ( it.current() ) {
00950     it.current()->close();
00951     ++it;
00952   }
00953 
00954   return true;
00955 }
00956 
00957 void KABCore::reinitXMLGUI()
00958 {
00959   mExtensionManager->createActions();
00960 }
00961 void KABCore::delayedAddressBookChanged()
00962 {
00963   mAddressBookChangedTimer->start( 1000 );
00964 }
00965 
00966 void KABCore::addressBookChanged()
00967 {
00968   mAddressBookChangedTimer->stop();
00969 
00970   if ( mJumpButtonBar )
00971     mJumpButtonBar->updateButtons();
00972 
00973   mSearchManager->reload();
00974   mViewManager->setSelected( QString::null, false );
00975   setContactSelected( QString::null );
00976 
00977   updateCategories();
00978 }
00979 
00980 AddresseeEditorDialog *KABCore::createAddresseeEditorDialog( QWidget *parent,
00981                                                              const char *name )
00982 {
00983   AddresseeEditorDialog *dialog = new AddresseeEditorDialog( this, parent,
00984                                                  name ? name : "editorDialog" );
00985   connect( dialog, SIGNAL( contactModified( const KABC::Addressee& ) ),
00986            SLOT( contactModified( const KABC::Addressee& ) ) );
00987   connect( dialog, SIGNAL( editorDestroyed( const QString& ) ),
00988            SLOT( slotEditorDestroyed( const QString& ) ) );
00989 
00990   return dialog;
00991 }
00992 
00993 void KABCore::slotEditorDestroyed( const QString &uid )
00994 {
00995   AddresseeEditorDialog *dialog = mEditorDict.take( uid );
00996 
00997   KABC::Addressee addr = dialog->addressee();
00998 
00999   if ( !addr.resource()->readOnly() ) {
01000     QApplication::setOverrideCursor( Qt::waitCursor );
01001     KABLock::self( mAddressBook )->unlock( addr.resource() );
01002     QApplication::restoreOverrideCursor();
01003   }
01004 }
01005 
01006 void KABCore::initGUI()
01007 {
01008   QVBoxLayout *topLayout = new QVBoxLayout( mWidget, 0, 0 );
01009   KToolBar* searchTB = new KToolBar( mWidget, "search toolbar");
01010   searchTB->boxLayout()->setSpacing( KDialog::spacingHint() );
01011   mIncSearchWidget = new IncSearchWidget( searchTB, "kde toolbar widget");
01012   searchTB->setStretchableWidget( mIncSearchWidget );
01013   connect( mIncSearchWidget, SIGNAL( doSearch( const QString& ) ),
01014            SLOT( incrementalTextSearch( const QString& ) ) );
01015 
01016   mFilterSelectionWidget = new FilterSelectionWidget( searchTB , "kde toolbar widget" );
01017 
01018   mDetailsSplitter = new QSplitter( mWidget );
01019   topLayout->addWidget( searchTB );
01020   topLayout->addWidget( mDetailsSplitter );
01021 
01022   mExtensionBarSplitter = new QSplitter( mDetailsSplitter );
01023   mExtensionBarSplitter->setOrientation( Qt::Vertical );
01024 
01025   mDetailsWidget = new QWidget( mDetailsSplitter );
01026   mDetailsLayout = new QHBoxLayout( mDetailsWidget );
01027 
01028   mDetailsPage = new QWidget( mDetailsWidget );
01029   mDetailsLayout->addWidget( mDetailsPage );
01030 
01031   QHBoxLayout *detailsPageLayout = new QHBoxLayout( mDetailsPage, 0, 0 );
01032   mDetails = new KPIM::AddresseeView( mDetailsPage );
01033   detailsPageLayout->addWidget( mDetails );
01034 
01035   connect( mDetails, SIGNAL( addressClicked( const QString&) ),
01036            this, SLOT( showContactsAddress( const QString& ) ) );
01037 
01038   mViewManager = new ViewManager( this, mExtensionBarSplitter );
01039   mViewManager->setFilterSelectionWidget( mFilterSelectionWidget );
01040 
01041   connect( mFilterSelectionWidget, SIGNAL( filterActivated( int ) ),
01042            mViewManager, SLOT( setActiveFilter( int ) ) );
01043 
01044   mExtensionManager = new ExtensionManager( this, mExtensionBarSplitter );
01045 
01046   topLayout->setStretchFactor( mDetailsSplitter, 1 );
01047 
01048   mXXPortManager = new XXPortManager( this, mWidget );
01049 
01050   initActions();
01051 }
01052 
01053 void KABCore::createJumpButtonBar()
01054 {
01055   mJumpButtonBar = new JumpButtonBar( this, mDetailsWidget );
01056   mDetailsLayout->addWidget( mJumpButtonBar );
01057   mDetailsLayout->setStretchFactor( mJumpButtonBar, 1 );
01058 
01059   connect( mJumpButtonBar, SIGNAL( jumpToLetter( const QString& ) ),
01060            SLOT( incrementalJumpButtonSearch( const QString& ) ) );
01061   connect( mViewManager, SIGNAL( sortFieldChanged() ),
01062            mJumpButtonBar, SLOT( updateButtons() ) );
01063 }
01064 
01065 void KABCore::initActions()
01066 {
01067   connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
01068            SLOT( clipboardDataChanged() ) );
01069 
01070   KAction *action;
01071 
01072   // file menu
01073   mActionMail = new KAction( i18n( "&Send Email to Contact..." ), "mail_send", 0,
01074                              this, SLOT( sendMail() ), actionCollection(), "file_mail" );
01075   action = KStdAction::print( this, SLOT( print() ), actionCollection() );
01076   mActionMail->setWhatsThis( i18n( "Send a mail to all selected contacts." ) );
01077   action->setWhatsThis( i18n( "Print a special number of contacts." ) );
01078 
01079   mActionSave = KStdAction::save( this,
01080                              SLOT( save() ), actionCollection(), "file_sync" );
01081   mActionSave->setWhatsThis( i18n( "Save all changes of the address book to the storage backend." ) );
01082 
01083   action = new KAction( i18n( "&New Contact..." ), "identity", CTRL+Key_N, this,
01084                SLOT( newContact() ), actionCollection(), "file_new_contact" );
01085   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." ) );
01086 
01087   mActionMailVCard = new KAction( i18n("Send &Contact..."), "mail_post_to", 0,
01088                                   this, SLOT( mailVCard() ),
01089                                   actionCollection(), "file_mail_vcard" );
01090   mActionMailVCard->setWhatsThis( i18n( "Send a mail with the selected contact as attachment." ) );
01091 
01092   mActionChat = new KAction( i18n("Chat &With..."), 0,
01093                                   this, SLOT( startChat() ),
01094                                   actionCollection(), "file_chat" );
01095   mActionChat->setWhatsThis( i18n( "Start a chat with the selected contact." ) );
01096 
01097   mActionEditAddressee = new KAction( i18n( "&Edit Contact..." ), "edit", 0,
01098                                       this, SLOT( editContact() ),
01099                                       actionCollection(), "file_properties" );
01100   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." ) );
01101 
01102   mActionMerge = new KAction( i18n( "&Merge Contacts" ), "", 0,
01103                               this, SLOT( mergeContacts() ),
01104                               actionCollection(), "edit_merge" );
01105 
01106   // edit menu
01107   mActionCopy = KStdAction::copy( this, SLOT( copyContacts() ), actionCollection() );
01108   mActionCut = KStdAction::cut( this, SLOT( cutContacts() ), actionCollection() );
01109   mActionPaste = KStdAction::paste( this, SLOT( pasteContacts() ), actionCollection() );
01110   action = KStdAction::selectAll( this, SLOT( selectAllContacts() ), actionCollection() );
01111   mActionCopy->setWhatsThis( i18n( "Copy the currently selected contact(s) to system clipboard in vCard format." ) );
01112   mActionCut->setWhatsThis( i18n( "Cuts the currently selected contact(s) to system clipboard in vCard format." ) );
01113   mActionPaste->setWhatsThis( i18n( "Paste the previously cut or copied contacts from clipboard." ) );
01114   action->setWhatsThis( i18n( "Selects all visible contacts from current view." ) );
01115 //  mActionUndo->setWhatsThis( i18n( "Undoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) );
01116 //  mActionRedo->setWhatsThis( i18n( "Redoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) );
01117 
01118   mActionDelete = new KAction( i18n( "&Delete Contact" ), "editdelete",
01119                                Key_Delete, this, SLOT( deleteContacts() ),
01120                                actionCollection(), "edit_delete" );
01121   mActionDelete->setWhatsThis( i18n( "Delete all selected contacts." ) );
01122 
01123 
01124   mActionStoreAddresseeIn = new KAction( i18n( "St&ore Contact In..." ), "kaddressbook", 0,
01125                                       this, SLOT( storeContactIn() ),
01126                                       actionCollection(), "edit_store_in" );
01127   mActionStoreAddresseeIn->setWhatsThis( 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." ) );
01128 
01129   // settings menu
01130   mActionJumpBar = new KToggleAction( i18n( "Show Jump Bar" ), "next", 0,
01131                                       actionCollection(), "options_show_jump_bar" );
01132   mActionJumpBar->setWhatsThis( i18n( "Toggle whether the jump button bar shall be visible." ) );
01133   mActionJumpBar->setCheckedState( i18n( "Hide Jump Bar") );
01134   connect( mActionJumpBar, SIGNAL( toggled( bool ) ), SLOT( setJumpButtonBarVisible( bool ) ) );
01135 
01136   mActionDetails = new KToggleAction( i18n( "Show Details" ), 0, 0,
01137                                       actionCollection(), "options_show_details" );
01138   mActionDetails->setWhatsThis( i18n( "Toggle whether the details page shall be visible." ) );
01139   mActionDetails->setCheckedState( i18n( "Hide Details") );
01140   connect( mActionDetails, SIGNAL( toggled( bool ) ), SLOT( setDetailsVisible( bool ) ) );
01141 
01142   if ( mIsPart )
01143     action = new KAction( i18n( "&Configure Address Book..." ), "configure", 0,
01144                           this, SLOT( configure() ), actionCollection(),
01145                           "kaddressbook_configure" );
01146   else
01147     action = KStdAction::preferences( this, SLOT( configure() ), actionCollection() );
01148 
01149   action->setWhatsThis( i18n( "You will be presented with a dialog, that offers you all possibilities to configure KAddressBook." ) );
01150 
01151   // misc
01152   action = new KAction( i18n( "&Lookup Addresses in LDAP Directory..." ), "find", 0,
01153                         this, SLOT( openLDAPDialog() ), actionCollection(), "ldap_lookup" );
01154   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." ) );
01155 
01156   mActionWhoAmI = new KAction( i18n( "Set as Personal Contact Data" ), "personal", 0, this,
01157                                SLOT( setWhoAmI() ), actionCollection(),
01158                                "edit_set_personal" );
01159   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." ) );
01160 
01161   mActionCategories = new KAction( i18n( "Select Categories..." ), 0, this,
01162                                    SLOT( setCategories() ), actionCollection(),
01163                                    "edit_set_categories" );
01164   mActionCategories->setWhatsThis( i18n( "Set the categories for all selected contacts." ) );
01165 
01166   KAction *clearLocation = new KAction( i18n( "Clear Search Bar" ),
01167                     QApplication::reverseLayout() ? "clear_left" : "locationbar_erase",
01168                     CTRL+Key_L, this, SLOT( slotClearSearchBar() ), actionCollection(), "clear_search" );
01169   clearLocation->setWhatsThis( i18n( "Clear Search Bar<p>"
01170                      "Clears the content of the quick search bar." ) );
01171 
01172   clipboardDataChanged();
01173 }
01174 
01175 void KABCore::clipboardDataChanged()
01176 {
01177   if ( mReadWrite )
01178     mActionPaste->setEnabled( !QApplication::clipboard()->text().isEmpty() );
01179 }
01180 
01181 void KABCore::updateIncSearchWidget()
01182 {
01183   mIncSearchWidget->setViewFields( mViewManager->viewFields() );
01184 }
01185 
01186 void KABCore::updateCategories()
01187 {
01188   QStringList categories( allCategories() );
01189   categories.sort();
01190 
01191   const QStringList customCategories( KABPrefs::instance()->customCategories() );
01192   QStringList::ConstIterator it;
01193   const QStringList::ConstIterator endIt( customCategories.end() );
01194   for ( it = customCategories.begin(); it != endIt; ++it ) {
01195     if ( categories.find( *it ) == categories.end() ) {
01196       categories.append( *it );
01197     }
01198   }
01199 
01200   KABPrefs::instance()->mCustomCategories = categories;
01201   KABPrefs::instance()->writeConfig();
01202 
01203   if ( mCategoryEditDialog )
01204     mCategoryEditDialog->reload();
01205 }
01206 
01207 QStringList KABCore::allCategories() const
01208 {
01209   QStringList categories, allCategories;
01210   QStringList::ConstIterator catIt;
01211 
01212   KABC::AddressBook::ConstIterator it;
01213   const KABC::AddressBook::ConstIterator endIt( mAddressBook->end() );
01214   for ( it = mAddressBook->begin(); it != endIt; ++it ) {
01215     categories = (*it).categories();
01216     const QStringList::ConstIterator catEndIt( categories.end() );
01217     for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) {
01218       if ( !allCategories.contains( *catIt ) )
01219         allCategories.append( *catIt );
01220     }
01221   }
01222 
01223   return allCategories;
01224 }
01225 
01226 void KABCore::setCategories()
01227 {
01228   // Show the category dialog
01229   if ( mCategorySelectDialog == 0 ) {
01230     mCategorySelectDialog = new KPIM::CategorySelectDialog( KABPrefs::instance(), mWidget );
01231     connect( mCategorySelectDialog, SIGNAL( categoriesSelected( const QStringList& ) ),
01232              SLOT( categoriesSelected( const QStringList& ) ) );
01233     connect( mCategorySelectDialog, SIGNAL( editCategories() ), SLOT( editCategories() ) );
01234   }
01235 
01236   mCategorySelectDialog->show();
01237   mCategorySelectDialog->raise();
01238 }
01239 
01240 void KABCore::categoriesSelected( const QStringList &categories )
01241 {
01242   bool merge = false;
01243   QString msg = i18n( "Merge with existing categories?" );
01244   if ( KMessageBox::questionYesNo( mWidget, msg, QString::null, i18n( "Merge" ), i18n( "Do Not Merge" ) ) == KMessageBox::Yes )
01245     merge = true;
01246 
01247   QStringList uids = mViewManager->selectedUids();
01248   QStringList::ConstIterator it;
01249   const QStringList::ConstIterator endIt( uids.end() );
01250   for ( it = uids.begin(); it != endIt; ++it ) {
01251     KABC::Addressee addr = mAddressBook->findByUid( *it );
01252     if ( !addr.isEmpty() ) {
01253       if ( !merge )
01254         addr.setCategories( categories );
01255       else {
01256         QStringList addrCategories = addr.categories();
01257         QStringList::ConstIterator catIt;
01258         const QStringList::ConstIterator catEndIt( categories.end() );
01259         for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) {
01260           if ( !addrCategories.contains( *catIt ) )
01261             addrCategories.append( *catIt );
01262         }
01263         addr.setCategories( addrCategories );
01264       }
01265 
01266       mAddressBook->insertAddressee( addr );
01267     }
01268   }
01269 
01270   if ( uids.count() > 0 )
01271     setModified( true );
01272 }
01273 
01274 void KABCore::editCategories()
01275 {
01276   if ( mCategoryEditDialog == 0 ) {
01277     mCategoryEditDialog = new KPIM::CategoryEditDialog( KABPrefs::instance(), mWidget );
01278     connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ),
01279              mCategorySelectDialog, SLOT( updateCategoryConfig() ) );
01280   }
01281 
01282   mCategoryEditDialog->show();
01283   mCategoryEditDialog->raise();
01284 }
01285 
01286 void KABCore::slotClearSearchBar()
01287 {
01288   mIncSearchWidget->clear();
01289   mIncSearchWidget->setFocus();
01290 }
01291 
01292 void KABCore::slotContactsUpdated()
01293 {
01294   if ( mStatusBar ) {
01295     QString msg( i18n( "%n contact matches", "%n contacts matching", mSearchManager->contacts().count() ) );
01296     if ( !mStatusBar->hasItem( 1 ) )
01297       mStatusBar->insertItem( msg, 1 );
01298     else
01299       mStatusBar->changeItem( msg, 1 );
01300   }
01301 
01302   emit contactsUpdated();
01303 }
01304 
01305 bool KABCore::handleCommandLine( KAddressBookIface* iface )
01306 {
01307   KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
01308   QCString addrStr = args->getOption( "addr" );
01309   QCString uidStr = args->getOption( "uid" );
01310 
01311   QString addr, uid, vcard;
01312   if ( !addrStr.isEmpty() )
01313     addr = QString::fromLocal8Bit( addrStr );
01314   if ( !uidStr.isEmpty() )
01315     uid = QString::fromLocal8Bit( uidStr );
01316 
01317   bool doneSomething = false;
01318 
01319   // 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
01320   if ( !addr.isEmpty() ) {
01321     iface->addEmail( addr );
01322     doneSomething = true;
01323   }
01324 
01325   if ( !uid.isEmpty() ) {
01326     iface->showContactEditor( uid );
01327     doneSomething = true;
01328   }
01329 
01330   if ( args->isSet( "new-contact" ) ) {
01331     iface->newContact();
01332     doneSomething = true;
01333   }
01334 
01335   if ( args->count() >= 1 ) {
01336     for ( int i = 0; i < args->count(); ++i )
01337       iface->importVCard( args->url( i ).url() );
01338     doneSomething = true;
01339   }
01340   return doneSomething;
01341 }
01342 
01343 #ifdef KDEPIM_NEW_DISTRLISTS
01344 KPIM::DistributionList::List KABCore::distributionLists() const
01345 {
01346   return mSearchManager->distributionLists();
01347 }
01348 
01349 QStringList KABCore::distributionListNames() const
01350 {
01351   return mSearchManager->distributionListNames();
01352 }
01353 #endif
01354 
01355 #include "kabcore.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys