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 <qlabel.h>
00032 #include <qlayout.h>
00033 #include <qptrlist.h>
00034 #include <qwidgetstack.h>
00035 #include <qregexp.h>
00036 #include <qvbox.h>
00037 
00038 #include <kabc/addresseelist.h>
00039 #include <kabc/errorhandler.h>
00040 #include <kabc/resource.h>
00041 #include <kabc/stdaddressbook.h>
00042 #include <kabc/vcardconverter.h>
00043 #include <kabc/resourcefile.h>
00044 #include <kaboutdata.h>
00045 #include <kaccelmanager.h>
00046 #include <kapplication.h>
00047 #include <dcopclient.h>
00048 #include <kactionclasses.h>
00049 #include <kcmdlineargs.h>
00050 #include <kcmultidialog.h>
00051 #include <kdebug.h>
00052 #include <kdeversion.h>
00053 #include <kimproxy.h>
00054 #include <klocale.h>
00055 #include <kmessagebox.h>
00056 #include <kprinter.h>
00057 #include <kprotocolinfo.h>
00058 #include <kpushbutton.h>
00059 #include <kresources/selectdialog.h>
00060 #include <kstandarddirs.h>
00061 #include <kstatusbar.h>
00062 #include <kstdguiitem.h>
00063 #include <kxmlguiclient.h>
00064 #include <ktoolbar.h>
00065 #include <libkdepim/addresseeview.h>
00066 #include <libkdepim/categoryeditdialog.h>
00067 #include <libkdepim/categoryselectdialog.h>
00068 #include "distributionlisteditor.h"
00069 
00070 #include "addresseeutil.h"
00071 #include "addresseeeditordialog.h"
00072 #include "distributionlistentryview.h"
00073 #include "extensionmanager.h"
00074 #include "filterselectionwidget.h"
00075 #include "incsearchwidget.h"
00076 #include "jumpbuttonbar.h"
00077 #include "kablock.h"
00078 #include "kabprefs.h"
00079 #include "kabtools.h"
00080 #include "kaddressbookservice.h"
00081 #include "kaddressbookiface.h"
00082 #include "ldapsearchdialog.h"
00083 #include "locationmap.h"
00084 #include "printing/printingwizard.h"
00085 #include "searchmanager.h"
00086 #include "undocmds.h"
00087 #include "viewmanager.h"
00088 #include "xxportmanager.h"
00089 
00090 #include "kabcore.h"
00091 
00092 KABCore::KABCore( KXMLGUIClient *client, bool readWrite, QWidget *parent,
00093                   const QString &file, const char *name )
00094   : KAB::Core( client, parent, name ), mStatusBar( 0 ), mViewManager( 0 ),
00095     mExtensionManager( 0 ), mJumpButtonBar( 0 ), mCategorySelectDialog( 0 ),
00096     mCategoryEditDialog( 0 ), mLdapSearchDialog( 0 ), mReadWrite( readWrite ),
00097     mModified( false )
00098 {
00099   mWidget = new QWidget( parent, name );
00100 
00101   mIsPart = !parent->isA( "KAddressBookMain" );
00102 
00103   mAddressBookChangedTimer = new QTimer( this );
00104   connect( mAddressBookChangedTimer, SIGNAL( timeout() ),
00105            this, SLOT( addressBookChanged() ) );
00106 
00107   if ( file.isEmpty() ) {
00108     mAddressBook = KABC::StdAddressBook::self( true );
00109   } else {
00110     kdDebug(5720) << "KABCore(): document '" << file << "'" << endl;
00111     mAddressBook = new KABC::AddressBook;
00112     mAddressBook->addResource( new KABC::ResourceFile( file ) );
00113     if ( !mAddressBook->load() ) {
00114       KMessageBox::error( parent, i18n("Unable to load '%1'.").arg( file ) );
00115     }
00116   }
00117   mAddressBook->setErrorHandler( new KABC::GuiErrorHandler( mWidget ) );
00118 
00119 #if ! KDE_IS_VERSION(3,5,8)
00120   mAddressBook->addCustomField( i18n( "Department" ), KABC::Field::Organization,
00121                                 "X-Department", "KADDRESSBOOK" );
00122 #endif
00123   mAddressBook->addCustomField( i18n( "Profession" ), KABC::Field::Organization,
00124                                 "X-Profession", "KADDRESSBOOK" );
00125   mAddressBook->addCustomField( i18n( "Assistant's Name" ), KABC::Field::Organization,
00126                                 "X-AssistantsName", "KADDRESSBOOK" );
00127   mAddressBook->addCustomField( i18n( "Manager's Name" ), KABC::Field::Organization,
00128                                 "X-ManagersName", "KADDRESSBOOK" );
00129   mAddressBook->addCustomField( i18n( "Partner's Name" ), KABC::Field::Personal,
00130                                 "X-SpousesName", "KADDRESSBOOK" );
00131   mAddressBook->addCustomField( i18n( "Office" ), KABC::Field::Personal,
00132                                 "X-Office", "KADDRESSBOOK" );
00133   mAddressBook->addCustomField( i18n( "IM Address" ), KABC::Field::Personal,
00134                                 "X-IMAddress", "KADDRESSBOOK" );
00135   mAddressBook->addCustomField( i18n( "Anniversary" ), KABC::Field::Personal,
00136                                 "X-Anniversary", "KADDRESSBOOK" );
00137   mAddressBook->addCustomField( i18n( "Blog" ), KABC::Field::Personal,
00138                                 "BlogFeed", "KADDRESSBOOK" );
00139 
00140   mSearchManager = new KAB::SearchManager( mAddressBook, parent );
00141 
00142   connect( mSearchManager, SIGNAL( contactsUpdated() ),
00143            this, SLOT( slotContactsUpdated() ) );
00144 
00145   initGUI();
00146 
00147   connect( mAddressBook, SIGNAL( addressBookChanged( AddressBook* ) ),
00148            SLOT( delayedAddressBookChanged() ) );
00149   connect( mAddressBook, SIGNAL( loadingFinished( Resource* ) ),
00150            SLOT( delayedAddressBookChanged() ) );
00151 
00152   mIncSearchWidget->setFocus();
00153 
00154   connect( mViewManager, SIGNAL( selected( const QString& ) ),
00155            SLOT( setContactSelected( const QString& ) ) );
00156   connect( mViewManager, SIGNAL( executed( const QString& ) ),
00157            SLOT( editContact( const QString& ) ) );
00158   connect( mViewManager, SIGNAL( modified() ),
00159            SLOT( setModified() ) );
00160   connect( mViewManager, SIGNAL( urlDropped( const KURL& ) ),
00161            mXXPortManager, SLOT( importVCard( const KURL& ) ) );
00162   connect( mViewManager, SIGNAL( viewFieldsChanged() ),
00163            SLOT( updateIncSearchWidget() ) );
00164   connect( mExtensionManager, SIGNAL( modified( const KABC::Addressee::List& ) ),
00165            this, SLOT( extensionModified( const KABC::Addressee::List& ) ) );
00166   connect( mExtensionManager, SIGNAL( deleted( const QStringList& ) ),
00167            this, SLOT( extensionDeleted( const QStringList& ) ) );
00168 
00169   connect( mXXPortManager, SIGNAL( modified() ),
00170            SLOT( setModified() ) );
00171 
00172   connect( mDetailsViewer, SIGNAL( highlightedMessage( const QString& ) ),
00173            SLOT( detailsHighlighted( const QString& ) ) );
00174 
00175   connect( mIncSearchWidget, SIGNAL( scrollUp() ),
00176            mViewManager, SLOT( scrollUp() ) );
00177   connect( mIncSearchWidget, SIGNAL( scrollDown() ),
00178            mViewManager, SLOT( scrollDown() ) );
00179 
00180   mAddressBookService = new KAddressBookService( this );
00181 
00182   mCommandHistory = new KCommandHistory( actionCollection(), true );
00183   connect( mCommandHistory, SIGNAL( commandExecuted() ),
00184            mSearchManager, SLOT( reload() ) );
00185 
00186   mSearchManager->reload();
00187 
00188   setModified( false );
00189 
00190   KAcceleratorManager::manage( mWidget );
00191 
00192   mKIMProxy = ::KIMProxy::instance( kapp->dcopClient() );
00193 }
00194 
00195 KABCore::~KABCore()
00196 {
00197   mAddressBook->disconnect();
00198 
00199   mAddressBook = 0;
00200   KABC::StdAddressBook::close();
00201   mKIMProxy = 0;
00202 }
00203 
00204 void KABCore::restoreSettings()
00205 {
00206   bool state = KABPrefs::instance()->jumpButtonBarVisible();
00207   mActionJumpBar->setChecked( state );
00208   setJumpButtonBarVisible( state );
00209 
00210   state = KABPrefs::instance()->detailsPageVisible();
00211   mActionDetails->setChecked( state );
00212   setDetailsVisible( state );
00213 
00214   mViewManager->restoreSettings();
00215   mExtensionManager->restoreSettings();
00216 
00217   updateIncSearchWidget();
00218   mIncSearchWidget->setCurrentItem( KABPrefs::instance()->currentIncSearchField() );
00219 
00220   QValueList<int> 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   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.9", 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 ( !mDetailsViewer->isHidden() )
00328     mDetailsViewer->setAddressee( addr );
00329 #ifdef KDEPIM_NEW_DISTRLISTS 
00330   if ( !mSelectedDistributionList.isNull() && mDistListEntryView->isShown() ) {
00331       showDistributionListEntry( uid );
00332   }
00333 #endif
00334   mExtensionManager->setSelectionChanged();
00335 
00336   // update the actions
00337   bool selected = !uid.isEmpty();
00338 
00339   if ( mReadWrite ) {
00340     mActionCut->setEnabled( selected );
00341 
00342     QClipboard *cb = QApplication::clipboard();
00343     KABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( cb->text() );
00344     mActionPaste->setEnabled( !list.isEmpty() );
00345   }
00346 
00347   mActionCopy->setEnabled( selected );
00348   mActionDelete->setEnabled( selected );
00349   mActionEditAddressee->setEnabled( selected );
00350   mActionCopyAddresseeTo->setEnabled( selected );
00351   mActionMoveAddresseeTo->setEnabled( selected );
00352   mActionMail->setEnabled( selected );
00353   mActionMailVCard->setEnabled( selected );
00354   mActionChat->setEnabled( selected && mKIMProxy && mKIMProxy->initialize() );
00355   mActionWhoAmI->setEnabled( selected );
00356   mActionCategories->setEnabled( selected );
00357   mActionMerge->setEnabled( selected );
00358 }
00359 
00360 void KABCore::sendMail()
00361 {
00362   sendMail( mViewManager->selectedEmails().join( ", " ) );
00363 }
00364 
00365 void KABCore::sendMail( const QString& email )
00366 {
00367   kapp->invokeMailer( email, "" );
00368 }
00369 
00370 void KABCore::mailVCard()
00371 {
00372   QStringList uids = mViewManager->selectedUids();
00373   if ( !uids.isEmpty() )
00374     mailVCard( uids );
00375 }
00376 
00377 void KABCore::mailVCard( const QStringList &uids )
00378 {
00379   KABTools::mailVCards( uids, mAddressBook );
00380 }
00381 
00382 void KABCore::startChat()
00383 {
00384   QStringList uids = mViewManager->selectedUids();
00385   if ( !uids.isEmpty() )
00386     mKIMProxy->chatWithContact( uids.first() );
00387 }
00388 
00389 void KABCore::browse( const QString& url )
00390 {
00391   kapp->invokeBrowser( url );
00392 }
00393 
00394 void KABCore::selectAllContacts()
00395 {
00396   mViewManager->setSelected( QString::null, true );
00397 }
00398 
00399 void KABCore::deleteContacts()
00400 {
00401   QStringList uidList = mViewManager->selectedUids();
00402 
00403   deleteContacts( uidList );
00404 }
00405 
00406 void KABCore::deleteDistributionLists( const QStringList & names )
00407 {
00408   if ( names.isEmpty() )
00409       return;
00410   if ( KMessageBox::warningContinueCancelList( mWidget, i18n( "Do you really want to delete this distribution list?",
00411                                                  "Do you really want to delete these %n distribution lists?", names.count() ),
00412                                                  names, QString::null, KStdGuiItem::del() ) == KMessageBox::Cancel )
00413    return;
00414 
00415   QStringList uids;
00416   for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it ) {
00417       uids.append( KPIM::DistributionList::findByName( mAddressBook, *it ).uid() ); 
00418   }
00419   DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
00420   mCommandHistory->addCommand( command );  
00421   setModified( true );
00422 }
00423 
00424 void KABCore::deleteContacts( const QStringList &uids )
00425 {
00426   if ( uids.count() > 0 ) {
00427     QStringList names;
00428     QStringList::ConstIterator it = uids.begin();
00429     const QStringList::ConstIterator endIt( uids.end() );
00430     while ( it != endIt ) {
00431       KABC::Addressee addr = mAddressBook->findByUid( *it );
00432       names.append( addr.realName().isEmpty() ? addr.preferredEmail() : addr.realName() );
00433       ++it;
00434     }
00435 
00436     if ( KMessageBox::warningContinueCancelList( mWidget, i18n( "Do you really want to delete this contact?",
00437                                                  "Do you really want to delete these %n contacts?", uids.count() ),
00438                                                  names, QString::null, KStdGuiItem::del() ) == KMessageBox::Cancel )
00439       return;
00440 
00441     DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
00442     mCommandHistory->addCommand( command );
00443 
00444     // now if we deleted anything, refresh
00445     setContactSelected( QString::null );
00446     setModified( true );
00447   }
00448 }
00449 
00450 void KABCore::copyContacts()
00451 {
00452   KABC::Addressee::List addrList = mViewManager->selectedAddressees();
00453 
00454   QString clipText = AddresseeUtil::addresseesToClipboard( addrList );
00455 
00456   kdDebug(5720) << "KABCore::copyContacts: " << clipText << endl;
00457 
00458   QClipboard *cb = QApplication::clipboard();
00459   cb->setText( clipText );
00460 }
00461 
00462 void KABCore::cutContacts()
00463 {
00464   QStringList uidList = mViewManager->selectedUids();
00465 
00466   if ( uidList.size() > 0 ) {
00467     CutCommand *command = new CutCommand( mAddressBook, uidList );
00468     mCommandHistory->addCommand( command );
00469 
00470     setModified( true );
00471   }
00472 }
00473 
00474 void KABCore::pasteContacts()
00475 {
00476   QClipboard *cb = QApplication::clipboard();
00477 
00478   KABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( cb->text() );
00479 
00480   pasteContacts( list );
00481 }
00482 
00483 void KABCore::pasteContacts( KABC::Addressee::List &list )
00484 {
00485   KABC::Resource *resource = requestResource( mWidget );
00486   if ( !resource )
00487     return;
00488 
00489   KABC::Addressee::List::Iterator it;
00490   const KABC::Addressee::List::Iterator endIt( list.end() );
00491   for ( it = list.begin(); it != endIt; ++it )
00492     (*it).setResource( resource );
00493 
00494   PasteCommand *command = new PasteCommand( this, list );
00495   mCommandHistory->addCommand( command );
00496 
00497   setModified( true );
00498 }
00499 
00500 void KABCore::mergeContacts()
00501 {
00502   KABC::Addressee::List list = mViewManager->selectedAddressees();
00503   if ( list.count() < 2 )
00504     return;
00505 
00506   KABC::Addressee addr = KABTools::mergeContacts( list );
00507 
00508   KABC::Addressee::List::Iterator it = list.begin();
00509   const KABC::Addressee::List::Iterator endIt( list.end() );
00510   KABC::Addressee origAddr = *it;
00511   QStringList uids;
00512   ++it;
00513   while ( it != endIt ) {
00514     uids.append( (*it).uid() );
00515     ++it;
00516   }
00517 
00518   DeleteCommand *command = new DeleteCommand( mAddressBook, uids );
00519   mCommandHistory->addCommand( command );
00520 
00521   EditCommand *editCommand = new EditCommand( mAddressBook, origAddr, addr );
00522   mCommandHistory->addCommand( editCommand );
00523 
00524   mSearchManager->reload();
00525 }
00526 
00527 void KABCore::setWhoAmI()
00528 {
00529   KABC::Addressee::List addrList = mViewManager->selectedAddressees();
00530 
00531   if ( addrList.count() > 1 ) {
00532     KMessageBox::sorry( mWidget, i18n( "Please select only one contact." ) );
00533     return;
00534   }
00535 
00536   QString text( i18n( "<qt>Do you really want to use <b>%1</b> as your new personal contact?</qt>" ) );
00537   if ( KMessageBox::questionYesNo( mWidget, text.arg( addrList[ 0 ].assembledName() ), QString::null, i18n("Use"), i18n("Do Not Use") ) == KMessageBox::Yes )
00538     static_cast<KABC::StdAddressBook*>( KABC::StdAddressBook::self( true ) )->setWhoAmI( addrList[ 0 ] );
00539 }
00540 
00541 void KABCore::incrementalTextSearch( const QString& text )
00542 {
00543   setContactSelected( QString::null );
00544   mSearchManager->search( text, mIncSearchWidget->currentFields() );
00545 }
00546 
00547 void KABCore::incrementalJumpButtonSearch( const QString& character )
00548 {
00549   mViewManager->setSelected( QString::null, false );
00550 
00551   KABC::AddresseeList list = mSearchManager->contacts();
00552   KABC::Field *field = mViewManager->currentSortField();
00553   if ( field ) {
00554     list.sortByField( field );
00555     KABC::AddresseeList::ConstIterator it;
00556     const KABC::AddresseeList::ConstIterator endIt( list.end() );
00557     for ( it = list.begin(); it != endIt; ++it ) {
00558       if ( field->value( *it ).startsWith( character, false ) ) {
00559         mViewManager->setSelected( (*it).uid(), true );
00560         return;
00561       }
00562     }
00563   }
00564 }
00565 
00566 void KABCore::setModified()
00567 {
00568   setModified( true );
00569 }
00570 
00571 void KABCore::setModified( bool modified )
00572 {
00573   mModified = modified;
00574   mActionSave->setEnabled( mModified );
00575 
00576   mSearchManager->reload();
00577 }
00578 
00579 bool KABCore::modified() const
00580 {
00581   return mModified;
00582 }
00583 
00584 void KABCore::contactModified( const KABC::Addressee &addr )
00585 {
00586   Command *command = 0;
00587 
00588   // check if it exists already
00589   KABC::Addressee origAddr = mAddressBook->findByUid( addr.uid() );
00590   if ( origAddr.isEmpty() ) {
00591     KABC::Addressee::List addressees;
00592     addressees.append( addr );
00593     command = new NewCommand( mAddressBook, addressees );
00594   } else {
00595     command = new EditCommand( mAddressBook, origAddr, addr );
00596   }
00597 
00598   mCommandHistory->addCommand( command );
00599 
00600   setContactSelected( addr.uid() );
00601   setModified( true );
00602 }
00603 
00604 void KABCore::newDistributionList()
00605 {
00606 #ifdef KDEPIM_NEW_DISTRLISTS
00607   QString name = i18n( "New Distribution List" );
00608   const KPIM::DistributionList distList = KPIM::DistributionList::findByName( addressBook(), name );
00609   if ( !distList.isEmpty() ) {
00610     bool foundUnused = false;
00611     int i = 1;
00612     while ( !foundUnused ) {
00613       name = i18n( "New Distribution List (%1)" ).arg( i++ );  
00614       foundUnused = KPIM::DistributionList::findByName( addressBook(), name ).isEmpty();
00615     }
00616   }
00617   KPIM::DistributionList list;
00618   list.setUid( KApplication::randomString( 10 ) );
00619   list.setName( name );
00620   editDistributionList( list );
00621 #endif
00622 }
00623 
00624 void KABCore::newContact()
00625 {
00626   AddresseeEditorDialog *dialog = 0;
00627 
00628   KABC::Resource* resource = requestResource( mWidget );
00629 
00630   if ( resource ) {
00631     KABC::Addressee addr;
00632     addr.setResource( resource );
00633 
00634     if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) )
00635       return;
00636 
00637     dialog = createAddresseeEditorDialog( mWidget );
00638     dialog->setAddressee( addr );
00639   } else
00640     return;
00641 
00642   mEditorDict.insert( dialog->addressee().uid(), dialog );
00643 
00644   dialog->show();
00645 }
00646 
00647 void KABCore::addEmail( const QString &aStr )
00648 {
00649   QString fullName, email;
00650 
00651   KABC::Addressee::parseEmailAddress( aStr, fullName, email );
00652 
00653 #if KDE_IS_VERSION(3,4,89)
00654   // This ugly hack will be removed in 4.0
00655   // addressbook may not be reloaded yet, as done asynchronously sometimes, so wait
00656   while ( !mAddressBook->loadingHasFinished() ) {
00657     QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00658     // use sleep here to reduce cpu usage
00659     usleep( 100 );
00660   }
00661 #endif
00662 
00663   // Try to lookup the addressee matching the email address
00664   bool found = false;
00665   QStringList emailList;
00666   KABC::AddressBook::Iterator it;
00667   const KABC::AddressBook::Iterator endIt( mAddressBook->end() );
00668   for ( it = mAddressBook->begin(); !found && (it != endIt); ++it ) {
00669     emailList = (*it).emails();
00670     if ( emailList.contains( email ) > 0 ) {
00671       found = true;
00672       (*it).setNameFromString( fullName );
00673       editContact( (*it).uid() );
00674     }
00675   }
00676 
00677   if ( !found ) {
00678     KABC::Addressee addr;
00679     addr.setNameFromString( fullName );
00680     addr.insertEmail( email, true );
00681 
00682     mAddressBook->insertAddressee( addr );
00683     mViewManager->refreshView( addr.uid() );
00684     editContact( addr.uid() );
00685   }
00686 }
00687 
00688 void KABCore::importVCard( const KURL &url )
00689 {
00690   mXXPortManager->importVCard( url );
00691 }
00692 
00693 void KABCore::importVCardFromData( const QString &vCard )
00694 {
00695   mXXPortManager->importVCardFromData( vCard );
00696 }
00697 
00698 void KABCore::editContact( const QString &uid )
00699 {
00700   if ( mExtensionManager->isQuickEditVisible() )
00701     return;
00702 
00703   // First, locate the contact entry
00704   QString localUID = uid;
00705   if ( localUID.isNull() ) {
00706     QStringList uidList = mViewManager->selectedUids();
00707     if ( uidList.count() > 0 )
00708       localUID = *( uidList.at( 0 ) );
00709   }
00710 #if KDE_IS_VERSION(3,4,89)
00711   // This ugly hack will be removed in 4.0
00712   // for calls with given uid, as done from commandline and DCOP
00713   // addressbook may not be reloaded yet, as done asynchronously, so wait
00714   else while ( !mAddressBook->loadingHasFinished() ) {
00715     QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00716     // use sleep here to reduce cpu usage
00717     usleep( 100 );
00718   }
00719 #endif
00720 
00721   KABC::Addressee addr = mAddressBook->findByUid( localUID );
00722   if ( !addr.isEmpty() ) {
00723     AddresseeEditorDialog *dialog = mEditorDict.find( addr.uid() );
00724     if ( !dialog ) {
00725 
00726       if ( !addr.resource()->readOnly() )
00727         if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) ) {
00728           return;
00729         }
00730 
00731       dialog = createAddresseeEditorDialog( mWidget );
00732 
00733       mEditorDict.insert( addr.uid(), dialog );
00734 
00735       dialog->setAddressee( addr );
00736     }
00737 
00738     dialog->raise();
00739     dialog->show();
00740   }
00741 }
00742 
00743 
00744 void KABCore::copySelectedContactToResource()
00745 {
00746     storeContactIn( QString(), true /*copy*/);
00747 }
00748 
00749 void KABCore::moveSelectedContactToResource()
00750 {
00751     storeContactIn( QString(), false /*copy*/);
00752 }
00753 
00754 void KABCore::storeContactIn( const QString &uid, bool copy /*false*/ )
00755 {
00756   // First, locate the contact entry
00757   QStringList uidList;
00758   if ( uid.isNull() ) {
00759     uidList = mViewManager->selectedUids();
00760   } else {
00761     uidList << uid;
00762   }
00763   KABC::Resource *resource = requestResource( mWidget );
00764   if ( !resource )
00765     return;
00766 
00767   KABLock::self( mAddressBook )->lock( resource );
00768   QStringList::Iterator it( uidList.begin() );
00769   const QStringList::Iterator endIt( uidList.end() );
00770   while ( it != endIt ) {
00771     KABC::Addressee addr = mAddressBook->findByUid( *it++ );
00772     if ( !addr.isEmpty() ) {
00773       KABC::Addressee newAddr( addr );
00774       // We need to set a new uid, otherwise the insert below is
00775       // ignored. This is bad for syncing, but unavoidable, afaiks
00776       newAddr.setUid( KApplication::randomString( 10 ) );
00777       newAddr.setResource( resource );
00778       addressBook()->insertAddressee( newAddr );
00779       if ( !copy ) {
00780           KABLock::self( mAddressBook )->lock( addr.resource() );
00781           addressBook()->removeAddressee( addr );
00782           KABLock::self( mAddressBook )->unlock( addr.resource() );
00783       }
00784     }
00785   }
00786   KABLock::self( mAddressBook )->unlock( resource );
00787 
00788   addressBookChanged();
00789   setModified( true );
00790 }
00791 
00792 void KABCore::save()
00793 {
00794   QPtrList<KABC::Resource> resources = mAddressBook->resources();
00795   QPtrListIterator<KABC::Resource> it( resources );
00796   while ( it.current() && !it.current()->readOnly() ) {
00797     KABC::Ticket *ticket = mAddressBook->requestSaveTicket( it.current() );
00798     if ( ticket ) {
00799       if ( !mAddressBook->save( ticket ) ) {
00800         KMessageBox::error( mWidget,
00801                             i18n( "<qt>Unable to save address book <b>%1</b>.</qt>" ).arg( it.current()->resourceName() ) );
00802         mAddressBook->releaseSaveTicket( ticket );
00803       } else {
00804         setModified( false );
00805       }
00806     } else {
00807       KMessageBox::error( mWidget,
00808                           i18n( "<qt>Unable to get access for saving the address book <b>%1</b>.</qt>" )
00809                           .arg( it.current()->resourceName() ) );
00810     }
00811 
00812     ++it;
00813   }
00814 }
00815 
00816 void KABCore::setJumpButtonBarVisible( bool visible )
00817 {
00818   if ( visible ) {
00819     if ( !mJumpButtonBar )
00820       createJumpButtonBar();
00821     mJumpButtonBar->show();
00822   } else
00823     if ( mJumpButtonBar )
00824       mJumpButtonBar->hide();
00825 }
00826 
00827 void KABCore::setDetailsVisible( bool visible )
00828 {
00829   if ( visible )
00830     mDetailsPage->show();
00831   else
00832     mDetailsPage->hide();
00833 }
00834 
00835 void KABCore::extensionModified( const KABC::Addressee::List &list )
00836 {
00837   if ( list.count() != 0 ) {
00838     KABC::Addressee::List::ConstIterator it;
00839     const KABC::Addressee::List::ConstIterator endIt( list.end() );
00840     for ( it = list.begin(); it != endIt; ++it ) {
00841       Command *command = 0;
00842 
00843       // check if it exists already
00844       KABC::Addressee origAddr = mAddressBook->findByUid( (*it).uid() );
00845       if ( origAddr.isEmpty() ) {
00846         KABC::Addressee::List addressees;
00847         addressees.append( *it );
00848         command = new NewCommand( mAddressBook, addressees );
00849       } else
00850         command = new EditCommand( mAddressBook, origAddr, *it );
00851 
00852       mCommandHistory->blockSignals( true );
00853       mCommandHistory->addCommand( command );
00854       mCommandHistory->blockSignals( false );
00855     }
00856 
00857     setModified(true);
00858   }
00859 }
00860 
00861 void KABCore::extensionDeleted( const QStringList &uidList )
00862 {
00863   DeleteCommand *command = new DeleteCommand( mAddressBook, uidList );
00864   mCommandHistory->addCommand( command );
00865 
00866   // now if we deleted anything, refresh
00867   setContactSelected( QString::null );
00868   setModified( true );
00869 }
00870 
00871 QString KABCore::getNameByPhone( const QString &phone )
00872 {
00873 #if KDE_IS_VERSION(3,4,89)
00874   // This ugly hack will be removed in 4.0
00875   // addressbook may not be reloaded yet, as done asynchronously, so wait
00876   while ( !mAddressBook->loadingHasFinished() ) {
00877     QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput );
00878     // use sleep here to reduce cpu usage
00879     usleep( 100 );
00880   }
00881 #endif
00882 
00883   QRegExp r( "[/*/-/ ]" );
00884   QString localPhone( phone );
00885 
00886   bool found = false;
00887   QString ownerName = "";
00888   KABC::PhoneNumber::List phoneList;
00889 
00890   KABC::AddressBook::ConstIterator iter;
00891   const KABC::AddressBook::ConstIterator endIter( mAddressBook->end() );
00892 
00893   for ( iter = mAddressBook->begin(); !found && ( iter != endIter ); ++iter ) {
00894     phoneList = (*iter).phoneNumbers();
00895     KABC::PhoneNumber::List::Iterator phoneIter( phoneList.begin() );
00896     const KABC::PhoneNumber::List::Iterator phoneEndIter( phoneList.end() );
00897     for ( ; !found && ( phoneIter != phoneEndIter ); ++phoneIter) {
00898       // Get rid of separator chars so just the numbers are compared.
00899       if ( (*phoneIter).number().replace( r, "" ) == localPhone.replace( r, "" ) ) {
00900         ownerName = (*iter).realName();
00901         found = true;
00902       }
00903     }
00904   }
00905 
00906   return ownerName;
00907 }
00908 
00909 void KABCore::openLDAPDialog()
00910 {
00911   if ( !KProtocolInfo::isKnownProtocol( KURL( "ldap://localhost" ) ) ) {
00912     KMessageBox::error( mWidget, i18n( "Your KDE installation is missing LDAP "
00913                                        "support, please ask your administrator or distributor for more information." ),
00914                         i18n( "No LDAP IO Slave Available" ) );
00915     return;
00916   }
00917 
00918   if ( !mLdapSearchDialog ) {
00919     mLdapSearchDialog = new LDAPSearchDialog( mAddressBook, this, mWidget );
00920     connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ),
00921             SLOT( addressBookChanged() ) );
00922     connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ),
00923             SLOT( setModified() ) );
00924   } else
00925     mLdapSearchDialog->restoreSettings();
00926 
00927   if ( mLdapSearchDialog->isOK() )
00928     mLdapSearchDialog->exec();
00929 }
00930 
00931 void KABCore::configure()
00932 {
00933   // Save the current config so we do not loose anything if the user accepts
00934   saveSettings();
00935 
00936   KCMultiDialog dlg( mWidget, "", true );
00937   connect( &dlg, SIGNAL( configCommitted() ),
00938            this, SLOT( configurationChanged() ) );
00939 
00940   dlg.addModule( "kabconfig.desktop" );
00941   dlg.addModule( "kabldapconfig.desktop" );
00942   dlg.addModule( "kabcustomfields.desktop" );
00943 
00944   dlg.exec();
00945 }
00946 
00947 void KABCore::print()
00948 {
00949   KPrinter printer;
00950   printer.setDocName( i18n( "Address Book" ) );
00951   printer.setDocFileName( "addressbook" );
00952 
00953   if ( !printer.setup( mWidget, i18n("Print Addresses") ) )
00954     return;
00955 
00956   KABPrinting::PrintingWizard wizard( &printer, mAddressBook,
00957                                       mViewManager->selectedUids(), mWidget );
00958 
00959   wizard.exec();
00960 }
00961 
00962 void KABCore::detailsHighlighted( const QString &msg )
00963 {
00964   if ( mStatusBar ) {
00965     if ( !mStatusBar->hasItem( 2 ) )
00966       mStatusBar->insertItem( msg, 2 );
00967     else
00968       mStatusBar->changeItem( msg, 2 );
00969   }
00970 }
00971 
00972 void KABCore::showContactsAddress( const QString &addrUid )
00973 {
00974   QStringList uidList = mViewManager->selectedUids();
00975   if ( uidList.isEmpty() )
00976     return;
00977 
00978   KABC::Addressee addr = mAddressBook->findByUid( uidList.first() );
00979   if ( addr.isEmpty() )
00980     return;
00981 
00982   const KABC::Address::List list = addr.addresses();
00983   KABC::Address::List::ConstIterator it;
00984   const KABC::Address::List::ConstIterator endIt( list.end() );
00985   for ( it = list.begin(); it != endIt; ++it )
00986     if ( (*it).id() == addrUid ) {
00987       LocationMap::instance()->showAddress( *it );
00988       break;
00989     }
00990 }
00991 
00992 void KABCore::configurationChanged()
00993 {
00994   mExtensionManager->reconfigure();
00995   mViewManager->refreshView();
00996 }
00997 
00998 bool KABCore::queryClose()
00999 {
01000   saveSettings();
01001   KABPrefs::instance()->writeConfig();
01002 
01003   QPtrList<KABC::Resource> resources = mAddressBook->resources();
01004   QPtrListIterator<KABC::Resource> it( resources );
01005   while ( it.current() ) {
01006     it.current()->close();
01007     ++it;
01008   }
01009 
01010   return true;
01011 }
01012 
01013 void KABCore::reinitXMLGUI()
01014 {
01015   mExtensionManager->createActions();
01016 }
01017 void KABCore::delayedAddressBookChanged()
01018 {
01019   mAddressBookChangedTimer->start( 1000 );
01020 }
01021 
01022 void KABCore::addressBookChanged()
01023 {
01024   const QStringList selectedUids = mViewManager->selectedUids();
01025 
01026   mAddressBookChangedTimer->stop();
01027 
01028   if ( mJumpButtonBar )
01029     mJumpButtonBar->updateButtons();
01030 
01031   mSearchManager->reload();
01032 
01033   mViewManager->setSelected( QString::null, false );
01034 
01035   QString uid = QString::null;
01036   if ( !selectedUids.isEmpty() ) {
01037     uid = selectedUids.first();
01038     mViewManager->setSelected( uid, true );
01039   }
01040 
01041   setContactSelected( uid );
01042 
01043   updateCategories();
01044 }
01045 
01046 AddresseeEditorDialog *KABCore::createAddresseeEditorDialog( QWidget *parent,
01047                                                              const char *name )
01048 {
01049   AddresseeEditorDialog *dialog = new AddresseeEditorDialog( this, parent,
01050                                                  name ? name : "editorDialog" );
01051   connect( dialog, SIGNAL( contactModified( const KABC::Addressee& ) ),
01052            SLOT( contactModified( const KABC::Addressee& ) ) );
01053   connect( dialog, SIGNAL( editorDestroyed( const QString& ) ),
01054            SLOT( slotEditorDestroyed( const QString& ) ) );
01055 
01056   return dialog;
01057 }
01058 
01059 void KABCore::activateDetailsWidget( QWidget *widget )
01060 {
01061   if ( mDetailsStack->visibleWidget() == widget )
01062     return;
01063   mDetailsStack->raiseWidget( widget );
01064 }
01065 
01066 void KABCore::deactivateDetailsWidget( QWidget *widget )
01067 {
01068   if ( mDetailsStack->visibleWidget() != widget )
01069     return;
01070   mDetailsStack->raiseWidget( mDetailsWidget );
01071 }
01072 
01073 void KABCore::slotEditorDestroyed( const QString &uid )
01074 {
01075   AddresseeEditorDialog *dialog = mEditorDict.take( uid );
01076 
01077   KABC::Addressee addr = dialog->addressee();
01078 
01079   if ( !addr.resource()->readOnly() ) {
01080     QApplication::setOverrideCursor( Qt::waitCursor );
01081     KABLock::self( mAddressBook )->unlock( addr.resource() );
01082     QApplication::restoreOverrideCursor();
01083   }
01084 }
01085 
01086 void KABCore::initGUI()
01087 {
01088   QVBoxLayout *topLayout = new QVBoxLayout( mWidget, 0, 0 );
01089   KToolBar* searchTB = new KToolBar( mWidget, "search toolbar");
01090   searchTB->boxLayout()->setSpacing( KDialog::spacingHint() );
01091   mIncSearchWidget = new IncSearchWidget( searchTB, "kde toolbar widget");
01092   searchTB->setStretchableWidget( mIncSearchWidget );
01093   connect( mIncSearchWidget, SIGNAL( doSearch( const QString& ) ),
01094            SLOT( incrementalTextSearch( const QString& ) ) );
01095 
01096   mDetailsSplitter = new QSplitter( mWidget );
01097   topLayout->addWidget( searchTB );
01098   topLayout->addWidget( mDetailsSplitter );
01099 
01100   mDetailsStack = new QWidgetStack( mDetailsSplitter );
01101   mExtensionManager = new ExtensionManager( new QWidget( mDetailsSplitter ), mDetailsStack, this, this );
01102   connect( mExtensionManager, SIGNAL( detailsWidgetDeactivated( QWidget* ) ), 
01103            this, SLOT( deactivateDetailsWidget( QWidget* ) ) );
01104   connect( mExtensionManager, SIGNAL( detailsWidgetActivated( QWidget* ) ), 
01105            this, SLOT( activateDetailsWidget( QWidget* ) ) );
01106 
01107   
01108   QWidget *viewWidget = new QWidget( mDetailsSplitter );
01109   QVBoxLayout *viewLayout = new QVBoxLayout( viewWidget );
01110   viewLayout->setSpacing( KDialog::spacingHint() );
01111 
01112   mViewHeaderLabel = new QLabel( viewWidget );
01113 //  mViewHeaderLabel->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed );
01114   mViewHeaderLabel->setText( i18n( "Contacts" ) );
01115   viewLayout->addWidget( mViewHeaderLabel );
01116   mViewManager = new ViewManager( this, viewWidget );
01117   viewLayout->addWidget( mViewManager, 1 );
01118 
01119 #ifdef KDEPIM_NEW_DISTRLISTS
01120   mDistListButtonWidget = new QWidget( viewWidget );
01121   QHBoxLayout *buttonLayout = new QHBoxLayout( mDistListButtonWidget );
01122   buttonLayout->setSpacing( KDialog::spacingHint() );
01123   buttonLayout->addStretch( 1 );
01124 
01125   KPushButton *addDistListButton = new KPushButton( mDistListButtonWidget );
01126   addDistListButton->setText( i18n( "Add" ) );
01127   connect( addDistListButton, SIGNAL( clicked() ), 
01128            this, SLOT( editSelectedDistributionList() ) );
01129   buttonLayout->addWidget( addDistListButton );
01130   mDistListButtonWidget->setShown( false );
01131   viewLayout->addWidget( mDistListButtonWidget );
01132 
01133   KPushButton *removeDistListButton = new KPushButton( mDistListButtonWidget );
01134   removeDistListButton->setText( i18n( "Remove" ) );
01135   connect( removeDistListButton, SIGNAL( clicked() ), 
01136            this, SLOT( removeSelectedContactsFromDistList() ) );
01137   buttonLayout->addWidget( removeDistListButton );
01138 #endif
01139 
01140   mFilterSelectionWidget = new FilterSelectionWidget( searchTB , "kde toolbar widget" );
01141   mViewManager->setFilterSelectionWidget( mFilterSelectionWidget );
01142 
01143   connect( mFilterSelectionWidget, SIGNAL( filterActivated( int ) ),
01144            mViewManager, SLOT( setActiveFilter( int ) ) );
01145 
01146   mDetailsWidget = new QWidget( mDetailsSplitter );
01147   mDetailsLayout = new QHBoxLayout( mDetailsWidget );
01148 
01149   mDetailsPage = new QWidget( mDetailsWidget );
01150   mDetailsLayout->addWidget( mDetailsPage );
01151 
01152   QHBoxLayout *detailsPageLayout = new QHBoxLayout( mDetailsPage, 0, 0 );
01153   mDetailsViewer = new KPIM::AddresseeView( mDetailsPage );
01154   mDetailsViewer->setVScrollBarMode( QScrollView::Auto );
01155   detailsPageLayout->addWidget( mDetailsViewer );
01156 
01157   mDistListEntryView = new KAB::DistributionListEntryView( this, mWidget );
01158   connect( mDistListEntryView, SIGNAL( distributionListClicked( const QString& ) ),
01159            this, SLOT( sendMailToDistributionList( const QString& ) ) );
01160   mDetailsStack->addWidget( mDistListEntryView );
01161   mDetailsStack->addWidget( mDetailsWidget );
01162   mDetailsStack->raiseWidget( mDetailsWidget );
01163   mDetailsSplitter->moveToLast( mDetailsStack );
01164 
01165   connect( mDetailsViewer, SIGNAL( addressClicked( const QString&) ),
01166            this, SLOT( showContactsAddress( const QString& ) ) );
01167 
01168   topLayout->setStretchFactor( mDetailsSplitter, 1 );
01169 
01170   mXXPortManager = new XXPortManager( this, mWidget );
01171 
01172   initActions();
01173 }
01174 
01175 void KABCore::createJumpButtonBar()
01176 {
01177   mJumpButtonBar = new JumpButtonBar( this, mDetailsWidget );
01178   mDetailsLayout->addWidget( mJumpButtonBar );
01179   mDetailsLayout->setStretchFactor( mJumpButtonBar, 1 );
01180 
01181   connect( mJumpButtonBar, SIGNAL( jumpToLetter( const QString& ) ),
01182            SLOT( incrementalJumpButtonSearch( const QString& ) ) );
01183   connect( mViewManager, SIGNAL( sortFieldChanged() ),
01184            mJumpButtonBar, SLOT( updateButtons() ) );
01185 }
01186 
01187 void KABCore::initActions()
01188 {
01189   connect( QApplication::clipboard(), SIGNAL( dataChanged() ),
01190            SLOT( clipboardDataChanged() ) );
01191 
01192   KAction *action;
01193 
01194   // file menu
01195   mActionMail = new KAction( i18n( "&Send Email to Contact..." ), "mail_send", 0,
01196                              this, SLOT( sendMail() ), actionCollection(), "file_mail" );
01197   action = KStdAction::print( this, SLOT( print() ), actionCollection() );
01198   mActionMail->setWhatsThis( i18n( "Send a mail to all selected contacts." ) );
01199   action->setWhatsThis( i18n( "Print a special number of contacts." ) );
01200 
01201   mActionSave = KStdAction::save( this,
01202                              SLOT( save() ), actionCollection(), "file_sync" );
01203   mActionSave->setWhatsThis( i18n( "Save all changes of the address book to the storage backend." ) );
01204 
01205   action = new KAction( i18n( "&New Contact..." ), "identity", CTRL+Key_N, this,
01206                SLOT( newContact() ), actionCollection(), "file_new_contact" );
01207   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." ) );
01208 
01209   action = new KAction( i18n( "&New Distribution List..." ), "kontact_contacts", 0, this,
01210                SLOT( newDistributionList() ), actionCollection(), "file_new_distributionlist" );
01211   action->setWhatsThis( i18n( "Create a new distribution list<p>You will be presented with a dialog where you can create a new distribution list." ) );
01212 
01213   mActionMailVCard = new KAction( i18n("Send &Contact..."), "mail_post_to", 0,
01214                                   this, SLOT( mailVCard() ),
01215                                   actionCollection(), "file_mail_vcard" );
01216   mActionMailVCard->setWhatsThis( i18n( "Send a mail with the selected contact as attachment." ) );
01217 
01218   mActionChat = new KAction( i18n("Chat &With..."), 0,
01219                                   this, SLOT( startChat() ),
01220                                   actionCollection(), "file_chat" );
01221   mActionChat->setWhatsThis( i18n( "Start a chat with the selected contact." ) );
01222 
01223   mActionEditAddressee = new KAction( i18n( "&Edit Contact..." ), "edit", 0,
01224                                       this, SLOT( editContact() ),
01225                                       actionCollection(), "file_properties" );
01226   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." ) );
01227 
01228   mActionMerge = new KAction( i18n( "&Merge Contacts" ), "", 0,
01229                               this, SLOT( mergeContacts() ),
01230                               actionCollection(), "edit_merge" );
01231 
01232   // edit menu
01233   mActionCopy = KStdAction::copy( this, SLOT( copyContacts() ), actionCollection() );
01234   mActionCut = KStdAction::cut( this, SLOT( cutContacts() ), actionCollection() );
01235   mActionPaste = KStdAction::paste( this, SLOT( pasteContacts() ), actionCollection() );
01236   action = KStdAction::selectAll( this, SLOT( selectAllContacts() ), actionCollection() );
01237   mActionCopy->setWhatsThis( i18n( "Copy the currently selected contact(s) to system clipboard in vCard format." ) );
01238   mActionCut->setWhatsThis( i18n( "Cuts the currently selected contact(s) to system clipboard in vCard format." ) );
01239   mActionPaste->setWhatsThis( i18n( "Paste the previously cut or copied contacts from clipboard." ) );
01240   action->setWhatsThis( i18n( "Selects all visible contacts from current view." ) );
01241 //  mActionUndo->setWhatsThis( i18n( "Undoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) );
01242 //  mActionRedo->setWhatsThis( i18n( "Redoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) );
01243 
01244   mActionDelete = new KAction( i18n( "&Delete Contact" ), "editdelete",
01245                                Key_Delete, this, SLOT( deleteContacts() ),
01246                                actionCollection(), "edit_delete" );
01247   mActionDelete->setWhatsThis( i18n( "Delete all selected contacts." ) );
01248 
01249 
01250   mActionCopyAddresseeTo = new KAction( i18n( "&Copy Contact To..." ), "", 0,
01251                                       this, SLOT( copySelectedContactToResource() ),
01252                                       actionCollection(), "copy_contact_to" );
01253   const QString copyMoveWhatsThis = i18n( "Store a contact in a different Addressbook<p>You will be presented with a dialog where you can select a new storage place for this contact." );
01254   mActionCopyAddresseeTo->setWhatsThis( copyMoveWhatsThis );
01255 
01256   mActionMoveAddresseeTo = new KAction( i18n( "M&ove Contact To..." ), "", 0,
01257                                       this, SLOT( moveSelectedContactToResource() ),
01258                                       actionCollection(), "move_contact_to" );
01259   mActionMoveAddresseeTo->setWhatsThis( copyMoveWhatsThis );
01260 
01261   // settings menu
01262   mActionJumpBar = new KToggleAction( i18n( "Show Jump Bar" ), "next", 0,
01263                                       actionCollection(), "options_show_jump_bar" );
01264   mActionJumpBar->setWhatsThis( i18n( "Toggle whether the jump button bar shall be visible." ) );
01265   mActionJumpBar->setCheckedState( i18n( "Hide Jump Bar") );
01266   connect( mActionJumpBar, SIGNAL( toggled( bool ) ), SLOT( setJumpButtonBarVisible( bool ) ) );
01267 
01268   mActionDetails = new KToggleAction( i18n( "Show Details" ), 0, 0,
01269                                       actionCollection(), "options_show_details" );
01270   mActionDetails->setWhatsThis( i18n( "Toggle whether the details page shall be visible." ) );
01271   mActionDetails->setCheckedState( i18n( "Hide Details") );
01272   connect( mActionDetails, SIGNAL( toggled( bool ) ), SLOT( setDetailsVisible( bool ) ) );
01273 
01274   if ( mIsPart )
01275     action = new KAction( i18n( "&Configure Address Book..." ), "configure", 0,
01276                           this, SLOT( configure() ), actionCollection(),
01277                           "kaddressbook_configure" );
01278   else
01279     action = KStdAction::preferences( this, SLOT( configure() ), actionCollection() );
01280 
01281   action->setWhatsThis( i18n( "You will be presented with a dialog, that offers you all possibilities to configure KAddressBook." ) );
01282 
01283   // misc
01284   action = new KAction( i18n( "&Lookup Addresses in LDAP Directory..." ), "find", 0,
01285                         this, SLOT( openLDAPDialog() ), actionCollection(), "ldap_lookup" );
01286   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." ) );
01287 
01288   mActionWhoAmI = new KAction( i18n( "Set as Personal Contact Data" ), "personal", 0, this,
01289                                SLOT( setWhoAmI() ), actionCollection(),
01290                                "edit_set_personal" );
01291   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." ) );
01292 
01293   mActionCategories = new KAction( i18n( "Select Categories..." ), 0, this,
01294                                    SLOT( setCategories() ), actionCollection(),
01295                                    "edit_set_categories" );
01296   mActionCategories->setWhatsThis( i18n( "Set the categories for all selected contacts." ) );
01297 
01298   KAction *clearLocation = new KAction( i18n( "Clear Search Bar" ),
01299                     QApplication::reverseLayout() ? "clear_left" : "locationbar_erase",
01300                     CTRL+Key_L, this, SLOT( slotClearSearchBar() ), actionCollection(), "clear_search" );
01301   clearLocation->setWhatsThis( i18n( "Clear Search Bar<p>"
01302                      "Clears the content of the quick search bar." ) );
01303 
01304   clipboardDataChanged();
01305 }
01306 
01307 void KABCore::clipboardDataChanged()
01308 {
01309   if ( mReadWrite )
01310     mActionPaste->setEnabled( !QApplication::clipboard()->text().isEmpty() );
01311 }
01312 
01313 void KABCore::updateIncSearchWidget()
01314 {
01315   mIncSearchWidget->setViewFields( mViewManager->viewFields() );
01316 }
01317 
01318 void KABCore::updateCategories()
01319 {
01320   QStringList categories( allCategories() );
01321   categories.sort();
01322 
01323   const QStringList customCategories( KABPrefs::instance()->customCategories() );
01324   QStringList::ConstIterator it;
01325   const QStringList::ConstIterator endIt( customCategories.end() );
01326   for ( it = customCategories.begin(); it != endIt; ++it ) {
01327     if ( categories.find( *it ) == categories.end() ) {
01328       categories.append( *it );
01329     }
01330   }
01331 
01332   KABPrefs::instance()->mCustomCategories = categories;
01333   KABPrefs::instance()->writeConfig();
01334 
01335   if ( mCategoryEditDialog )
01336     mCategoryEditDialog->reload();
01337 }
01338 
01339 QStringList KABCore::allCategories() const
01340 {
01341   QStringList categories, allCategories;
01342   QStringList::ConstIterator catIt;
01343 
01344   KABC::AddressBook::ConstIterator it;
01345   const KABC::AddressBook::ConstIterator endIt( mAddressBook->end() );
01346   for ( it = mAddressBook->begin(); it != endIt; ++it ) {
01347     categories = (*it).categories();
01348     const QStringList::ConstIterator catEndIt( categories.end() );
01349     for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) {
01350       if ( !allCategories.contains( *catIt ) )
01351         allCategories.append( *catIt );
01352     }
01353   }
01354 
01355   return allCategories;
01356 }
01357 
01358 void KABCore::setCategories()
01359 {
01360   // Show the category dialog
01361   if ( mCategorySelectDialog == 0 ) {
01362     mCategorySelectDialog = new KPIM::CategorySelectDialog( KABPrefs::instance(), mWidget );
01363     connect( mCategorySelectDialog, SIGNAL( categoriesSelected( const QStringList& ) ),
01364              SLOT( categoriesSelected( const QStringList& ) ) );
01365     connect( mCategorySelectDialog, SIGNAL( editCategories() ), SLOT( editCategories() ) );
01366   }
01367 
01368   mCategorySelectDialog->show();
01369   mCategorySelectDialog->raise();
01370 }
01371 
01372 void KABCore::categoriesSelected( const QStringList &categories )
01373 {
01374   bool merge = false;
01375   QString msg = i18n( "Merge with existing categories?" );
01376   if ( KMessageBox::questionYesNo( mWidget, msg, QString::null, i18n( "Merge" ), i18n( "Do Not Merge" ) ) == KMessageBox::Yes )
01377     merge = true;
01378 
01379   QStringList uids = mViewManager->selectedUids();
01380   QStringList::ConstIterator it;
01381   const QStringList::ConstIterator endIt( uids.end() );
01382   for ( it = uids.begin(); it != endIt; ++it ) {
01383     KABC::Addressee addr = mAddressBook->findByUid( *it );
01384     if ( !addr.isEmpty() ) {
01385       if ( !merge )
01386         addr.setCategories( categories );
01387       else {
01388         QStringList addrCategories = addr.categories();
01389         QStringList::ConstIterator catIt;
01390         const QStringList::ConstIterator catEndIt( categories.end() );
01391         for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) {
01392           if ( !addrCategories.contains( *catIt ) )
01393             addrCategories.append( *catIt );
01394         }
01395         addr.setCategories( addrCategories );
01396       }
01397 
01398       mAddressBook->insertAddressee( addr );
01399     }
01400   }
01401 
01402   if ( uids.count() > 0 )
01403     setModified( true );
01404 }
01405 
01406 void KABCore::editCategories()
01407 {
01408   if ( mCategoryEditDialog == 0 ) {
01409     mCategoryEditDialog = new KPIM::CategoryEditDialog( KABPrefs::instance(), mWidget );
01410     connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ),
01411              mCategorySelectDialog, SLOT( updateCategoryConfig() ) );
01412   }
01413 
01414   mCategoryEditDialog->show();
01415   mCategoryEditDialog->raise();
01416 }
01417 
01418 void KABCore::slotClearSearchBar()
01419 {
01420   mIncSearchWidget->clear();
01421   mIncSearchWidget->setFocus();
01422 }
01423 
01424 void KABCore::slotContactsUpdated()
01425 {
01426   if ( mStatusBar ) {
01427     QString msg( i18n( "%n contact matches", "%n contacts matching", mSearchManager->contacts().count() ) );
01428     if ( !mStatusBar->hasItem( 1 ) )
01429       mStatusBar->insertItem( msg, 1 );
01430     else
01431       mStatusBar->changeItem( msg, 1 );
01432   }
01433 
01434   emit contactsUpdated();
01435 }
01436 
01437 bool KABCore::handleCommandLine( KAddressBookIface* iface )
01438 {
01439   KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
01440   QCString addrStr = args->getOption( "addr" );
01441   QCString uidStr = args->getOption( "uid" );
01442 
01443   QString addr, uid, vcard;
01444   if ( !addrStr.isEmpty() )
01445     addr = QString::fromLocal8Bit( addrStr );
01446   if ( !uidStr.isEmpty() )
01447     uid = QString::fromLocal8Bit( uidStr );
01448 
01449   bool doneSomething = false;
01450 
01451   // 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
01452   if ( !addr.isEmpty() ) {
01453     iface->addEmail( addr );
01454     doneSomething = true;
01455   }
01456 
01457   if ( !uid.isEmpty() ) {
01458     iface->showContactEditor( uid );
01459     doneSomething = true;
01460   }
01461 
01462   if ( args->isSet( "new-contact" ) ) {
01463     iface->newContact();
01464     doneSomething = true;
01465   }
01466 
01467   if ( args->count() >= 1 ) {
01468     for ( int i = 0; i < args->count(); ++i )
01469       iface->importVCard( args->url( i ).url() );
01470     doneSomething = true;
01471   }
01472   return doneSomething;
01473 }
01474 
01475 void KABCore::removeSelectedContactsFromDistList()
01476 {
01477 #ifdef KDEPIM_NEW_DISTRLISTS
01478 
01479   KPIM::DistributionList dist = KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList );
01480   if ( dist.isEmpty() )
01481     return;
01482   const QStringList uids = selectedUIDs();
01483   if ( uids.isEmpty() )
01484       return;
01485   for ( QStringList::ConstIterator it = uids.begin(); it != uids.end(); ++it ) {
01486       dist.removeEntry ( *it );
01487   }
01488   addressBook()->insertAddressee( dist );
01489   setModified();
01490 #endif
01491 }
01492 
01493 void KABCore::sendMailToDistributionList( const QString &name )
01494 {
01495 #ifdef KDEPIM_NEW_DISTRLISTS
01496   KPIM::DistributionList dist = KPIM::DistributionList::findByName( addressBook(), name );
01497   if ( dist.isEmpty() )
01498     return;
01499   typedef KPIM::DistributionList::Entry::List EntryList; 
01500   QStringList mails;
01501   const EntryList entries = dist.entries( addressBook() );
01502   for ( EntryList::ConstIterator it = entries.begin(); it != entries.end(); ++it )
01503     mails += (*it).addressee.fullEmail( (*it).email );
01504   sendMail( mails.join( ", " ) ); 
01505 #endif
01506 }
01507 
01508 void KABCore::editSelectedDistributionList()
01509 {
01510 #ifdef KDEPIM_NEW_DISTRLISTS
01511   editDistributionList( KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList ) );
01512 #endif
01513 }
01514 
01515 
01516 void KABCore::editDistributionList( const QString &name )
01517 {
01518 #ifdef KDEPIM_NEW_DISTRLISTS
01519   editDistributionList( KPIM::DistributionList::findByName( addressBook(), name ) );
01520 #endif
01521 }
01522 
01523 #ifdef KDEPIM_NEW_DISTRLISTS
01524 
01525 void KABCore::showDistributionListEntry( const QString& uid )
01526 {
01527   KPIM::DistributionList dist = KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList );
01528   if ( !dist.isEmpty() ) {
01529     mDistListEntryView->clear();
01530     typedef KPIM::DistributionList::Entry::List EntryList;   
01531     const EntryList entries = dist.entries( addressBook() ); 
01532     for (EntryList::ConstIterator it = entries.begin(); it != entries.end(); ++it ) {
01533       if ( (*it).addressee.uid() == uid ) {
01534         mDistListEntryView->setEntry( dist, *it );
01535         break;
01536       }
01537     }
01538   }
01539 }
01540 
01541 void KABCore::editDistributionList( const KPIM::DistributionList &dist )
01542 {
01543   if ( dist.isEmpty() )
01544     return;
01545   QGuardedPtr<KPIM::DistributionListEditor::EditorWidget> dlg = new KPIM::DistributionListEditor::EditorWidget( addressBook(), widget() );
01546   dlg->setDistributionList( dist );
01547   if ( dlg->exec() == QDialog::Accepted ) {
01548     const KPIM::DistributionList newDist = dlg->distributionList();
01549     if ( newDist != dist ) {
01550       addressBook()->insertAddressee( newDist );
01551       setModified();
01552     }
01553   }
01554   delete dlg;
01555 }
01556 
01557 
01558 KPIM::DistributionList::List KABCore::distributionLists() const
01559 {
01560   return mSearchManager->distributionLists();
01561 }
01562 
01563 void KABCore::setSelectedDistributionList( const QString &name )
01564 {
01565   mSelectedDistributionList = name;
01566   mSearchManager->setSelectedDistributionList( name );
01567   mViewHeaderLabel->setText( name.isNull() ? i18n( "Contacts" ) : i18n( "Distribution List: %1" ).arg( name ) );
01568   mDistListButtonWidget->setShown( !mSelectedDistributionList.isNull() );
01569   if ( !name.isNull() ) {
01570     mDetailsStack->raiseWidget( mDistListEntryView );
01571     const QStringList selectedUids = selectedUIDs();
01572     showDistributionListEntry( selectedUids.isEmpty() ? QString() : selectedUids.first() );
01573   }
01574   else
01575     mDetailsStack->raiseWidget( mExtensionManager->activeDetailsWidget() ? mExtensionManager->activeDetailsWidget() : mDetailsWidget );
01576 }
01577 
01578 QStringList KABCore::distributionListNames() const
01579 {
01580   return mSearchManager->distributionListNames();
01581 }
01582 #endif
01583 
01584 #include "kabcore.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys