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.6", I18N_NOOP( "The KDE Address Book" ),
00297                                       KAboutData::License_GPL_V2,
00298                                       I18N_NOOP( "(c) 1997-2005, The KDE PIM Team" ) );
00299   about->addAuthor( "Tobias Koenig", I18N_NOOP( "Current maintainer" ), "tokoe@kde.org" );
00300   about->addAuthor( "Don Sanders", I18N_NOOP( "Original author" ) );
00301   about->addAuthor( "Cornelius Schumacher",
00302                     I18N_NOOP( "Co-maintainer, libkabc port, CSV import/export" ),
00303                     "schumacher@kde.org" );
00304   about->addAuthor( "Mike Pilone", I18N_NOOP( "GUI and framework redesign" ),
00305                     "mpilone@slac.com" );
00306   about->addAuthor( "Greg Stern", I18N_NOOP( "DCOP interface" ) );
00307   about->addAuthor( "Mark Westcott", I18N_NOOP( "Contact pinning" ) );
00308   about->addAuthor( "Mischel Boyer de la Giroday", I18N_NOOP( "LDAP Lookup" ),
00309                     "michel@klaralvdalens-datakonsult.se" );
00310   about->addAuthor( "Steffen Hansen", I18N_NOOP( "LDAP Lookup" ),
00311                     "hansen@kde.org" );
00312 
00313   return about;
00314 }
00315 
00316 void KABCore::setStatusBar( KStatusBar *statusBar )
00317 {
00318   mStatusBar = statusBar;
00319 }
00320 
00321 KStatusBar *KABCore::statusBar() const
00322 {
00323   return mStatusBar;
00324 }
00325 
00326 void KABCore::setContactSelected( const QString &uid )
00327 {
00328   KABC::Addressee addr = mAddressBook->findByUid( uid );
00329   if ( !mDetails->isHidden() )
00330     mDetails->setAddressee( addr );
00331 
00332   mExtensionManager->setSelectionChanged();
00333 
00334   // update the actions
00335   bool selected = !uid.isEmpty();
00336 
00337   if ( mReadWrite ) {
00338     mActionCut->setEnabled( selected );
00339 
00340     QClipboard *cb = QApplication::clipboard();
00341     KABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( cb->text() );
00342     mActionPaste->setEnabled( !list.isEmpty() );
00343   }
00344 
00345   mActionCopy->setEnabled( selected );
00346   mActionDelete->setEnabled( selected );
00347   mActionEditAddressee->setEnabled( selected );
00348   mActionStoreAddresseeIn->setEnabled( selected );
00349   mActionMail->setEnabled( selected );
00350   mActionMailVCard->setEnabled( selected );
00351   mActionChat->setEnabled( selected && mKIMProxy && mKIMProxy->initialize() );
00352   mActionWhoAmI->setEnabled( selected );
00353   mActionCategories->setEnabled( selected );
00354   mActionMerge->setEnabled( selected );
00355 }
00356 
00357 void KABCore::sendMail()
00358 {
00359   sendMail( mViewManager->selectedEmails().join( ", " ) );
00360 }
00361 
00362 void KABCore::sendMail( const QString& email )
00363 {
00364   kapp->invokeMailer( email, "" );
00365 }
00366 
00367 void KABCore::mailVCard()
00368 {
00369   QStringList uids = mViewManager->selectedUids();
00370   if ( !uids.isEmpty() )
00371     mailVCard( uids );
00372 }
00373 
00374 void KABCore::mailVCard( const QStringList &uids )
00375 {
00376   KABTools::mailVCards( uids, mAddressBook );
00377 }
00378 
00379 void KABCore::startChat()
00380 {
00381   QStringList uids = mViewManager->selectedUids();
00382   if ( !uids.isEmpty() )
00383     mKIMProxy->chatWithContact( uids.first() );
00384 }
00385 
00386 void KABCore::browse( const QString& url )
00387 {
00388   kapp->invokeBrowser( url );
00389 }
00390 
00391 void KABCore::selectAllContacts()
00392 {
00393   mViewManager->setSelected( QString::null, true );
00394 }
00395 
00396 void KABCore::deleteContacts()
00397 {
00398   QStringList uidList = mViewManager->selectedUids();
00399 
00400   deleteContacts( uidList );
00401 }
00402 
00403 void KABCore::deleteContacts( const QStringList &uids )
00404 {
00405   if ( uids.count() > 0 ) {
00406     QStringList names;
00407     QStringList::ConstIterator it = uids.begin();
00408     const QStringList::ConstIterator endIt( uids.end() );
00409     while ( it != endIt ) {
00410       KABC::Addressee addr = mAddressBook->findByUid( *it );
00411       names.append( addr.realName().isEmpty() ? addr.preferredEmail() : addr.realName() );
00412       ++it;
00413     }
00414 
00415     if ( KMessageBox::warningContinueCancelList( mWidget, i18n( "Do you really want to delete this contact?",
00416                                                  "Do you really want to delete these %n contacts?", uids.count() ),
00417                                                  names, QString::null, KStdGuiItem::del() ) == KMessageBox::Cancel )
00418       return;
00419 
00420     DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
00421     mCommandHistory->addCommand( command );
00422 
00423     // now if we deleted anything, refresh
00424     setContactSelected( QString::null );
00425     setModified( true );
00426   }
00427 }
00428 
00429 void KABCore::copyContacts()
00430 {
00431   KABC::Addressee::List addrList = mViewManager->selectedAddressees();
00432 
00433   QString clipText = AddresseeUtil::addresseesToClipboard( addrList );
00434 
00435   kdDebug(5720) << "KABCore::copyContacts: " << clipText << endl;
00436 
00437   QClipboard *cb = QApplication::clipboard();
00438   cb->setText( clipText );
00439 }
00440 
00441 void KABCore::cutContacts()
00442 {
00443   QStringList uidList = mViewManager->selectedUids();
00444 
00445   if ( uidList.size() > 0 ) {
00446     CutCommand *command = new CutCommand( mAddressBook, uidList );
00447     mCommandHistory->addCommand( command );
00448 
00449     setModified( true );
00450   }
00451 }
00452 
00453 void KABCore::pasteContacts()
00454 {
00455   QClipboard *cb = QApplication::clipboard();
00456 
00457   KABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( cb->text() );
00458 
00459   pasteContacts( list );
00460 }
00461 
00462 void KABCore::pasteContacts( KABC::Addressee::List &list )
00463 {
00464   KABC::Resource *resource = requestResource( mWidget );
00465   if ( !resource )
00466     return;
00467 
00468   KABC::Addressee::List::Iterator it;
00469   const KABC::Addressee::List::Iterator endIt( list.end() );
00470   for ( it = list.begin(); it != endIt; ++it )
00471     (*it).setResource( resource );
00472 
00473   PasteCommand *command = new PasteCommand( this, list );
00474   mCommandHistory->addCommand( command );
00475 
00476   setModified( true );
00477 }
00478 
00479 void KABCore::mergeContacts()
00480 {
00481   KABC::Addressee::List list = mViewManager->selectedAddressees();
00482   if ( list.count() < 2 )
00483     return;
00484 
00485   KABC::Addressee addr = KABTools::mergeContacts( list );
00486 
00487   KABC::Addressee::List::Iterator it = list.begin();
00488   const KABC::Addressee::List::Iterator endIt( list.end() );
00489   KABC::Addressee origAddr = *it;
00490   QStringList uids;
00491   ++it;
00492   while ( it != endIt ) {
00493     uids.append( (*it).uid() );
00494     ++it;
00495   }
00496 
00497   DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
00498   mCommandHistory->addCommand( command );
00499 
00500   EditCommand *editCommand = new EditCommand( mAddressBook, origAddr, addr );
00501   mCommandHistory->addCommand( editCommand );
00502 
00503   mSearchManager->reload();
00504 }
00505 
00506 void KABCore::setWhoAmI()
00507 {
00508   KABC::Addressee::List addrList = mViewManager->selectedAddressees();
00509 
00510   if ( addrList.count() > 1 ) {
00511     KMessageBox::sorry( mWidget, i18n( "Please select only one contact." ) );
00512     return;
00513   }
00514 
00515   QString text( i18n( "<qt>Do you really want to use <b>%1</b> as your new personal contact?</qt>" ) );
00516   if ( KMessageBox::questionYesNo( mWidget, text.arg( addrList[ 0 ].assembledName() ), QString::null, i18n("Use"), i18n("Do Not Use") ) == KMessageBox::Yes )
00517     static_cast<KABC::StdAddressBook*>( KABC::StdAddressBook::self( true ) )->setWhoAmI( addrList[ 0 ] );
00518 }
00519 
00520 void KABCore::incrementalTextSearch( const QString& text )
00521 {
00522   setContactSelected( QString::null );
00523   mSearchManager->search( text, mIncSearchWidget->currentFields() );
00524 }
00525 
00526 void KABCore::incrementalJumpButtonSearch( const QString& character )
00527 {
00528   mViewManager->setSelected( QString::null, false );
00529 
00530   KABC::AddresseeList list = mSearchManager->contacts();
00531   KABC::Field *field = mViewManager->currentSortField();
00532   if ( field ) {
00533     list.sortByField( field );
00534     KABC::AddresseeList::ConstIterator it;
00535     const KABC::AddresseeList::ConstIterator endIt( list.end() );
00536     for ( it = list.begin(); it != endIt; ++it ) {
00537       if ( field->value( *it ).startsWith( character, false ) ) {
00538         mViewManager->setSelected( (*it).uid(), true );
00539         return;
00540       }
00541     }
00542   }
00543 }
00544 
00545 void KABCore::setModified()
00546 {
00547   setModified( true );
00548 }
00549 
00550 void KABCore::setModified( bool modified )
00551 {
00552   mModified = modified;
00553   mActionSave->setEnabled( mModified );
00554 
00555   mSearchManager->reload();
00556 }
00557 
00558 bool KABCore::modified() const
00559 {
00560   return mModified;
00561 }
00562 
00563 void KABCore::contactModified( const KABC::Addressee &addr )
00564 {
00565   Command *command = 0;
00566 
00567   // check if it exists already
00568   KABC::Addressee origAddr = mAddressBook->findByUid( addr.uid() );
00569   if ( origAddr.isEmpty() ) {
00570     KABC::Addressee::List addressees;
00571     addressees.append( addr );
00572     command = new NewCommand( mAddressBook, addressees );
00573   } else {
00574     command = new EditCommand( mAddressBook, origAddr, addr );
00575   }
00576 
00577   mCommandHistory->addCommand( command );
00578 
00579   setContactSelected( addr.uid() );
00580   setModified( true );
00581 }
00582 
00583 void KABCore::newContact()
00584 {
00585   AddresseeEditorDialog *dialog = 0;
00586 
00587   KABC::Resource* resource = requestResource( mWidget );
00588 
00589   if ( resource ) {
00590     KABC::Addressee addr;
00591     addr.setResource( resource );
00592 
00593     if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) )
00594       return;
00595 
00596     dialog = createAddresseeEditorDialog( mWidget );
00597     dialog->setAddressee( addr );
00598   } else
00599     return;
00600 
00601   mEditorDict.insert( dialog->addressee().uid(), dialog );
00602 
00603   dialog->show();
00604 }
00605 
00606 void KABCore::addEmail( const QString &aStr )
00607 {
00608   QString fullName, email;
00609 
00610   KABC::Addressee::parseEmailAddress( aStr, fullName, email );
00611 
00612 #if KDE_IS_VERSION(3,4,89)
00613   // This ugly hack will be removed in 4.0
00614   // addressbook may not be reloaded yet, as done asynchronously sometimes, so wait
00615   while ( !mAddressBook->loadingHasFinished() ) {
00616     QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00617     // use sleep here to reduce cpu usage
00618     usleep( 100 );
00619   }
00620 #endif
00621 
00622   // Try to lookup the addressee matching the email address
00623   bool found = false;
00624   QStringList emailList;
00625   KABC::AddressBook::Iterator it;
00626   const KABC::AddressBook::Iterator endIt( mAddressBook->end() );
00627   for ( it = mAddressBook->begin(); !found && (it != endIt); ++it ) {
00628     emailList = (*it).emails();
00629     if ( emailList.contains( email ) > 0 ) {
00630       found = true;
00631       (*it).setNameFromString( fullName );
00632       editContact( (*it).uid() );
00633     }
00634   }
00635 
00636   if ( !found ) {
00637     KABC::Addressee addr;
00638     addr.setNameFromString( fullName );
00639     addr.insertEmail( email, true );
00640 
00641     mAddressBook->insertAddressee( addr );
00642     mViewManager->refreshView( addr.uid() );
00643     editContact( addr.uid() );
00644   }
00645 }
00646 
00647 void KABCore::importVCard( const KURL &url )
00648 {
00649   mXXPortManager->importVCard( url );
00650 }
00651 
00652 void KABCore::importVCard( const QString &vCardURL )
00653 {
00654   mXXPortManager->importVCard( vCardURL );
00655 }
00656 
00657 void KABCore::editContact( const QString &uid )
00658 {
00659   if ( mExtensionManager->isQuickEditVisible() )
00660     return;
00661 
00662   // First, locate the contact entry
00663   QString localUID = uid;
00664   if ( localUID.isNull() ) {
00665     QStringList uidList = mViewManager->selectedUids();
00666     if ( uidList.count() > 0 )
00667       localUID = *( uidList.at( 0 ) );
00668   }
00669 #if KDE_IS_VERSION(3,4,89)
00670   // This ugly hack will be removed in 4.0
00671   // for calls with given uid, as done from commandline and DCOP
00672   // addressbook may not be reloaded yet, as done asynchronously, so wait
00673   else while ( !mAddressBook->loadingHasFinished() ) {
00674     QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00675     // use sleep here to reduce cpu usage
00676     usleep( 100 );
00677   }
00678 #endif
00679 
00680   KABC::Addressee addr = mAddressBook->findByUid( localUID );
00681   if ( !addr.isEmpty() ) {
00682     AddresseeEditorDialog *dialog = mEditorDict.find( addr.uid() );
00683     if ( !dialog ) {
00684 
00685       if ( !addr.resource()->readOnly() )
00686         if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) ) {
00687           return;
00688         }
00689 
00690       dialog = createAddresseeEditorDialog( mWidget );
00691 
00692       mEditorDict.insert( addr.uid(), dialog );
00693 
00694       dialog->setAddressee( addr );
00695     }
00696 
00697     dialog->raise();
00698     dialog->show();
00699   }
00700 }
00701 
00702 void KABCore::storeContactIn( const QString &uid )
00703 {
00704   // First, locate the contact entry
00705   QStringList uidList;
00706   if ( uid.isNull() ) {
00707     uidList = mViewManager->selectedUids();
00708   } else {
00709     uidList << uid;
00710   }
00711   KABC::Resource *resource = requestResource( mWidget );
00712   if ( !resource )
00713     return;
00714 
00715   KABLock::self( mAddressBook )->lock( resource );
00716   QStringList::Iterator it( uidList.begin() );
00717   const QStringList::Iterator endIt( uidList.end() );
00718   while ( it != endIt ) {
00719     KABC::Addressee addr = mAddressBook->findByUid( *it++ );
00720     if ( !addr.isEmpty() ) {
00721       KABC::Addressee newAddr( addr );
00722       // We need to set a new uid, otherwise the insert below is
00723       // ignored. This is bad for syncing, but unavoidable, afaiks
00724       newAddr.setUid( KApplication::randomString( 10 ) );
00725       newAddr.setResource( resource );
00726       addressBook()->insertAddressee( newAddr );
00727       KABLock::self( mAddressBook )->lock( addr.resource() );
00728       addressBook()->removeAddressee( addr );
00729       KABLock::self( mAddressBook )->unlock( addr.resource() );
00730     }
00731   }
00732   KABLock::self( mAddressBook )->unlock( resource );
00733 }
00734 
00735 void KABCore::save()
00736 {
00737   QPtrList<KABC::Resource> resources = mAddressBook->resources();
00738   QPtrListIterator<KABC::Resource> it( resources );
00739   while ( it.current() && !it.current()->readOnly() ) {
00740     KABC::Ticket *ticket = mAddressBook->requestSaveTicket( it.current() );
00741     if ( ticket ) {
00742       if ( !mAddressBook->save( ticket ) ) {
00743         KMessageBox::error( mWidget,
00744                             i18n( "<qt>Unable to save address book <b>%1</b>.</qt>" ).arg( it.current()->resourceName() ) );
00745         mAddressBook->releaseSaveTicket( ticket );
00746       } else {
00747         setModified( false );
00748       }
00749     } else {
00750       KMessageBox::error( mWidget,
00751                           i18n( "<qt>Unable to get access for saving the address book <b>%1</b>.</qt>" )
00752                           .arg( it.current()->resourceName() ) );
00753     }
00754 
00755     ++it;
00756   }
00757 }
00758 
00759 void KABCore::setJumpButtonBarVisible( bool visible )
00760 {
00761   if ( visible ) {
00762     if ( !mJumpButtonBar )
00763       createJumpButtonBar();
00764     mJumpButtonBar->show();
00765   } else
00766     if ( mJumpButtonBar )
00767       mJumpButtonBar->hide();
00768 }
00769 
00770 void KABCore::setDetailsVisible( bool visible )
00771 {
00772   if ( visible )
00773     mDetailsPage->show();
00774   else
00775     mDetailsPage->hide();
00776 }
00777 
00778 void KABCore::extensionModified( const KABC::Addressee::List &list )
00779 {
00780   if ( list.count() != 0 ) {
00781     KABC::Addressee::List::ConstIterator it;
00782     const KABC::Addressee::List::ConstIterator endIt( list.end() );
00783     for ( it = list.begin(); it != endIt; ++it ) {
00784       Command *command = 0;
00785 
00786       // check if it exists already
00787       KABC::Addressee origAddr = mAddressBook->findByUid( (*it).uid() );
00788       if ( origAddr.isEmpty() ) {
00789         KABC::Addressee::List addressees;
00790         addressees.append( *it );
00791         command = new NewCommand( mAddressBook, addressees );
00792       } else
00793         command = new EditCommand( mAddressBook, origAddr, *it );
00794 
00795       mCommandHistory->blockSignals( true );
00796       mCommandHistory->addCommand( command );
00797       mCommandHistory->blockSignals( false );
00798     }
00799 
00800     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   mAddressBookChangedTimer->stop();
00968 
00969   if ( mJumpButtonBar )
00970     mJumpButtonBar->updateButtons();
00971 
00972   mSearchManager->reload();
00973   mViewManager->setSelected( QString::null, false );
00974   setContactSelected( QString::null );
00975 
00976   updateCategories();
00977 }
00978 
00979 AddresseeEditorDialog *KABCore::createAddresseeEditorDialog( QWidget *parent,
00980                                                              const char *name )
00981 {
00982   AddresseeEditorDialog *dialog = new AddresseeEditorDialog( this, parent,
00983                                                  name ? name : "editorDialog" );
00984   connect( dialog, SIGNAL( contactModified( const KABC::Addressee& ) ),
00985            SLOT( contactModified( const KABC::Addressee& ) ) );
00986   connect( dialog, SIGNAL( editorDestroyed( const QString& ) ),
00987            SLOT( slotEditorDestroyed( const QString& ) ) );
00988 
00989   return dialog;
00990 }
00991 
00992 void KABCore::slotEditorDestroyed( const QString &uid )
00993 {
00994   AddresseeEditorDialog *dialog = mEditorDict.take( uid );
00995 
00996   KABC::Addressee addr = dialog->addressee();
00997 
00998   if ( !addr.resource()->readOnly() ) {
00999     QApplication::setOverrideCursor( Qt::waitCursor );
01000     KABLock::self( mAddressBook )->unlock( addr.resource() );
01001     QApplication::restoreOverrideCursor();
01002   }
01003 }
01004 
01005 void KABCore::initGUI()
01006 {
01007   QVBoxLayout *topLayout = new QVBoxLayout( mWidget, 0, 0 );
01008   KToolBar* searchTB = new KToolBar( mWidget, "search toolbar");
01009   searchTB->boxLayout()->setSpacing( KDialog::spacingHint() );
01010   mIncSearchWidget = new IncSearchWidget( searchTB, "kde toolbar widget");
01011   searchTB->setStretchableWidget( mIncSearchWidget );
01012   connect( mIncSearchWidget, SIGNAL( doSearch( const QString& ) ),
01013            SLOT( incrementalTextSearch( const QString& ) ) );
01014 
01015   mFilterSelectionWidget = new FilterSelectionWidget( searchTB , "kde toolbar widget" );
01016 
01017   mDetailsSplitter = new QSplitter( mWidget );
01018   topLayout->addWidget( searchTB );
01019   topLayout->addWidget( mDetailsSplitter );
01020 
01021   mExtensionBarSplitter = new QSplitter( mDetailsSplitter );
01022   mExtensionBarSplitter->setOrientation( Qt::Vertical );
01023 
01024   mDetailsWidget = new QWidget( mDetailsSplitter );
01025   mDetailsLayout = new QHBoxLayout( mDetailsWidget );
01026 
01027   mDetailsPage = new QWidget( mDetailsWidget );
01028   mDetailsLayout->addWidget( mDetailsPage );
01029 
01030   QHBoxLayout *detailsPageLayout = new QHBoxLayout( mDetailsPage, 0, 0 );
01031   mDetails = new KPIM::AddresseeView( mDetailsPage );
01032   detailsPageLayout->addWidget( mDetails );
01033 
01034   connect( mDetails, SIGNAL( addressClicked( const QString&) ),
01035            this, SLOT( showContactsAddress( const QString& ) ) );
01036 
01037   mViewManager = new ViewManager( this, mExtensionBarSplitter );
01038   mViewManager->setFilterSelectionWidget( mFilterSelectionWidget );
01039 
01040   connect( mFilterSelectionWidget, SIGNAL( filterActivated( int ) ),
01041            mViewManager, SLOT( setActiveFilter( int ) ) );
01042 
01043   mExtensionManager = new ExtensionManager( this, mExtensionBarSplitter );
01044 
01045   topLayout->setStretchFactor( mDetailsSplitter, 1 );
01046 
01047   mXXPortManager = new XXPortManager( this, mWidget );
01048 
01049   initActions();
01050 }
01051 
01052 void KABCore::createJumpButtonBar()
01053 {
01054   mJumpButtonBar = new JumpButtonBar( this, mDetailsWidget );
01055   mDetailsLayout->addWidget( mJumpButtonBar );
01056   mDetailsLayout->setStretchFactor( mJumpButtonBar, 1 );
01057 
01058   connect( mJumpButtonBar, SIGNAL( jumpToLetter( const QString& ) ),
01059            SLOT( incrementalJumpButtonSearch( const QString& ) ) );
01060   connect( mViewManager, SIGNAL( sortFieldChanged() ),
01061            mJumpButtonBar, SLOT( updateButtons() ) );
01062 }
01063 
01064 void KABCore::initActions()
01065 {
01066   connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
01067            SLOT( clipboardDataChanged() ) );
01068 
01069   KAction *action;
01070 
01071   // file menu
01072   mActionMail = new KAction( i18n( "&Send Email to Contact..." ), "mail_send", 0,
01073                              this, SLOT( sendMail() ), actionCollection(), "file_mail" );
01074   action = KStdAction::print( this, SLOT( print() ), actionCollection() );
01075   mActionMail->setWhatsThis( i18n( "Send a mail to all selected contacts." ) );
01076   action->setWhatsThis( i18n( "Print a special number of contacts." ) );
01077 
01078   mActionSave = KStdAction::save( this,
01079                              SLOT( save() ), actionCollection(), "file_sync" );
01080   mActionSave->setWhatsThis( i18n( "Save all changes of the address book to the storage backend." ) );
01081 
01082   action = new KAction( i18n( "&New Contact..." ), "identity", CTRL+Key_N, this,
01083                SLOT( newContact() ), actionCollection(), "file_new_contact" );
01084   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." ) );
01085 
01086   mActionMailVCard = new KAction( i18n("Send &Contact..."), "mail_post_to", 0,
01087                                   this, SLOT( mailVCard() ),
01088                                   actionCollection(), "file_mail_vcard" );
01089   mActionMailVCard->setWhatsThis( i18n( "Send a mail with the selected contact as attachment." ) );
01090 
01091   mActionChat = new KAction( i18n("Chat &With..."), 0,
01092                                   this, SLOT( startChat() ),
01093                                   actionCollection(), "file_chat" );
01094   mActionChat->setWhatsThis( i18n( "Start a chat with the selected contact." ) );
01095 
01096   mActionEditAddressee = new KAction( i18n( "&Edit Contact..." ), "edit", 0,
01097                                       this, SLOT( editContact() ),
01098                                       actionCollection(), "file_properties" );
01099   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." ) );
01100 
01101   mActionMerge = new KAction( i18n( "&Merge Contacts" ), "", 0,
01102                               this, SLOT( mergeContacts() ),
01103                               actionCollection(), "edit_merge" );
01104 
01105   // edit menu
01106   mActionCopy = KStdAction::copy( this, SLOT( copyContacts() ), actionCollection() );
01107   mActionCut = KStdAction::cut( this, SLOT( cutContacts() ), actionCollection() );
01108   mActionPaste = KStdAction::paste( this, SLOT( pasteContacts() ), actionCollection() );
01109   action = KStdAction::selectAll( this, SLOT( selectAllContacts() ), actionCollection() );
01110   mActionCopy->setWhatsThis( i18n( "Copy the currently selected contact(s) to system clipboard in vCard format." ) );
01111   mActionCut->setWhatsThis( i18n( "Cuts the currently selected contact(s) to system clipboard in vCard format." ) );
01112   mActionPaste->setWhatsThis( i18n( "Paste the previously cut or copied contacts from clipboard." ) );
01113   action->setWhatsThis( i18n( "Selects all visible contacts from current view." ) );
01114 //  mActionUndo->setWhatsThis( i18n( "Undoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) );
01115 //  mActionRedo->setWhatsThis( i18n( "Redoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) );
01116 
01117   mActionDelete = new KAction( i18n( "&Delete Contact" ), "editdelete",
01118                                Key_Delete, this, SLOT( deleteContacts() ),
01119                                actionCollection(), "edit_delete" );
01120   mActionDelete->setWhatsThis( i18n( "Delete all selected contacts." ) );
01121 
01122 
01123   mActionStoreAddresseeIn = new KAction( i18n( "St&ore Contact In..." ), "kaddressbook", 0,
01124                                       this, SLOT( storeContactIn() ),
01125                                       actionCollection(), "edit_store_in" );
01126   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." ) );
01127 
01128   // settings menu
01129   mActionJumpBar = new KToggleAction( i18n( "Show Jump Bar" ), "next", 0,
01130                                       actionCollection(), "options_show_jump_bar" );
01131   mActionJumpBar->setWhatsThis( i18n( "Toggle whether the jump button bar shall be visible." ) );
01132   mActionJumpBar->setCheckedState( i18n( "Hide Jump Bar") );
01133   connect( mActionJumpBar, SIGNAL( toggled( bool ) ), SLOT( setJumpButtonBarVisible( bool ) ) );
01134 
01135   mActionDetails = new KToggleAction( i18n( "Show Details" ), 0, 0,
01136                                       actionCollection(), "options_show_details" );
01137   mActionDetails->setWhatsThis( i18n( "Toggle whether the details page shall be visible." ) );
01138   mActionDetails->setCheckedState( i18n( "Hide Details") );
01139   connect( mActionDetails, SIGNAL( toggled( bool ) ), SLOT( setDetailsVisible( bool ) ) );
01140 
01141   if ( mIsPart )
01142     action = new KAction( i18n( "&Configure Address Book..." ), "configure", 0,
01143                           this, SLOT( configure() ), actionCollection(),
01144                           "kaddressbook_configure" );
01145   else
01146     action = KStdAction::preferences( this, SLOT( configure() ), actionCollection() );
01147 
01148   action->setWhatsThis( i18n( "You will be presented with a dialog, that offers you all possibilities to configure KAddressBook." ) );
01149 
01150   // misc
01151   action = new KAction( i18n( "&Lookup Addresses in LDAP Directory..." ), "find", 0,
01152                         this, SLOT( openLDAPDialog() ), actionCollection(), "ldap_lookup" );
01153   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." ) );
01154 
01155   mActionWhoAmI = new KAction( i18n( "Set as Personal Contact Data" ), "personal", 0, this,
01156                                SLOT( setWhoAmI() ), actionCollection(),
01157                                "edit_set_personal" );
01158   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." ) );
01159 
01160   mActionCategories = new KAction( i18n( "Select Categories..." ), 0, this,
01161                                    SLOT( setCategories() ), actionCollection(),
01162                                    "edit_set_categories" );
01163   mActionCategories->setWhatsThis( i18n( "Set the categories for all selected contacts." ) );
01164 
01165   KAction *clearLocation = new KAction( i18n( "Clear Search Bar" ),
01166                     QApplication::reverseLayout() ? "clear_left" : "locationbar_erase",
01167                     CTRL+Key_L, this, SLOT( slotClearSearchBar() ), actionCollection(), "clear_search" );
01168   clearLocation->setWhatsThis( i18n( "Clear Search Bar<p>"
01169                      "Clears the content of the quick search bar." ) );
01170 
01171   clipboardDataChanged();
01172 }
01173 
01174 void KABCore::clipboardDataChanged()
01175 {
01176   if ( mReadWrite )
01177     mActionPaste->setEnabled( !QApplication::clipboard()->text().isEmpty() );
01178 }
01179 
01180 void KABCore::updateIncSearchWidget()
01181 {
01182   mIncSearchWidget->setViewFields( mViewManager->viewFields() );
01183 }
01184 
01185 void KABCore::updateCategories()
01186 {
01187   QStringList categories( allCategories() );
01188   categories.sort();
01189 
01190   const QStringList customCategories( KABPrefs::instance()->customCategories() );
01191   QStringList::ConstIterator it;
01192   const QStringList::ConstIterator endIt( customCategories.end() );
01193   for ( it = customCategories.begin(); it != endIt; ++it ) {
01194     if ( categories.find( *it ) == categories.end() ) {
01195       categories.append( *it );
01196     }
01197   }
01198 
01199   KABPrefs::instance()->mCustomCategories = categories;
01200   KABPrefs::instance()->writeConfig();
01201 
01202   if ( mCategoryEditDialog )
01203     mCategoryEditDialog->reload();
01204 }
01205 
01206 QStringList KABCore::allCategories() const
01207 {
01208   QStringList categories, allCategories;
01209   QStringList::ConstIterator catIt;
01210 
01211   KABC::AddressBook::ConstIterator it;
01212   const KABC::AddressBook::ConstIterator endIt( mAddressBook->end() );
01213   for ( it = mAddressBook->begin(); it != endIt; ++it ) {
01214     categories = (*it).categories();
01215     const QStringList::ConstIterator catEndIt( categories.end() );
01216     for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) {
01217       if ( !allCategories.contains( *catIt ) )
01218         allCategories.append( *catIt );
01219     }
01220   }
01221 
01222   return allCategories;
01223 }
01224 
01225 void KABCore::setCategories()
01226 {
01227   // Show the category dialog
01228   if ( mCategorySelectDialog == 0 ) {
01229     mCategorySelectDialog = new KPIM::CategorySelectDialog( KABPrefs::instance(), mWidget );
01230     connect( mCategorySelectDialog, SIGNAL( categoriesSelected( const QStringList& ) ),
01231              SLOT( categoriesSelected( const QStringList& ) ) );
01232     connect( mCategorySelectDialog, SIGNAL( editCategories() ), SLOT( editCategories() ) );
01233   }
01234 
01235   mCategorySelectDialog->show();
01236   mCategorySelectDialog->raise();
01237 }
01238 
01239 void KABCore::categoriesSelected( const QStringList &categories )
01240 {
01241   bool merge = false;
01242   QString msg = i18n( "Merge with existing categories?" );
01243   if ( KMessageBox::questionYesNo( mWidget, msg, QString::null, i18n( "Merge" ), i18n( "Do Not Merge" ) ) == KMessageBox::Yes )
01244     merge = true;
01245 
01246   QStringList uids = mViewManager->selectedUids();
01247   QStringList::ConstIterator it;
01248   const QStringList::ConstIterator endIt( uids.end() );
01249   for ( it = uids.begin(); it != endIt; ++it ) {
01250     KABC::Addressee addr = mAddressBook->findByUid( *it );
01251     if ( !addr.isEmpty() ) {
01252       if ( !merge )
01253         addr.setCategories( categories );
01254       else {
01255         QStringList addrCategories = addr.categories();
01256         QStringList::ConstIterator catIt;
01257         const QStringList::ConstIterator catEndIt( categories.end() );
01258         for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) {
01259           if ( !addrCategories.contains( *catIt ) )
01260             addrCategories.append( *catIt );
01261         }
01262         addr.setCategories( addrCategories );
01263       }
01264 
01265       mAddressBook->insertAddressee( addr );
01266     }
01267   }
01268 
01269   if ( uids.count() > 0 )
01270     setModified( true );
01271 }
01272 
01273 void KABCore::editCategories()
01274 {
01275   if ( mCategoryEditDialog == 0 ) {
01276     mCategoryEditDialog = new KPIM::CategoryEditDialog( KABPrefs::instance(), mWidget );
01277     connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ),
01278              mCategorySelectDialog, SLOT( updateCategoryConfig() ) );
01279   }
01280 
01281   mCategoryEditDialog->show();
01282   mCategoryEditDialog->raise();
01283 }
01284 
01285 void KABCore::slotClearSearchBar()
01286 {
01287   mIncSearchWidget->clear();
01288   mIncSearchWidget->setFocus();
01289 }
01290 
01291 void KABCore::slotContactsUpdated()
01292 {
01293   if ( mStatusBar ) {
01294     QString msg( i18n( "%n contact matches", "%n contacts matching", mSearchManager->contacts().count() ) );
01295     if ( !mStatusBar->hasItem( 1 ) )
01296       mStatusBar->insertItem( msg, 1 );
01297     else
01298       mStatusBar->changeItem( msg, 1 );
01299   }
01300 
01301   emit contactsUpdated();
01302 }
01303 
01304 bool KABCore::handleCommandLine( KAddressBookIface* iface )
01305 {
01306   KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
01307   QCString addrStr = args->getOption( "addr" );
01308   QCString uidStr = args->getOption( "uid" );
01309 
01310   QString addr, uid, vcard;
01311   if ( !addrStr.isEmpty() )
01312     addr = QString::fromLocal8Bit( addrStr );
01313   if ( !uidStr.isEmpty() )
01314     uid = QString::fromLocal8Bit( uidStr );
01315 
01316   bool doneSomething = false;
01317 
01318   // 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
01319   if ( !addr.isEmpty() ) {
01320     iface->addEmail( addr );
01321     doneSomething = true;
01322   }
01323 
01324   if ( !uid.isEmpty() ) {
01325     iface->showContactEditor( uid );
01326     doneSomething = true;
01327   }
01328 
01329   if ( args->isSet( "new-contact" ) ) {
01330     iface->newContact();
01331     doneSomething = true;
01332   }
01333 
01334   if ( args->count() >= 1 ) {
01335     for ( int i = 0; i < args->count(); ++i )
01336       iface->importVCard( args->url( i ).url() );
01337     doneSomething = true;
01338   }
01339   return doneSomething;
01340 }
01341 
01342 #ifdef KDEPIM_NEW_DISTRLISTS
01343 KPIM::DistributionList::List KABCore::distributionLists() const
01344 {
01345   return mSearchManager->distributionLists();
01346 }
01347 
01348 QStringList KABCore::distributionListNames() const
01349 {
01350   return mSearchManager->distributionListNames();
01351 }
01352 #endif
01353 
01354 #include "kabcore.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys