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