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   setMainWidget( page );
00228   page->setMinimumSize( 750, 400 );
00229 }
00230 
00231 AddressesDialog::~AddressesDialog()
00232 {
00233   delete d;
00234   d = 0;
00235 }
00236 
00237 AddresseeViewItem* AddressesDialog::selectedToItem()
00238 {
00239   if ( !d->toItem )
00240   {
00241     d->toItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("To"), AddresseeViewItem::To );
00242     connect(d->toItem, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00243             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00244   }
00245   return d->toItem;
00246 }
00247 
00248 AddresseeViewItem* AddressesDialog::selectedCcItem()
00249 {
00250   if ( !d->ccItem )
00251   {
00252     d->ccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("CC"), AddresseeViewItem::CC );
00253     connect(d->ccItem, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00254             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00255   }
00256   return d->ccItem;
00257 }
00258 
00259 AddresseeViewItem* AddressesDialog::selectedBccItem()
00260 {
00261   if ( !d->bccItem )
00262   {
00263     d->bccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("BCC"), AddresseeViewItem::BCC );
00264     connect(d->bccItem, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00265             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00266   }
00267   return d->bccItem;
00268 }
00269 
00270 void
00271 AddressesDialog::setSelectedTo( const QStringList& l )
00272 {
00273   QString name, email;
00274   for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) {
00275     KABC::Addressee addr;
00276     KABC::Addressee::parseEmailAddress( *it, name, email );
00277     addr.setNameFromString( name );
00278     addr.insertEmail( email );
00279     addAddresseeToSelected( addr, selectedToItem() );
00280   }
00281 }
00282 
00283 void
00284 AddressesDialog::setSelectedCC( const QStringList& l )
00285 {
00286   QString name, email;
00287   for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) {
00288     KABC::Addressee addr;
00289     KABC::Addressee::parseEmailAddress( *it, name, email );
00290     addr.setNameFromString( name );
00291     addr.insertEmail( email );
00292     addAddresseeToSelected( addr, selectedCcItem() );
00293   }
00294 }
00295 
00296 void
00297 AddressesDialog::setSelectedBCC( const QStringList& l )
00298 {
00299   QString name, email;
00300   for ( QStringList::ConstIterator it = l.begin(); it != l.end(); ++it ) {
00301     KABC::Addressee addr;
00302     KABC::Addressee::parseEmailAddress( *it, name, email );
00303     addr.setNameFromString( name );
00304     addr.insertEmail( email );
00305     addAddresseeToSelected( addr, selectedBccItem() );
00306   }
00307 }
00308 
00309 void
00310 AddressesDialog::setRecentAddresses( const KABC::Addressee::List& list )
00311 {
00312   d->recentAddresses = list;
00313 
00314   updateRecentAddresses();
00315 
00316   checkForSingleAvailableGroup();
00317 }
00318 
00319 void
00320 AddressesDialog::updateRecentAddresses()
00321 {
00322   static const QString &recentGroup = KGlobal::staticQString( i18n( "Recent Addresses" ) );
00323 
00324   if ( !d->recent ) {
00325     d->recent = new AddresseeViewItem( d->ui->mAvailableView, recentGroup );
00326     connect(d->recent, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00327             this, SLOT(availableAddressSelected(AddresseeViewItem*, bool)));
00328     d->recent->setVisible( false );
00329     d->groupDict.insert( recentGroup, d->recent );
00330   }
00331 
00332   KABC::Addressee::List::ConstIterator it;
00333   for ( it = d->recentAddresses.begin(); it != d->recentAddresses.end(); ++it )
00334     addAddresseeToAvailable( *it, d->recent );
00335 
00336   if ( d->recent->childCount() > 0 ) {
00337     d->recent->setVisible( true );
00338   }
00339 }
00340 
00341 void
00342 AddressesDialog::setShowCC( bool b )
00343 {
00344   d->ui->mCCButton->setShown( b );
00345 }
00346 
00347 void
00348 AddressesDialog::setShowBCC( bool b )
00349 {
00350   d->ui->mBCCButton->setShown( b );
00351 }
00352 
00353 QStringList
00354 AddressesDialog::to() const
00355 {
00356   QStringList emails = allDistributionLists( d->toItem );
00357   KABC::Addressee::List l = toAddresses();
00358   emails += entryToString( l );
00359 
00360   return emails;
00361 }
00362 
00363 QStringList
00364 AddressesDialog::cc() const
00365 {
00366   QStringList emails = allDistributionLists( d->ccItem );
00367   KABC::Addressee::List l = ccAddresses();
00368   emails += entryToString( l );
00369 
00370   return emails;
00371 }
00372 
00373 QStringList
00374 AddressesDialog::bcc() const
00375 {
00376   QStringList emails = allDistributionLists( d->bccItem );
00377 
00378   KABC::Addressee::List l = bccAddresses();
00379   emails += entryToString( l );
00380 
00381   return emails;
00382 }
00383 
00384 KABC::Addressee::List
00385 AddressesDialog::toAddresses()  const
00386 {
00387   return allAddressee( d->toItem );
00388 }
00389 KABC::Addressee::List
00390 AddressesDialog::allToAddressesNoDuplicates()  const
00391 {
00392   KABC::Addressee::List aList = allAddressee( d->toItem );
00393   const QStringList dList = toDistributionLists();
00394   KABC::AddressBook* abook = KABC::StdAddressBook::self( true );
00395 #ifdef KDEPIM_NEW_DISTRLISTS
00396   for ( QStringList::ConstIterator it = dList.begin(); it != dList.end(); ++it ) {
00397     const QValueList<KPIM::DistributionList::Entry> eList
00398       = KPIM::DistributionList::findByName(abook, *it).entries(abook);
00399     QValueList<KPIM::DistributionList::Entry>::ConstIterator eit;
00400     for( eit = eList.begin(); eit != eList.end(); ++eit ) {
00401       KABC::Addressee a = (*eit).addressee;
00402       if ( !a.preferredEmail().isEmpty() && aList.find( a ) == aList.end() ) {
00403           aList.append( a ) ;
00404       }
00405     }
00406   }
00407 #else
00408   KABC::DistributionListManager manager( abook );
00409   manager.load();
00410   for ( QStringList::ConstIterator it = dList.begin(); it != dList.end(); ++it ) {
00411     const QValueList<KABC::DistributionList::Entry> eList = manager.list( *it )->entries();
00412     QValueList<KABC::DistributionList::Entry>::ConstIterator eit;
00413     for( eit = eList.begin(); eit != eList.end(); ++eit ) {
00414       KABC::Addressee a = (*eit).addressee;
00415       if ( !a.preferredEmail().isEmpty() && aList.find( a ) == aList.end() ) {
00416           aList.append( a ) ;
00417       }
00418     }
00419   }
00420 #endif
00421   return aList;
00422 }
00423 
00424 KABC::Addressee::List
00425 AddressesDialog::ccAddresses()  const
00426 {
00427   return allAddressee( d->ccItem );
00428 }
00429 
00430 KABC::Addressee::List
00431 AddressesDialog::bccAddresses()  const
00432 {
00433   return allAddressee( d->bccItem );
00434 }
00435 
00436 
00437 QStringList
00438 AddressesDialog::toDistributionLists() const
00439 {
00440   return allDistributionLists( d->toItem );
00441 }
00442 
00443 QStringList
00444 AddressesDialog::ccDistributionLists() const
00445 {
00446   return allDistributionLists( d->ccItem );
00447 }
00448 
00449 QStringList
00450 AddressesDialog::bccDistributionLists() const
00451 {
00452   return allDistributionLists( d->bccItem );
00453 }
00454 
00455 void
00456 AddressesDialog::updateAvailableAddressees()
00457 {
00458   d->ui->mAvailableView->clear();
00459   d->groupDict.clear();
00460 
00461   static const QString &personalGroup = KGlobal::staticQString( i18n( "Other Addresses" ) );
00462   d->ui->mAvailableView->setRootIsDecorated( true );
00463   d->personal = new AddresseeViewItem( d->ui->mAvailableView, personalGroup );
00464   //connect(d->personal, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00465   //        this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00466   d->personal->setVisible( false );
00467   d->groupDict.insert( personalGroup, d->personal );
00468 
00469   KABC::AddressBook *addressBook = KABC::StdAddressBook::self( true );
00470   for( KABC::AddressBook::Iterator it = addressBook->begin();
00471        it != addressBook->end(); ++it ) {
00472     addAddresseeToAvailable( *it, d->personal );
00473   }
00474 
00475   d->recent = 0;
00476   updateRecentAddresses();
00477 
00478   addDistributionLists();
00479   if ( d->personal->childCount() > 0 ) {
00480     d->personal->setVisible( true );
00481   }
00482 
00483   checkForSingleAvailableGroup();
00484 }
00485 
00486 void AddressesDialog::checkForSingleAvailableGroup()
00487 {
00488   QListViewItem* item = d->ui->mAvailableView->firstChild();
00489   QListViewItem* firstGroup = 0;
00490   int found = 0;
00491   while (item)
00492   {
00493     if (item->isVisible())
00494     {
00495       if (!firstGroup && static_cast<AddresseeViewItem*>(item)->category() != AddresseeViewItem::Entry)
00496       {
00497         firstGroup = item;
00498       }
00499       ++found;
00500     }
00501     item = item->nextSibling();
00502   }
00503 
00504   if (found == 1 && firstGroup)
00505   {
00506     firstGroup->setOpen(true);
00507   }
00508 }
00509 
00510 void
00511 AddressesDialog::availableSelectionChanged()
00512 {
00513   bool selection = !selectedAvailableAddresses.isEmpty();
00514   d->ui->mToButton->setEnabled(selection);
00515   d->ui->mCCButton->setEnabled(selection);
00516   d->ui->mBCCButton->setEnabled(selection);
00517 }
00518 
00519 void
00520 AddressesDialog::selectedSelectionChanged()
00521 {
00522   bool selection = !selectedSelectedAddresses.isEmpty();
00523   d->ui->mRemoveButton->setEnabled(selection);
00524 }
00525 
00526 void
00527 AddressesDialog::availableAddressSelected( AddresseeViewItem* item, bool selected )
00528 {
00529   if (selected)
00530   {
00531     selectedAvailableAddresses.append(item);
00532   }
00533   else
00534   {
00535     selectedAvailableAddresses.remove(item);
00536   }
00537 }
00538 
00539 void
00540 AddressesDialog::selectedAddressSelected( AddresseeViewItem* item, bool selected )
00541 {
00542   // we have to avoid that a parent and a child is selected together
00543   // because in this case we get a double object deletion ( program crashes )
00544   // when removing the selected items from list
00545   AddresseeViewItem* parent = static_cast<AddresseeViewItem*>(((QListViewItem*)item)->parent());
00546   if ( parent  && selected )
00547     parent->setSelected( false );
00548   if (selected)
00549   {
00550     selectedSelectedAddresses.append(item);
00551   }
00552   else
00553   {
00554     selectedSelectedAddresses.remove(item);
00555   }
00556   if ( selected ) {
00557     AddresseeViewItem* child = static_cast<AddresseeViewItem*>(item->firstChild());
00558     while (child) {
00559       child->setSelected( false );
00560       child = static_cast<AddresseeViewItem*>(child->nextSibling());
00561     }
00562   }
00563 }
00564 
00565 void
00566 AddressesDialog::initConnections()
00567 {
00568   connect( d->ui->mFilterEdit, SIGNAL(textChanged(const QString &)),
00569            SLOT(filterChanged(const QString &)) );
00570   connect( d->ui->mToButton, SIGNAL(clicked()),
00571            SLOT(addSelectedTo()) );
00572   connect( d->ui->mCCButton, SIGNAL(clicked()),
00573            SLOT(addSelectedCC()) );
00574   connect( d->ui->mBCCButton, SIGNAL(clicked()),
00575            SLOT(addSelectedBCC())  );
00576   connect( d->ui->mSaveAs, SIGNAL(clicked()),
00577            SLOT(saveAs())  );
00578   connect( d->ui->mLdapSearch, SIGNAL(clicked()),
00579            SLOT(searchLdap())  );
00580   connect( d->ui->mRemoveButton, SIGNAL(clicked()),
00581            SLOT(removeEntry()) );
00582   connect( d->ui->mAvailableView, SIGNAL(selectionChanged()),
00583            SLOT(availableSelectionChanged())  );
00584   connect( d->ui->mAvailableView, SIGNAL(doubleClicked(QListViewItem*)),
00585            SLOT(addSelectedTo()) );
00586   connect( d->ui->mSelectedView, SIGNAL(selectionChanged()),
00587            SLOT(selectedSelectionChanged()) );
00588   connect( d->ui->mSelectedView, SIGNAL(doubleClicked(QListViewItem*)),
00589            SLOT(removeEntry()) );
00590 
00591 #ifndef KDEPIM_NEW_DISTRLISTS
00592   connect( KABC::DistributionListWatcher::self(), SIGNAL( changed() ),
00593            this, SLOT( updateAvailableAddressees() ) );
00594 #endif
00595 
00596   connect( KABC::StdAddressBook::self( true ), SIGNAL( addressBookChanged(AddressBook*) ),
00597            this, SLOT( updateAvailableAddressees() ) );
00598 }
00599 
00600 void
00601 AddressesDialog::addAddresseeToAvailable( const KABC::Addressee& addr, AddresseeViewItem* defaultParent, bool useCategory )
00602 {
00603   if ( addr.preferredEmail().isEmpty() )
00604     return;
00605 
00606   if ( useCategory ) {
00607     QStringList categories = addr.categories();
00608 
00609     for ( QStringList::Iterator it = categories.begin(); it != categories.end(); ++it ) {
00610       if ( !d->groupDict[ *it ] ) {  //we don't have the category yet
00611         AddresseeViewItem* category = new AddresseeViewItem( d->ui->mAvailableView, *it );
00612         d->groupDict.insert( *it,  category );
00613       }
00614 
00615       for ( uint i = 0; i < addr.emails().count(); ++i ) {
00616         AddresseeViewItem* addressee = new AddresseeViewItem( d->groupDict[ *it ], addr, i );
00617         connect(addressee, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00618                 this, SLOT(availableAddressSelected(AddresseeViewItem*, bool)));
00619       }
00620     }
00621   }
00622 
00623   bool noCategory = false;
00624   if ( useCategory ) {
00625     if ( addr.categories().isEmpty() )
00626       noCategory = true;
00627   } else
00628     noCategory = true;
00629 
00630   if ( defaultParent && noCategory ) { // only non-categorized items here
00631     AddresseeViewItem* addressee = new AddresseeViewItem( defaultParent, addr );
00632     connect(addressee, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00633             this, SLOT(availableAddressSelected(AddresseeViewItem*, bool)));
00634   }
00635 }
00636 
00637 void
00638 AddressesDialog::addAddresseeToSelected( const KABC::Addressee& addr, AddresseeViewItem* defaultParent )
00639 {
00640   if ( addr.preferredEmail().isEmpty() )
00641     return;
00642 
00643   if ( defaultParent ) {
00644     AddresseeViewItem *myChild = static_cast<AddresseeViewItem*>( defaultParent->firstChild() );
00645     while( myChild ) {
00646       if ( myChild->addressee().preferredEmail() == addr.preferredEmail() )
00647         return;//already got it
00648       myChild = static_cast<AddresseeViewItem*>( myChild->nextSibling() );
00649     }
00650     AddresseeViewItem* addressee = new AddresseeViewItem( defaultParent, addr );
00651     connect(addressee, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00652             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00653     defaultParent->setOpen( true );
00654   }
00655 
00656   d->ui->mSaveAs->setEnabled(true);
00657 }
00658 
00659 void
00660 AddressesDialog::addAddresseesToSelected( AddresseeViewItem *parent,
00661                                           const QPtrList<AddresseeViewItem>& addresses )
00662 {
00663   Q_ASSERT( parent );
00664 
00665   QPtrListIterator<AddresseeViewItem> itr( addresses );
00666 
00667   if (itr.current())
00668   {
00669     d->ui->mSaveAs->setEnabled(true);
00670   }
00671 
00672   while ( itr.current() ) {
00673     AddresseeViewItem* address = itr.current();
00674     ++itr;
00675 
00676     if (selectedToAvailableMapping.find(address) != 0)
00677     {
00678       continue;
00679     }
00680 
00681     AddresseeViewItem* newItem = 0;
00682     if (address->category() == AddresseeViewItem::Entry)
00683     {
00684       newItem = new AddresseeViewItem( parent, address->addressee() );
00685     }
00686     else if (address->category() == AddresseeViewItem::DistList)
00687     {
00688       newItem = new AddresseeViewItem( parent, address->name() );
00689     }
00690     else
00691     {
00692       newItem = new AddresseeViewItem( parent, address->name(), allAddressee( address ) );
00693     }
00694 
00695     address->setSelected( false );
00696     address->setVisible( false );
00697     selectedToAvailableMapping.insert(address, newItem);
00698     selectedToAvailableMapping.insert(newItem, address);
00699     connect(newItem, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00700             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00701   }
00702 
00703   parent->setOpen( true );
00704 }
00705 
00706 QStringList
00707 AddressesDialog::entryToString( const KABC::Addressee::List& l ) const
00708 {
00709   QStringList entries;
00710 
00711   for( KABC::Addressee::List::ConstIterator it = l.begin(); it != l.end(); ++it ) {
00712     entries += (*it).fullEmail();
00713   }
00714   return entries;
00715 }
00716 
00717 void
00718 AddressesDialog::addSelectedTo()
00719 {
00720   if ( !d->toItem )
00721   {
00722     d->toItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("To"), AddresseeViewItem::To );
00723     connect(d->toItem, SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00724             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00725   }
00726 
00727   addAddresseesToSelected( d->toItem, selectedAvailableAddresses );
00728   selectedAvailableAddresses.clear();
00729 
00730   if ( d->toItem->childCount() > 0 )
00731     d->toItem->setVisible( true );
00732   else
00733   {
00734     delete d->toItem;
00735     d->toItem = 0;
00736   }
00737 }
00738 
00739 void
00740 AddressesDialog::addSelectedCC()
00741 {
00742   if ( !d->ccItem )
00743   {
00744     d->ccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("CC"), AddresseeViewItem::CC );
00745     connect(d->ccItem , SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00746             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00747   }
00748 
00749   addAddresseesToSelected( d->ccItem, selectedAvailableAddresses );
00750   selectedAvailableAddresses.clear();
00751 
00752   if ( d->ccItem->childCount() > 0 )
00753     d->ccItem->setVisible( true );
00754   else
00755   {
00756     delete d->ccItem;
00757     d->ccItem = 0;
00758   }
00759 }
00760 
00761 void
00762 AddressesDialog::addSelectedBCC()
00763 {
00764   if ( !d->bccItem )
00765   {
00766     d->bccItem = new AddresseeViewItem( d->ui->mSelectedView, i18n("BCC"), AddresseeViewItem::BCC );
00767     connect(d->bccItem , SIGNAL(addressSelected(AddresseeViewItem*, bool)),
00768             this, SLOT(selectedAddressSelected(AddresseeViewItem*, bool)));
00769   }
00770 
00771   addAddresseesToSelected( d->bccItem, selectedAvailableAddresses );
00772   selectedAvailableAddresses.clear();
00773 
00774   if ( d->bccItem->childCount() > 0 )
00775     d->bccItem->setVisible( true );
00776   else
00777   {
00778     delete d->bccItem;
00779     d->bccItem = 0;
00780   }
00781 }
00782 
00783 void AddressesDialog::unmapSelectedAddress(AddresseeViewItem* item)
00784 {
00785   AddresseeViewItem* correspondingItem = selectedToAvailableMapping[item];
00786   if (correspondingItem)
00787   {
00788     correspondingItem->setVisible( true );
00789     selectedToAvailableMapping.remove( item );
00790     selectedToAvailableMapping.remove( correspondingItem );
00791   }
00792 
00793   AddresseeViewItem* child = static_cast<AddresseeViewItem*>(item->firstChild());
00794   while (child)
00795   {
00796     unmapSelectedAddress(child);
00797     child = static_cast<AddresseeViewItem*>(child->nextSibling());
00798   }
00799 }
00800 
00801 void
00802 AddressesDialog::removeEntry()
00803 {
00804   QPtrList<AddresseeViewItem> lst;
00805   bool resetTo  = false;
00806   bool resetCC  = false;
00807   bool resetBCC = false;
00808 
00809   lst.setAutoDelete( false );
00810   QPtrListIterator<AddresseeViewItem> it( selectedSelectedAddresses );
00811   while ( it.current() ) {
00812     AddresseeViewItem* item = it.current();
00813     ++it;
00814     if ( d->toItem == item )
00815       resetTo = true;
00816     else if ( d->ccItem == item )
00817       resetCC = true;
00818     else if( d->bccItem == item )
00819       resetBCC = true;
00820     // we may only append parent items
00821     unmapSelectedAddress(item);
00822     lst.append( item );
00823   }
00824   selectedSelectedAddresses.clear();
00825   lst.setAutoDelete( true );
00826   lst.clear();
00827   if ( resetTo )
00828     d->toItem  = 0;
00829   else if ( d->toItem && d->toItem->childCount() == 0 )
00830   {
00831     delete d->toItem;
00832     d->toItem = 0;
00833   }
00834   if ( resetCC )
00835     d->ccItem = 0;
00836   else if ( d->ccItem && d->ccItem->childCount() == 0 )
00837   {
00838     delete d->ccItem;
00839     d->ccItem = 0;
00840   }
00841   if ( resetBCC )
00842     d->bccItem  = 0;
00843   else if ( d->bccItem && d->bccItem->childCount() == 0 )
00844   {
00845     delete d->bccItem;
00846     d->bccItem = 0;
00847   }
00848   d->ui->mSaveAs->setEnabled(d->ui->mSelectedView->firstChild() != 0);
00849 }
00850 
00851 #ifdef KDEPIM_NEW_DISTRLISTS
00852 
00853 // copied from kabcore.cpp :(
00854 // KDE4: should be in libkabc I think
00855 static KABC::Resource *requestResource( KABC::AddressBook* abook, QWidget *parent )
00856 {
00857   QPtrList<KABC::Resource> kabcResources = abook->resources();
00858 
00859   QPtrList<KRES::Resource> kresResources;
00860   QPtrListIterator<KABC::Resource> resIt( kabcResources );
00861   KABC::Resource *resource;
00862   while ( ( resource = resIt.current() ) != 0 ) {
00863     ++resIt;
00864     if ( !resource->readOnly() ) {
00865       KRES::Resource *res = static_cast<KRES::Resource*>( resource );
00866       if ( res )
00867         kresResources.append( res );
00868     }
00869   }
00870 
00871   KRES::Resource *res = KRES::SelectDialog::getResource( kresResources, parent );
00872   return static_cast<KABC::Resource*>( res );
00873 }
00874 #endif
00875 
00876 void
00877 AddressesDialog::saveAs()
00878 {
00879 #ifndef KDEPIM_NEW_DISTRLISTS
00880   KABC::DistributionListManager manager( KABC::StdAddressBook::self( true ) );
00881   manager.load();
00882 #endif
00883 
00884   if ( !d->ui->mSelectedView->firstChild() ) {
00885     KMessageBox::information( 0,
00886                               i18n("There are no addresses in your list. "
00887                                    "First add some addresses from your address book, "
00888                                    "then try again.") );
00889     return;
00890   }
00891 
00892   bool ok = false;
00893   QString name = KInputDialog::getText( i18n("New Distribution List"),
00894                                         i18n("Please enter name:"),
00895                                         QString::null, &ok,
00896                                         this );
00897   if ( !ok || name.isEmpty() )
00898     return;
00899 
00900   bool alreadyExists = false;
00901 #ifdef KDEPIM_NEW_DISTRLISTS
00902   KABC::AddressBook* abook = KABC::StdAddressBook::self( true );
00903   KPIM::DistributionList dlist = KPIM::DistributionList::findByName( abook, name );
00904   alreadyExists = !dlist.isEmpty();
00905 #else
00906   alreadyExists = manager.list( name );
00907 #endif
00908 
00909   if ( alreadyExists ) {
00910     KMessageBox::information( 0,
00911                               i18n( "<qt>Distribution list with the given name <b>%1</b> "
00912                                     "already exists. Please select a different name.</qt>" )
00913                               .arg( name ) );
00914     return;
00915   }
00916 
00917 #ifdef KDEPIM_NEW_DISTRLISTS
00918   KABC::Resource* resource = requestResource( abook, this );
00919   if ( !resource )
00920     return;
00921 
00922   dlist.setResource( resource );
00923   dlist.setName( name );
00924   KABC::Addressee::List addrl = allAddressee( d->ui->mSelectedView, false );
00925   for ( KABC::Addressee::List::iterator itr = addrl.begin();
00926         itr != addrl.end(); ++itr ) {
00927     dlist.insertEntry( *itr );
00928   }
00929   abook->insertAddressee( dlist );
00930 #else
00931   KABC::DistributionList *dlist = new KABC::DistributionList( &manager, name );
00932   KABC::Addressee::List addrl = allAddressee( d->ui->mSelectedView, false );
00933   for ( KABC::Addressee::List::iterator itr = addrl.begin();
00934         itr != addrl.end(); ++itr ) {
00935     dlist->insertEntry( *itr );
00936   }
00937 
00938   manager.save();
00939 #endif
00940 }
00941 
00942 void
00943 AddressesDialog::searchLdap()
00944 {
00945     if ( !d->ldapSearchDialog ) {
00946       d->ldapSearchDialog = new LDAPSearchDialog( this );
00947       connect( d->ldapSearchDialog, SIGNAL( addresseesAdded() ),
00948                SLOT(ldapSearchResult() ) );
00949     }
00950     d->ldapSearchDialog->show();
00951 }
00952 
00953 void
00954 AddressesDialog::ldapSearchResult()
00955 {
00956   QStringList emails = KPIM::splitEmailAddrList( d->ldapSearchDialog->selectedEMails() );
00957   QStringList::iterator it( emails.begin() );
00958   QStringList::iterator end( emails.end() );
00959   for ( ; it != end; ++it ){
00960       QString name;
00961       QString email;
00962       KPIM::getNameAndMail( (*it), name, email );
00963       KABC::Addressee ad;
00964       ad.setNameFromString( name );
00965       ad.insertEmail( email );
00966       addAddresseeToSelected( ad, selectedToItem() );
00967   }
00968 }
00969 
00970 void
00971 AddressesDialog::launchAddressBook()
00972 {
00973   kapp->startServiceByDesktopName( "kaddressbook", QString() );
00974 }
00975 
00976 void
00977 AddressesDialog::filterChanged( const QString& txt )
00978 {
00979   QListViewItemIterator it( d->ui->mAvailableView );
00980   bool showAll = false;
00981 
00982   if ( txt.isEmpty() )
00983     showAll = true;
00984 
00985   int personalVisible = 0;
00986   int recentVisible = 0;
00987   while ( it.current() ) {
00988     AddresseeViewItem* item = static_cast<AddresseeViewItem*>( it.current() );
00989     ++it;
00990     if ( showAll ) {
00991       item->setVisible( true );
00992       if ( item->category() == AddresseeViewItem::Group )
00993         item->setOpen( false );//close to not have too many entries
00994       continue;
00995     }
00996     if ( item->category() == AddresseeViewItem::Entry ) {
00997       bool matches = item->matches( txt ) ;
00998       item->setVisible( matches );
00999       QListViewItem *parent = static_cast<QListViewItem*>( item )->parent();
01000       if ( matches && parent ) {
01001         parent->setOpen( true );//open the parents with found entries
01002         if ( parent == d->personal ) {
01003           personalVisible++;
01004         } else {
01005           recentVisible++;
01006         }
01007       }
01008     }
01009   }
01010 
01011   if ( !showAll && personalVisible == 0 ) {
01012     d->personal->setVisible( false );
01013   }
01014   if ( !showAll && recentVisible == 0 ) {
01015     d->recent->setVisible( false );
01016   }
01017 }
01018 
01019 KABC::Addressee::List
01020 AddressesDialog::allAddressee( KListView* view, bool onlySelected ) const
01021 {
01022   KABC::Addressee::List lst;
01023   QListViewItemIterator it( view );
01024   while ( it.current() ) {
01025     AddresseeViewItem* item = static_cast<AddresseeViewItem*>( it.current() );
01026     if ( !onlySelected || item->isSelected() ) {
01027       if ( item->category() != AddresseeViewItem::Entry  ) {
01028         AddresseeViewItem *myChild = static_cast<AddresseeViewItem*>( item->firstChild() );
01029         while( myChild ) {
01030           lst.append( myChild->addressee() );
01031           myChild = static_cast<AddresseeViewItem*>( myChild->nextSibling() );
01032         }
01033       } else {
01034         lst.append( item->addressee() );
01035       }
01036     }
01037     ++it;
01038   }
01039 
01040   return lst;
01041 }
01042 
01043 KABC::Addressee::List
01044 AddressesDialog::allAddressee( AddresseeViewItem* parent ) const
01045 {
01046   KABC::Addressee::List lst;
01047 
01048   if ( !parent ) return lst;
01049 
01050   if ( parent->category() == AddresseeViewItem::Entry )
01051   {
01052     lst.append( parent->addressee() );
01053     return lst;
01054   }
01055 
01056   AddresseeViewItem *myChild = static_cast<AddresseeViewItem*>( parent->firstChild() );
01057   while( myChild ) {
01058     if ( myChild->category() == AddresseeViewItem::FilledGroup )
01059       lst += myChild->addresses();
01060     else if ( !myChild->addressee().isEmpty() )
01061       lst.append( myChild->addressee() );
01062     myChild = static_cast<AddresseeViewItem*>( myChild->nextSibling() );
01063   }
01064 
01065   return lst;
01066 }
01067 
01068 QStringList
01069 AddressesDialog::allDistributionLists( AddresseeViewItem* parent ) const
01070 {
01071   QStringList lists;
01072 
01073   if ( !parent )
01074     return QStringList();
01075 
01076   AddresseeViewItem *item = static_cast<AddresseeViewItem*>( parent->firstChild() );
01077   while ( item ) {
01078     if ( item->category() == AddresseeViewItem::DistList && !item->name().isEmpty() )
01079       lists.append( item->name() );
01080 
01081     item = static_cast<AddresseeViewItem*>( item->nextSibling() );
01082   }
01083 
01084   return lists;
01085 }
01086 
01087 void
01088 AddressesDialog::addDistributionLists()
01089 {
01090   KABC::AddressBook* abook = KABC::StdAddressBook::self( true );
01091 
01092 #ifdef KDEPIM_NEW_DISTRLISTS
01093   const QValueList<KPIM::DistributionList> distLists =
01094     KPIM::DistributionList::allDistributionLists( abook );
01095 #else
01096   KABC::DistributionListManager manager( abook );
01097   manager.load();
01098 
01099   QStringList distLists = manager.listNames();
01100 #endif
01101 
01102   if ( distLists.isEmpty() )
01103     return;
01104 
01105   AddresseeViewItem *topItem = new AddresseeViewItem( d->ui->mAvailableView,
01106                                                       i18n( "Distribution Lists" ) );
01107 
01108 #ifdef KDEPIM_NEW_DISTRLISTS
01109   QValueList<KPIM::DistributionList>::ConstIterator listIt;
01110 #else
01111   QStringList::Iterator listIt;
01112 #endif
01113   for ( listIt = distLists.begin(); listIt != distLists.end(); ++listIt ) {
01114 #ifdef KDEPIM_NEW_DISTRLISTS
01115     KPIM::DistributionList dlist = *listIt;
01116     KPIM::DistributionList::Entry::List entries = dlist.entries(abook);
01117 #else
01118     KABC::DistributionList& dlist = *manager.list( *listIt );
01119     KABC::DistributionList::Entry::List entries = dlist.entries();
01120 #endif
01121 
01122     AddresseeViewItem *item = new AddresseeViewItem( topItem, dlist.name() );
01123     connect( item, SIGNAL( addressSelected( AddresseeViewItem*, bool ) ),
01124              this, SLOT( availableAddressSelected( AddresseeViewItem*, bool ) ) );
01125 
01126 #ifdef KDEPIM_NEW_DISTRLISTS
01127     KPIM::DistributionList::Entry::List::Iterator itemIt;
01128 #else
01129     KABC::DistributionList::Entry::List::Iterator itemIt;
01130 #endif
01131     for ( itemIt = entries.begin(); itemIt != entries.end(); ++itemIt )
01132       addAddresseeToAvailable( (*itemIt).addressee, item, false );
01133   }
01134 }
01135 
01136 } // namespace
01137 
01138 #include "addressesdialog.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys