libkdepim

addressesdialog.cpp

00001 /*  -*- mode: C++; c-file-style: "gnu" -*-
00002  *
00003  *  This file is part of libkdepim.
00004  *
00005  *  Copyright (c) 2003 Zack Rusin <zack@kde.org>
00006  *  Copyright (c) 2003 Aaron J. Seigo <aseigo@kde.org>
00007  *
00008  *  This library is free software; you can redistribute it and/or
00009  *  modify it under the terms of the GNU Library General Public
00010  *  License as published by the Free Software Foundation; either
00011  *  version 2 of the License, or (at your option) any later version.
00012  *
00013  *  This library is distributed in the hope that it will be useful,
00014  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00016  *  Library General Public License for more details.
00017  *
00018  *  You should have received a copy of the GNU Library General Public License
00019  *  along with this library; see the file COPYING.LIB.  If not, write to
00020  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00021  *  Boston, MA 02110-1301, USA.
00022  *
00023  */
00024 
00025 #include "addressesdialog.h"
00026 #include "addresspicker.h"
00027 #include "ldapsearchdialog.h"
00028 
00029 #include <config.h>
00030 
00031 #include <libemailfunctions/email.h>
00032 
00033 #ifdef KDEPIM_NEW_DISTRLISTS
00034 #include "distributionlist.h"
00035 #include <kresources/selectdialog.h>
00036 #include <kabc/resource.h>
00037 #else
00038 #include <kabc/distributionlist.h>
00039 #endif
00040 
00041 #include <kabc/stdaddressbook.h>
00042 #include <kapplication.h>
00043 #include <kdebug.h>
00044 #include <kglobal.h>
00045 #include <kiconloader.h>
00046 #include <kinputdialog.h>
00047 #include <klineedit.h>
00048 #include <klocale.h>
00049 #include <kmessagebox.h>
00050 #include <kprocess.h>
00051 #include <kpushbutton.h>
00052 #include <krun.h>
00053 #include <kstandarddirs.h>
00054 
00055 #include <qdict.h>
00056 #include <qlayout.h>
00057 #include <qvbox.h>
00058 #include <qwidget.h>
00059 
00060 namespace KPIM {
00061 
00062 // private start :
00063 struct AddresseeViewItem::AddresseeViewItemPrivate {
00064   KABC::Addressee               address;
00065   AddresseeViewItem::Category   category;
00066   KABC::Addressee::List         addresses;
00067 };
00068 
00069 struct AddressesDialog::AddressesDialogPrivate {
00070   AddressesDialogPrivate() :
00071     ui(0), personal(0), recent(0),
00072     toItem(0), ccItem(0), bccItem(0),
00073     ldapSearchDialog(0)
00074   {}
00075 
00076   AddressPickerUI             *ui;
00077 
00078   AddresseeViewItem           *personal;
00079   AddresseeViewItem           *recent;
00080 
00081   AddresseeViewItem           *toItem;
00082   AddresseeViewItem           *ccItem;
00083   AddresseeViewItem           *bccItem;
00084 
00085   QDict<AddresseeViewItem>     groupDict;
00086 
00087   KABC::Addressee::List       recentAddresses;
00088   LDAPSearchDialog            *ldapSearchDialog;
00089 };
00090 // privates end
00091 
00092 AddresseeViewItem::AddresseeViewItem( AddresseeViewItem *parent, const KABC::Addressee& addr,
00093                                       int emailIndex )
00094   : QObject( 0 ), KListViewItem( parent, addr.realName(),
00095                                ( emailIndex == 0 ? addr.preferredEmail() : addr.emails()[ emailIndex ] ) )
00096 {
00097   d = new AddresseeViewItemPrivate;
00098   d->address = addr;
00099   d->category = Entry;
00100 
00101   if ( text( 0 ).stripWhiteSpace().isEmpty() )
00102     setText( 0, addr.preferredEmail() );
00103 
00104   if ( addr.photo().url().isEmpty() ) {
00105     if ( addr.photo().data().isNull() )
00106       setPixmap( 0, KGlobal::iconLoader()->loadIcon( "personal", KIcon::Small ) );
00107     else
00108       setPixmap( 0, addr.photo().data().smoothScale( 16, 16 ) );
00109   } else {
00110     setPixmap( 0, KGlobal::iconLoader()->loadIcon( addr.photo().url(), KIcon::Small ) );
00111   }
00112 }
00113 
00114 AddresseeViewItem::AddresseeViewItem( KListView *lv, const QString& name, Category cat )
00115   : QObject(0), KListViewItem( lv, name )
00116 {
00117   d = new AddresseeViewItemPrivate;
00118   d->category = cat;
00119 }
00120 
00121 AddresseeViewItem::AddresseeViewItem(  AddresseeViewItem *parent, const QString& name,
00122                                        const KABC::Addressee::List &lst )
00123   : QObject(0), KListViewItem( parent, name, i18n("<group>") )
00124 {
00125   d = new AddresseeViewItemPrivate;
00126   d->category = FilledGroup;
00127   d->addresses = lst;
00128 }
00129 
00130 AddresseeViewItem::AddresseeViewItem(  AddresseeViewItem *parent, const QString& name )
00131   : QObject(0), KListViewItem( parent, name, i18n("<group>") )
00132 {
00133   d = new AddresseeViewItemPrivate;
00134   d->category = DistList;
00135 
00136   setPixmap( 0, KGlobal::iconLoader()->loadIcon( "kdmconfig", KIcon::Small ) );
00137 }
00138 
00139 AddresseeViewItem::~AddresseeViewItem()
00140 {
00141   delete d;
00142   d = 0;
00143 }
00144 
00145 KABC::Addressee
00146 AddresseeViewItem::addressee() const
00147 {
00148   return d->address;
00149 }
00150 
00151 KABC::Addressee::List
00152 AddresseeViewItem::addresses() const
00153 {
00154   return d->addresses;
00155 }
00156 
00157 AddresseeViewItem::Category
00158 AddresseeViewItem::category() const
00159 {
00160   return d->category;
00161 }
00162 
00163 QString
00164 AddresseeViewItem::name() const
00165 {
00166   return text(0);
00167 }
00168 
00169 QString
00170 AddresseeViewItem::email() const
00171 {
00172   return text(1);
00173 }
00174 
00175 bool AddresseeViewItem::matches(const QString& txt) const
00176 {
00177     return d->address.realName().contains(txt, false) || d->address.preferredEmail().contains(txt, false);
00178 }
00179 
00180 void AddresseeViewItem::setSelected(bool selected)
00181 {
00182     if (selected == isSelected())
00183     {
00184         return;
00185     }
00186 
00187     emit addressSelected( this, selected );
00188     QListViewItem::setSelected(selected);
00189 }
00190 
00191 int
00192 AddresseeViewItem::compare( QListViewItem * i, int col, bool ascending ) const
00193 {
00194   if ( category() == Group || category() == Entry )
00195     return KListViewItem::compare( i , col, ascending );
00196 
00197   AddresseeViewItem *item = static_cast<AddresseeViewItem*>( i );
00198   int a = static_cast<int>( category() );
00199   int b = static_cast<int>( item->category() );
00200 
00201   if ( ascending )
00202     if ( a < b )
00203       return -1;
00204     else
00205       return 1;
00206   else
00207     if ( a < b )
00208       return 1;
00209     else
00210       return -1;
00211 }
00212 
00213 AddressesDialog::AddressesDialog( QWidget *widget, const char *name )
00214   : KDialogBase( widget, name, true, i18n("Address Selection"),
00215                  Ok|Cancel, Ok, true )
00216 {
00217   QVBox *page = makeVBoxMainWidget();
00218   d = new AddressesDialogPrivate;
00219   d->ui = new AddressPickerUI( page );
00220 
00221   KABC::StdAddressBook::self( true );
00222   updateAvailableAddressees();
00223   initConnections();
00224 
00225   d->ui->mAvailableView->setFocus();
00226 }
00227 
00228 AddressesDialog::~AddressesDialog()
00229 {
00230   delete d;
00231   d = 0;
00232 }
00233 
00234 AddresseeViewItem* AddressesDialog::selectedToItem()
00235 {
00236   if ( !d->toItem )
00237   {
00238     d->toItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("To"), AddresseeViewItem::To );
00239     connect(d->toItem, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00240             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00241   }
00242   return d->toItem;
00243 }
00244 
00245 AddresseeViewItem* AddressesDialog::selectedCcItem()
00246 {
00247   if ( !d->ccItem )
00248   {
00249     d->ccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("CC"), AddresseeViewItem::CC );
00250     connect(d->ccItem, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00251             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00252   }
00253   return d->ccItem;
00254 }
00255 
00256 AddresseeViewItem* AddressesDialog::selectedBccItem()
00257 {
00258   if ( !d->bccItem )
00259   {
00260     d->bccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("BCC"), AddresseeViewItem::BCC );
00261     connect(d->bccItem, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00262             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00263   }
00264   return d->bccItem;
00265 }
00266 
00267 void
00268 AddressesDialog::setSelectedTo( const QStringList& l )
00269 {
00270   QString name, email;
00271   for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) {
00272     KABC::Addressee addr;
00273     KABC::Addressee::parseEmailAddress( *it, name, email );
00274     addr.setNameFromString( name );
00275     addr.insertEmail( email );
00276     addAddresseeToSelected( addr, selectedToItem() );
00277   }
00278 }
00279 
00280 void
00281 AddressesDialog::setSelectedCC( const QStringList& l )
00282 {
00283   QString name, email;
00284   for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) {
00285     KABC::Addressee addr;
00286     KABC::Addressee::parseEmailAddress( *it, name, email );
00287     addr.setNameFromString( name );
00288     addr.insertEmail( email );
00289     addAddresseeToSelected( addr, selectedCcItem() );
00290   }
00291 }
00292 
00293 void
00294 AddressesDialog::setSelectedBCC( const QStringList& l )
00295 {
00296   QString name, email;
00297   for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) {
00298     KABC::Addressee addr;
00299     KABC::Addressee::parseEmailAddress( *it, name, email );
00300     addr.setNameFromString( name );
00301     addr.insertEmail( email );
00302     addAddresseeToSelected( addr, selectedBccItem() );
00303   }
00304 }
00305 
00306 void
00307 AddressesDialog::setRecentAddresses( const KABC::Addressee::List& list )
00308 {
00309   d->recentAddresses = list;
00310 
00311   updateRecentAddresses();
00312 
00313   checkForSingleAvailableGroup();
00314 }
00315 
00316 void
00317 AddressesDialog::updateRecentAddresses()
00318 {
00319   static const QString &recentGroup = KGlobal::staticQString( i18n( "Recent Addresses" ) );
00320 
00321   if ( !d->recent ) {
00322     d->recent = new AddresseeViewItem( d->ui->mAvailableView, recentGroup );
00323     connect(d->recent, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00324             this, SLOT(availableAddressSelected(AddresseeViewItem*, bool)));
00325     d->recent->setVisible( false );
00326     d->groupDict.insert( recentGroup, d->recent );
00327   }
00328 
00329   KABC::Addressee::List::ConstIterator it;
00330   for ( it = d->recentAddresses.begin(); it != d->recentAddresses.end(); ++it )
00331     addAddresseeToAvailable( *it, d->recent );
00332 
00333   if ( d->recent->childCount() > 0 ) {
00334     d->recent->setVisible( true );
00335   }
00336 }
00337 
00338 void
00339 AddressesDialog::setShowCC( bool b )
00340 {
00341   d->ui->mCCButton->setShown( b );
00342 }
00343 
00344 void
00345 AddressesDialog::setShowBCC( bool b )
00346 {
00347   d->ui->mBCCButton->setShown( b );
00348 }
00349 
00350 QStringList
00351 AddressesDialog::to() const
00352 {
00353   QStringList emails = allDistributionLists( d->toItem );
00354   KABC::Addressee::List l = toAddresses();
00355   emails += entryToString( l );
00356 
00357   return emails;
00358 }
00359 
00360 QStringList
00361 AddressesDialog::cc() const
00362 {
00363   QStringList emails = allDistributionLists( d->ccItem );
00364   KABC::Addressee::List l = ccAddresses();
00365   emails += entryToString( l );
00366 
00367   return emails;
00368 }
00369 
00370 QStringList
00371 AddressesDialog::bcc() const
00372 {
00373   QStringList emails = allDistributionLists( d->bccItem );
00374 
00375   KABC::Addressee::List l = bccAddresses();
00376   emails += entryToString( l );
00377 
00378   return emails;
00379 }
00380 
00381 KABC::Addressee::List
00382 AddressesDialog::toAddresses()  const
00383 {
00384   return allAddressee( d->toItem );
00385 }
00386 KABC::Addressee::List
00387 AddressesDialog::allToAddressesNoDuplicates()  const
00388 {
00389   KABC::Addressee::List aList = allAddressee( d->toItem );
00390   const QStringList dList = toDistributionLists();
00391   KABC::AddressBook* abook = KABC::StdAddressBook::self( true );
00392 #ifdef KDEPIM_NEW_DISTRLISTS
00393   for ( QStringList::ConstIterator it = dList.begin(); it != dList.end(); ++it ) {
00394     const QValueList<KPIM::DistributionList::Entry> eList
00395       = KPIM::DistributionList::findByName(abook, *it).entries(abook);
00396     QValueList<KPIM::DistributionList::Entry>::ConstIterator eit;
00397     for( eit = eList.begin(); eit != eList.end(); ++eit ) {
00398       KABC::Addressee a = (*eit).addressee;
00399       if ( !a.preferredEmail().isEmpty() && aList.find( a ) == aList.end() ) {
00400           aList.append( a ) ;
00401       }
00402     }
00403   }
00404 #else
00405   KABC::DistributionListManager manager( abook );
00406   manager.load();
00407   for ( QStringList::ConstIterator it = dList.begin(); it != dList.end(); ++it ) {
00408     const QValueList<KABC::DistributionList::Entry> eList = manager.list( *it )->entries();
00409     QValueList<KABC::DistributionList::Entry>::ConstIterator eit;
00410     for( eit = eList.begin(); eit != eList.end(); ++eit ) {
00411       KABC::Addressee a = (*eit).addressee;
00412       if ( !a.preferredEmail().isEmpty() && aList.find( a ) == aList.end() ) {
00413           aList.append( a ) ;
00414       }
00415     }
00416   }
00417 #endif
00418   return aList;
00419 }
00420 
00421 KABC::Addressee::List
00422 AddressesDialog::ccAddresses()  const
00423 {
00424   return allAddressee( d->ccItem );
00425 }
00426 
00427 KABC::Addressee::List
00428 AddressesDialog::bccAddresses()  const
00429 {
00430   return allAddressee( d->bccItem );
00431 }
00432 
00433 
00434 QStringList
00435 AddressesDialog::toDistributionLists() const
00436 {
00437   return allDistributionLists( d->toItem );
00438 }
00439 
00440 QStringList
00441 AddressesDialog::ccDistributionLists() const
00442 {
00443   return allDistributionLists( d->ccItem );
00444 }
00445 
00446 QStringList
00447 AddressesDialog::bccDistributionLists() const
00448 {
00449   return allDistributionLists( d->bccItem );
00450 }
00451 
00452 void
00453 AddressesDialog::updateAvailableAddressees()
00454 {
00455   d->ui->mAvailableView->clear();
00456   d->groupDict.clear();
00457 
00458   static const QString &personalGroup = KGlobal::staticQString( i18n( "Other Addresses" ) );
00459   d->ui->mAvailableView->setRootIsDecorated( true );
00460   d->personal = new AddresseeViewItem( d->ui->mAvailableView, personalGroup );
00461   //connect(d->personal, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00462   //        this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00463   d->personal->setVisible( false );
00464   d->groupDict.insert( personalGroup, d->personal );
00465 
00466   KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true );
00467   for( KABC::AddressBook::Iterator it = addressBook->begin();
00468        it != addressBook->end(); ++it ) {
00469     addAddresseeToAvailable( *it, d->personal );
00470   }
00471 
00472   d->recent = 0;
00473   updateRecentAddresses();
00474 
00475   addDistributionLists();
00476   if ( d->personal->childCount() > 0 ) {
00477     d->personal->setVisible( true );
00478   }
00479 
00480   checkForSingleAvailableGroup();
00481 }
00482 
00483 void AddressesDialog::checkForSingleAvailableGroup()
00484 {
00485   QListViewItem* item = d->ui->mAvailableView->firstChild();
00486   QListViewItem* firstGroup = 0;
00487   int found = 0;
00488   while (item)
00489   {
00490     if (item->isVisible())
00491     {
00492       if (!firstGroup && static_cast<AddresseeViewItem*>(item)->category() != AddresseeViewItem::Entry)
00493       {
00494         firstGroup = item;
00495       }
00496       ++found;
00497     }
00498     item = item->nextSibling();
00499   }
00500 
00501   if (found == 1 && firstGroup)
00502   {
00503     firstGroup->setOpen(true);
00504   }
00505 }
00506 
00507 void
00508 AddressesDialog::availableSelectionChanged()
00509 {
00510   bool selection = !selectedAvailableAddresses.isEmpty();
00511   d->ui->mToButton->setEnabled(selection);
00512   d->ui->mCCButton->setEnabled(selection);
00513   d->ui->mBCCButton->setEnabled(selection);
00514 }
00515 
00516 void
00517 AddressesDialog::selectedSelectionChanged()
00518 {
00519   bool selection = !selectedSelectedAddresses.isEmpty();
00520   d->ui->mRemoveButton->setEnabled(selection);
00521 }
00522 
00523 void
00524 AddressesDialog::availableAddressSelected( AddresseeViewItem* item, bool selected )
00525 {
00526   if (selected)
00527   {
00528     selectedAvailableAddresses.append(item);
00529   }
00530   else
00531   {
00532     selectedAvailableAddresses.remove(item);
00533   }
00534 }
00535 
00536 void
00537 AddressesDialog::selectedAddressSelected( AddresseeViewItem* item, bool selected )
00538 {
00539   // we have to avoid that a parent and a child is selected together
00540   // because in this case we get a double object deletion ( program crashes )
00541   // when removing the selected items from list
00542   AddresseeViewItem* parent = static_cast<AddresseeViewItem*>(((QListViewItem*)item)->parent());
00543   if ( parent  && selected )
00544     parent->setSelected( false );
00545   if (selected)
00546   {
00547     selectedSelectedAddresses.append(item);
00548   }
00549   else
00550   {
00551     selectedSelectedAddresses.remove(item);
00552   }
00553   if ( selected ) {
00554     AddresseeViewItem* child = static_cast<AddresseeViewItem*>(item->firstChild());
00555     while (child) {
00556       child->setSelected( false );
00557       child = static_cast<AddresseeViewItem*>(child->nextSibling());
00558     }
00559   }
00560 }
00561 
00562 void
00563 AddressesDialog::initConnections()
00564 {
00565   connect( d->ui->mFilterEdit, SIGNAL(textChanged(const QString &)),
00566            SLOT(filterChanged(const QString &)) );
00567   connect( d->ui->mToButton, SIGNAL(clicked()),
00568            SLOT(addSelectedTo()) );
00569   connect( d->ui->mCCButton, SIGNAL(clicked()),
00570            SLOT(addSelectedCC()) );
00571   connect( d->ui->mBCCButton, SIGNAL(clicked()),
00572            SLOT(addSelectedBCC())  );
00573   connect( d->ui->mSaveAs, SIGNAL(clicked()),
00574            SLOT(saveAs())  );
00575   connect( d->ui->mLdapSearch, SIGNAL(clicked()),
00576            SLOT(searchLdap())  );
00577   connect( d->ui->mRemoveButton, SIGNAL(clicked()),
00578            SLOT(removeEntry()) );
00579   connect( d->ui->mAvailableView, SIGNAL(selectionChanged()),
00580            SLOT(availableSelectionChanged())  );
00581   connect( d->ui->mAvailableView, SIGNAL(doubleClicked(QListViewItem*)),
00582            SLOT(addSelectedTo()) );
00583   connect( d->ui->mSelectedView, SIGNAL(selectionChanged()),
00584            SLOT(selectedSelectionChanged()) );
00585   connect( d->ui->mSelectedView, SIGNAL(doubleClicked(QListViewItem*)),
00586            SLOT(removeEntry()) );
00587 
00588 #ifndef KDEPIM_NEW_DISTRLISTS
00589   connect( KABC::DistributionListWatcher::self(), SIGNAL( changed() ),
00590            this, SLOT( updateAvailableAddressees() ) );
00591 #endif
00592 
00593   connect( KABC::StdAddressBook::self( true ), SIGNAL( addressBookChanged(AddressBook*) ),
00594            this, SLOT( updateAvailableAddressees() ) );
00595 }
00596 
00597 void
00598 AddressesDialog::addAddresseeToAvailable( const KABC::Addressee& addr, AddresseeViewItem* defaultParent, bool useCategory )
00599 {
00600   if ( addr.preferredEmail().isEmpty() )
00601     return;
00602 
00603   if ( useCategory ) {
00604     QStringList categories = addr.categories();
00605 
00606     for ( QStringList::Iterator it = categories.begin(); it != categories.end(); ++it ) {
00607       if ( !d->groupDict[ *it ] ) {  //we don't have the category yet
00608         AddresseeViewItem* category = new AddresseeViewItem( d->ui->mAvailableView, *it );
00609         d->groupDict.insert( *it,  category );
00610       }
00611 
00612       for ( uint i = 0; i < addr.emails().count(); ++i ) {
00613         AddresseeViewItem* addressee = new AddresseeViewItem( d->groupDict[ *it ], addr, i );
00614         connect(addressee, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00615                 this, SLOT(availableAddressSelected(AddresseeViewItem*, bool)));
00616       }
00617     }
00618   }
00619 
00620   bool noCategory = false;
00621   if ( useCategory ) {
00622     if ( addr.categories().isEmpty() )
00623       noCategory = true;
00624   } else
00625     noCategory = true;
00626 
00627   if ( defaultParent && noCategory ) { // only non-categorized items here
00628     AddresseeViewItem* addressee = new AddresseeViewItem( defaultParent, addr );
00629     connect(addressee, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00630             this, SLOT(availableAddressSelected(AddresseeViewItem*, bool)));
00631   }
00632 }
00633 
00634 void
00635 AddressesDialog::addAddresseeToSelected( const KABC::Addressee& addr, AddresseeViewItem* defaultParent )
00636 {
00637   if ( addr.preferredEmail().isEmpty() )
00638     return;
00639 
00640   if ( defaultParent ) {
00641     AddresseeViewItem *myChild = static_cast<AddresseeViewItem*>( defaultParent->firstChild() );
00642     while( myChild ) {
00643       if ( myChild->addressee().preferredEmail() == addr.preferredEmail() )
00644         return;//already got it
00645       myChild = static_cast<AddresseeViewItem*>( myChild->nextSibling() );
00646     }
00647     AddresseeViewItem* addressee = new AddresseeViewItem( defaultParent, addr );
00648     connect(addressee, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00649             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00650     defaultParent->setOpen( true );
00651   }
00652 
00653   d->ui->mSaveAs->setEnabled(true);
00654 }
00655 
00656 void
00657 AddressesDialog::addAddresseesToSelected( AddresseeViewItem *parent,
00658                                           const QPtrList<AddresseeViewItem>& addresses )
00659 {
00660   Q_ASSERT( parent );
00661 
00662   QPtrListIterator<AddresseeViewItem> itr( addresses );
00663 
00664   if (itr.current())
00665   {
00666     d->ui->mSaveAs->setEnabled(true);
00667   }
00668 
00669   while ( itr.current() ) {
00670     AddresseeViewItem* address = itr.current();
00671     ++itr;
00672 
00673     if (selectedToAvailableMapping.find(address) != 0)
00674     {
00675       continue;
00676     }
00677 
00678     AddresseeViewItem* newItem = 0;
00679     if (address->category() == AddresseeViewItem::Entry)
00680     {
00681       newItem = new AddresseeViewItem( parent, address->addressee() );
00682     }
00683     else if (address->category() == AddresseeViewItem::DistList)
00684     {
00685       newItem = new AddresseeViewItem( parent, address->name() );
00686     }
00687     else
00688     {
00689       newItem = new AddresseeViewItem( parent, address->name(), allAddressee( address ) );
00690     }
00691 
00692     address->setSelected( false );
00693     address->setVisible( false );
00694     selectedToAvailableMapping.insert(address, newItem);
00695     selectedToAvailableMapping.insert(newItem, address);
00696     connect(newItem, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00697             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00698   }
00699 
00700   parent->setOpen( true );
00701 }
00702 
00703 QStringList
00704 AddressesDialog::entryToString( const KABC::Addressee::List& l ) const
00705 {
00706   QStringList entries;
00707 
00708   for( KABC::Addressee::List::ConstIterator it = l.begin(); it != l.end(); ++it ) {
00709     entries += (*it).fullEmail();
00710   }
00711   return entries;
00712 }
00713 
00714 void
00715 AddressesDialog::addSelectedTo()
00716 {
00717   if ( !d->toItem )
00718   {
00719     d->toItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("To"), AddresseeViewItem::To );
00720     connect(d->toItem, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00721             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00722   }
00723 
00724   addAddresseesToSelected( d->toItem, selectedAvailableAddresses );
00725   selectedAvailableAddresses.clear();
00726 
00727   if ( d->toItem->childCount() > 0 )
00728     d->toItem->setVisible( true );
00729   else
00730   {
00731     delete d->toItem;
00732     d->toItem = 0;
00733   }
00734 }
00735 
00736 void
00737 AddressesDialog::addSelectedCC()
00738 {
00739   if ( !d->ccItem )
00740   {
00741     d->ccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("CC"), AddresseeViewItem::CC );
00742     connect(d->ccItem , SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00743             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00744   }
00745 
00746   addAddresseesToSelected( d->ccItem, selectedAvailableAddresses );
00747   selectedAvailableAddresses.clear();
00748 
00749   if ( d->ccItem->childCount() > 0 )
00750     d->ccItem->setVisible( true );
00751   else
00752   {
00753     delete d->ccItem;
00754     d->ccItem = 0;
00755   }
00756 }
00757 
00758 void
00759 AddressesDialog::addSelectedBCC()
00760 {
00761   if ( !d->bccItem )
00762   {
00763     d->bccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("BCC"), AddresseeViewItem::BCC );
00764     connect(d->bccItem , SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00765             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00766   }
00767 
00768   addAddresseesToSelected( d->bccItem, selectedAvailableAddresses );
00769   selectedAvailableAddresses.clear();
00770 
00771   if ( d->bccItem->childCount() > 0 )
00772     d->bccItem->setVisible( true );
00773   else
00774   {
00775     delete d->bccItem;
00776     d->bccItem = 0;
00777   }
00778 }
00779 
00780 void AddressesDialog::unmapSelectedAddress(AddresseeViewItem* item)
00781 {
00782   AddresseeViewItem* correspondingItem = selectedToAvailableMapping[item];
00783   if (correspondingItem)
00784   {
00785     correspondingItem->setVisible( true );
00786     selectedToAvailableMapping.remove( item );
00787     selectedToAvailableMapping.remove( correspondingItem );
00788   }
00789 
00790   AddresseeViewItem* child = static_cast<AddresseeViewItem*>(item->firstChild());
00791   while (child)
00792   {
00793     unmapSelectedAddress(child);
00794     child = static_cast<AddresseeViewItem*>(child->nextSibling());
00795   }
00796 }
00797 
00798 void
00799 AddressesDialog::removeEntry()
00800 {
00801   QPtrList<AddresseeViewItem> lst;
00802   bool resetTo  = false;
00803   bool resetCC  = false;
00804   bool resetBCC = false;
00805 
00806   lst.setAutoDelete( false );
00807   QPtrListIterator<AddresseeViewItem> it( selectedSelectedAddresses );
00808   while ( it.current() ) {
00809     AddresseeViewItem* item = it.current();
00810     ++it;
00811     if ( d->toItem == item )
00812       resetTo = true;
00813     else if ( d->ccItem == item )
00814       resetCC = true;
00815     else if( d->bccItem == item )
00816       resetBCC = true;
00817     // we may only append parent items
00818     unmapSelectedAddress(item);
00819     lst.append( item );
00820   }
00821   selectedSelectedAddresses.clear();
00822   lst.setAutoDelete( true );
00823   lst.clear();
00824   if ( resetTo )
00825     d->toItem  = 0;
00826   else if ( d->toItem && d->toItem->childCount() == 0 )
00827   {
00828     delete d->toItem;
00829     d->toItem = 0;
00830   }
00831   if ( resetCC )
00832     d->ccItem = 0;
00833   else if ( d->ccItem && d->ccItem->childCount() == 0 )
00834   {
00835     delete d->ccItem;
00836     d->ccItem = 0;
00837   }
00838   if ( resetBCC )
00839     d->bccItem  = 0;
00840   else if ( d->bccItem && d->bccItem->childCount() == 0 )
00841   {
00842     delete d->bccItem;
00843     d->bccItem = 0;
00844   }
00845   d->ui->mSaveAs->setEnabled(d->ui->mSelectedView->firstChild() != 0);
00846 }
00847 
00848 #ifdef KDEPIM_NEW_DISTRLISTS
00849 
00850 // copied from kabcore.cpp :(
00851 // KDE4: should be in libkabc I think
00852 static KABC::Resource *requestResource( KABC::AddressBook* abook, QWidget *parent )
00853 {
00854   QPtrList<KABC::Resource> kabcResources = abook->resources();
00855 
00856   QPtrList<KRES::Resource> kresResources;
00857   QPtrListIterator<KABC::Resource> resIt( kabcResources );
00858   KABC::Resource *resource;
00859   while ( ( resource = resIt.current() ) != 0 ) {
00860     ++resIt;
00861     if ( !resource->readOnly() ) {
00862       KRES::Resource *res = static_cast<KRES::Resource*>( resource );
00863       if ( res )
00864         kresResources.append( res );
00865     }
00866   }
00867 
00868   KRES::Resource *res = KRES::SelectDialog::getResource( kresResources, parent );
00869   return static_cast<KABC::Resource*>( res );
00870 }
00871 #endif
00872 
00873 void
00874 AddressesDialog::saveAs()
00875 {
00876 #ifndef KDEPIM_NEW_DISTRLISTS
00877   KABC::DistributionListManager manager( KABC::StdAddressBook::self( true ) );
00878   manager.load();
00879 #endif
00880 
00881   if ( !d->ui->mSelectedView->firstChild() ) {
00882     KMessageBox::information( 0,
00883                               i18n("There are no addresses in your list. "
00884                                    "First add some addresses from your address book, "
00885                                    "then try again.") );
00886     return;
00887   }
00888 
00889   bool ok = false;
00890   QString name = KInputDialog::getText( i18n("New Distribution List"),
00891                                         i18n("Please enter name:"),
00892                                         QString::null, &ok,
00893                                         this );
00894   if ( !ok || name.isEmpty() )
00895     return;
00896 
00897   bool alreadyExists = false;
00898 #ifdef KDEPIM_NEW_DISTRLISTS
00899   KABC::AddressBook* abook = KABC::StdAddressBook::self( true );
00900   KPIM::DistributionList dlist = KPIM::DistributionList::findByName( abook, name );
00901   alreadyExists = !dlist.isEmpty();
00902 #else
00903   alreadyExists = manager.list( name );
00904 #endif
00905 
00906   if ( alreadyExists ) {
00907     KMessageBox::information( 0,
00908                               i18n( "<qt>Distribution list with the given name <b>%1</b> "
00909                                     "already exists. Please select a different name.</qt>" )
00910                               .arg( name ) );
00911     return;
00912   }
00913 
00914 #ifdef KDEPIM_NEW_DISTRLISTS
00915   KABC::Resource* resource = requestResource( abook, this );
00916   if ( !resource )
00917     return;
00918 
00919   dlist.setResource( resource );
00920   dlist.setName( name );
00921   KABC::Addressee::List addrl = allAddressee( d->ui->mSelectedView, false );
00922   for ( KABC::Addressee::List::iterator itr = addrl.begin();
00923         itr != addrl.end(); ++itr ) {
00924     dlist.insertEntry( *itr );
00925   }
00926   abook->insertAddressee( dlist );
00927 #else
00928   KABC::DistributionList *dlist = new KABC::DistributionList( &manager, name );
00929   KABC::Addressee::List addrl = allAddressee( d->ui->mSelectedView, false );
00930   for ( KABC::Addressee::List::iterator itr = addrl.begin();
00931         itr != addrl.end(); ++itr ) {
00932     dlist->insertEntry( *itr );
00933   }
00934 
00935   manager.save();
00936 #endif
00937 }
00938 
00939 void
00940 AddressesDialog::searchLdap()
00941 {
00942     if ( !d->ldapSearchDialog ) {
00943       d->ldapSearchDialog = new LDAPSearchDialog( this );
00944       connect( d->ldapSearchDialog, SIGNAL( addresseesAdded() ),
00945                SLOT(ldapSearchResult() ) );
00946     }
00947     d->ldapSearchDialog->show();
00948 }
00949 
00950 void
00951 AddressesDialog::ldapSearchResult()
00952 {
00953   QStringList emails = KPIM::splitEmailAddrList( d->ldapSearchDialog->selectedEMails() );
00954   QStringList::iterator it( emails.begin() );
00955   QStringList::iterator end( emails.end() );
00956   for ( ; it != end; ++it ){
00957       QString name;
00958       QString email;
00959       KPIM::getNameAndMail( (*it), name, email );
00960       KABC::Addressee ad;
00961       ad.setNameFromString( name );
00962       ad.insertEmail( email );
00963       addAddresseeToSelected( ad, selectedToItem() );
00964   }
00965 }
00966 
00967 void
00968 AddressesDialog::launchAddressBook()
00969 {
00970   kapp->startServiceByDesktopName( "kaddressbook", QString() );
00971 }
00972 
00973 void
00974 AddressesDialog::filterChanged( const QString& txt )
00975 {
00976   QListViewItemIterator it( d->ui->mAvailableView );
00977   bool showAll = false;
00978 
00979   if ( txt.isEmpty() )
00980     showAll = true;
00981 
00982   while ( it.current() ) {
00983     AddresseeViewItem* item = static_cast<AddresseeViewItem*>( it.current() );
00984     ++it;
00985     if ( showAll ) {
00986       item->setVisible( true );
00987       if ( item->category() == AddresseeViewItem::Group )
00988         item->setOpen( false );//close to not have too many entries
00989       continue;
00990     }
00991     if ( item->category() == AddresseeViewItem::Entry ) {
00992       bool matches = item->matches( txt ) ;
00993       item->setVisible( matches );
00994       if ( matches && static_cast<QListViewItem*>(item)->parent() ) {
00995           static_cast<QListViewItem*>(item)->parent()->setOpen( true );//open the parents with found entries
00996       }
00997     }
00998   }
00999 }
01000 
01001 KABC::Addressee::List
01002 AddressesDialog::allAddressee( KListView* view, bool onlySelected ) const
01003 {
01004   KABC::Addressee::List lst;
01005   QListViewItemIterator it( view );
01006   while ( it.current() ) {
01007     AddresseeViewItem* item = static_cast<AddresseeViewItem*>( it.current() );
01008     if ( !onlySelected || item->isSelected() ) {
01009       if ( item->category() != AddresseeViewItem::Entry  ) {
01010         AddresseeViewItem *myChild = static_cast<AddresseeViewItem*>( item->firstChild() );
01011         while( myChild ) {
01012           lst.append( myChild->addressee() );
01013           myChild = static_cast<AddresseeViewItem*>( myChild->nextSibling() );
01014         }
01015       } else {
01016         lst.append( item->addressee() );
01017       }
01018     }
01019     ++it;
01020   }
01021 
01022   return lst;
01023 }
01024 
01025 KABC::Addressee::List
01026 AddressesDialog::allAddressee( AddresseeViewItem* parent ) const
01027 {
01028   KABC::Addressee::List lst;
01029 
01030   if ( !parent ) return lst;
01031 
01032   if ( parent->category() == AddresseeViewItem::Entry )
01033   {
01034     lst.append( parent->addressee() );
01035     return lst;
01036   }
01037 
01038   AddresseeViewItem *myChild = static_cast<AddresseeViewItem*>( parent->firstChild() );
01039   while( myChild ) {
01040     if ( myChild->category() == AddresseeViewItem::FilledGroup )
01041       lst += myChild->addresses();
01042     else if ( !myChild->addressee().isEmpty() )
01043       lst.append( myChild->addressee() );
01044     myChild = static_cast<AddresseeViewItem*>( myChild->nextSibling() );
01045   }
01046 
01047   return lst;
01048 }
01049 
01050 QStringList
01051 AddressesDialog::allDistributionLists( AddresseeViewItem* parent ) const
01052 {
01053   QStringList lists;
01054 
01055   if ( !parent )
01056     return QStringList();
01057 
01058   AddresseeViewItem *item = static_cast<AddresseeViewItem*>( parent->firstChild() );
01059   while ( item ) {
01060     if ( item->category() == AddresseeViewItem::DistList && !item->name().isEmpty() )
01061       lists.append( item->name() );
01062 
01063     item = static_cast<AddresseeViewItem*>( item->nextSibling() );
01064   }
01065 
01066   return lists;
01067 }
01068 
01069 void
01070 AddressesDialog::addDistributionLists()
01071 {
01072   KABC::AddressBook* abook = KABC::StdAddressBook::self( true );
01073 
01074 #ifdef KDEPIM_NEW_DISTRLISTS
01075   const QValueList<KPIM::DistributionList> distLists =
01076     KPIM::DistributionList::allDistributionLists( abook );
01077 #else
01078   KABC::DistributionListManager manager( abook );
01079   manager.load();
01080 
01081   QStringList distLists = manager.listNames();
01082 #endif
01083 
01084   if ( distLists.isEmpty() )
01085     return;
01086 
01087   AddresseeViewItem *topItem = new AddresseeViewItem( d->ui->mAvailableView,
01088                                                       i18n( "Distribution Lists" ) );
01089 
01090 #ifdef KDEPIM_NEW_DISTRLISTS
01091   QValueList<KPIM::DistributionList>::ConstIterator listIt;
01092 #else
01093   QStringList::Iterator listIt;
01094 #endif
01095   for ( listIt = distLists.begin(); listIt != distLists.end(); ++listIt ) {
01096 #ifdef KDEPIM_NEW_DISTRLISTS
01097     KPIM::DistributionList dlist = *listIt;
01098     KPIM::DistributionList::Entry::List entries = dlist.entries(abook);
01099 #else
01100     KABC::DistributionList& dlist = *manager.list( *listIt );
01101     KABC::DistributionList::Entry::List entries = dlist.entries();
01102 #endif
01103 
01104     AddresseeViewItem *item = new AddresseeViewItem( topItem, dlist.name() );
01105     connect( item, SIGNAL( addressSelected( AddresseeViewItem*, bool ) ),
01106              this, SLOT( availableAddressSelected( AddresseeViewItem*, bool ) ) );
01107 
01108 #ifdef KDEPIM_NEW_DISTRLISTS
01109     KPIM::DistributionList::Entry::List::Iterator itemIt;
01110 #else
01111     KABC::DistributionList::Entry::List::Iterator itemIt;
01112 #endif
01113     for ( itemIt = entries.begin(); itemIt != entries.end(); ++itemIt )
01114       addAddresseeToAvailable( (*itemIt).addressee, item, false );
01115   }
01116 }
01117 
01118 } // namespace
01119 
01120 #include "addressesdialog.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys