diff options
Diffstat (limited to 'libtdepim/addressesdialog.cpp')
-rw-r--r-- | libtdepim/addressesdialog.cpp | 1197 |
1 files changed, 1197 insertions, 0 deletions
diff --git a/libtdepim/addressesdialog.cpp b/libtdepim/addressesdialog.cpp new file mode 100644 index 000000000..27f601833 --- /dev/null +++ b/libtdepim/addressesdialog.cpp @@ -0,0 +1,1197 @@ +/* -*- mode: C++; c-file-style: "gnu" -*- + * + * This file is part of libtdepim. + * + * Copyright (c) 2003 Zack Rusin <zack@kde.org> + * Copyright (c) 2003 Aaron J. Seigo <aseigo@kde.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public License + * along with this library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + */ + +#include "addressesdialog.h" +#include "addresspicker.h" +#include "ldapsearchdialog.h" + +#include <config.h> + +#include <libemailfunctions/email.h> + +#ifdef KDEPIM_NEW_DISTRLISTS +#include "distributionlist.h" +#include <kresources/selectdialog.h> +#include <kabc/resource.h> +#else +#include <kabc/distributionlist.h> +#endif + +#include <kabc/stdaddressbook.h> +#include <kapplication.h> +#include <kdebug.h> +#include <kglobal.h> +#include <kiconloader.h> +#include <kinputdialog.h> +#include <klineedit.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kprocess.h> +#include <kpushbutton.h> +#include <krun.h> +#include <kstandarddirs.h> + +#include <tqdict.h> +#include <tqlayout.h> +#include <tqvbox.h> +#include <tqwidget.h> + +namespace KPIM { + +// private start : +struct AddresseeViewItem::AddresseeViewItemPrivate { + KABC::Addressee address; + AddresseeViewItem::Category category; + KABC::Addressee::List addresses; +}; + +struct AddressesDialog::AddressesDialogPrivate { + AddressesDialogPrivate() : + ui(0), personal(0), recent(0), + toItem(0), ccItem(0), bccItem(0), + ldapSearchDialog(0) + {} + + AddressPickerUI *ui; + + AddresseeViewItem *personal; + AddresseeViewItem *recent; + AddresseeViewItem *topdist; + TQPtrList<AddresseeViewItem> dists; + + AddresseeViewItem *toItem; + AddresseeViewItem *ccItem; + AddresseeViewItem *bccItem; + + TQDict<AddresseeViewItem> groupDict; + + KABC::Addressee::List recentAddresses; + LDAPSearchDialog *ldapSearchDialog; +}; +// privates end + +AddresseeViewItem::AddresseeViewItem( AddresseeViewItem *parent, const KABC::Addressee& addr, + int emailIndex ) + : TQObject( 0 ), KListViewItem( parent, addr.realName(), + ( emailIndex == 0 ? addr.preferredEmail() : addr.emails()[ emailIndex ] ) ) +{ + d = new AddresseeViewItemPrivate; + d->address = addr; + d->category = Entry; + + if ( text( 0 ).stripWhiteSpace().isEmpty() ) + setText( 0, addr.preferredEmail() ); + + if ( addr.photo().url().isEmpty() ) { + if ( addr.photo().data().isNull() ) + setPixmap( 0, KGlobal::iconLoader()->loadIcon( "personal", KIcon::Small ) ); + else + setPixmap( 0, addr.photo().data().smoothScale( 16, 16 ) ); + } else { + setPixmap( 0, KGlobal::iconLoader()->loadIcon( addr.photo().url(), KIcon::Small ) ); + } +} + +AddresseeViewItem::AddresseeViewItem( KListView *lv, const TQString& name, Category cat ) + : TQObject(0), KListViewItem( lv, name ) +{ + d = new AddresseeViewItemPrivate; + d->category = cat; +} + +AddresseeViewItem::AddresseeViewItem( AddresseeViewItem *parent, const TQString& name, + const KABC::Addressee::List &lst ) + : TQObject(0), KListViewItem( parent, name, i18n("<group>") ) +{ + d = new AddresseeViewItemPrivate; + d->category = FilledGroup; + d->addresses = lst; +} + +AddresseeViewItem::AddresseeViewItem( AddresseeViewItem *parent, const TQString& name ) + : TQObject(0), KListViewItem( parent, name, i18n("<group>") ) +{ + d = new AddresseeViewItemPrivate; + d->category = DistList; + + setPixmap( 0, KGlobal::iconLoader()->loadIcon( "kdmconfig", KIcon::Small ) ); +} + +AddresseeViewItem::~AddresseeViewItem() +{ + delete d; + d = 0; +} + +KABC::Addressee +AddresseeViewItem::addressee() const +{ + return d->address; +} + +KABC::Addressee::List +AddresseeViewItem::addresses() const +{ + return d->addresses; +} + +AddresseeViewItem::Category +AddresseeViewItem::category() const +{ + return d->category; +} + +TQString +AddresseeViewItem::name() const +{ + return text(0); +} + +TQString +AddresseeViewItem::email() const +{ + return text(1); +} + +bool AddresseeViewItem::matches(const TQString& txt) const +{ + return d->address.realName().contains(txt, false) || d->address.preferredEmail().contains(txt, false); +} + +void AddresseeViewItem::setSelected(bool selected) +{ + if (selected == isSelected()) + { + return; + } + + emit addressSelected( this, selected ); + TQListViewItem::setSelected(selected); +} + +int +AddresseeViewItem::compare( TQListViewItem * i, int col, bool ascending ) const +{ + if ( category() == Group || category() == Entry ) + return KListViewItem::compare( i , col, ascending ); + + AddresseeViewItem *item = static_cast<AddresseeViewItem*>( i ); + int a = static_cast<int>( category() ); + int b = static_cast<int>( item->category() ); + + if ( ascending ) + if ( a < b ) + return -1; + else + return 1; + else + if ( a < b ) + return 1; + else + return -1; +} + +AddressesDialog::AddressesDialog( TQWidget *widget, const char *name ) + : KDialogBase( widget, name, true, i18n("Address Selection"), + Ok|Cancel, Ok, true ) +{ + TQVBox *page = makeVBoxMainWidget(); + d = new AddressesDialogPrivate; + d->ui = new AddressPickerUI( page ); + + KABC::StdAddressBook::self( true ); + updateAvailableAddressees(); + initConnections(); + + d->ui->mAvailableView->setFocus(); + + setMainWidget( page ); + page->setMinimumSize( 750, 400 ); +} + +AddressesDialog::~AddressesDialog() +{ + delete d; + d = 0; +} + +AddresseeViewItem* AddressesDialog::selectedToItem() +{ + if ( !d->toItem ) + { + d->toItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("To"), AddresseeViewItem::To ); + connect(d->toItem, TQT_SIGNAL(addressSelected(AddresseeViewItem*, bool)), + this, TQT_SLOT(selectedAddressSelected(AddresseeViewItem*, bool))); + } + return d->toItem; +} + +AddresseeViewItem* AddressesDialog::selectedCcItem() +{ + if ( !d->ccItem ) + { + d->ccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("CC"), AddresseeViewItem::CC ); + connect(d->ccItem, TQT_SIGNAL(addressSelected(AddresseeViewItem*, bool)), + this, TQT_SLOT(selectedAddressSelected(AddresseeViewItem*, bool))); + } + return d->ccItem; +} + +AddresseeViewItem* AddressesDialog::selectedBccItem() +{ + if ( !d->bccItem ) + { + d->bccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("BCC"), AddresseeViewItem::BCC ); + connect(d->bccItem, TQT_SIGNAL(addressSelected(AddresseeViewItem*, bool)), + this, TQT_SLOT(selectedAddressSelected(AddresseeViewItem*, bool))); + } + return d->bccItem; +} + +void +AddressesDialog::setSelectedTo( const TQStringList& l ) +{ + TQString name, email; + for ( TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) { + KABC::Addressee addr; + KABC::Addressee::parseEmailAddress( *it, name, email ); + addr.setNameFromString( name ); + addr.insertEmail( email ); + addAddresseeToSelected( addr, selectedToItem() ); + } +} + +void +AddressesDialog::setSelectedCC( const TQStringList& l ) +{ + TQString name, email; + for ( TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) { + KABC::Addressee addr; + KABC::Addressee::parseEmailAddress( *it, name, email ); + addr.setNameFromString( name ); + addr.insertEmail( email ); + addAddresseeToSelected( addr, selectedCcItem() ); + } +} + +void +AddressesDialog::setSelectedBCC( const TQStringList& l ) +{ + TQString name, email; + for ( TQStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) { + KABC::Addressee addr; + KABC::Addressee::parseEmailAddress( *it, name, email ); + addr.setNameFromString( name ); + addr.insertEmail( email ); + addAddresseeToSelected( addr, selectedBccItem() ); + } +} + +void +AddressesDialog::setRecentAddresses( const KABC::Addressee::List& list ) +{ + d->recentAddresses = list; + + updateRecentAddresses(); + + checkForSingleAvailableGroup(); +} + +void +AddressesDialog::updateRecentAddresses() +{ + static const TQString &recentGroup = KGlobal::staticQString( i18n( "Recent Addresses" ) ); + + if ( !d->recent ) { + d->recent = new AddresseeViewItem( d->ui->mAvailableView, recentGroup ); + connect(d->recent, TQT_SIGNAL(addressSelected(AddresseeViewItem*, bool)), + this, TQT_SLOT(availableAddressSelected(AddresseeViewItem*, bool))); + d->recent->setVisible( false ); + d->groupDict.insert( recentGroup, d->recent ); + } + + KABC::Addressee::List::ConstIterator it; + for ( it = d->recentAddresses.begin(); it != d->recentAddresses.end(); ++it ) + addAddresseeToAvailable( *it, d->recent ); + + if ( d->recent->childCount() > 0 ) { + d->recent->setOpen( true ); + d->recent->setVisible( true ); + } +} + +void +AddressesDialog::setShowCC( bool b ) +{ + d->ui->mCCButton->setShown( b ); +} + +void +AddressesDialog::setShowBCC( bool b ) +{ + d->ui->mBCCButton->setShown( b ); +} + +TQStringList +AddressesDialog::to() const +{ + TQStringList emails = allDistributionLists( d->toItem ); + KABC::Addressee::List l = toAddresses(); + emails += entryToString( l ); + + return emails; +} + +TQStringList +AddressesDialog::cc() const +{ + TQStringList emails = allDistributionLists( d->ccItem ); + KABC::Addressee::List l = ccAddresses(); + emails += entryToString( l ); + + return emails; +} + +TQStringList +AddressesDialog::bcc() const +{ + TQStringList emails = allDistributionLists( d->bccItem ); + + KABC::Addressee::List l = bccAddresses(); + emails += entryToString( l ); + + return emails; +} + +KABC::Addressee::List +AddressesDialog::toAddresses() const +{ + return allAddressee( d->toItem ); +} +KABC::Addressee::List +AddressesDialog::allToAddressesNoDuplicates() const +{ + KABC::Addressee::List aList = allAddressee( d->toItem ); + const TQStringList dList = toDistributionLists(); + KABC::AddressBook* abook = KABC::StdAddressBook::self( true ); +#ifdef KDEPIM_NEW_DISTRLISTS + for ( TQStringList::ConstIterator it = dList.begin(); it != dList.end(); ++it ) { + const TQValueList<KPIM::DistributionList::Entry> eList + = KPIM::DistributionList::findByName(abook, *it).entries(abook); + TQValueList<KPIM::DistributionList::Entry>::ConstIterator eit; + for( eit = eList.begin(); eit != eList.end(); ++eit ) { + KABC::Addressee a = (*eit).addressee; + if ( !a.preferredEmail().isEmpty() && aList.find( a ) == aList.end() ) { + aList.append( a ) ; + } + } + } +#else + KABC::DistributionListManager manager( abook ); + manager.load(); + for ( TQStringList::ConstIterator it = dList.begin(); it != dList.end(); ++it ) { + const TQValueList<KABC::DistributionList::Entry> eList = manager.list( *it )->entries(); + TQValueList<KABC::DistributionList::Entry>::ConstIterator eit; + for( eit = eList.begin(); eit != eList.end(); ++eit ) { + KABC::Addressee a = (*eit).addressee; + if ( !a.preferredEmail().isEmpty() && aList.find( a ) == aList.end() ) { + aList.append( a ) ; + } + } + } +#endif + return aList; +} + +KABC::Addressee::List +AddressesDialog::ccAddresses() const +{ + return allAddressee( d->ccItem ); +} + +KABC::Addressee::List +AddressesDialog::bccAddresses() const +{ + return allAddressee( d->bccItem ); +} + + +TQStringList +AddressesDialog::toDistributionLists() const +{ + return allDistributionLists( d->toItem ); +} + +TQStringList +AddressesDialog::ccDistributionLists() const +{ + return allDistributionLists( d->ccItem ); +} + +TQStringList +AddressesDialog::bccDistributionLists() const +{ + return allDistributionLists( d->bccItem ); +} + +void +AddressesDialog::updateAvailableAddressees() +{ + d->ui->mAvailableView->clear(); + d->groupDict.clear(); + + static const TQString &personalGroup = KGlobal::staticQString( i18n( "Other Addresses" ) ); + d->ui->mAvailableView->setRootIsDecorated( true ); + d->personal = new AddresseeViewItem( d->ui->mAvailableView, personalGroup ); + //connect(d->personal, TQT_SIGNAL(addressSelected(AddresseeViewItem*, bool)), + // this, TQT_SLOT(selectedAddressSelected(AddresseeViewItem*, bool))); + d->personal->setVisible( false ); + d->groupDict.insert( personalGroup, d->personal ); + + KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true ); + for( KABC::AddressBook::Iterator it = addressBook->begin(); + it != addressBook->end(); ++it ) { + addAddresseeToAvailable( *it, d->personal ); + } + + d->recent = 0; + updateRecentAddresses(); + + d->topdist = 0; + addDistributionLists(); + if ( d->personal->childCount() > 0 ) { + d->personal->setOpen( true ); + d->personal->setVisible( true ); + } + + checkForSingleAvailableGroup(); +} + +void AddressesDialog::checkForSingleAvailableGroup() +{ + TQListViewItem* item = d->ui->mAvailableView->firstChild(); + TQListViewItem* firstGroup = 0; + int found = 0; + while (item) + { + if (item->isVisible()) + { + if (!firstGroup && static_cast<AddresseeViewItem*>(item)->category() != AddresseeViewItem::Entry) + { + firstGroup = item; + } + ++found; + } + item = item->nextSibling(); + } + + if (found == 1 && firstGroup) + { + firstGroup->setOpen(true); + } +} + +void +AddressesDialog::availableSelectionChanged() +{ + bool selection = !selectedAvailableAddresses.isEmpty(); + d->ui->mToButton->setEnabled(selection); + d->ui->mCCButton->setEnabled(selection); + d->ui->mBCCButton->setEnabled(selection); +} + +void +AddressesDialog::selectedSelectionChanged() +{ + bool selection = !selectedSelectedAddresses.isEmpty(); + d->ui->mRemoveButton->setEnabled(selection); +} + +void +AddressesDialog::availableAddressSelected( AddresseeViewItem* item, bool selected ) +{ + if (selected) + { + selectedAvailableAddresses.append(item); + } + else + { + selectedAvailableAddresses.remove(item); + } +} + +void +AddressesDialog::selectedAddressSelected( AddresseeViewItem* item, bool selected ) +{ + // we have to avoid that a parent and a child is selected together + // because in this case we get a double object deletion ( program crashes ) + // when removing the selected items from list + AddresseeViewItem* parent = static_cast<AddresseeViewItem*>(((TQListViewItem*)item)->parent()); + if ( parent && selected ) + parent->setSelected( false ); + if (selected) + { + selectedSelectedAddresses.append(item); + } + else + { + selectedSelectedAddresses.remove(item); + } + if ( selected ) { + AddresseeViewItem* child = static_cast<AddresseeViewItem*>(item->firstChild()); + while (child) { + child->setSelected( false ); + child = static_cast<AddresseeViewItem*>(child->nextSibling()); + } + } +} + +void +AddressesDialog::initConnections() +{ + connect( d->ui->mFilterEdit, TQT_SIGNAL(textChanged(const TQString &)), + TQT_SLOT(filterChanged(const TQString &)) ); + connect( d->ui->mToButton, TQT_SIGNAL(clicked()), + TQT_SLOT(addSelectedTo()) ); + connect( d->ui->mCCButton, TQT_SIGNAL(clicked()), + TQT_SLOT(addSelectedCC()) ); + connect( d->ui->mBCCButton, TQT_SIGNAL(clicked()), + TQT_SLOT(addSelectedBCC()) ); + connect( d->ui->mSaveAs, TQT_SIGNAL(clicked()), + TQT_SLOT(saveAs()) ); + connect( d->ui->mLdapSearch, TQT_SIGNAL(clicked()), + TQT_SLOT(searchLdap()) ); + connect( d->ui->mRemoveButton, TQT_SIGNAL(clicked()), + TQT_SLOT(removeEntry()) ); + connect( d->ui->mAvailableView, TQT_SIGNAL(selectionChanged()), + TQT_SLOT(availableSelectionChanged()) ); + connect( d->ui->mAvailableView, TQT_SIGNAL(doubleClicked(TQListViewItem*)), + TQT_SLOT(addSelectedTo()) ); + connect( d->ui->mSelectedView, TQT_SIGNAL(selectionChanged()), + TQT_SLOT(selectedSelectionChanged()) ); + connect( d->ui->mSelectedView, TQT_SIGNAL(doubleClicked(TQListViewItem*)), + TQT_SLOT(removeEntry()) ); + +#ifndef KDEPIM_NEW_DISTRLISTS + connect( KABC::DistributionListWatcher::self(), TQT_SIGNAL( changed() ), + this, TQT_SLOT( updateAvailableAddressees() ) ); +#endif + + connect( KABC::StdAddressBook::self( true ), TQT_SIGNAL( addressBookChanged(AddressBook*) ), + this, TQT_SLOT( updateAvailableAddressees() ) ); +} + +void +AddressesDialog::addAddresseeToAvailable( const KABC::Addressee& addr, AddresseeViewItem* defaultParent, bool useCategory ) +{ + if ( addr.preferredEmail().isEmpty() ) + return; + + if ( useCategory ) { + TQStringList categories = addr.categories(); + + for ( TQStringList::Iterator it = categories.begin(); it != categories.end(); ++it ) { + if ( !d->groupDict[ *it ] ) { //we don't have the category yet + AddresseeViewItem* category = new AddresseeViewItem( d->ui->mAvailableView, *it ); + d->groupDict.insert( *it, category ); + } + + for ( uint i = 0; i < addr.emails().count(); ++i ) { + AddresseeViewItem* addressee = new AddresseeViewItem( d->groupDict[ *it ], addr, i ); + connect(addressee, TQT_SIGNAL(addressSelected(AddresseeViewItem*, bool)), + this, TQT_SLOT(availableAddressSelected(AddresseeViewItem*, bool))); + } + } + } + + bool noCategory = false; + if ( useCategory ) { + if ( addr.categories().isEmpty() ) + noCategory = true; + } else + noCategory = true; + + if ( defaultParent && noCategory ) { // only non-categorized items here + AddresseeViewItem* addressee = new AddresseeViewItem( defaultParent, addr ); + connect(addressee, TQT_SIGNAL(addressSelected(AddresseeViewItem*, bool)), + this, TQT_SLOT(availableAddressSelected(AddresseeViewItem*, bool))); + } +} + +void +AddressesDialog::addAddresseeToSelected( const KABC::Addressee& addr, AddresseeViewItem* defaultParent ) +{ + if ( addr.preferredEmail().isEmpty() ) + return; + + if ( defaultParent ) { + AddresseeViewItem *myChild = static_cast<AddresseeViewItem*>( defaultParent->firstChild() ); + while( myChild ) { + if ( myChild->addressee().preferredEmail() == addr.preferredEmail() ) + return;//already got it + myChild = static_cast<AddresseeViewItem*>( myChild->nextSibling() ); + } + AddresseeViewItem* addressee = new AddresseeViewItem( defaultParent, addr ); + connect(addressee, TQT_SIGNAL(addressSelected(AddresseeViewItem*, bool)), + this, TQT_SLOT(selectedAddressSelected(AddresseeViewItem*, bool))); + defaultParent->setOpen( true ); + } + + d->ui->mSaveAs->setEnabled(true); +} + +void +AddressesDialog::addAddresseesToSelected( AddresseeViewItem *parent, + const TQPtrList<AddresseeViewItem>& addresses ) +{ + Q_ASSERT( parent ); + + TQPtrListIterator<AddresseeViewItem> itr( addresses ); + + if (itr.current()) + { + d->ui->mSaveAs->setEnabled(true); + } + + while ( itr.current() ) { + AddresseeViewItem* address = itr.current(); + ++itr; + + if (selectedToAvailableMapping.find(address) != 0) + { + continue; + } + + AddresseeViewItem* newItem = 0; + if (address->category() == AddresseeViewItem::Entry) + { + newItem = new AddresseeViewItem( parent, address->addressee() ); + } + else if (address->category() == AddresseeViewItem::DistList) + { + newItem = new AddresseeViewItem( parent, address->name() ); + } + else + { + newItem = new AddresseeViewItem( parent, address->name(), allAddressee( address ) ); + } + + address->setSelected( false ); + address->setVisible( false ); + selectedToAvailableMapping.insert(address, newItem); + selectedToAvailableMapping.insert(newItem, address); + connect(newItem, TQT_SIGNAL(addressSelected(AddresseeViewItem*, bool)), + this, TQT_SLOT(selectedAddressSelected(AddresseeViewItem*, bool))); + } + + parent->setOpen( true ); +} + +TQStringList +AddressesDialog::entryToString( const KABC::Addressee::List& l ) const +{ + TQStringList entries; + + for( KABC::Addressee::List::ConstIterator it = l.begin(); it != l.end(); ++it ) { + entries += (*it).fullEmail(); + } + return entries; +} + +void +AddressesDialog::addSelectedTo() +{ + if ( !d->toItem ) + { + d->toItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("To"), AddresseeViewItem::To ); + connect(d->toItem, TQT_SIGNAL(addressSelected(AddresseeViewItem*, bool)), + this, TQT_SLOT(selectedAddressSelected(AddresseeViewItem*, bool))); + } + + addAddresseesToSelected( d->toItem, selectedAvailableAddresses ); + selectedAvailableAddresses.clear(); + + if ( d->toItem->childCount() > 0 ) { + d->toItem->setVisible( true ); + } else { + delete d->toItem; + d->toItem = 0; + } +} + +void +AddressesDialog::addSelectedCC() +{ + if ( !d->ccItem ) + { + d->ccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("CC"), AddresseeViewItem::CC ); + connect(d->ccItem , TQT_SIGNAL(addressSelected(AddresseeViewItem*, bool)), + this, TQT_SLOT(selectedAddressSelected(AddresseeViewItem*, bool))); + } + + addAddresseesToSelected( d->ccItem, selectedAvailableAddresses ); + selectedAvailableAddresses.clear(); + + if ( d->ccItem->childCount() > 0 ) { + d->ccItem->setVisible( true ); + } else { + delete d->ccItem; + d->ccItem = 0; + } +} + +void +AddressesDialog::addSelectedBCC() +{ + if ( !d->bccItem ) + { + d->bccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("BCC"), AddresseeViewItem::BCC ); + connect(d->bccItem , TQT_SIGNAL(addressSelected(AddresseeViewItem*, bool)), + this, TQT_SLOT(selectedAddressSelected(AddresseeViewItem*, bool))); + } + + addAddresseesToSelected( d->bccItem, selectedAvailableAddresses ); + selectedAvailableAddresses.clear(); + + if ( d->bccItem->childCount() > 0 ) { + d->bccItem->setVisible( true ); + } else { + delete d->bccItem; + d->bccItem = 0; + } +} + +void AddressesDialog::unmapSelectedAddress(AddresseeViewItem* item) +{ + AddresseeViewItem* correspondingItem = selectedToAvailableMapping[item]; + if (correspondingItem) + { + correspondingItem->setVisible( true ); + selectedToAvailableMapping.remove( item ); + selectedToAvailableMapping.remove( correspondingItem ); + } + + AddresseeViewItem* child = static_cast<AddresseeViewItem*>(item->firstChild()); + while (child) + { + unmapSelectedAddress(child); + child = static_cast<AddresseeViewItem*>(child->nextSibling()); + } +} + +void +AddressesDialog::removeEntry() +{ + TQPtrList<AddresseeViewItem> lst; + bool resetTo = false; + bool resetCC = false; + bool resetBCC = false; + + lst.setAutoDelete( false ); + TQPtrListIterator<AddresseeViewItem> it( selectedSelectedAddresses ); + while ( it.current() ) { + AddresseeViewItem* item = it.current(); + ++it; + if ( d->toItem == item ) + resetTo = true; + else if ( d->ccItem == item ) + resetCC = true; + else if( d->bccItem == item ) + resetBCC = true; + // we may only append parent items + unmapSelectedAddress(item); + lst.append( item ); + } + selectedSelectedAddresses.clear(); + lst.setAutoDelete( true ); + lst.clear(); + if ( resetTo ) + d->toItem = 0; + else if ( d->toItem && d->toItem->childCount() == 0 ) + { + delete d->toItem; + d->toItem = 0; + } + if ( resetCC ) + d->ccItem = 0; + else if ( d->ccItem && d->ccItem->childCount() == 0 ) + { + delete d->ccItem; + d->ccItem = 0; + } + if ( resetBCC ) + d->bccItem = 0; + else if ( d->bccItem && d->bccItem->childCount() == 0 ) + { + delete d->bccItem; + d->bccItem = 0; + } + d->ui->mSaveAs->setEnabled(d->ui->mSelectedView->firstChild() != 0); +} + +#ifdef KDEPIM_NEW_DISTRLISTS + +// copied from kabcore.cpp :( +// KDE4: should be in libkabc I think +static KABC::Resource *requestResource( KABC::AddressBook* abook, TQWidget *parent ) +{ + TQPtrList<KABC::Resource> kabcResources = abook->resources(); + + TQPtrList<KRES::Resource> kresResources; + TQPtrListIterator<KABC::Resource> resIt( kabcResources ); + KABC::Resource *resource; + while ( ( resource = resIt.current() ) != 0 ) { + ++resIt; + if ( !resource->readOnly() ) { + KRES::Resource *res = static_cast<KRES::Resource*>( resource ); + if ( res ) + kresResources.append( res ); + } + } + + KRES::Resource *res = KRES::SelectDialog::getResource( kresResources, parent ); + return static_cast<KABC::Resource*>( res ); +} +#endif + +void +AddressesDialog::saveAs() +{ +#ifndef KDEPIM_NEW_DISTRLISTS + KABC::DistributionListManager manager( KABC::StdAddressBook::self( true ) ); + manager.load(); +#endif + + if ( !d->ui->mSelectedView->firstChild() ) { + KMessageBox::information( 0, + i18n("There are no addresses in your list. " + "First add some addresses from your address book, " + "then try again.") ); + return; + } + + bool ok = false; + TQString name = KInputDialog::getText( i18n("New Distribution List"), + i18n("Please enter name:"), + TQString(), &ok, + this ); + if ( !ok || name.isEmpty() ) + return; + + bool alreadyExists = false; +#ifdef KDEPIM_NEW_DISTRLISTS + KABC::AddressBook* abook = KABC::StdAddressBook::self( true ); + KPIM::DistributionList dlist = KPIM::DistributionList::findByName( abook, name ); + alreadyExists = !dlist.isEmpty(); +#else + alreadyExists = manager.list( name ); +#endif + + if ( alreadyExists ) { + KMessageBox::information( 0, + i18n( "<qt>Distribution list with the given name <b>%1</b> " + "already exists. Please select a different name.</qt>" ) + .tqarg( name ) ); + return; + } + +#ifdef KDEPIM_NEW_DISTRLISTS + KABC::Resource* resource = requestResource( abook, this ); + if ( !resource ) + return; + + dlist.setResource( resource ); + dlist.setName( name ); + KABC::Addressee::List addrl = allAddressee( d->ui->mSelectedView, false ); + for ( KABC::Addressee::List::iterator itr = addrl.begin(); + itr != addrl.end(); ++itr ) { + dlist.insertEntry( *itr ); + } + abook->insertAddressee( dlist ); +#else + KABC::DistributionList *dlist = new KABC::DistributionList( &manager, name ); + KABC::Addressee::List addrl = allAddressee( d->ui->mSelectedView, false ); + for ( KABC::Addressee::List::iterator itr = addrl.begin(); + itr != addrl.end(); ++itr ) { + dlist->insertEntry( *itr ); + } + + manager.save(); +#endif +} + +void +AddressesDialog::searchLdap() +{ + if ( !d->ldapSearchDialog ) { + d->ldapSearchDialog = new LDAPSearchDialog( this ); + connect( d->ldapSearchDialog, TQT_SIGNAL( addresseesAdded() ), + TQT_SLOT(ldapSearchResult() ) ); + } + d->ldapSearchDialog->show(); +} + +void +AddressesDialog::ldapSearchResult() +{ + TQStringList emails = KPIM::splitEmailAddrList( d->ldapSearchDialog->selectedEMails() ); + TQStringList::iterator it( emails.begin() ); + TQStringList::iterator end( emails.end() ); + for ( ; it != end; ++it ){ + TQString name; + TQString email; + KPIM::getNameAndMail( (*it), name, email ); + KABC::Addressee ad; + ad.setNameFromString( name ); + ad.insertEmail( email ); + addAddresseeToSelected( ad, selectedToItem() ); + } +} + +void +AddressesDialog::launchAddressBook() +{ + kapp->startServiceByDesktopName( "kaddressbook", TQString() ); +} + +void +AddressesDialog::filterChanged( const TQString& txt ) +{ + TQListViewItemIterator it( d->ui->mAvailableView ); + bool showAll = false; + + if ( txt.isEmpty() ) + showAll = true; + + int personalVisible = 0; + int recentVisible = 0; + while ( it.current() ) { + AddresseeViewItem* item = static_cast<AddresseeViewItem*>( it.current() ); + ++it; + + if ( showAll ) { + item->setOpen( true ); + item->setVisible( true ); + // allen: I do not like the following behavior. comment out and see if anyone screams + //if ( item->category() == AddresseeViewItem::Group ) + // item->setOpen( false );//close to not have too many entries + continue; + } + + if ( item->category() == AddresseeViewItem::Entry ) { + bool matches = item->matches( txt ); + item->setVisible( matches ); + TQListViewItem *parent = static_cast<TQListViewItem*>( item )->parent(); + if ( matches && parent ) { + if ( parent == d->personal ) { + personalVisible++; + } else if ( parent == d->recent ) { + recentVisible++; + } + } + } + if ( item->category() == AddresseeViewItem::Group ) { + item->setOpen( true ); + item->setVisible( true ); + } + } + + if ( !showAll && personalVisible == 0 ) { + d->personal->setOpen( false ); + d->personal->setVisible( false ); + } + if ( !showAll && recentVisible == 0 ) { + d->recent->setOpen( false ); + d->recent->setVisible( false ); + } + + int distlistgroupVisible = 0; + if ( !showAll ) { + TQPtrListIterator<AddresseeViewItem> it( d->dists ); + for ( ; it.current(); ++it ) { + TQListViewItem *p = *it; + p->setVisible( true ); + AddresseeViewItem *p2 = static_cast<AddresseeViewItem*>( p->firstChild() ); + int pcount = 0; + while ( p2 ) { + if ( p2->matches( txt ) ) { + p2->setVisible( true ); + pcount++; + } else { + p2->setVisible( false ); + } + p2 = static_cast<AddresseeViewItem*>( p2->nextSibling() ); + } + if ( !pcount && !p->text( 0 ).contains( txt, false ) ) { + p->setVisible( false ); + } + distlistgroupVisible += pcount; + if ( p->text( 0 ).contains( txt, false ) ) { + distlistgroupVisible++; + } + } + } + if ( d->topdist ) { + if ( showAll || distlistgroupVisible > 0 ) { + d->topdist->setOpen( true ); + } else { + d->topdist->setOpen( false ); + d->topdist->setVisible( false ); + } + } +} + +KABC::Addressee::List +AddressesDialog::allAddressee( KListView* view, bool onlySelected ) const +{ + KABC::Addressee::List lst; + TQListViewItemIterator it( view ); + while ( it.current() ) { + AddresseeViewItem* item = static_cast<AddresseeViewItem*>( it.current() ); + if ( !onlySelected || item->isSelected() ) { + if ( item->category() != AddresseeViewItem::Entry ) { + AddresseeViewItem *myChild = static_cast<AddresseeViewItem*>( item->firstChild() ); + while( myChild ) { + lst.append( myChild->addressee() ); + myChild = static_cast<AddresseeViewItem*>( myChild->nextSibling() ); + } + } else { + lst.append( item->addressee() ); + } + } + ++it; + } + + return lst; +} + +KABC::Addressee::List +AddressesDialog::allAddressee( AddresseeViewItem* parent ) const +{ + KABC::Addressee::List lst; + + if ( !parent ) return lst; + + if ( parent->category() == AddresseeViewItem::Entry ) + { + lst.append( parent->addressee() ); + return lst; + } + + AddresseeViewItem *myChild = static_cast<AddresseeViewItem*>( parent->firstChild() ); + while( myChild ) { + if ( myChild->category() == AddresseeViewItem::FilledGroup ) + lst += myChild->addresses(); + else if ( !myChild->addressee().isEmpty() ) + lst.append( myChild->addressee() ); + myChild = static_cast<AddresseeViewItem*>( myChild->nextSibling() ); + } + + return lst; +} + +TQStringList +AddressesDialog::allDistributionLists( AddresseeViewItem* parent ) const +{ + TQStringList lists; + + if ( !parent ) + return TQStringList(); + + AddresseeViewItem *item = static_cast<AddresseeViewItem*>( parent->firstChild() ); + while ( item ) { + if ( item->category() == AddresseeViewItem::DistList && !item->name().isEmpty() ) + lists.append( item->name() ); + + item = static_cast<AddresseeViewItem*>( item->nextSibling() ); + } + + return lists; +} + +void +AddressesDialog::addDistributionLists() +{ + KABC::AddressBook* abook = KABC::StdAddressBook::self( true ); + +#ifdef KDEPIM_NEW_DISTRLISTS + const TQValueList<KPIM::DistributionList> distLists = + KPIM::DistributionList::allDistributionLists( abook ); +#else + KABC::DistributionListManager manager( abook ); + manager.load(); + + TQStringList distLists = manager.listNames(); +#endif + + if ( distLists.isEmpty() ) + return; + + if ( !d->topdist ) { + d->topdist = new AddresseeViewItem( d->ui->mAvailableView, i18n( "Distribution Lists" ) ); + } + +#ifdef KDEPIM_NEW_DISTRLISTS + TQValueList<KPIM::DistributionList>::ConstIterator listIt; +#else + TQStringList::Iterator listIt; +#endif + int total = 0; + for ( listIt = distLists.begin(); listIt != distLists.end(); ++listIt ) { +#ifdef KDEPIM_NEW_DISTRLISTS + KPIM::DistributionList dlist = *listIt; + KPIM::DistributionList::Entry::List entries = dlist.entries(abook); +#else + KABC::DistributionList& dlist = *manager.list( *listIt ); + KABC::DistributionList::Entry::List entries = dlist.entries(); +#endif + + AddresseeViewItem *item = new AddresseeViewItem( d->topdist, dlist.name() ); + d->dists.append( item ); + connect( item, TQT_SIGNAL( addressSelected( AddresseeViewItem*, bool ) ), + this, TQT_SLOT( availableAddressSelected( AddresseeViewItem*, bool ) ) ); + +#ifdef KDEPIM_NEW_DISTRLISTS + KPIM::DistributionList::Entry::List::Iterator itemIt; +#else + KABC::DistributionList::Entry::List::Iterator itemIt; +#endif + for ( itemIt = entries.begin(); itemIt != entries.end(); ++itemIt ) { + addAddresseeToAvailable( (*itemIt).addressee, item, false ); + } + if ( item->childCount() > 0 ) { + item->setOpen( true ); + item->setVisible( true ); + } + total += item->childCount(); + } + if ( total > 0 ) { + d->topdist->setOpen( true ); + d->topdist->setVisible( true ); + } +} + +} // namespace + +#include "addressesdialog.moc" |