ldapsearchdialog.cpp
00001 /* ldapsearchdialogimpl.cpp - LDAP access 00002 * Copyright (C) 2002 Klar�vdalens Datakonsult AB 00003 * 00004 * Author: Steffen Hansen <hansen@kde.org> 00005 * 00006 * This file is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This file is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 00019 */ 00020 00021 #include "config.h" 00022 00023 #include <tqcheckbox.h> 00024 #include <tqgroupbox.h> 00025 #include <tqheader.h> 00026 #include <tqlabel.h> 00027 #include <tqlayout.h> 00028 #include <tqlistview.h> 00029 #include <tqmap.h> 00030 #include <tqpushbutton.h> 00031 00032 #include <addresseelineedit.h> 00033 #include <kapplication.h> 00034 #include <kbuttonbox.h> 00035 #include <kcombobox.h> 00036 #include <kconfig.h> 00037 #include <klineedit.h> 00038 #include <klocale.h> 00039 #include <kmessagebox.h> 00040 00041 #include "kabcore.h" 00042 #include "ldapsearchdialog.h" 00043 #include "kablock.h" 00044 00045 #ifdef KDEPIM_NEW_DISTRLISTS 00046 #include "distributionlistpicker.h" 00047 #endif 00048 00049 static TQString asUtf8( const TQByteArray &val ) 00050 { 00051 if ( val.isEmpty() ) 00052 return TQString(); 00053 00054 const char *data = val.data(); 00055 00056 //TQString::fromUtf8() bug workaround 00057 if ( data[ val.size() - 1 ] == '\0' ) 00058 return TQString::fromUtf8( data, val.size() - 1 ); 00059 else 00060 return TQString::fromUtf8( data, val.size() ); 00061 } 00062 00063 static TQString join( const KPIM::LdapAttrValue& lst, const TQString& sep ) 00064 { 00065 TQString res; 00066 bool alredy = false; 00067 for ( KPIM::LdapAttrValue::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { 00068 if ( alredy ) 00069 res += sep; 00070 alredy = true; 00071 res += asUtf8( *it ); 00072 } 00073 return res; 00074 } 00075 00076 static TQMap<TQString, TQString>& adrbookattr2ldap() 00077 { 00078 static TQMap<TQString, TQString> keys; 00079 00080 if ( keys.isEmpty() ) { 00081 keys[ i18n( "Title" ) ] = "title"; 00082 keys[ i18n( "Full Name" ) ] = "cn"; 00083 keys[ i18n( "Email" ) ] = "mail"; 00084 keys[ i18n( "Home Number" ) ] = "homePhone"; 00085 keys[ i18n( "Work Number" ) ] = "telephoneNumber"; 00086 keys[ i18n( "Mobile Number" ) ] = "mobile"; 00087 keys[ i18n( "Fax Number" ) ] = "facsimileTelephoneNumber"; 00088 keys[ i18n( "Pager" ) ] = "pager"; 00089 keys[ i18n( "Street") ] = "street"; 00090 keys[ i18n( "State" ) ] = "st"; 00091 keys[ i18n( "Country" ) ] = "co"; 00092 keys[ i18n( "City" ) ] = "l"; 00093 keys[ i18n( "Organization" ) ] = "o"; 00094 keys[ i18n( "Company" ) ] = "Company"; 00095 keys[ i18n( "Department" ) ] = "department"; 00096 keys[ i18n( "Zip Code" ) ] = "postalCode"; 00097 keys[ i18n( "Postal Address" ) ] = "postalAddress"; 00098 keys[ i18n( "Description" ) ] = "description"; 00099 keys[ i18n( "User ID" ) ] = "uid"; 00100 } 00101 return keys; 00102 } 00103 00104 class ContactListItem : public TQListViewItem 00105 { 00106 public: 00107 ContactListItem( TQListView* parent, const KPIM::LdapAttrMap& attrs ) 00108 : TQListViewItem( parent ), mAttrs( attrs ) 00109 { } 00110 00111 KPIM::LdapAttrMap mAttrs; 00112 00113 virtual TQString text( int col ) const 00114 { 00115 // Look up a suitable attribute for column col 00116 const TQString colName = listView()->columnText( col ); 00117 const TQString ldapAttrName = adrbookattr2ldap()[ colName ]; 00118 return join( mAttrs[ ldapAttrName ], ", " ); 00119 } 00120 }; 00121 00122 class LDAPSearchDialog::Private 00123 { 00124 public: 00125 static TQValueList<ContactListItem*> selectedItems( TQListView* ); 00126 TQMap<const ContactListItem*, TQString> itemToServer; 00127 }; 00128 00129 TQValueList<ContactListItem*> LDAPSearchDialog::Private::selectedItems( TQListView* view ) 00130 { 00131 TQValueList<ContactListItem*> selected; 00132 ContactListItem* cli = static_cast<ContactListItem*>( view->firstChild() ); 00133 while ( cli ) { 00134 if ( cli->isSelected() ) 00135 selected.append( cli ); 00136 cli = static_cast<ContactListItem*>( cli->nextSibling() ); 00137 } 00138 return selected; 00139 } 00140 00141 LDAPSearchDialog::LDAPSearchDialog( KABC::AddressBook *ab, KABCore *core, 00142 TQWidget* parent, const char* name ) 00143 : KDialogBase( Plain, i18n( "Search for Addresses in Directory" ), Help | User1 | User2 | 00144 Cancel, Default, parent, name, false, true ), 00145 mAddressBook( ab ), mCore( core ), d( new Private ) 00146 { 00147 setButtonCancel( KStdGuiItem::close() ); 00148 TQFrame *page = plainPage(); 00149 TQVBoxLayout *topLayout = new TQVBoxLayout( page, marginHint(), spacingHint() ); 00150 00151 TQGroupBox *groupBox = new TQGroupBox( i18n( "Search for Addresses in Directory" ), 00152 page ); 00153 groupBox->setFrameShape( TQGroupBox::Box ); 00154 groupBox->setFrameShadow( TQGroupBox::Sunken ); 00155 groupBox->setColumnLayout( 0, Qt::Vertical ); 00156 TQGridLayout *boxLayout = new TQGridLayout( groupBox->layout(), 2, 00157 5, spacingHint() ); 00158 boxLayout->setColStretch( 1, 1 ); 00159 00160 TQLabel *label = new TQLabel( i18n( "Search for:" ), groupBox ); 00161 boxLayout->addWidget( label, 0, 0 ); 00162 00163 mSearchEdit = new KLineEdit( groupBox ); 00164 boxLayout->addWidget( mSearchEdit, 0, 1 ); 00165 label->setBuddy( mSearchEdit ); 00166 00167 label = new TQLabel( i18n( "In LDAP attribute", "in" ), groupBox ); 00168 boxLayout->addWidget( label, 0, 2 ); 00169 00170 mFilterCombo = new KComboBox( groupBox ); 00171 mFilterCombo->insertItem( i18n( "Name" ) ); 00172 mFilterCombo->insertItem( i18n( "Email" ) ); 00173 mFilterCombo->insertItem( i18n( "Home Number" ) ); 00174 mFilterCombo->insertItem( i18n( "Work Number" ) ); 00175 boxLayout->addWidget( mFilterCombo, 0, 3 ); 00176 00177 TQSize buttonSize; 00178 mSearchButton = new TQPushButton( i18n( "Stop" ), groupBox ); 00179 buttonSize = mSearchButton->sizeHint(); 00180 mSearchButton->setText( i18n( "&Search" ) ); 00181 if ( buttonSize.width() < mSearchButton->sizeHint().width() ) 00182 buttonSize = mSearchButton->sizeHint(); 00183 mSearchButton->setFixedWidth( buttonSize.width() ); 00184 00185 mSearchButton->setDefault( true ); 00186 boxLayout->addWidget( mSearchButton, 0, 4 ); 00187 00188 mRecursiveCheckbox = new TQCheckBox( i18n( "Recursive search" ), groupBox ); 00189 mRecursiveCheckbox->setChecked( true ); 00190 boxLayout->addMultiCellWidget( mRecursiveCheckbox, 1, 1, 0, 4 ); 00191 00192 mSearchType = new KComboBox( groupBox ); 00193 mSearchType->insertItem( i18n( "Contains" ) ); 00194 mSearchType->insertItem( i18n( "Starts With" ) ); 00195 boxLayout->addMultiCellWidget( mSearchType, 1, 1, 3, 4 ); 00196 00197 topLayout->addWidget( groupBox ); 00198 00199 mResultListView = new TQListView( page ); 00200 mResultListView->setSelectionMode( TQListView::Multi ); 00201 mResultListView->setAllColumnsShowFocus( true ); 00202 mResultListView->setShowSortIndicator( true ); 00203 topLayout->addWidget( mResultListView ); 00204 00205 KButtonBox *buttons = new KButtonBox( page, Qt::Horizontal ); 00206 buttons->addButton( i18n( "Select All" ), TQT_TQOBJECT(this), TQT_SLOT( slotSelectAll() ) ); 00207 buttons->addButton( i18n( "Unselect All" ), TQT_TQOBJECT(this), TQT_SLOT( slotUnselectAll() ) ); 00208 00209 topLayout->addWidget( buttons ); 00210 00211 resize( TQSize( 600, 400).expandedTo( minimumSizeHint() ) ); 00212 00213 setButtonText( User1, i18n( "Add Selected" ) ); 00214 00215 showButton( User2, false ); 00216 00217 #ifdef KDEPIM_NEW_DISTRLISTS 00218 showButton( User2, true ); 00219 setButtonText( User2, i18n( "Add to Distribution List..." ) ); 00220 #endif 00221 00222 mNumHosts = 0; 00223 mIsOK = false; 00224 00225 connect( mRecursiveCheckbox, TQT_SIGNAL( toggled( bool ) ), 00226 this, TQT_SLOT( slotSetScope( bool ) ) ); 00227 connect( mSearchButton, TQT_SIGNAL( clicked() ), 00228 this, TQT_SLOT( slotStartSearch() ) ); 00229 00230 setTabOrder(mSearchEdit, mFilterCombo); 00231 setTabOrder(mFilterCombo, mSearchButton); 00232 mSearchEdit->setFocus(); 00233 00234 restoreSettings(); 00235 } 00236 00237 LDAPSearchDialog::~LDAPSearchDialog() 00238 { 00239 saveSettings(); 00240 delete d; 00241 } 00242 00243 void LDAPSearchDialog::restoreSettings() 00244 { 00245 // Create one KPIM::LdapClient per selected server and configure it. 00246 00247 // First clean the list to make sure it is empty at 00248 // the beginning of the process 00249 mLdapClientList.setAutoDelete( true ); 00250 mLdapClientList.clear(); 00251 00252 KConfig kabConfig( "kaddressbookrc" ); 00253 kabConfig.setGroup( "LDAPSearch" ); 00254 mSearchType->setCurrentItem( kabConfig.readNumEntry( "SearchType", 0 ) ); 00255 00256 // then read the config file and register all selected 00257 // server in the list 00258 KConfig* config = KPIM::LdapSearch::config(); 00259 KConfigGroupSaver saver( config, "LDAP" ); 00260 mNumHosts = config->readUnsignedNumEntry( "NumSelectedHosts" ); 00261 if ( !mNumHosts ) { 00262 KMessageBox::error( this, i18n( "You must select a LDAP server before searching.\nYou can do this from the menu Settings/Configure KAddressBook." ) ); 00263 mIsOK = false; 00264 } else { 00265 mIsOK = true; 00266 for ( int j = 0; j < mNumHosts; ++j ) { 00267 KPIM::LdapClient* ldapClient = new KPIM::LdapClient( 0, TQT_TQOBJECT(this), "ldapclient" ); 00268 KPIM::LdapServer ldapServer; 00269 KPIM::LdapSearch::readConfig( ldapServer, config, j, true ); 00270 ldapClient->setServer( ldapServer ); 00271 TQStringList attrs; 00272 00273 for ( TQMap<TQString,TQString>::ConstIterator it = adrbookattr2ldap().begin(); it != adrbookattr2ldap().end(); ++it ) 00274 attrs << *it; 00275 00276 ldapClient->setAttrs( attrs ); 00277 00278 connect( ldapClient, TQT_SIGNAL( result( const KPIM::LdapObject& ) ), 00279 this, TQT_SLOT( slotAddResult( const KPIM::LdapObject& ) ) ); 00280 connect( ldapClient, TQT_SIGNAL( done() ), 00281 this, TQT_SLOT( slotSearchDone() ) ); 00282 connect( ldapClient, TQT_SIGNAL( error( const TQString& ) ), 00283 this, TQT_SLOT( slotError( const TQString& ) ) ); 00284 00285 mLdapClientList.append( ldapClient ); 00286 } 00287 00289 while ( mResultListView->header()->count() > 0 ) { 00290 mResultListView->removeColumn(0); 00291 } 00292 00293 mResultListView->addColumn( i18n( "Full Name" ) ); 00294 mResultListView->addColumn( i18n( "Email" ) ); 00295 mResultListView->addColumn( i18n( "Home Number" ) ); 00296 mResultListView->addColumn( i18n( "Work Number" ) ); 00297 mResultListView->addColumn( i18n( "Mobile Number" ) ); 00298 mResultListView->addColumn( i18n( "Fax Number" ) ); 00299 mResultListView->addColumn( i18n( "Company" ) ); 00300 mResultListView->addColumn( i18n( "Organization" ) ); 00301 mResultListView->addColumn( i18n( "Street" ) ); 00302 mResultListView->addColumn( i18n( "State" ) ); 00303 mResultListView->addColumn( i18n( "Country" ) ); 00304 mResultListView->addColumn( i18n( "Zip Code" ) ); 00305 mResultListView->addColumn( i18n( "Postal Address" ) ); 00306 mResultListView->addColumn( i18n( "City" ) ); 00307 mResultListView->addColumn( i18n( "Department" ) ); 00308 mResultListView->addColumn( i18n( "Description" ) ); 00309 mResultListView->addColumn( i18n( "User ID" ) ); 00310 mResultListView->addColumn( i18n( "Title" ) ); 00311 00312 mResultListView->clear(); 00313 d->itemToServer.clear(); 00314 } 00315 } 00316 00317 void LDAPSearchDialog::saveSettings() 00318 { 00319 KConfig config( "kaddressbookrc" ); 00320 config.setGroup( "LDAPSearch" ); 00321 config.writeEntry( "SearchType", mSearchType->currentItem() ); 00322 config.sync(); 00323 } 00324 00325 void LDAPSearchDialog::cancelQuery() 00326 { 00327 for ( KPIM::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) { 00328 client->cancelQuery(); 00329 } 00330 } 00331 00332 void LDAPSearchDialog::slotAddResult( const KPIM::LdapObject& obj ) 00333 { 00334 ContactListItem* item = new ContactListItem( mResultListView, obj.attrs ); 00335 d->itemToServer[item] = obj.client->server().host(); 00336 } 00337 00338 void LDAPSearchDialog::slotSetScope( bool rec ) 00339 { 00340 for ( KPIM::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) { 00341 if ( rec ) 00342 client->setScope( "sub" ); 00343 else 00344 client->setScope( "one" ); 00345 } 00346 } 00347 00348 TQString LDAPSearchDialog::makeFilter( const TQString& query, const TQString& attr, 00349 bool startsWith ) 00350 { 00351 /* The reasoning behind this filter is: 00352 * If it's a person, or a distlist, show it, even if it doesn't have an email address. 00353 * If it's not a person, or a distlist, only show it if it has an email attribute. 00354 * This allows both resource accounts with an email address which are not a person and 00355 * person entries without an email address to show up, while still not showing things 00356 * like structural entries in the ldap tree. */ 00357 TQString result( "&(|(objectclass=person)(objectclass=groupofnames)(mail=*))(" ); 00358 if( query.isEmpty() ) 00359 // Return a filter that matches everything 00360 return result + "|(cn=*)(sn=*)" + ")"; 00361 00362 if ( attr == i18n( "Name" ) ) { 00363 result += startsWith ? "|(cn=%1*)(sn=%2*)" : "|(cn=*%1*)(sn=*%2*)"; 00364 result = result.arg( query ).arg( query ); 00365 } else { 00366 result += (startsWith ? "%1=%2*" : "%1=*%2*"); 00367 if ( attr == i18n( "Email" ) ) { 00368 result = result.arg( "mail" ).arg( query ); 00369 } else if ( attr == i18n( "Home Number" ) ) { 00370 result = result.arg( "homePhone" ).arg( query ); 00371 } else if ( attr == i18n( "Work Number" ) ) { 00372 result = result.arg( "telephoneNumber" ).arg( query ); 00373 } else { 00374 // Error? 00375 result = TQString(); 00376 return result; 00377 } 00378 } 00379 result += ")"; 00380 return result; 00381 } 00382 00383 void LDAPSearchDialog::slotStartSearch() 00384 { 00385 cancelQuery(); 00386 00387 TQApplication::setOverrideCursor( TQt::waitCursor ); 00388 mSearchButton->setText( i18n( "Stop" ) ); 00389 00390 disconnect( mSearchButton, TQT_SIGNAL( clicked() ), 00391 this, TQT_SLOT( slotStartSearch() ) ); 00392 connect( mSearchButton, TQT_SIGNAL( clicked() ), 00393 this, TQT_SLOT( slotStopSearch() ) ); 00394 00395 bool startsWith = (mSearchType->currentItem() == 1); 00396 00397 TQString filter = makeFilter( mSearchEdit->text().stripWhiteSpace(), mFilterCombo->currentText(), startsWith ); 00398 00399 // loop in the list and run the KPIM::LdapClients 00400 mResultListView->clear(); 00401 d->itemToServer.clear(); 00402 for ( KPIM::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) 00403 client->startQuery( filter ); 00404 00405 saveSettings(); 00406 } 00407 00408 void LDAPSearchDialog::slotStopSearch() 00409 { 00410 cancelQuery(); 00411 slotSearchDone(); 00412 } 00413 00414 void LDAPSearchDialog::slotSearchDone() 00415 { 00416 // If there are no more active clients, we are done. 00417 for ( KPIM::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) { 00418 if ( client->isActive() ) 00419 return; 00420 } 00421 00422 disconnect( mSearchButton, TQT_SIGNAL( clicked() ), 00423 this, TQT_SLOT( slotStopSearch() ) ); 00424 connect( mSearchButton, TQT_SIGNAL( clicked() ), 00425 this, TQT_SLOT( slotStartSearch() ) ); 00426 00427 mSearchButton->setText( i18n( "&Search" ) ); 00428 TQApplication::restoreOverrideCursor(); 00429 } 00430 00431 void LDAPSearchDialog::slotError( const TQString& error ) 00432 { 00433 TQApplication::restoreOverrideCursor(); 00434 KMessageBox::error( this, error ); 00435 } 00436 00437 void LDAPSearchDialog::closeEvent( TQCloseEvent* e ) 00438 { 00439 slotStopSearch(); 00440 e->accept(); 00441 } 00442 00447 TQString LDAPSearchDialog::selectedEMails() const 00448 { 00449 TQStringList result; 00450 ContactListItem* cli = static_cast<ContactListItem*>( mResultListView->firstChild() ); 00451 while ( cli ) { 00452 if ( cli->isSelected() ) { 00453 TQString email = asUtf8( cli->mAttrs[ "mail" ].first() ).stripWhiteSpace(); 00454 if ( !email.isEmpty() ) { 00455 TQString name = asUtf8( cli->mAttrs[ "cn" ].first() ).stripWhiteSpace(); 00456 if ( name.isEmpty() ) { 00457 result << email; 00458 } else { 00459 result << name + " <" + email + ">"; 00460 } 00461 } 00462 } 00463 cli = static_cast<ContactListItem*>( cli->nextSibling() ); 00464 } 00465 00466 return result.join( ", " ); 00467 } 00468 00469 void LDAPSearchDialog::slotHelp() 00470 { 00471 kapp->invokeHelp( "ldap-queries" ); 00472 } 00473 00474 void LDAPSearchDialog::slotUnselectAll() 00475 { 00476 mResultListView->selectAll( false ); 00477 } 00478 00479 void LDAPSearchDialog::slotSelectAll() 00480 { 00481 mResultListView->selectAll( true ); 00482 } 00483 00484 KABC::Addressee LDAPSearchDialog::convertLdapAttributesToAddressee( const KPIM::LdapAttrMap& attrs ) 00485 { 00486 KABC::Addressee addr; 00487 00488 // name 00489 addr.setNameFromString( asUtf8( attrs["cn"].first() ) ); 00490 00491 // email 00492 KPIM::LdapAttrValue lst = attrs["mail"]; 00493 KPIM::LdapAttrValue::ConstIterator it = lst.begin(); 00494 bool pref = true; 00495 if ( it != lst.end() ) { 00496 addr.insertEmail( asUtf8( *it ), pref ); 00497 pref = false; 00498 ++it; 00499 } 00500 00501 addr.setOrganization( asUtf8( attrs[ "o" ].first() ) ); 00502 if ( addr.organization().isEmpty() ) 00503 addr.setOrganization( asUtf8( attrs[ "Company" ].first() ) ); 00504 00505 #if KDE_IS_VERSION(3,5,8) 00506 addr.setDepartment( asUtf8( attrs[ "department" ].first() ) ); 00507 #else 00508 addr.insertCustom( "KADDRESSBOOK", "X-Department", asUtf8( attrs[ "department" ].first() ) ); 00509 #endif 00510 00511 // Address 00512 KABC::Address workAddr( KABC::Address::Work ); 00513 00514 workAddr.setStreet( asUtf8( attrs[ "street" ].first()) ); 00515 workAddr.setLocality( asUtf8( attrs[ "l" ].first()) ); 00516 workAddr.setRegion( asUtf8( attrs[ "st" ].first())); 00517 workAddr.setPostalCode( asUtf8( attrs[ "postalCode" ].first()) ); 00518 workAddr.setCountry( asUtf8( attrs[ "co" ].first()) ); 00519 00520 if ( !workAddr.isEmpty() ) 00521 addr.insertAddress( workAddr ); 00522 00523 // phone 00524 KABC::PhoneNumber homeNr = asUtf8( attrs[ "homePhone" ].first() ); 00525 homeNr.setType( KABC::PhoneNumber::Home ); 00526 addr.insertPhoneNumber( homeNr ); 00527 00528 KABC::PhoneNumber workNr = asUtf8( attrs[ "telephoneNumber" ].first() ); 00529 workNr.setType( KABC::PhoneNumber::Work ); 00530 addr.insertPhoneNumber( workNr ); 00531 00532 KABC::PhoneNumber faxNr = asUtf8( attrs[ "facsimileTelephoneNumber" ].first() ); 00533 faxNr.setType( KABC::PhoneNumber::Fax ); 00534 addr.insertPhoneNumber( faxNr ); 00535 00536 KABC::PhoneNumber cellNr = asUtf8( attrs[ "mobile" ].first() ); 00537 cellNr.setType( KABC::PhoneNumber::Cell ); 00538 addr.insertPhoneNumber( cellNr ); 00539 00540 KABC::PhoneNumber pagerNr = asUtf8( attrs[ "pager" ].first() ); 00541 pagerNr.setType( KABC::PhoneNumber::Pager ); 00542 addr.insertPhoneNumber( pagerNr ); 00543 return addr; 00544 } 00545 00546 #ifdef KDEPIM_NEW_DISTRLISTS 00547 KPIM::DistributionList LDAPSearchDialog::selectDistributionList() 00548 { 00549 TQGuardedPtr<KPIM::DistributionListPickerDialog> picker = new KPIM::DistributionListPickerDialog( mCore->addressBook(), this ); 00550 picker->setLabelText( i18n( "Select a distribution list to add the selected contacts to." ) ); 00551 picker->setCaption( i18n( "Select Distribution List" ) ); 00552 picker->exec(); 00553 const KPIM::DistributionList list = KPIM::DistributionList::findByName( mCore->addressBook(), picker 00554 ? picker->selectedDistributionList() : TQString() ); 00555 delete picker; 00556 return list; 00557 } 00558 #endif 00559 00560 KABC::Addressee::List LDAPSearchDialog::importContactsUnlessTheyExist( const TQValueList<ContactListItem*>& selectedItems, 00561 KABC::Resource * const resource ) 00562 { 00563 const TQDateTime now = TQDateTime::currentDateTime(); 00564 TQStringList importedAddrs; 00565 KABC::Addressee::List localAddrs; 00566 00567 KABLock::self( mCore->addressBook() )->lock( resource ); 00568 00569 for ( TQValueList<ContactListItem*>::ConstIterator it = selectedItems.begin(); it != selectedItems.end(); ++it ) { 00570 const ContactListItem * const cli = *it; 00571 KABC::Addressee addr = convertLdapAttributesToAddressee( cli->mAttrs ); 00572 const KABC::Addressee::List existing = mCore->addressBook()->findByEmail( addr.preferredEmail() ); 00573 00574 if ( existing.isEmpty() ) { 00575 addr.setUid( KApplication::randomString( 10 ) ); 00576 addr.setNote( i18n( "arguments are host name, datetime", "Imported from LDAP directory %1 on %2" ).arg( d->itemToServer[cli], KGlobal::locale()->formatDateTime( now ) ) ); 00577 addr.setResource( resource ); 00578 mCore->addressBook()->insertAddressee( addr ); 00579 TQString displayString; 00580 if ( !addr.fullEmail().isEmpty() ) { 00581 displayString = addr.fullEmail(); 00582 } 00583 else { 00584 displayString = addr.formattedName(); 00585 } 00586 importedAddrs.append( displayString ); 00587 localAddrs.append( addr ); 00588 } else { 00589 localAddrs.append( existing.first() ); 00590 } 00591 } 00592 KABLock::self( mCore->addressBook() )->unlock( resource ); 00593 if ( !importedAddrs.isEmpty() ) { 00594 KMessageBox::informationList( this, i18n( "The following contact was imported into your address book:", 00595 "The following %n contacts were imported into your address book:", importedAddrs.count() ), 00596 importedAddrs ); 00597 emit addresseesAdded(); 00598 } 00599 return localAddrs; 00600 } 00601 00602 void LDAPSearchDialog::slotUser2() 00603 { 00604 #ifdef KDEPIM_NEW_DISTRLISTS 00605 const TQValueList<ContactListItem*> selectedItems = d->selectedItems( mResultListView ); 00606 if ( selectedItems.isEmpty() ) { 00607 KMessageBox::information( this, i18n( "Please select the contacts you want to add to the distribution list." ), i18n( "No Contacts Selected" ) ); 00608 return; 00609 } 00610 00611 KABC::Resource *resource = mCore->requestResource( this ); 00612 if ( !resource ) return; 00613 00614 KPIM::DistributionList dist = selectDistributionList(); 00615 if ( dist.isEmpty() ) 00616 return; 00617 00618 00619 KABC::Addressee::List localAddrs = importContactsUnlessTheyExist( selectedItems, resource ); 00620 00621 if ( localAddrs.isEmpty() ) 00622 return; 00623 00624 for ( KABC::Addressee::List::ConstIterator it = localAddrs.begin(); it != localAddrs.end(); ++it ) { 00625 dist.insertEntry( *it, TQString() ); 00626 } 00627 KABLock::self( mCore->addressBook() )->lock( resource ); 00628 mCore->addressBook()->insertAddressee( dist ); 00629 KABLock::self( mCore->addressBook() )->unlock( resource ); 00630 emit addresseesAdded(); 00631 #endif 00632 } 00633 00634 void LDAPSearchDialog::slotUser1() 00635 { 00636 KABC::Resource *resource = mCore->requestResource( this ); 00637 if ( !resource ) return; 00638 const TQValueList<ContactListItem*> selectedItems = d->selectedItems( mResultListView ); 00639 if( selectedItems.isEmpty() ) 00640 return; 00641 importContactsUnlessTheyExist( selectedItems, resource ); 00642 } 00643 00644 #include "ldapsearchdialog.moc"