diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 (patch) | |
tree | 67208f7c145782a7e90b123b982ca78d88cc2c87 /kaddressbook/kabcore.cpp | |
download | tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.tar.gz tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.zip |
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kaddressbook/kabcore.cpp')
-rw-r--r-- | kaddressbook/kabcore.cpp | 1647 |
1 files changed, 1647 insertions, 0 deletions
diff --git a/kaddressbook/kabcore.cpp b/kaddressbook/kabcore.cpp new file mode 100644 index 000000000..0702ce04e --- /dev/null +++ b/kaddressbook/kabcore.cpp @@ -0,0 +1,1647 @@ +/* + This file is part of KAddressbook. + Copyright (c) 2003 - 2004 Tobias Koenig <tokoe@kde.org> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +// Needed for ugly hack, to be removed in 4.0 +#include <unistd.h> // for usleep +#include <qeventloop.h> + +#include <qclipboard.h> +#include <qdir.h> +#include <qfile.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qptrlist.h> +#include <qwidgetstack.h> +#include <qregexp.h> +#include <qvbox.h> + +#include <kabc/addresseelist.h> +#include <kabc/errorhandler.h> +#include <kabc/resource.h> +#include <kabc/stdaddressbook.h> +#include <kabc/vcardconverter.h> +#include <kabc/resourcefile.h> +#include <kaboutdata.h> +#include <kaccelmanager.h> +#include <kapplication.h> +#include <dcopclient.h> +#include <kactionclasses.h> +#include <kcmdlineargs.h> +#include <kcmultidialog.h> +#include <kdebug.h> +#include <kdeversion.h> +#include <kimproxy.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kprinter.h> +#include <kprotocolinfo.h> +#include <kpushbutton.h> +#include <kresources/selectdialog.h> +#include <kstandarddirs.h> +#include <kstatusbar.h> +#include <kstdguiitem.h> +#include <kxmlguiclient.h> +#include <ktoolbar.h> +#include <libkdepim/addresseeview.h> +#include <libkdepim/categoryeditdialog.h> +#include <libkdepim/categoryselectdialog.h> +#include <libkdepim/resourceabc.h> +#include "distributionlisteditor.h" + +#include "addresseeutil.h" +#include "addresseeeditordialog.h" +#include "distributionlistentryview.h" +#include "extensionmanager.h" +#include "filterselectionwidget.h" +#include "incsearchwidget.h" +#include "jumpbuttonbar.h" +#include "kablock.h" +#include "kabprefs.h" +#include "kabtools.h" +#include "kaddressbookservice.h" +#include "kaddressbookiface.h" +#include "ldapsearchdialog.h" +#include "locationmap.h" +#include "printing/printingwizard.h" +#include "searchmanager.h" +#include "undocmds.h" +#include "viewmanager.h" +#include "xxportmanager.h" + +#include "kabcore.h" + +KABCore::KABCore( KXMLGUIClient *client, bool readWrite, QWidget *parent, + const QString &file, const char *name ) + : KAB::Core( client, parent, name ), mStatusBar( 0 ), mViewManager( 0 ), + mExtensionManager( 0 ), mJumpButtonBar( 0 ), mCategorySelectDialog( 0 ), + mCategoryEditDialog( 0 ), mLdapSearchDialog( 0 ), mReadWrite( readWrite ), + mModified( false ) +{ + mWidget = new QWidget( parent, name ); + + mIsPart = !parent->isA( "KAddressBookMain" ); + + mAddressBookChangedTimer = new QTimer( this ); + connect( mAddressBookChangedTimer, SIGNAL( timeout() ), + this, SLOT( addressBookChanged() ) ); + + if ( file.isEmpty() ) { + mAddressBook = KABC::StdAddressBook::self( true ); + } else { + kdDebug(5720) << "KABCore(): document '" << file << "'" << endl; + mAddressBook = new KABC::AddressBook; + mAddressBook->addResource( new KABC::ResourceFile( file ) ); + if ( !mAddressBook->load() ) { + KMessageBox::error( parent, i18n("Unable to load '%1'.").arg( file ) ); + } + } + mAddressBook->setErrorHandler( new KABC::GuiErrorHandler( mWidget ) ); + +#if ! KDE_IS_VERSION(3,5,8) + mAddressBook->addCustomField( i18n( "Department" ), KABC::Field::Organization, + "X-Department", "KADDRESSBOOK" ); +#endif + mAddressBook->addCustomField( i18n( "Profession" ), KABC::Field::Organization, + "X-Profession", "KADDRESSBOOK" ); + mAddressBook->addCustomField( i18n( "Assistant's Name" ), KABC::Field::Organization, + "X-AssistantsName", "KADDRESSBOOK" ); + mAddressBook->addCustomField( i18n( "Manager's Name" ), KABC::Field::Organization, + "X-ManagersName", "KADDRESSBOOK" ); + mAddressBook->addCustomField( i18n( "Partner's Name" ), KABC::Field::Personal, + "X-SpousesName", "KADDRESSBOOK" ); + mAddressBook->addCustomField( i18n( "Office" ), KABC::Field::Personal, + "X-Office", "KADDRESSBOOK" ); + mAddressBook->addCustomField( i18n( "IM Address" ), KABC::Field::Personal, + "X-IMAddress", "KADDRESSBOOK" ); + mAddressBook->addCustomField( i18n( "Anniversary" ), KABC::Field::Personal, + "X-Anniversary", "KADDRESSBOOK" ); + mAddressBook->addCustomField( i18n( "Blog" ), KABC::Field::Personal, + "BlogFeed", "KADDRESSBOOK" ); + + mSearchManager = new KAB::SearchManager( mAddressBook, parent ); + + connect( mSearchManager, SIGNAL( contactsUpdated() ), + this, SLOT( slotContactsUpdated() ) ); + + initGUI(); + + connect( mAddressBook, SIGNAL( addressBookChanged( AddressBook* ) ), + SLOT( delayedAddressBookChanged() ) ); + connect( mAddressBook, SIGNAL( loadingFinished( Resource* ) ), + SLOT( delayedAddressBookChanged() ) ); + + mIncSearchWidget->setFocus(); + + connect( mViewManager, SIGNAL( selected( const QString& ) ), + SLOT( setContactSelected( const QString& ) ) ); + connect( mViewManager, SIGNAL( executed( const QString& ) ), + SLOT( editContact( const QString& ) ) ); + connect( mViewManager, SIGNAL( modified() ), + SLOT( setModified() ) ); + connect( mViewManager, SIGNAL( urlDropped( const KURL& ) ), + mXXPortManager, SLOT( importVCard( const KURL& ) ) ); + connect( mViewManager, SIGNAL( viewFieldsChanged() ), + SLOT( updateIncSearchWidget() ) ); + connect( mExtensionManager, SIGNAL( modified( const KABC::Addressee::List& ) ), + this, SLOT( extensionModified( const KABC::Addressee::List& ) ) ); + connect( mExtensionManager, SIGNAL( deleted( const QStringList& ) ), + this, SLOT( extensionDeleted( const QStringList& ) ) ); + + connect( mXXPortManager, SIGNAL( modified() ), + SLOT( setModified() ) ); + + connect( mDetailsViewer, SIGNAL( highlightedMessage( const QString& ) ), + SLOT( detailsHighlighted( const QString& ) ) ); + + connect( mIncSearchWidget, SIGNAL( scrollUp() ), + mViewManager, SLOT( scrollUp() ) ); + connect( mIncSearchWidget, SIGNAL( scrollDown() ), + mViewManager, SLOT( scrollDown() ) ); + + mAddressBookService = new KAddressBookService( this ); + + mCommandHistory = new KCommandHistory( actionCollection(), true ); + connect( mCommandHistory, SIGNAL( commandExecuted() ), + mSearchManager, SLOT( reload() ) ); + + mSearchManager->reload(); + + setModified( false ); + + KAcceleratorManager::manage( mWidget ); + + mKIMProxy = ::KIMProxy::instance( kapp->dcopClient() ); +} + +KABCore::~KABCore() +{ + mAddressBook->disconnect(); + + mAddressBook = 0; + KABC::StdAddressBook::close(); + mKIMProxy = 0; +} + +void KABCore::restoreSettings() +{ + bool state = KABPrefs::instance()->jumpButtonBarVisible(); + mActionJumpBar->setChecked( state ); + setJumpButtonBarVisible( state ); + + state = KABPrefs::instance()->detailsPageVisible(); + mActionDetails->setChecked( state ); + setDetailsVisible( state ); + + mViewManager->restoreSettings(); + mExtensionManager->restoreSettings(); + + updateIncSearchWidget(); + mIncSearchWidget->setCurrentItem( KABPrefs::instance()->currentIncSearchField() ); + + QValueList<int> splitterSize = KABPrefs::instance()->detailsSplitter(); + if ( splitterSize.count() == 0 ) { + splitterSize.append( 360 ); + splitterSize.append( 260 ); + } + mDetailsSplitter->setSizes( splitterSize ); + + const QValueList<int> leftSplitterSizes = KABPrefs::instance()->leftSplitter(); + if ( !leftSplitterSizes.isEmpty() ) + mLeftSplitter->setSizes( leftSplitterSizes ); +} + +void KABCore::saveSettings() +{ + KABPrefs::instance()->setJumpButtonBarVisible( mActionJumpBar->isChecked() ); + KABPrefs::instance()->setDetailsPageVisible( mActionDetails->isChecked() ); + KABPrefs::instance()->setDetailsSplitter( mDetailsSplitter->sizes() ); + KABPrefs::instance()->setLeftSplitter( mLeftSplitter->sizes() ); + + mExtensionManager->saveSettings(); + mViewManager->saveSettings(); + + KABPrefs::instance()->setCurrentIncSearchField( mIncSearchWidget->currentItem() ); +} + +KABC::AddressBook *KABCore::addressBook() const +{ + return mAddressBook; +} + +KConfig *KABCore::config() const +{ + return KABPrefs::instance()->config(); +} + +KActionCollection *KABCore::actionCollection() const +{ + return guiClient()->actionCollection(); +} + +KABC::Field *KABCore::currentSortField() const +{ + return mViewManager->currentSortField(); +} + +QStringList KABCore::selectedUIDs() const +{ + return mViewManager->selectedUids(); +} + +KABC::Resource *KABCore::requestResource( QWidget *parent ) +{ + QPtrList<KABC::Resource> kabcResources = addressBook()->resources(); + + QPtrList<KRES::Resource> kresResources; + QPtrListIterator<KABC::Resource> resIt( kabcResources ); + KABC::Resource *resource; + while ( ( resource = resIt.current() ) != 0 ) { + ++resIt; + if ( !resource->readOnly() ) { + KRES::Resource *res = resource; // downcast + kresResources.append( res ); + } + } + + KRES::Resource *res = KRES::SelectDialog::getResource( kresResources, parent ); + return static_cast<KABC::Resource*>( res ); // upcast +} + +QWidget *KABCore::widget() const +{ + return mWidget; +} + +KAboutData *KABCore::createAboutData() +{ + KAboutData *about = new KAboutData( "kaddressbook", I18N_NOOP( "KAddressBook" ), + "3.5.10", I18N_NOOP( "The KDE Address Book" ), + KAboutData::License_GPL_V2, + I18N_NOOP( "(c) 1997-2005, The KDE PIM Team" ) ); + about->addAuthor( "Tobias Koenig", I18N_NOOP( "Current maintainer" ), "tokoe@kde.org" ); + about->addAuthor( "Don Sanders", I18N_NOOP( "Original author" ) ); + about->addAuthor( "Cornelius Schumacher", + I18N_NOOP( "Co-maintainer, libkabc port, CSV import/export" ), + "schumacher@kde.org" ); + about->addAuthor( "Mike Pilone", I18N_NOOP( "GUI and framework redesign" ), + "mpilone@slac.com" ); + about->addAuthor( "Greg Stern", I18N_NOOP( "DCOP interface" ) ); + about->addAuthor( "Mark Westcott", I18N_NOOP( "Contact pinning" ) ); + about->addAuthor( "Mischel Boyer de la Giroday", I18N_NOOP( "LDAP Lookup" ), + "michel@klaralvdalens-datakonsult.se" ); + about->addAuthor( "Steffen Hansen", I18N_NOOP( "LDAP Lookup" ), + "hansen@kde.org" ); + + return about; +} + +void KABCore::setStatusBar( KStatusBar *statusBar ) +{ + mStatusBar = statusBar; +} + +KStatusBar *KABCore::statusBar() const +{ + return mStatusBar; +} + +void KABCore::setContactSelected( const QString &uid ) +{ + KABC::Addressee addr = mAddressBook->findByUid( uid ); + if ( !mDetailsViewer->isHidden() ) + mDetailsViewer->setAddressee( addr ); +#ifdef KDEPIM_NEW_DISTRLISTS + if ( !mSelectedDistributionList.isNull() && mDistListEntryView->isShown() ) { + showDistributionListEntry( uid ); + } +#endif + mExtensionManager->setSelectionChanged(); + + KABC::Addressee::List list = mViewManager->selectedAddressees(); + const bool someSelected = list.size() > 0; + const bool singleSelected = list.size() == 1; + bool writable = mReadWrite; + + if ( writable ) { + //check if every single (sub)resource is writable + //### We have a performance problem here - everytime *one* item is added or + // removed we re-check *all* items. If this turns out to be a bottleneck + // we need to keep some state and check new items only. + KABC::Addressee::List::ConstIterator addrIt = list.constBegin(); + for ( ; addrIt != list.constEnd(); ++addrIt ) { + KABC::Resource *res = ( *addrIt ).resource(); + if ( !res ) { + kdDebug() << "KABCore::setContactSelected: this addressee has no resource!" << endl; + writable = false; + break; + } + if ( res->readOnly() ) { + writable = false; + break; + } + //HACK: manual polymorphism + if ( res->inherits( "KPIM::ResourceABC" ) ) { + KPIM::ResourceABC *resAbc = static_cast<KPIM::ResourceABC *>( res ); + + QString subresource = resAbc->uidToResourceMap()[ ( *addrIt ).uid() ]; + if ( !subresource.isEmpty() && !resAbc->subresourceWritable( subresource ) ) { + writable = false; + break; + } + } + } + } + + bool moreThanOneResource = mAddressBook->resources().count() > 1; + if ( !moreThanOneResource && !mAddressBook->resources().isEmpty() ) { + KABC::Resource *res = mAddressBook->resources().first(); + if ( res->inherits( "KPIM::ResourceABC" ) ) { + KPIM::ResourceABC *resAbc = static_cast<KPIM::ResourceABC *>( res ); + const QStringList subresources = resAbc->subresources(); + int writeables = 0; + for ( QStringList::ConstIterator it = subresources.begin(); it != subresources.end(); ++it ) { + if ( resAbc->subresourceActive(*it) && resAbc->subresourceWritable(*it) ) { + writeables++; + } + } + moreThanOneResource = ( writeables >= 2 ); + } + } + + // update the actions + + mActionCopy->setEnabled( someSelected ); + mActionCut->setEnabled( someSelected && writable ); + mActionDelete->setEnabled( someSelected && writable ); + // the "edit" dialog doubles as the details dialog and it knows when the addressee is read-only + // (### this does not make much sense from the user perspective!) + mActionEditAddressee->setEnabled( singleSelected ); + mActionCopyAddresseeTo->setEnabled( someSelected && moreThanOneResource ); + mActionMoveAddresseeTo->setEnabled( someSelected && moreThanOneResource && writable ); + mActionMail->setEnabled( someSelected ); + mActionMailVCard->setEnabled( someSelected ); + mActionChat->setEnabled( singleSelected && mKIMProxy && mKIMProxy->initialize() ); + mActionWhoAmI->setEnabled( singleSelected ); + mActionCategories->setEnabled( someSelected && writable ); + mActionMerge->setEnabled( ( list.size() == 2 ) && writable ); + + if ( mReadWrite ) { + QClipboard *cb = QApplication::clipboard(); + list = AddresseeUtil::clipboardToAddressees( cb->text() ); + mActionPaste->setEnabled( !list.isEmpty() ); + } +} + +void KABCore::sendMail() +{ + //FIXME: breaks with email addresses containing "," + sendMail( mViewManager->selectedEmails().join( ", " ) ); +} + +void KABCore::sendMail( const QString& email ) +{ + kapp->invokeMailer( email, "" ); +} + +void KABCore::mailVCard() +{ + QStringList uids = mViewManager->selectedUids(); + if ( !uids.isEmpty() ) + mailVCard( uids ); +} + +void KABCore::mailVCard( const QStringList &uids ) +{ + KABTools::mailVCards( uids, mAddressBook ); +} + +void KABCore::startChat() +{ + QStringList uids = mViewManager->selectedUids(); + if ( !uids.isEmpty() ) + mKIMProxy->chatWithContact( uids.first() ); +} + +void KABCore::browse( const QString& url ) +{ + kapp->invokeBrowser( url ); +} + +void KABCore::selectAllContacts() +{ + mViewManager->setSelected( QString::null, true ); +} + +void KABCore::deleteContacts() +{ + QStringList uidList = mViewManager->selectedUids(); + + deleteContacts( uidList ); +} + +void KABCore::deleteDistributionLists( const QStringList & names ) +{ + if ( names.isEmpty() ) + return; + if ( KMessageBox::warningContinueCancelList( mWidget, i18n( "Do you really want to delete this distribution list?", + "Do you really want to delete these %n distribution lists?", names.count() ), + names, QString::null, KStdGuiItem::del() ) == KMessageBox::Cancel ) + return; + + QStringList uids; + for ( QStringList::ConstIterator it = names.begin(); it != names.end(); ++it ) { + uids.append( KPIM::DistributionList::findByName( mAddressBook, *it ).uid() ); + } + DeleteCommand *command = new DeleteCommand( mAddressBook, uids ); + mCommandHistory->addCommand( command ); + setModified( true ); +} + +void KABCore::deleteContacts( const QStringList &uids ) +{ + if ( uids.count() > 0 ) { + QStringList names; + QStringList::ConstIterator it = uids.begin(); + const QStringList::ConstIterator endIt( uids.end() ); + while ( it != endIt ) { + KABC::Addressee addr = mAddressBook->findByUid( *it ); + names.append( addr.realName().isEmpty() ? addr.preferredEmail() : addr.realName() ); + ++it; + } + + if ( KMessageBox::warningContinueCancelList( mWidget, i18n( "Do you really want to delete this contact?", + "Do you really want to delete these %n contacts?", uids.count() ), + names, QString::null, KStdGuiItem::del() ) == KMessageBox::Cancel ) + return; + + DeleteCommand *command = new DeleteCommand( mAddressBook, uids ); + mCommandHistory->addCommand( command ); + + // now if we deleted anything, refresh + setContactSelected( QString::null ); + setModified( true ); + } +} + +void KABCore::copyContacts() +{ + KABC::Addressee::List addrList = mViewManager->selectedAddressees(); + + QString clipText = AddresseeUtil::addresseesToClipboard( addrList ); + + kdDebug(5720) << "KABCore::copyContacts: " << clipText << endl; + + QClipboard *cb = QApplication::clipboard(); + cb->setText( clipText ); +} + +void KABCore::cutContacts() +{ + QStringList uidList = mViewManager->selectedUids(); + + if ( uidList.size() > 0 ) { + CutCommand *command = new CutCommand( mAddressBook, uidList ); + mCommandHistory->addCommand( command ); + + setModified( true ); + } +} + +void KABCore::pasteContacts() +{ + QClipboard *cb = QApplication::clipboard(); + + KABC::Addressee::List list = AddresseeUtil::clipboardToAddressees( cb->text() ); + + pasteContacts( list ); +} + +void KABCore::pasteContacts( KABC::Addressee::List &list ) +{ + KABC::Resource *resource = requestResource( mWidget ); + if ( !resource ) + return; + + KABC::Addressee::List::Iterator it; + const KABC::Addressee::List::Iterator endIt( list.end() ); + for ( it = list.begin(); it != endIt; ++it ) + (*it).setResource( resource ); + + PasteCommand *command = new PasteCommand( this, list ); + mCommandHistory->addCommand( command ); + + setModified( true ); +} + +void KABCore::mergeContacts() +{ + KABC::Addressee::List list = mViewManager->selectedAddressees(); + if ( list.count() < 2 ) + return; + + KABC::Addressee addr = KABTools::mergeContacts( list ); + + KABC::Addressee::List::Iterator it = list.begin(); + const KABC::Addressee::List::Iterator endIt( list.end() ); + KABC::Addressee origAddr = *it; + QStringList uids; + ++it; + while ( it != endIt ) { + uids.append( (*it).uid() ); + ++it; + } + + DeleteCommand *command = new DeleteCommand( mAddressBook, uids ); + mCommandHistory->addCommand( command ); + + EditCommand *editCommand = new EditCommand( mAddressBook, origAddr, addr ); + mCommandHistory->addCommand( editCommand ); + + mSearchManager->reload(); +} + +void KABCore::setWhoAmI() +{ + KABC::Addressee::List addrList = mViewManager->selectedAddressees(); + + if ( addrList.count() > 1 ) { + // can probably be removed because we now check the selection in setContactSelected(). + KMessageBox::sorry( mWidget, i18n( "Please select only one contact." ) ); + return; + } + + QString text( i18n( "<qt>Do you really want to use <b>%1</b> as your new personal contact?</qt>" ) ); + if ( KMessageBox::questionYesNo( mWidget, text.arg( addrList[ 0 ].assembledName() ), QString::null, i18n("Use"), i18n("Do Not Use") ) == KMessageBox::Yes ) + static_cast<KABC::StdAddressBook*>( KABC::StdAddressBook::self( true ) )->setWhoAmI( addrList[ 0 ] ); +} + +void KABCore::incrementalTextSearch( const QString& text ) +{ + setContactSelected( QString::null ); + mSearchManager->search( text, mIncSearchWidget->currentFields() ); +} + +void KABCore::incrementalJumpButtonSearch( const QString& character ) +{ + mViewManager->setSelected( QString::null, false ); + + KABC::AddresseeList list = mSearchManager->contacts(); + KABC::Field *field = mViewManager->currentSortField(); + if ( field ) { + list.sortByField( field ); + KABC::AddresseeList::ConstIterator it; + const KABC::AddresseeList::ConstIterator endIt( list.end() ); + for ( it = list.begin(); it != endIt; ++it ) { + if ( field->value( *it ).startsWith( character, false ) ) { + mViewManager->setSelected( (*it).uid(), true ); + return; + } + } + } +} + +void KABCore::setModified() +{ + setModified( true ); +} + +void KABCore::setModified( bool modified ) +{ + mModified = modified; + mActionSave->setEnabled( mModified ); + + mSearchManager->reload(); +} + +bool KABCore::modified() const +{ + return mModified; +} + +void KABCore::contactModified( const KABC::Addressee &addr ) +{ + Command *command = 0; + + // check if it exists already + KABC::Addressee origAddr = mAddressBook->findByUid( addr.uid() ); + if ( origAddr.isEmpty() ) { + KABC::Addressee::List addressees; + addressees.append( addr ); + command = new NewCommand( mAddressBook, addressees ); + } else { + command = new EditCommand( mAddressBook, origAddr, addr ); + } + + mCommandHistory->addCommand( command ); + + setContactSelected( addr.uid() ); + setModified( true ); +} + +void KABCore::newDistributionList() +{ +#ifdef KDEPIM_NEW_DISTRLISTS + QString name = i18n( "New Distribution List" ); + const KPIM::DistributionList distList = KPIM::DistributionList::findByName( addressBook(), name ); + if ( !distList.isEmpty() ) { + bool foundUnused = false; + int i = 1; + while ( !foundUnused ) { + name = i18n( "New Distribution List (%1)" ).arg( i++ ); + foundUnused = KPIM::DistributionList::findByName( addressBook(), name ).isEmpty(); + } + } + KPIM::DistributionList list; + list.setUid( KApplication::randomString( 10 ) ); + list.setName( name ); + editDistributionList( list ); +#endif +} + +void KABCore::newContact() +{ + AddresseeEditorDialog *dialog = 0; + + KABC::Resource* resource = requestResource( mWidget ); + + if ( resource ) { + KABC::Addressee addr; + addr.setResource( resource ); + + if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) ) + return; + + dialog = createAddresseeEditorDialog( mWidget ); + dialog->setAddressee( addr ); + } else + return; + + mEditorDict.insert( dialog->addressee().uid(), dialog ); + + dialog->show(); +} + +void KABCore::addEmail( const QString &aStr ) +{ + QString fullName, email; + + KABC::Addressee::parseEmailAddress( aStr, fullName, email ); + +#if KDE_IS_VERSION(3,4,89) + // This ugly hack will be removed in 4.0 + // addressbook may not be reloaded yet, as done asynchronously sometimes, so wait + while ( !mAddressBook->loadingHasFinished() ) { + QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput ); + // use sleep here to reduce cpu usage + usleep( 100 ); + } +#endif + + // Try to lookup the addressee matching the email address + bool found = false; + QStringList emailList; + KABC::AddressBook::Iterator it; + const KABC::AddressBook::Iterator endIt( mAddressBook->end() ); + for ( it = mAddressBook->begin(); !found && (it != endIt); ++it ) { + emailList = (*it).emails(); + if ( emailList.contains( email ) > 0 ) { + found = true; + (*it).setNameFromString( fullName ); + editContact( (*it).uid() ); + } + } + + if ( !found ) { + KABC::Addressee addr; + addr.setNameFromString( fullName ); + addr.insertEmail( email, true ); + + mAddressBook->insertAddressee( addr ); + mViewManager->refreshView( addr.uid() ); + editContact( addr.uid() ); + } +} + +void KABCore::importVCard( const KURL &url ) +{ + mXXPortManager->importVCard( url ); +} + +void KABCore::importVCardFromData( const QString &vCard ) +{ + mXXPortManager->importVCardFromData( vCard ); +} + +void KABCore::editContact( const QString &uid ) +{ + if ( mExtensionManager->isQuickEditVisible() ) + return; + + // First, locate the contact entry + QString localUID = uid; + if ( localUID.isNull() ) { + QStringList uidList = mViewManager->selectedUids(); + if ( uidList.count() > 0 ) + localUID = *( uidList.at( 0 ) ); + } +#if KDE_IS_VERSION(3,4,89) + // This ugly hack will be removed in 4.0 + // for calls with given uid, as done from commandline and DCOP + // addressbook may not be reloaded yet, as done asynchronously, so wait + else while ( !mAddressBook->loadingHasFinished() ) { + QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput ); + // use sleep here to reduce cpu usage + usleep( 100 ); + } +#endif + + KABC::Addressee addr = mAddressBook->findByUid( localUID ); + if ( !addr.isEmpty() ) { + AddresseeEditorDialog *dialog = mEditorDict.find( addr.uid() ); + if ( !dialog ) { + + if ( !addr.resource()->readOnly() ) + if ( !KABLock::self( mAddressBook )->lock( addr.resource() ) ) { + return; + } + + dialog = createAddresseeEditorDialog( mWidget ); + + mEditorDict.insert( addr.uid(), dialog ); + + dialog->setAddressee( addr ); + } + + dialog->raise(); + dialog->show(); + } +} + + +void KABCore::copySelectedContactToResource() +{ + storeContactIn( QString(), true /*copy*/); +} + +void KABCore::moveSelectedContactToResource() +{ + storeContactIn( QString(), false /*copy*/); +} + +void KABCore::storeContactIn( const QString &uid, bool copy /*false*/ ) +{ + // First, locate the contact entry + QStringList uidList; + if ( uid.isNull() ) { + uidList = mViewManager->selectedUids(); + } else { + uidList << uid; + } + KABC::Resource *resource = requestResource( mWidget ); + if ( !resource ) + return; + + KABLock::self( mAddressBook )->lock( resource ); + QStringList::Iterator it( uidList.begin() ); + const QStringList::Iterator endIt( uidList.end() ); + while ( it != endIt ) { + KABC::Addressee addr = mAddressBook->findByUid( *it++ ); + if ( !addr.isEmpty() ) { + KABC::Addressee newAddr( addr ); + // We need to set a new uid, otherwise the insert below is + // ignored. This is bad for syncing, but unavoidable, afaiks + newAddr.setUid( KApplication::randomString( 10 ) ); + newAddr.setResource( resource ); + addressBook()->insertAddressee( newAddr ); + const bool inserted = addressBook()->find( newAddr ) != addressBook()->end(); + if ( !copy && inserted ) { + KABLock::self( mAddressBook )->lock( addr.resource() ); + addressBook()->removeAddressee( addr ); + KABLock::self( mAddressBook )->unlock( addr.resource() ); + } + } + } + KABLock::self( mAddressBook )->unlock( resource ); + + addressBookChanged(); + setModified( true ); +} + +void KABCore::save() +{ + QPtrList<KABC::Resource> resources = mAddressBook->resources(); + QPtrListIterator<KABC::Resource> it( resources ); + while ( it.current() && !it.current()->readOnly() ) { + KABC::Ticket *ticket = mAddressBook->requestSaveTicket( it.current() ); + if ( ticket ) { + if ( !mAddressBook->save( ticket ) ) { + KMessageBox::error( mWidget, + i18n( "<qt>Unable to save address book <b>%1</b>.</qt>" ).arg( it.current()->resourceName() ) ); + mAddressBook->releaseSaveTicket( ticket ); + } else { + setModified( false ); + } + } else { + KMessageBox::error( mWidget, + i18n( "<qt>Unable to get access for saving the address book <b>%1</b>.</qt>" ) + .arg( it.current()->resourceName() ) ); + } + + ++it; + } +} + +void KABCore::setJumpButtonBarVisible( bool visible ) +{ + if ( visible ) { + if ( !mJumpButtonBar ) + createJumpButtonBar(); + mJumpButtonBar->show(); + } else + if ( mJumpButtonBar ) + mJumpButtonBar->hide(); +} + +void KABCore::setDetailsVisible( bool visible ) +{ + if ( visible ) + mDetailsPage->show(); + else + mDetailsPage->hide(); +} + +void KABCore::extensionModified( const KABC::Addressee::List &list ) +{ + if ( list.count() != 0 ) { + KABC::Addressee::List::ConstIterator it; + const KABC::Addressee::List::ConstIterator endIt( list.end() ); + for ( it = list.begin(); it != endIt; ++it ) { + Command *command = 0; + + // check if it exists already + KABC::Addressee origAddr = mAddressBook->findByUid( (*it).uid() ); + if ( origAddr.isEmpty() ) { + KABC::Addressee::List addressees; + addressees.append( *it ); + command = new NewCommand( mAddressBook, addressees ); + } else + command = new EditCommand( mAddressBook, origAddr, *it ); + + mCommandHistory->blockSignals( true ); + mCommandHistory->addCommand( command ); + mCommandHistory->blockSignals( false ); + } + + setModified(true); + } +} + +void KABCore::extensionDeleted( const QStringList &uidList ) +{ + DeleteCommand *command = new DeleteCommand( mAddressBook, uidList ); + mCommandHistory->addCommand( command ); + + // now if we deleted anything, refresh + setContactSelected( QString::null ); + setModified( true ); +} + +QString KABCore::getNameByPhone( const QString &phone ) +{ +#if KDE_IS_VERSION(3,4,89) + // This ugly hack will be removed in 4.0 + // addressbook may not be reloaded yet, as done asynchronously, so wait + while ( !mAddressBook->loadingHasFinished() ) { + QApplication::eventLoop()->processEvents( QEventLoop::ExcludeUserInput ); + // use sleep here to reduce cpu usage + usleep( 100 ); + } +#endif + + QRegExp r( "[/*/-/ ]" ); + QString localPhone( phone ); + + bool found = false; + QString ownerName = ""; + KABC::PhoneNumber::List phoneList; + + KABC::AddressBook::ConstIterator iter; + const KABC::AddressBook::ConstIterator endIter( mAddressBook->end() ); + + for ( iter = mAddressBook->begin(); !found && ( iter != endIter ); ++iter ) { + phoneList = (*iter).phoneNumbers(); + KABC::PhoneNumber::List::Iterator phoneIter( phoneList.begin() ); + const KABC::PhoneNumber::List::Iterator phoneEndIter( phoneList.end() ); + for ( ; !found && ( phoneIter != phoneEndIter ); ++phoneIter) { + // Get rid of separator chars so just the numbers are compared. + if ( (*phoneIter).number().replace( r, "" ) == localPhone.replace( r, "" ) ) { + ownerName = (*iter).realName(); + found = true; + } + } + } + + return ownerName; +} + +void KABCore::openLDAPDialog() +{ + if ( !KProtocolInfo::isKnownProtocol( KURL( "ldap://localhost" ) ) ) { + KMessageBox::error( mWidget, i18n( "Your KDE installation is missing LDAP " + "support, please ask your administrator or distributor for more information." ), + i18n( "No LDAP IO Slave Available" ) ); + return; + } + + if ( !mLdapSearchDialog ) { + mLdapSearchDialog = new LDAPSearchDialog( mAddressBook, this, mWidget ); + connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ), + SLOT( addressBookChanged() ) ); + connect( mLdapSearchDialog, SIGNAL( addresseesAdded() ), + SLOT( setModified() ) ); + } else + mLdapSearchDialog->restoreSettings(); + + if ( mLdapSearchDialog->isOK() ) + mLdapSearchDialog->exec(); +} + +void KABCore::configure() +{ + // Save the current config so we do not loose anything if the user accepts + saveSettings(); + + KCMultiDialog dlg( mWidget, "", true ); + connect( &dlg, SIGNAL( configCommitted() ), + this, SLOT( configurationChanged() ) ); + + dlg.addModule( "kabconfig.desktop" ); + dlg.addModule( "kabldapconfig.desktop" ); + dlg.addModule( "kabcustomfields.desktop" ); + + dlg.exec(); +} + +void KABCore::print() +{ + KPrinter printer; + printer.setDocName( i18n( "Address Book" ) ); + printer.setDocFileName( "addressbook" ); + + if ( !printer.setup( mWidget, i18n("Print Addresses") ) ) + return; + + KABPrinting::PrintingWizard wizard( &printer, mAddressBook, + mViewManager->selectedUids(), mWidget ); + + wizard.exec(); +} + +void KABCore::detailsHighlighted( const QString &msg ) +{ + if ( mStatusBar ) { + if ( !mStatusBar->hasItem( 2 ) ) + mStatusBar->insertItem( msg, 2 ); + else + mStatusBar->changeItem( msg, 2 ); + } +} + +void KABCore::showContactsAddress( const QString &addrUid ) +{ + QStringList uidList = mViewManager->selectedUids(); + if ( uidList.isEmpty() ) + return; + + KABC::Addressee addr = mAddressBook->findByUid( uidList.first() ); + if ( addr.isEmpty() ) + return; + + const KABC::Address::List list = addr.addresses(); + KABC::Address::List::ConstIterator it; + const KABC::Address::List::ConstIterator endIt( list.end() ); + for ( it = list.begin(); it != endIt; ++it ) + if ( (*it).id() == addrUid ) { + LocationMap::instance()->showAddress( *it ); + break; + } +} + +void KABCore::configurationChanged() +{ + mExtensionManager->reconfigure(); + mViewManager->refreshView(); +} + +bool KABCore::queryClose() +{ + saveSettings(); + KABPrefs::instance()->writeConfig(); + + QPtrList<KABC::Resource> resources = mAddressBook->resources(); + QPtrListIterator<KABC::Resource> it( resources ); + while ( it.current() ) { + it.current()->close(); + ++it; + } + + return true; +} + +void KABCore::reinitXMLGUI() +{ + mExtensionManager->createActions(); +} +void KABCore::delayedAddressBookChanged() +{ + mAddressBookChangedTimer->start( 1000 ); +} + +void KABCore::addressBookChanged() +{ + const QStringList selectedUids = mViewManager->selectedUids(); + + mAddressBookChangedTimer->stop(); + + if ( mJumpButtonBar ) + mJumpButtonBar->updateButtons(); + + mSearchManager->reload(); + + mViewManager->setSelected( QString::null, false ); + + QString uid = QString::null; + if ( !selectedUids.isEmpty() ) { + uid = selectedUids.first(); + mViewManager->setSelected( uid, true ); + } + + setContactSelected( uid ); + + updateCategories(); +} + +AddresseeEditorDialog *KABCore::createAddresseeEditorDialog( QWidget *parent, + const char *name ) +{ + AddresseeEditorDialog *dialog = new AddresseeEditorDialog( this, parent, + name ? name : "editorDialog" ); + connect( dialog, SIGNAL( contactModified( const KABC::Addressee& ) ), + SLOT( contactModified( const KABC::Addressee& ) ) ); + connect( dialog, SIGNAL( editorDestroyed( const QString& ) ), + SLOT( slotEditorDestroyed( const QString& ) ) ); + + return dialog; +} + +void KABCore::activateDetailsWidget( QWidget *widget ) +{ + if ( mDetailsStack->visibleWidget() == widget ) + return; + mDetailsStack->raiseWidget( widget ); +} + +void KABCore::deactivateDetailsWidget( QWidget *widget ) +{ + if ( mDetailsStack->visibleWidget() != widget ) + return; + mDetailsStack->raiseWidget( mDetailsWidget ); +} + +void KABCore::slotEditorDestroyed( const QString &uid ) +{ + AddresseeEditorDialog *dialog = mEditorDict.take( uid ); + + KABC::Addressee addr = dialog->addressee(); + + if ( !addr.resource()->readOnly() ) { + QApplication::setOverrideCursor( Qt::waitCursor ); + KABLock::self( mAddressBook )->unlock( addr.resource() ); + QApplication::restoreOverrideCursor(); + } +} + +void KABCore::initGUI() +{ + QVBoxLayout *topLayout = new QVBoxLayout( mWidget, 0, 0 ); + KToolBar* searchTB = new KToolBar( mWidget, "search toolbar"); + searchTB->boxLayout()->setSpacing( KDialog::spacingHint() ); + mIncSearchWidget = new IncSearchWidget( searchTB, "kde toolbar widget"); + searchTB->setStretchableWidget( mIncSearchWidget ); + connect( mIncSearchWidget, SIGNAL( doSearch( const QString& ) ), + SLOT( incrementalTextSearch( const QString& ) ) ); + + mDetailsSplitter = new QSplitter( mWidget ); + + mLeftSplitter = new QSplitter( mDetailsSplitter ); + mLeftSplitter->setOrientation( KABPrefs::instance()->contactListAboveExtensions() ? Qt::Vertical : Qt::Horizontal ); + + topLayout->addWidget( searchTB ); + topLayout->addWidget( mDetailsSplitter ); + + mDetailsStack = new QWidgetStack( mDetailsSplitter ); + mExtensionManager = new ExtensionManager( new QWidget( mLeftSplitter ), mDetailsStack, this, this ); + connect( mExtensionManager, SIGNAL( detailsWidgetDeactivated( QWidget* ) ), + this, SLOT( deactivateDetailsWidget( QWidget* ) ) ); + connect( mExtensionManager, SIGNAL( detailsWidgetActivated( QWidget* ) ), + this, SLOT( activateDetailsWidget( QWidget* ) ) ); + + QWidget *viewWidget = new QWidget( mLeftSplitter ); + if ( KABPrefs::instance()->contactListAboveExtensions() ) + mLeftSplitter->moveToFirst( viewWidget ); + QVBoxLayout *viewLayout = new QVBoxLayout( viewWidget ); + viewLayout->setSpacing( KDialog::spacingHint() ); + + mViewHeaderLabel = new QLabel( viewWidget ); +// mViewHeaderLabel->setSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed ); + mViewHeaderLabel->setText( i18n( "Contacts" ) ); + viewLayout->addWidget( mViewHeaderLabel ); + mViewManager = new ViewManager( this, viewWidget ); + viewLayout->addWidget( mViewManager, 1 ); + +#ifdef KDEPIM_NEW_DISTRLISTS + mDistListButtonWidget = new QWidget( viewWidget ); + QHBoxLayout *buttonLayout = new QHBoxLayout( mDistListButtonWidget ); + buttonLayout->setSpacing( KDialog::spacingHint() ); + buttonLayout->addStretch( 1 ); + + KPushButton *addDistListButton = new KPushButton( mDistListButtonWidget ); + addDistListButton->setText( i18n( "Add" ) ); + connect( addDistListButton, SIGNAL( clicked() ), + this, SLOT( editSelectedDistributionList() ) ); + buttonLayout->addWidget( addDistListButton ); + mDistListButtonWidget->setShown( false ); + viewLayout->addWidget( mDistListButtonWidget ); + + KPushButton *removeDistListButton = new KPushButton( mDistListButtonWidget ); + removeDistListButton->setText( i18n( "Remove" ) ); + connect( removeDistListButton, SIGNAL( clicked() ), + this, SLOT( removeSelectedContactsFromDistList() ) ); + buttonLayout->addWidget( removeDistListButton ); +#endif + + mFilterSelectionWidget = new FilterSelectionWidget( searchTB , "kde toolbar widget" ); + mViewManager->setFilterSelectionWidget( mFilterSelectionWidget ); + + connect( mFilterSelectionWidget, SIGNAL( filterActivated( int ) ), + mViewManager, SLOT( setActiveFilter( int ) ) ); + + mDetailsWidget = new QWidget( mDetailsSplitter ); + mDetailsLayout = new QHBoxLayout( mDetailsWidget ); + + mDetailsPage = new QWidget( mDetailsWidget ); + mDetailsLayout->addWidget( mDetailsPage ); + + QHBoxLayout *detailsPageLayout = new QHBoxLayout( mDetailsPage, 0, 0 ); + mDetailsViewer = new KPIM::AddresseeView( mDetailsPage ); + mDetailsViewer->setVScrollBarMode( QScrollView::Auto ); + detailsPageLayout->addWidget( mDetailsViewer ); + + mDistListEntryView = new KAB::DistributionListEntryView( this, mWidget ); + connect( mDistListEntryView, SIGNAL( distributionListClicked( const QString& ) ), + this, SLOT( sendMailToDistributionList( const QString& ) ) ); + mDetailsStack->addWidget( mDistListEntryView ); + mDetailsStack->addWidget( mDetailsWidget ); + mDetailsStack->raiseWidget( mDetailsWidget ); + mDetailsSplitter->moveToLast( mDetailsStack ); + + connect( mDetailsViewer, SIGNAL( addressClicked( const QString&) ), + this, SLOT( showContactsAddress( const QString& ) ) ); + + topLayout->setStretchFactor( mDetailsSplitter, 1 ); + + mXXPortManager = new XXPortManager( this, mWidget ); + + initActions(); +} + +void KABCore::createJumpButtonBar() +{ + mJumpButtonBar = new JumpButtonBar( this, mDetailsWidget ); + mDetailsLayout->addWidget( mJumpButtonBar ); + mDetailsLayout->setStretchFactor( mJumpButtonBar, 1 ); + + connect( mJumpButtonBar, SIGNAL( jumpToLetter( const QString& ) ), + SLOT( incrementalJumpButtonSearch( const QString& ) ) ); + connect( mViewManager, SIGNAL( sortFieldChanged() ), + mJumpButtonBar, SLOT( updateButtons() ) ); +} + +void KABCore::initActions() +{ + connect( QApplication::clipboard(), SIGNAL( dataChanged() ), + SLOT( clipboardDataChanged() ) ); + + KAction *action; + + // file menu + mActionMail = new KAction( i18n( "&Send Email to Contact..." ), "mail_send", 0, + this, SLOT( sendMail() ), actionCollection(), "file_mail" ); + action = KStdAction::print( this, SLOT( print() ), actionCollection() ); + mActionMail->setWhatsThis( i18n( "Send a mail to all selected contacts." ) ); + action->setWhatsThis( i18n( "Print a special number of contacts." ) ); + + mActionSave = KStdAction::save( this, + SLOT( save() ), actionCollection(), "file_sync" ); + mActionSave->setWhatsThis( i18n( "Save all changes of the address book to the storage backend." ) ); + + action = new KAction( i18n( "&New Contact..." ), "identity", CTRL+Key_N, this, + SLOT( newContact() ), actionCollection(), "file_new_contact" ); + 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." ) ); + + action = new KAction( i18n( "&New Distribution List..." ), "kontact_contacts", 0, this, + SLOT( newDistributionList() ), actionCollection(), "file_new_distributionlist" ); + action->setWhatsThis( i18n( "Create a new distribution list<p>You will be presented with a dialog where you can create a new distribution list." ) ); + + mActionMailVCard = new KAction( i18n("Send &Contact..."), "mail_post_to", 0, + this, SLOT( mailVCard() ), + actionCollection(), "file_mail_vcard" ); + mActionMailVCard->setWhatsThis( i18n( "Send a mail with the selected contact as attachment." ) ); + + mActionChat = new KAction( i18n("Chat &With..."), 0, + this, SLOT( startChat() ), + actionCollection(), "file_chat" ); + mActionChat->setWhatsThis( i18n( "Start a chat with the selected contact." ) ); + + mActionEditAddressee = new KAction( i18n( "&Edit Contact..." ), "edit", 0, + this, SLOT( editContact() ), + actionCollection(), "file_properties" ); + 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." ) ); + + mActionMerge = new KAction( i18n( "&Merge Contacts" ), "", 0, + this, SLOT( mergeContacts() ), + actionCollection(), "edit_merge" ); + + // edit menu + mActionCopy = KStdAction::copy( this, SLOT( copyContacts() ), actionCollection() ); + mActionCut = KStdAction::cut( this, SLOT( cutContacts() ), actionCollection() ); + mActionPaste = KStdAction::paste( this, SLOT( pasteContacts() ), actionCollection() ); + action = KStdAction::selectAll( this, SLOT( selectAllContacts() ), actionCollection() ); + mActionCopy->setWhatsThis( i18n( "Copy the currently selected contact(s) to system clipboard in vCard format." ) ); + mActionCut->setWhatsThis( i18n( "Cuts the currently selected contact(s) to system clipboard in vCard format." ) ); + mActionPaste->setWhatsThis( i18n( "Paste the previously cut or copied contacts from clipboard." ) ); + action->setWhatsThis( i18n( "Selects all visible contacts from current view." ) ); +// mActionUndo->setWhatsThis( i18n( "Undoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) ); +// mActionRedo->setWhatsThis( i18n( "Redoes the last <b>Cut</b>, <b>Copy</b> or <b>Paste</b>." ) ); + + mActionDelete = new KAction( i18n( "&Delete Contact" ), "editdelete", + Key_Delete, this, SLOT( deleteContacts() ), + actionCollection(), "edit_delete" ); + mActionDelete->setWhatsThis( i18n( "Delete all selected contacts." ) ); + + + mActionCopyAddresseeTo = new KAction( i18n( "&Copy Contact To..." ), "", 0, + this, SLOT( copySelectedContactToResource() ), + actionCollection(), "copy_contact_to" ); + 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." ); + mActionCopyAddresseeTo->setWhatsThis( copyMoveWhatsThis ); + + mActionMoveAddresseeTo = new KAction( i18n( "M&ove Contact To..." ), "", 0, + this, SLOT( moveSelectedContactToResource() ), + actionCollection(), "move_contact_to" ); + mActionMoveAddresseeTo->setWhatsThis( copyMoveWhatsThis ); + + // settings menu + mActionJumpBar = new KToggleAction( i18n( "Show Jump Bar" ), "next", 0, + actionCollection(), "options_show_jump_bar" ); + mActionJumpBar->setWhatsThis( i18n( "Toggle whether the jump button bar shall be visible." ) ); + mActionJumpBar->setCheckedState( i18n( "Hide Jump Bar") ); + connect( mActionJumpBar, SIGNAL( toggled( bool ) ), SLOT( setJumpButtonBarVisible( bool ) ) ); + + mActionDetails = new KToggleAction( i18n( "Show Details" ), 0, 0, + actionCollection(), "options_show_details" ); + mActionDetails->setWhatsThis( i18n( "Toggle whether the details page shall be visible." ) ); + mActionDetails->setCheckedState( i18n( "Hide Details") ); + connect( mActionDetails, SIGNAL( toggled( bool ) ), SLOT( setDetailsVisible( bool ) ) ); + + if ( mIsPart ) + action = new KAction( i18n( "&Configure Address Book..." ), "configure", 0, + this, SLOT( configure() ), actionCollection(), + "kaddressbook_configure" ); + else + action = KStdAction::preferences( this, SLOT( configure() ), actionCollection() ); + + action->setWhatsThis( i18n( "You will be presented with a dialog, that offers you all possibilities to configure KAddressBook." ) ); + + // misc + action = new KAction( i18n( "&Lookup Addresses in LDAP Directory..." ), "find", 0, + this, SLOT( openLDAPDialog() ), actionCollection(), "ldap_lookup" ); + 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." ) ); + + mActionWhoAmI = new KAction( i18n( "Set as Personal Contact Data" ), "personal", 0, this, + SLOT( setWhoAmI() ), actionCollection(), + "edit_set_personal" ); + 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." ) ); + + mActionCategories = new KAction( i18n( "Select Categories..." ), 0, this, + SLOT( setCategories() ), actionCollection(), + "edit_set_categories" ); + mActionCategories->setWhatsThis( i18n( "Set the categories for all selected contacts." ) ); + + KAction *clearLocation = new KAction( i18n( "Clear Search Bar" ), + QApplication::reverseLayout() ? "clear_left" : "locationbar_erase", + CTRL+Key_L, this, SLOT( slotClearSearchBar() ), actionCollection(), "clear_search" ); + clearLocation->setWhatsThis( i18n( "Clear Search Bar<p>" + "Clears the content of the quick search bar." ) ); + + clipboardDataChanged(); +} + +void KABCore::clipboardDataChanged() +{ + if ( mReadWrite ) + mActionPaste->setEnabled( !QApplication::clipboard()->text().isEmpty() ); +} + +void KABCore::updateIncSearchWidget() +{ + mIncSearchWidget->setViewFields( mViewManager->viewFields() ); +} + +void KABCore::updateCategories() +{ + QStringList categories( allCategories() ); + categories.sort(); + + const QStringList customCategories( KABPrefs::instance()->customCategories() ); + QStringList::ConstIterator it; + const QStringList::ConstIterator endIt( customCategories.end() ); + for ( it = customCategories.begin(); it != endIt; ++it ) { + if ( categories.find( *it ) == categories.end() ) { + categories.append( *it ); + } + } + + KABPrefs::instance()->mCustomCategories = categories; + KABPrefs::instance()->writeConfig(); + + if ( mCategoryEditDialog ) + mCategoryEditDialog->reload(); +} + +QStringList KABCore::allCategories() const +{ + QStringList categories, allCategories; + QStringList::ConstIterator catIt; + + KABC::AddressBook::ConstIterator it; + const KABC::AddressBook::ConstIterator endIt( mAddressBook->end() ); + for ( it = mAddressBook->begin(); it != endIt; ++it ) { + categories = (*it).categories(); + const QStringList::ConstIterator catEndIt( categories.end() ); + for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) { + if ( !allCategories.contains( *catIt ) ) + allCategories.append( *catIt ); + } + } + + return allCategories; +} + +void KABCore::setCategories() +{ + // Show the category dialog + if ( mCategorySelectDialog == 0 ) { + mCategorySelectDialog = new KPIM::CategorySelectDialog( KABPrefs::instance(), mWidget ); + connect( mCategorySelectDialog, SIGNAL( categoriesSelected( const QStringList& ) ), + SLOT( categoriesSelected( const QStringList& ) ) ); + connect( mCategorySelectDialog, SIGNAL( editCategories() ), SLOT( editCategories() ) ); + } + + mCategorySelectDialog->show(); + mCategorySelectDialog->raise(); +} + +void KABCore::categoriesSelected( const QStringList &categories ) +{ + bool merge = false; + QString msg = i18n( "Merge with existing categories?" ); + if ( KMessageBox::questionYesNo( mWidget, msg, QString::null, i18n( "Merge" ), i18n( "Do Not Merge" ) ) == KMessageBox::Yes ) + merge = true; + + QStringList uids = mViewManager->selectedUids(); + QStringList::ConstIterator it; + const QStringList::ConstIterator endIt( uids.end() ); + for ( it = uids.begin(); it != endIt; ++it ) { + KABC::Addressee addr = mAddressBook->findByUid( *it ); + if ( !addr.isEmpty() ) { + if ( !merge ) + addr.setCategories( categories ); + else { + QStringList addrCategories = addr.categories(); + QStringList::ConstIterator catIt; + const QStringList::ConstIterator catEndIt( categories.end() ); + for ( catIt = categories.begin(); catIt != catEndIt; ++catIt ) { + if ( !addrCategories.contains( *catIt ) ) + addrCategories.append( *catIt ); + } + addr.setCategories( addrCategories ); + } + + mAddressBook->insertAddressee( addr ); + } + } + + if ( uids.count() > 0 ) + setModified( true ); +} + +void KABCore::editCategories() +{ + if ( mCategoryEditDialog == 0 ) { + mCategoryEditDialog = new KPIM::CategoryEditDialog( KABPrefs::instance(), mWidget ); + connect( mCategoryEditDialog, SIGNAL( categoryConfigChanged() ), + mCategorySelectDialog, SLOT( updateCategoryConfig() ) ); + } + + mCategoryEditDialog->show(); + mCategoryEditDialog->raise(); +} + +void KABCore::slotClearSearchBar() +{ + mIncSearchWidget->clear(); + mIncSearchWidget->setFocus(); +} + +void KABCore::slotContactsUpdated() +{ + if ( mStatusBar ) { + QString msg( i18n( "%n contact matches", "%n contacts matching", mSearchManager->contacts().count() ) ); + if ( !mStatusBar->hasItem( 1 ) ) + mStatusBar->insertItem( msg, 1 ); + else + mStatusBar->changeItem( msg, 1 ); + } + + emit contactsUpdated(); +} + +bool KABCore::handleCommandLine( KAddressBookIface* iface ) +{ + KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); + QCString addrStr = args->getOption( "addr" ); + QCString uidStr = args->getOption( "uid" ); + + QString addr, uid, vcard; + if ( !addrStr.isEmpty() ) + addr = QString::fromLocal8Bit( addrStr ); + if ( !uidStr.isEmpty() ) + uid = QString::fromLocal8Bit( uidStr ); + + bool doneSomething = false; + + // 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 + if ( !addr.isEmpty() ) { + iface->addEmail( addr ); + doneSomething = true; + } + + if ( !uid.isEmpty() ) { + iface->showContactEditor( uid ); + doneSomething = true; + } + + if ( args->isSet( "new-contact" ) ) { + iface->newContact(); + doneSomething = true; + } + + if ( args->count() >= 1 ) { + for ( int i = 0; i < args->count(); ++i ) + iface->importVCard( args->url( i ).url() ); + doneSomething = true; + } + return doneSomething; +} + +void KABCore::removeSelectedContactsFromDistList() +{ +#ifdef KDEPIM_NEW_DISTRLISTS + + KPIM::DistributionList dist = KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList ); + if ( dist.isEmpty() ) + return; + const QStringList uids = selectedUIDs(); + if ( uids.isEmpty() ) + return; + for ( QStringList::ConstIterator it = uids.begin(); it != uids.end(); ++it ) { + dist.removeEntry ( *it ); + } + addressBook()->insertAddressee( dist ); + setModified(); +#endif +} + +void KABCore::sendMailToDistributionList( const QString &name ) +{ +#ifdef KDEPIM_NEW_DISTRLISTS + KPIM::DistributionList dist = KPIM::DistributionList::findByName( addressBook(), name ); + if ( dist.isEmpty() ) + return; + typedef KPIM::DistributionList::Entry::List EntryList; + QStringList mails; + const EntryList entries = dist.entries( addressBook() ); + for ( EntryList::ConstIterator it = entries.begin(); it != entries.end(); ++it ) + mails += (*it).addressee.fullEmail( (*it).email ); + sendMail( mails.join( ", " ) ); +#endif +} + +void KABCore::editSelectedDistributionList() +{ +#ifdef KDEPIM_NEW_DISTRLISTS + editDistributionList( KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList ) ); +#endif +} + + +void KABCore::editDistributionList( const QString &name ) +{ +#ifdef KDEPIM_NEW_DISTRLISTS + editDistributionList( KPIM::DistributionList::findByName( addressBook(), name ) ); +#endif +} + +#ifdef KDEPIM_NEW_DISTRLISTS + +void KABCore::showDistributionListEntry( const QString& uid ) +{ + KPIM::DistributionList dist = KPIM::DistributionList::findByName( addressBook(), mSelectedDistributionList ); + if ( !dist.isEmpty() ) { + mDistListEntryView->clear(); + typedef KPIM::DistributionList::Entry::List EntryList; + const EntryList entries = dist.entries( addressBook() ); + for (EntryList::ConstIterator it = entries.begin(); it != entries.end(); ++it ) { + if ( (*it).addressee.uid() == uid ) { + mDistListEntryView->setEntry( dist, *it ); + break; + } + } + } +} + +void KABCore::editDistributionList( const KPIM::DistributionList &dist ) +{ + if ( dist.isEmpty() ) + return; + QGuardedPtr<KPIM::DistributionListEditor::EditorWidget> dlg = new KPIM::DistributionListEditor::EditorWidget( addressBook(), widget() ); + dlg->setDistributionList( dist ); + if ( dlg->exec() == QDialog::Accepted && dlg ) { + const KPIM::DistributionList newDist = dlg->distributionList(); + if ( newDist != dist ) { + addressBook()->insertAddressee( newDist ); + setModified(); + } + } + delete dlg; +} + + +KPIM::DistributionList::List KABCore::distributionLists() const +{ + return mSearchManager->distributionLists(); +} + +void KABCore::setSelectedDistributionList( const QString &name ) +{ + mSelectedDistributionList = name; + mSearchManager->setSelectedDistributionList( name ); + mViewHeaderLabel->setText( name.isNull() ? i18n( "Contacts" ) : i18n( "Distribution List: %1" ).arg( name ) ); + mDistListButtonWidget->setShown( !mSelectedDistributionList.isNull() ); + if ( !name.isNull() ) { + mDetailsStack->raiseWidget( mDistListEntryView ); + const QStringList selectedUids = selectedUIDs(); + showDistributionListEntry( selectedUids.isEmpty() ? QString() : selectedUids.first() ); + } + else + mDetailsStack->raiseWidget( mExtensionManager->activeDetailsWidget() ? mExtensionManager->activeDetailsWidget() : mDetailsWidget ); +} + +QStringList KABCore::distributionListNames() const +{ + return mSearchManager->distributionListNames(); +} +#endif + +#include "kabcore.moc" |