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