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.7", 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::importVCardFromData( const QString &vCard )
00653 {
00654   mXXPortManager->importVCardFromData( vCard );
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     setModified(true);
00801   }
00802 }
00803 
00804 void KABCore::extensionDeleted( const QStringList &uidList )
00805 {
00806   DeleteCommand *command = new DeleteCommand( mAddressBook, uidList );
00807   mCommandHistory->addCommand( command );
00808 
00809   // now if we deleted anything, refresh
00810   setContactSelected( QString::null );
00811   setModified( true );
00812 }
00813 
00814 QString KABCore::getNameByPhone( const QString &phone )
00815 {
00816 #if KDE_IS_VERSION(3,4,89)
00817   // This ugly hack will be removed in 4.0
00818   // addressbook may not be reloaded yet, as done asynchronously, so wait
00819   while ( !mAddressBook->loadingHasFinished() ) {
00820     QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00821     // use sleep here to reduce cpu usage
00822     usleep( 100 );
00823   }
00824 #endif
00825 
00826   QRegExp r( "[/*/-/ ]" );
00827   QString localPhone( phone );
00828 
00829   bool found = false;
00830   QString ownerName = "";
00831   KABC::PhoneNumber::List phoneList;
00832 
00833   KABC::AddressBook::ConstIterator iter;
00834   const KABC::AddressBook::ConstIterator endIter( mAddressBook->end() );
00835 
00836   for ( iter = mAddressBook->begin(); !found && ( iter != endIter ); ++iter ) {
00837     phoneList = (*iter).phoneNumbers();
00838     KABC::PhoneNumber::List::Iterator phoneIter( phoneList.begin() );
00839     const KABC::PhoneNumber::List::Iterator phoneEndIter( phoneList.end() );
00840     for ( ; !found && ( phoneIter != phoneEndIter ); ++phoneIter) {
00841       // Get rid of separator chars so just the numbers are compared.
00842       if ( (*phoneIter).number().replace( r, "" ) == localPhone.replace( r, "" ) ) {
00843         ownerName = (*iter).realName();
00844         found = true;
00845       }
00846     }
00847   }
00848 
00849   return ownerName;
00850 }
00851 
00852 void KABCore::openLDAPDialog()
00853 {
00854   if ( !KProtocolInfo::isKnownProtocol( KURL( "ldap://localhost" ) ) ) {
00855     KMessageBox::error( mWidget, i18n( "Your KDE installation is missing LDAP "
00856                                        "support, please ask your administrator or distributor for more information." ),
00857                         i18n( "No LDAP IO Slave Available" ) );
00858     return;
00859   }
00860 
00861   if ( !mLdapSearchDialog ) {
00862     mLdapSearchDialog = new LDAPSearchDialog( mAddressBook, this, mWidget );
00863     connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ),
00864             SLOT( addressBookChanged() ) );
00865     connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ),
00866             SLOT( setModified() ) );
00867   } else
00868     mLdapSearchDialog->restoreSettings();
00869 
00870   if ( mLdapSearchDialog->isOK() )
00871     mLdapSearchDialog->exec();
00872 }
00873 
00874 void KABCore::configure()
00875 {
00876   // Save the current config so we do not loose anything if the user accepts
00877   saveSettings();
00878 
00879   KCMultiDialog dlg( mWidget, "", true );
00880   connect( &dlg, SIGNAL( configCommitted() ),
00881            this, SLOT( configurationChanged() ) );
00882 
00883   dlg.addModule( "kabconfig.desktop" );
00884   dlg.addModule( "kabldapconfig.desktop" );
00885   dlg.addModule( "kabcustomfields.desktop" );
00886 
00887   dlg.exec();
00888 }
00889 
00890 void KABCore::print()
00891 {
00892   KPrinter printer;
00893   printer.setDocName( i18n( "Address Book" ) );
00894   printer.setDocFileName( "addressbook" );
00895 
00896   if ( !printer.setup( mWidget, i18n("Print Addresses") ) )
00897     return;
00898 
00899   KABPrinting::PrintingWizard wizard( &printer, mAddressBook,
00900                                       mViewManager->selectedUids(), mWidget );
00901 
00902   wizard.exec();
00903 }
00904 
00905 void KABCore::detailsHighlighted( const QString &msg )
00906 {
00907   if ( mStatusBar ) {
00908     if ( !mStatusBar->hasItem( 2 ) )
00909       mStatusBar->insertItem( msg, 2 );
00910     else
00911       mStatusBar->changeItem( msg, 2 );
00912   }
00913 }
00914 
00915 void KABCore::showContactsAddress( const QString &addrUid )
00916 {
00917   QStringList uidList = mViewManager->selectedUids();
00918   if ( uidList.isEmpty() )
00919     return;
00920 
00921   KABC::Addressee addr = mAddressBook->findByUid( uidList.first() );
00922   if ( addr.isEmpty() )
00923     return;
00924 
00925   const KABC::Address::List list = addr.addresses();
00926   KABC::Address::List::ConstIterator it;
00927   const KABC::Address::List::ConstIterator endIt( list.end() );
00928   for ( it = list.begin(); it != endIt; ++it )
00929     if ( (*it).id() == addrUid ) {
00930       LocationMap::instance()->showAddress( *it );
00931       break;
00932     }
00933 }
00934 
00935 void KABCore::configurationChanged()
00936 {
00937   mExtensionManager->reconfigure();
00938   mViewManager->refreshView();
00939 }
00940 
00941 bool KABCore::queryClose()
00942 {
00943   saveSettings();
00944   KABPrefs::instance()->writeConfig();
00945 
00946   QPtrList<KABC::Resource> resources = mAddressBook->resources();
00947   QPtrListIterator<KABC::Resource> it( resources );
00948   while ( it.current() ) {
00949     it.current()->close();
00950     ++it;
00951   }
00952 
00953   return true;
00954 }
00955 
00956 void KABCore::reinitXMLGUI()
00957 {
00958   mExtensionManager->createActions();
00959 }
00960 void KABCore::delayedAddressBookChanged()
00961 {
00962   mAddressBookChangedTimer->start( 1000 );
00963 }
00964 
00965 void KABCore::addressBookChanged()
00966 {
00967   const QStringList selectedUids = mViewManager->selectedUids();
00968 
00969   mAddressBookChangedTimer->stop();
00970 
00971   if ( mJumpButtonBar )
00972     mJumpButtonBar->updateButtons();
00973 
00974   mSearchManager->reload();
00975 
00976   mViewManager->setSelected( QString::null, false );
00977 
00978   QString uid = QString::null;
00979   if ( !selectedUids.isEmpty() ) {
00980     uid = selectedUids.first();
00981     mViewManager->setSelected( uid, true );
00982   }
00983 
00984   setContactSelected( uid );
00985 
00986   updateCategories();
00987 }
00988 
00989 AddresseeEditorDialog *KABCore::createAddresseeEditorDialog( QWidget *parent,
00990                                                              const char *name )
00991 {
00992   AddresseeEditorDialog *dialog = new AddresseeEditorDialog( this, parent,
00993                                                  name ? name : "editorDialog" );
00994   connect( dialog, SIGNAL( contactModified( const KABC::Addressee& ) ),
00995            SLOT( contactModified( const KABC::Addressee& ) ) );
00996   connect( dialog, SIGNAL( editorDestroyed( const QString& ) ),
00997            SLOT( slotEditorDestroyed( const QString& ) ) );
00998 
00999   return dialog;
01000 }
01001 
01002 void KABCore::slotEditorDestroyed( const QString &uid )
01003 {
01004   AddresseeEditorDialog *dialog = mEditorDict.take( uid );
01005 
01006   KABC::Addressee addr = dialog->addressee();
01007 
01008   if ( !addr.resource()->readOnly() ) {
01009     QApplication::setOverrideCursor( Qt::waitCursor );
01010     KABLock::self( mAddressBook )->unlock( addr.resource() );
01011     QApplication::restoreOverrideCursor();
01012   }
01013 }
01014 
01015 void KABCore::initGUI()
01016 {
01017   QVBoxLayout *topLayout = new QVBoxLayout( mWidget, 0, 0 );
01018   KToolBar* searchTB = new KToolBar( mWidget, "search toolbar");
01019   searchTB->boxLayout()->setSpacing( KDialog::spacingHint() );
01020   mIncSearchWidget = new IncSearchWidget( searchTB, "kde toolbar widget");
01021   searchTB->setStretchableWidget( mIncSearchWidget );
01022   connect( mIncSearchWidget, SIGNAL( doSearch( const QString& ) ),
01023            SLOT( incrementalTextSearch( const QString& ) ) );
01024 
01025   mFilterSelectionWidget = new FilterSelectionWidget( searchTB , "kde toolbar widget" );
01026 
01027   mDetailsSplitter = new QSplitter( mWidget );
01028   topLayout->addWidget( searchTB );
01029   topLayout->addWidget( mDetailsSplitter );
01030 
01031   mExtensionBarSplitter = new QSplitter( mDetailsSplitter );
01032   mExtensionBarSplitter->setOrientation( Qt::Vertical );
01033 
01034   mDetailsWidget = new QWidget( mDetailsSplitter );
01035   mDetailsLayout = new QHBoxLayout( mDetailsWidget );
01036 
01037   mDetailsPage = new QWidget( mDetailsWidget );
01038   mDetailsLayout->addWidget( mDetailsPage );
01039 
01040   QHBoxLayout *detailsPageLayout = new QHBoxLayout( mDetailsPage, 0, 0 );
01041   mDetails = new KPIM::AddresseeView( mDetailsPage );
01042   mDetails->setVScrollBarMode( QScrollView::Auto );
01043   detailsPageLayout->addWidget( mDetails );
01044 
01045   connect( mDetails, SIGNAL( addressClicked( const QString&) ),
01046            this, SLOT( showContactsAddress( const QString& ) ) );
01047 
01048   mViewManager = new ViewManager( this, mExtensionBarSplitter );
01049   mViewManager->setFilterSelectionWidget( mFilterSelectionWidget );
01050 
01051   connect( mFilterSelectionWidget, SIGNAL( filterActivated( int ) ),
01052            mViewManager, SLOT( setActiveFilter( int ) ) );
01053 
01054   mExtensionManager = new ExtensionManager( this, mExtensionBarSplitter );
01055 
01056   topLayout->setStretchFactor( mDetailsSplitter, 1 );
01057 
01058   mXXPortManager = new XXPortManager( this, mWidget );
01059 
01060   initActions();
01061 }
01062 
01063 void KABCore::createJumpButtonBar()
01064 {
01065   mJumpButtonBar = new JumpButtonBar( this, mDetailsWidget );
01066   mDetailsLayout->addWidget( mJumpButtonBar );
01067   mDetailsLayout->setStretchFactor( mJumpButtonBar, 1 );
01068 
01069   connect( mJumpButtonBar, SIGNAL( jumpToLetter( const QString& ) ),
01070            SLOT( incrementalJumpButtonSearch( const QString& ) ) );
01071   connect( mViewManager, SIGNAL( sortFieldChanged() ),
01072            mJumpButtonBar, SLOT( updateButtons() ) );
01073 }
01074 
01075 void KABCore::initActions()
01076 {
01077   connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
01078            SLOT( clipboardDataChanged() ) );
01079 
01080   KAction *action;
01081 
01082   // file menu
01083   mActionMail = new KAction( i18n( "&Send Email to Contact..." ), "mail_send", 0,
01084                              this, SLOT( sendMail() ), actionCollection(), "file_mail" );
01085   action = KStdAction::print( this, SLOT( print() ), actionCollection() );
01086   mActionMail->setWhatsThis( i18n( "Send a mail to all selected contacts." ) );
01087   action->setWhatsThis( i18n( "Print a special number of contacts." ) );
01088 
01089   mActionSave = KStdAction::save( this,
01090                              SLOT( save() ), actionCollection(), "file_sync" );
01091   mActionSave->setWhatsThis( i18n( "Save all changes of the address book to the storage backend." ) );
01092 
01093   action = new KAction( i18n( "&New Contact..." ), "identity", CTRL+Key_N, this,
01094                SLOT( newContact() ), actionCollection(), "file_new_contact" );
01095   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." ) );
01096 
01097   mActionMailVCard = new KAction( i18n("Send &Contact..."), "mail_post_to", 0,
01098                                   this, SLOT( mailVCard() ),
01099                                   actionCollection(), "file_mail_vcard" );
01100   mActionMailVCard->setWhatsThis( i18n( "Send a mail with the selected contact as attachment." ) );
01101 
01102   mActionChat = new KAction( i18n("Chat &With..."), 0,
01103                                   this, SLOT( startChat() ),
01104                                   actionCollection(), "file_chat" );
01105   mActionChat->setWhatsThis( i18n( "Start a chat with the selected contact." ) );
01106 
01107   mActionEditAddressee = new KAction( i18n( "&Edit Contact..." ), "edit", 0,
01108                                       this, SLOT( editContact() ),
01109                                       actionCollection(), "file_properties" );
01110   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." ) );
01111 
01112   mActionMerge = new KAction( i18n( "&Merge Contacts" ), "", 0,
01113                               this, SLOT( mergeContacts() ),
01114                               actionCollection(), "edit_merge" );
01115 
01116   // edit menu
01117   mActionCopy = KStdAction::copy( this, SLOT( copyContacts() ), actionCollection() );
01118   mActionCut = KStdAction::cut( this, SLOT( cutContacts() ), actionCollection() );
01119   mActionPaste = KStdAction::paste( this, SLOT( pasteContacts() ), actionCollection() );
01120   action = KStdAction::selectAll( this, SLOT( selectAllContacts() ), actionCollection() );
01121   mActionCopy->setWhatsThis( i18n( "Copy the currently selected contact(s) to system clipboard in vCard format." ) );
01122   mActionCut->setWhatsThis( i18n( "Cuts the currently selected contact(s) to system clipboard in vCard format." ) );
01123   mActionPaste->setWhatsThis( i18n( "Paste the previously cut or copied contacts from clipboard." ) );
01124   action->setWhatsThis( i18n( "Selects all visible contacts from current view." ) );
01125 //  mActionUndo->setWhatsThis( i18n( "Undoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) );
01126 //  mActionRedo->setWhatsThis( i18n( "Redoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) );
01127 
01128   mActionDelete = new KAction( i18n( "&Delete Contact" ), "editdelete",
01129                                Key_Delete, this, SLOT( deleteContacts() ),
01130                                actionCollection(), "edit_delete" );
01131   mActionDelete->setWhatsThis( i18n( "Delete all selected contacts." ) );
01132 
01133 
01134   mActionStoreAddresseeIn = new KAction( i18n( "St&ore Contact In..." ), "kaddressbook", 0,
01135                                       this, SLOT( storeContactIn() ),
01136                                       actionCollection(), "edit_store_in" );
01137   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." ) );
01138 
01139   // settings menu
01140   mActionJumpBar = new KToggleAction( i18n( "Show Jump Bar" ), "next", 0,
01141                                       actionCollection(), "options_show_jump_bar" );
01142   mActionJumpBar->setWhatsThis( i18n( "Toggle whether the jump button bar shall be visible." ) );
01143   mActionJumpBar->setCheckedState( i18n( "Hide Jump Bar") );
01144   connect( mActionJumpBar, SIGNAL( toggled( bool ) ), SLOT( setJumpButtonBarVisible( bool ) ) );
01145 
01146   mActionDetails = new KToggleAction( i18n( "Show Details" ), 0, 0,
01147                                       actionCollection(), "options_show_details" );
01148   mActionDetails->setWhatsThis( i18n( "Toggle whether the details page shall be visible." ) );
01149   mActionDetails->setCheckedState( i18n( "Hide Details") );
01150   connect( mActionDetails, SIGNAL( toggled( bool ) ), SLOT( setDetailsVisible( bool ) ) );
01151 
01152   if ( mIsPart )
01153     action = new KAction( i18n( "&Configure Address Book..." ), "configure", 0,
01154                           this, SLOT( configure() ), actionCollection(),
01155                           "kaddressbook_configure" );
01156   else
01157     action = KStdAction::preferences( this, SLOT( configure() ), actionCollection() );
01158 
01159   action->setWhatsThis( i18n( "You will be presented with a dialog, that offers you all possibilities to configure KAddressBook." ) );
01160 
01161   // misc
01162   action = new KAction( i18n( "&Lookup Addresses in LDAP Directory..." ), "find", 0,
01163                         this, SLOT( openLDAPDialog() ), actionCollection(), "ldap_lookup" );
01164   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." ) );
01165 
01166   mActionWhoAmI = new KAction( i18n( "Set as Personal Contact Data" ), "personal", 0, this,
01167                                SLOT( setWhoAmI() ), actionCollection(),
01168                                "edit_set_personal" );
01169   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." ) );
01170 
01171   mActionCategories = new KAction( i18n( "Select Categories..." ), 0, this,
01172                                    SLOT( setCategories() ), actionCollection(),
01173                                    "edit_set_categories" );
01174   mActionCategories->setWhatsThis( i18n( "Set the categories for all selected contacts." ) );
01175 
01176   KAction *clearLocation = new KAction( i18n( "Clear Search Bar" ),
01177                     QApplication::reverseLayout() ? "clear_left" : "locationbar_erase",
01178                     CTRL+Key_L, this, SLOT( slotClearSearchBar() ), actionCollection(), "clear_search" );
01179   clearLocation->setWhatsThis( i18n( "Clear Search Bar<p>"
01180                      "Clears the content of the quick search bar." ) );
01181 
01182   clipboardDataChanged();
01183 }
01184 
01185 void KABCore::clipboardDataChanged()
01186 {
01187   if ( mReadWrite )
01188     mActionPaste->setEnabled( !QApplication::clipboard()->text().isEmpty() );
01189 }
01190 
01191 void KABCore::updateIncSearchWidget()
01192 {
01193   mIncSearchWidget->setViewFields( mViewManager->viewFields() );
01194 }
01195 
01196 void KABCore::updateCategories()
01197 {
01198   QStringList categories( allCategories() );
01199   categories.sort();
01200 
01201   const QStringList customCategories( KABPrefs::instance()->customCategories() );
01202   QStringList::ConstIterator it;
01203   const QStringList::ConstIterator endIt( customCategories.end() );
01204   for ( it = customCategories.begin(); it != endIt; ++it ) {
01205     if ( categories.find( *it ) == categories.end() ) {
01206       categories.append( *it );
01207     }
01208   }
01209 
01210   KABPrefs::instance()->mCustomCategories = categories;
01211   KABPrefs::instance()->writeConfig();
01212 
01213   if ( mCategoryEditDialog )
01214     mCategoryEditDialog->reload();
01215 }
01216 
01217 QStringList KABCore::allCategories() const
01218 {
01219   QStringList categories, allCategories;
01220   QStringList::ConstIterator catIt;
01221 
01222   KABC::AddressBook::ConstIterator it;
01223   const KABC::AddressBook::ConstIterator endIt( mAddressBook->end() );
01224   for ( it = mAddressBook->begin(); it != endIt; ++it ) {
01225     categories = (*it).categories();
01226     const QStringList::ConstIterator catEndIt( categories.end() );
01227     for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) {
01228       if ( !allCategories.contains( *catIt ) )
01229         allCategories.append( *catIt );
01230     }
01231   }
01232 
01233   return allCategories;
01234 }
01235 
01236 void KABCore::setCategories()
01237 {
01238   // Show the category dialog
01239   if ( mCategorySelectDialog == 0 ) {
01240     mCategorySelectDialog = new KPIM::CategorySelectDialog( KABPrefs::instance(), mWidget );
01241     connect( mCategorySelectDialog, SIGNAL( categoriesSelected( const QStringList& ) ),
01242              SLOT( categoriesSelected( const QStringList& ) ) );
01243     connect( mCategorySelectDialog, SIGNAL( editCategories() ), SLOT( editCategories() ) );
01244   }
01245 
01246   mCategorySelectDialog->show();
01247   mCategorySelectDialog->raise();
01248 }
01249 
01250 void KABCore::categoriesSelected( const QStringList &categories )
01251 {
01252   bool merge = false;
01253   QString msg = i18n( "Merge with existing categories?" );
01254   if ( KMessageBox::questionYesNo( mWidget, msg, QString::null, i18n( "Merge" ), i18n( "Do Not Merge" ) ) == KMessageBox::Yes )
01255     merge = true;
01256 
01257   QStringList uids = mViewManager->selectedUids();
01258   QStringList::ConstIterator it;
01259   const QStringList::ConstIterator endIt( uids.end() );
01260   for ( it = uids.begin(); it != endIt; ++it ) {
01261     KABC::Addressee addr = mAddressBook->findByUid( *it );
01262     if ( !addr.isEmpty() ) {
01263       if ( !merge )
01264         addr.setCategories( categories );
01265       else {
01266         QStringList addrCategories = addr.categories();
01267         QStringList::ConstIterator catIt;
01268         const QStringList::ConstIterator catEndIt( categories.end() );
01269         for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) {
01270           if ( !addrCategories.contains( *catIt ) )
01271             addrCategories.append( *catIt );
01272         }
01273         addr.setCategories( addrCategories );
01274       }
01275 
01276       mAddressBook->insertAddressee( addr );
01277     }
01278   }
01279 
01280   if ( uids.count() > 0 )
01281     setModified( true );
01282 }
01283 
01284 void KABCore::editCategories()
01285 {
01286   if ( mCategoryEditDialog == 0 ) {
01287     mCategoryEditDialog = new KPIM::CategoryEditDialog( KABPrefs::instance(), mWidget );
01288     connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ),
01289              mCategorySelectDialog, SLOT( updateCategoryConfig() ) );
01290   }
01291 
01292   mCategoryEditDialog->show();
01293   mCategoryEditDialog->raise();
01294 }
01295 
01296 void KABCore::slotClearSearchBar()
01297 {
01298   mIncSearchWidget->clear();
01299   mIncSearchWidget->setFocus();
01300 }
01301 
01302 void KABCore::slotContactsUpdated()
01303 {
01304   if ( mStatusBar ) {
01305     QString msg( i18n( "%n contact matches", "%n contacts matching", mSearchManager->contacts().count() ) );
01306     if ( !mStatusBar->hasItem( 1 ) )
01307       mStatusBar->insertItem( msg, 1 );
01308     else
01309       mStatusBar->changeItem( msg, 1 );
01310   }
01311 
01312   emit contactsUpdated();
01313 }
01314 
01315 bool KABCore::handleCommandLine( KAddressBookIface* iface )
01316 {
01317   KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
01318   QCString addrStr = args->getOption( "addr" );
01319   QCString uidStr = args->getOption( "uid" );
01320 
01321   QString addr, uid, vcard;
01322   if ( !addrStr.isEmpty() )
01323     addr = QString::fromLocal8Bit( addrStr );
01324   if ( !uidStr.isEmpty() )
01325     uid = QString::fromLocal8Bit( uidStr );
01326 
01327   bool doneSomething = false;
01328 
01329   // 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
01330   if ( !addr.isEmpty() ) {
01331     iface->addEmail( addr );
01332     doneSomething = true;
01333   }
01334 
01335   if ( !uid.isEmpty() ) {
01336     iface->showContactEditor( uid );
01337     doneSomething = true;
01338   }
01339 
01340   if ( args->isSet( "new-contact" ) ) {
01341     iface->newContact();
01342     doneSomething = true;
01343   }
01344 
01345   if ( args->count() >= 1 ) {
01346     for ( int i = 0; i < args->count(); ++i )
01347       iface->importVCard( args->url( i ).url() );
01348     doneSomething = true;
01349   }
01350   return doneSomething;
01351 }
01352 
01353 #ifdef KDEPIM_NEW_DISTRLISTS
01354 KPIM::DistributionList::List KABCore::distributionLists() const
01355 {
01356   return mSearchManager->distributionLists();
01357 }
01358 
01359 QStringList KABCore::distributionListNames() const
01360 {
01361   return mSearchManager->distributionListNames();
01362 }
01363 #endif
01364 
01365 #include "kabcore.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys