kaddressbook

ldapsearchdialog.cpp
1/* ldapsearchdialogimpl.cpp - LDAP access
2 * Copyright (C) 2002 Klarälvdalens Datakonsult AB
3 *
4 * Author: Steffen Hansen <hansen@kde.org>
5 *
6 * This file is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This file is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "config.h"
22
23#include <tqcheckbox.h>
24#include <tqgroupbox.h>
25#include <tqheader.h>
26#include <tqlabel.h>
27#include <tqlayout.h>
28#include <tqlistview.h>
29#include <tqmap.h>
30#include <tqpushbutton.h>
31
32#include <addresseelineedit.h>
33#include <tdeapplication.h>
34#include <kbuttonbox.h>
35#include <kcombobox.h>
36#include <tdeconfig.h>
37#include <klineedit.h>
38#include <tdelocale.h>
39#include <tdemessagebox.h>
40
41#include "kabcore.h"
42#include "ldapsearchdialog.h"
43#include "kablock.h"
44
45#ifdef TDEPIM_NEW_DISTRLISTS
46#include "distributionlistpicker.h"
47#endif
48
49static TQString asUtf8( const TQByteArray &val )
50{
51 if ( val.isEmpty() )
52 return TQString();
53
54 const char *data = val.data();
55
56 //TQString::fromUtf8() bug workaround
57 if ( data[ val.size() - 1 ] == '\0' )
58 return TQString::fromUtf8( data, val.size() - 1 );
59 else
60 return TQString::fromUtf8( data, val.size() );
61}
62
63static TQString join( const KPIM::LdapAttrValue& lst, const TQString& sep )
64{
65 TQString res;
66 bool alredy = false;
67 for ( KPIM::LdapAttrValue::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
68 if ( alredy )
69 res += sep;
70 alredy = true;
71 res += asUtf8( *it );
72 }
73 return res;
74}
75
76static TQMap<TQString, TQString>& adrbookattr2ldap()
77{
78 static TQMap<TQString, TQString> keys;
79
80 if ( keys.isEmpty() ) {
81 keys[ i18n( "Title" ) ] = "title";
82 keys[ i18n( "Full Name" ) ] = "cn";
83 keys[ i18n( "Email" ) ] = "mail";
84 keys[ i18n( "Home Number" ) ] = "homePhone";
85 keys[ i18n( "Work Number" ) ] = "telephoneNumber";
86 keys[ i18n( "Mobile Number" ) ] = "mobile";
87 keys[ i18n( "Fax Number" ) ] = "facsimileTelephoneNumber";
88 keys[ i18n( "Pager" ) ] = "pager";
89 keys[ i18n( "Street") ] = "street";
90 keys[ i18n( "State" ) ] = "st";
91 keys[ i18n( "Country" ) ] = "co";
92 keys[ i18n( "City" ) ] = "l";
93 keys[ i18n( "Organization" ) ] = "o";
94 keys[ i18n( "Company" ) ] = "Company";
95 keys[ i18n( "Department" ) ] = "department";
96 keys[ i18n( "Zip Code" ) ] = "postalCode";
97 keys[ i18n( "Postal Address" ) ] = "postalAddress";
98 keys[ i18n( "Description" ) ] = "description";
99 keys[ i18n( "User ID" ) ] = "uid";
100 }
101 return keys;
102}
103
104class ContactListItem : public TQListViewItem
105{
106 public:
107 ContactListItem( TQListView* parent, const KPIM::LdapAttrMap& attrs )
108 : TQListViewItem( parent ), mAttrs( attrs )
109 { }
110
111 KPIM::LdapAttrMap mAttrs;
112
113 virtual TQString text( int col ) const
114 {
115 // Look up a suitable attribute for column col
116 const TQString colName = listView()->columnText( col );
117 const TQString ldapAttrName = adrbookattr2ldap()[ colName ];
118 return join( mAttrs[ ldapAttrName ], ", " );
119 }
120};
121
122class LDAPSearchDialog::Private
123{
124 public:
125 static TQValueList<ContactListItem*> selectedItems( TQListView* );
126 TQMap<const ContactListItem*, TQString> itemToServer;
127};
128
129TQValueList<ContactListItem*> LDAPSearchDialog::Private::selectedItems( TQListView* view )
130{
131 TQValueList<ContactListItem*> selected;
132 ContactListItem* cli = static_cast<ContactListItem*>( view->firstChild() );
133 while ( cli ) {
134 if ( cli->isSelected() )
135 selected.append( cli );
136 cli = static_cast<ContactListItem*>( cli->nextSibling() );
137 }
138 return selected;
139}
140
141LDAPSearchDialog::LDAPSearchDialog( TDEABC::AddressBook *ab, KABCore *core,
142 TQWidget* parent, const char* name )
143 : KDialogBase( Plain, i18n( "Search for Addresses in Directory" ), Help | User1 | User2 |
144 Cancel, Default, parent, name, false, true ),
145 mAddressBook( ab ), mCore( core ), d( new Private )
146{
147 setButtonCancel( KStdGuiItem::close() );
148 TQFrame *page = plainPage();
149 TQVBoxLayout *topLayout = new TQVBoxLayout( page, marginHint(), spacingHint() );
150
151 TQGroupBox *groupBox = new TQGroupBox( i18n( "Search for Addresses in Directory" ),
152 page );
153 groupBox->setFrameShape( TQGroupBox::Box );
154 groupBox->setFrameShadow( TQGroupBox::Sunken );
155 groupBox->setColumnLayout( 0, TQt::Vertical );
156 TQGridLayout *boxLayout = new TQGridLayout( groupBox->layout(), 2,
157 5, spacingHint() );
158 boxLayout->setColStretch( 1, 1 );
159
160 TQLabel *label = new TQLabel( i18n( "Search for:" ), groupBox );
161 boxLayout->addWidget( label, 0, 0 );
162
163 mSearchEdit = new KLineEdit( groupBox );
164 boxLayout->addWidget( mSearchEdit, 0, 1 );
165 label->setBuddy( mSearchEdit );
166
167 label = new TQLabel( i18n( "In LDAP attribute", "in" ), groupBox );
168 boxLayout->addWidget( label, 0, 2 );
169
170 mFilterCombo = new KComboBox( groupBox );
171 mFilterCombo->insertItem( i18n( "Name" ) );
172 mFilterCombo->insertItem( i18n( "Email" ) );
173 mFilterCombo->insertItem( i18n( "Home Number" ) );
174 mFilterCombo->insertItem( i18n( "Work Number" ) );
175 boxLayout->addWidget( mFilterCombo, 0, 3 );
176
177 TQSize buttonSize;
178 mSearchButton = new TQPushButton( i18n( "Stop" ), groupBox );
179 buttonSize = mSearchButton->sizeHint();
180 mSearchButton->setText( i18n( "&Search" ) );
181 if ( buttonSize.width() < mSearchButton->sizeHint().width() )
182 buttonSize = mSearchButton->sizeHint();
183 mSearchButton->setFixedWidth( buttonSize.width() );
184
185 mSearchButton->setDefault( true );
186 boxLayout->addWidget( mSearchButton, 0, 4 );
187
188 mRecursiveCheckbox = new TQCheckBox( i18n( "Recursive search" ), groupBox );
189 mRecursiveCheckbox->setChecked( true );
190 boxLayout->addMultiCellWidget( mRecursiveCheckbox, 1, 1, 0, 4 );
191
192 mSearchType = new KComboBox( groupBox );
193 mSearchType->insertItem( i18n( "Contains" ) );
194 mSearchType->insertItem( i18n( "Starts With" ) );
195 boxLayout->addMultiCellWidget( mSearchType, 1, 1, 3, 4 );
196
197 topLayout->addWidget( groupBox );
198
199 mResultListView = new TQListView( page );
200 mResultListView->setSelectionMode( TQListView::Multi );
201 mResultListView->setAllColumnsShowFocus( true );
202 mResultListView->setShowSortIndicator( true );
203 topLayout->addWidget( mResultListView );
204
205 KButtonBox *buttons = new KButtonBox( page, TQt::Horizontal );
206 buttons->addButton( i18n( "Select All" ), this, TQ_SLOT( slotSelectAll() ) );
207 buttons->addButton( i18n( "Unselect All" ), this, TQ_SLOT( slotUnselectAll() ) );
208
209 topLayout->addWidget( buttons );
210
211 resize( TQSize( 600, 400).expandedTo( minimumSizeHint() ) );
212
213 setButtonText( User1, i18n( "Add Selected" ) );
214
215 showButton( User2, false );
216
217#ifdef TDEPIM_NEW_DISTRLISTS
218 showButton( User2, true );
219 setButtonText( User2, i18n( "Add to Distribution List..." ) );
220#endif
221
222 mNumHosts = 0;
223 mIsOK = false;
224
225 connect( mRecursiveCheckbox, TQ_SIGNAL( toggled( bool ) ),
226 this, TQ_SLOT( slotSetScope( bool ) ) );
227 connect( mSearchButton, TQ_SIGNAL( clicked() ),
228 this, TQ_SLOT( slotStartSearch() ) );
229
230 setTabOrder(mSearchEdit, mFilterCombo);
231 setTabOrder(mFilterCombo, mSearchButton);
232 mSearchEdit->setFocus();
233
234 restoreSettings();
235}
236
237LDAPSearchDialog::~LDAPSearchDialog()
238{
239 saveSettings();
240 delete d;
241}
242
243void LDAPSearchDialog::restoreSettings()
244{
245 // Create one KPIM::LdapClient per selected server and configure it.
246
247 // First clean the list to make sure it is empty at
248 // the beginning of the process
249 mLdapClientList.setAutoDelete( true );
250 mLdapClientList.clear();
251
252 TDEConfig kabConfig( "kaddressbookrc" );
253 kabConfig.setGroup( "LDAPSearch" );
254 mSearchType->setCurrentItem( kabConfig.readNumEntry( "SearchType", 0 ) );
255
256 // then read the config file and register all selected
257 // server in the list
258 TDEConfig* config = KPIM::LdapSearch::config();
259 TDEConfigGroupSaver saver( config, "LDAP" );
260 mNumHosts = config->readUnsignedNumEntry( "NumSelectedHosts" );
261 if ( !mNumHosts ) {
262 KMessageBox::error( this, i18n( "You must select a LDAP server before searching.\nYou can do this from the menu Settings/Configure KAddressBook." ) );
263 mIsOK = false;
264 } else {
265 mIsOK = true;
266 for ( int j = 0; j < mNumHosts; ++j ) {
267 KPIM::LdapClient* ldapClient = new KPIM::LdapClient( 0, this, "ldapclient" );
268 KPIM::LdapServer ldapServer;
269 KPIM::LdapSearch::readConfig( ldapServer, config, j, true );
270 ldapClient->setServer( ldapServer );
271 TQStringList attrs;
272
273 for ( TQMap<TQString,TQString>::ConstIterator it = adrbookattr2ldap().begin(); it != adrbookattr2ldap().end(); ++it )
274 attrs << *it;
275
276 ldapClient->setAttrs( attrs );
277
278 connect( ldapClient, TQ_SIGNAL( result( const KPIM::LdapObject& ) ),
279 this, TQ_SLOT( slotAddResult( const KPIM::LdapObject& ) ) );
280 connect( ldapClient, TQ_SIGNAL( done() ),
281 this, TQ_SLOT( slotSearchDone() ) );
282 connect( ldapClient, TQ_SIGNAL( error( const TQString& ) ),
283 this, TQ_SLOT( slotError( const TQString& ) ) );
284
285 mLdapClientList.append( ldapClient );
286 }
287
289 while ( mResultListView->header()->count() > 0 ) {
290 mResultListView->removeColumn(0);
291 }
292
293 mResultListView->addColumn( i18n( "Full Name" ) );
294 mResultListView->addColumn( i18n( "Email" ) );
295 mResultListView->addColumn( i18n( "Home Number" ) );
296 mResultListView->addColumn( i18n( "Work Number" ) );
297 mResultListView->addColumn( i18n( "Mobile Number" ) );
298 mResultListView->addColumn( i18n( "Fax Number" ) );
299 mResultListView->addColumn( i18n( "Company" ) );
300 mResultListView->addColumn( i18n( "Organization" ) );
301 mResultListView->addColumn( i18n( "Street" ) );
302 mResultListView->addColumn( i18n( "State" ) );
303 mResultListView->addColumn( i18n( "Country" ) );
304 mResultListView->addColumn( i18n( "Zip Code" ) );
305 mResultListView->addColumn( i18n( "Postal Address" ) );
306 mResultListView->addColumn( i18n( "City" ) );
307 mResultListView->addColumn( i18n( "Department" ) );
308 mResultListView->addColumn( i18n( "Description" ) );
309 mResultListView->addColumn( i18n( "User ID" ) );
310 mResultListView->addColumn( i18n( "Title" ) );
311
312 mResultListView->clear();
313 d->itemToServer.clear();
314 }
315}
316
317void LDAPSearchDialog::saveSettings()
318{
319 TDEConfig config( "kaddressbookrc" );
320 config.setGroup( "LDAPSearch" );
321 config.writeEntry( "SearchType", mSearchType->currentItem() );
322 config.sync();
323}
324
325void LDAPSearchDialog::cancelQuery()
326{
327 for ( KPIM::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) {
328 client->cancelQuery();
329 }
330}
331
332void LDAPSearchDialog::slotAddResult( const KPIM::LdapObject& obj )
333{
334 ContactListItem* item = new ContactListItem( mResultListView, obj.attrs );
335 d->itemToServer[item] = obj.client->server().host();
336}
337
338void LDAPSearchDialog::slotSetScope( bool rec )
339{
340 for ( KPIM::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) {
341 if ( rec )
342 client->setScope( "sub" );
343 else
344 client->setScope( "one" );
345 }
346}
347
348TQString LDAPSearchDialog::makeFilter( const TQString& query, const TQString& attr,
349 bool startsWith )
350{
351 /* The reasoning behind this filter is:
352 * If it's a person, or a distlist, show it, even if it doesn't have an email address.
353 * If it's not a person, or a distlist, only show it if it has an email attribute.
354 * This allows both resource accounts with an email address which are not a person and
355 * person entries without an email address to show up, while still not showing things
356 * like structural entries in the ldap tree. */
357 TQString result( "&(|(objectclass=person)(objectclass=groupofnames)(mail=*))(" );
358 if( query.isEmpty() )
359 // Return a filter that matches everything
360 return result + "|(cn=*)(sn=*)" + ")";
361
362 if ( attr == i18n( "Name" ) ) {
363 result += startsWith ? "|(cn=%1*)(sn=%2*)" : "|(cn=*%1*)(sn=*%2*)";
364 result = result.arg( query ).arg( query );
365 } else {
366 result += (startsWith ? "%1=%2*" : "%1=*%2*");
367 if ( attr == i18n( "Email" ) ) {
368 result = result.arg( "mail" ).arg( query );
369 } else if ( attr == i18n( "Home Number" ) ) {
370 result = result.arg( "homePhone" ).arg( query );
371 } else if ( attr == i18n( "Work Number" ) ) {
372 result = result.arg( "telephoneNumber" ).arg( query );
373 } else {
374 // Error?
375 result = TQString();
376 return result;
377 }
378 }
379 result += ")";
380 return result;
381}
382
383void LDAPSearchDialog::slotStartSearch()
384{
385 cancelQuery();
386
387 TQApplication::setOverrideCursor( TQt::waitCursor );
388 mSearchButton->setText( i18n( "Stop" ) );
389
390 disconnect( mSearchButton, TQ_SIGNAL( clicked() ),
391 this, TQ_SLOT( slotStartSearch() ) );
392 connect( mSearchButton, TQ_SIGNAL( clicked() ),
393 this, TQ_SLOT( slotStopSearch() ) );
394
395 bool startsWith = (mSearchType->currentItem() == 1);
396
397 TQString filter = makeFilter( mSearchEdit->text().stripWhiteSpace(), mFilterCombo->currentText(), startsWith );
398
399 // loop in the list and run the KPIM::LdapClients
400 mResultListView->clear();
401 d->itemToServer.clear();
402 for ( KPIM::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() )
403 client->startQuery( filter );
404
405 saveSettings();
406}
407
408void LDAPSearchDialog::slotStopSearch()
409{
410 cancelQuery();
411 slotSearchDone();
412}
413
414void LDAPSearchDialog::slotSearchDone()
415{
416 // If there are no more active clients, we are done.
417 for ( KPIM::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) {
418 if ( client->isActive() )
419 return;
420 }
421
422 disconnect( mSearchButton, TQ_SIGNAL( clicked() ),
423 this, TQ_SLOT( slotStopSearch() ) );
424 connect( mSearchButton, TQ_SIGNAL( clicked() ),
425 this, TQ_SLOT( slotStartSearch() ) );
426
427 mSearchButton->setText( i18n( "&Search" ) );
428 TQApplication::restoreOverrideCursor();
429}
430
431void LDAPSearchDialog::slotError( const TQString& error )
432{
433 TQApplication::restoreOverrideCursor();
434 KMessageBox::error( this, error );
435}
436
437void LDAPSearchDialog::closeEvent( TQCloseEvent* e )
438{
439 slotStopSearch();
440 e->accept();
441}
442
447TQString LDAPSearchDialog::selectedEMails() const
448{
449 TQStringList result;
450 ContactListItem* cli = static_cast<ContactListItem*>( mResultListView->firstChild() );
451 while ( cli ) {
452 if ( cli->isSelected() ) {
453 TQString email = asUtf8( cli->mAttrs[ "mail" ].first() ).stripWhiteSpace();
454 if ( !email.isEmpty() ) {
455 TQString name = asUtf8( cli->mAttrs[ "cn" ].first() ).stripWhiteSpace();
456 if ( name.isEmpty() ) {
457 result << email;
458 } else {
459 result << name + " <" + email + ">";
460 }
461 }
462 }
463 cli = static_cast<ContactListItem*>( cli->nextSibling() );
464 }
465
466 return result.join( ", " );
467}
468
469void LDAPSearchDialog::slotHelp()
470{
471 tdeApp->invokeHelp( "ldap-queries" );
472}
473
474void LDAPSearchDialog::slotUnselectAll()
475{
476 mResultListView->selectAll( false );
477}
478
479void LDAPSearchDialog::slotSelectAll()
480{
481 mResultListView->selectAll( true );
482}
483
484TDEABC::Addressee LDAPSearchDialog::convertLdapAttributesToAddressee( const KPIM::LdapAttrMap& attrs )
485{
486 TDEABC::Addressee addr;
487
488 // name
489 addr.setNameFromString( asUtf8( attrs["cn"].first() ) );
490
491 // email
492 KPIM::LdapAttrValue lst = attrs["mail"];
493 KPIM::LdapAttrValue::ConstIterator it = lst.begin();
494 bool pref = true;
495 if ( it != lst.end() ) {
496 addr.insertEmail( asUtf8( *it ), pref );
497 pref = false;
498 ++it;
499 }
500
501 addr.setOrganization( asUtf8( attrs[ "o" ].first() ) );
502 if ( addr.organization().isEmpty() )
503 addr.setOrganization( asUtf8( attrs[ "Company" ].first() ) );
504
505#if KDE_IS_VERSION(3,5,8)
506 addr.setDepartment( asUtf8( attrs[ "department" ].first() ) );
507#else
508 addr.insertCustom( "KADDRESSBOOK", "X-Department", asUtf8( attrs[ "department" ].first() ) );
509#endif
510
511 // Address
512 TDEABC::Address workAddr( TDEABC::Address::Work );
513
514 workAddr.setStreet( asUtf8( attrs[ "street" ].first()) );
515 workAddr.setLocality( asUtf8( attrs[ "l" ].first()) );
516 workAddr.setRegion( asUtf8( attrs[ "st" ].first()));
517 workAddr.setPostalCode( asUtf8( attrs[ "postalCode" ].first()) );
518 workAddr.setCountry( asUtf8( attrs[ "co" ].first()) );
519
520 if ( !workAddr.isEmpty() )
521 addr.insertAddress( workAddr );
522
523 // phone
524 TDEABC::PhoneNumber homeNr = asUtf8( attrs[ "homePhone" ].first() );
525 homeNr.setType( TDEABC::PhoneNumber::Home );
526 addr.insertPhoneNumber( homeNr );
527
528 TDEABC::PhoneNumber workNr = asUtf8( attrs[ "telephoneNumber" ].first() );
529 workNr.setType( TDEABC::PhoneNumber::Work );
530 addr.insertPhoneNumber( workNr );
531
532 TDEABC::PhoneNumber faxNr = asUtf8( attrs[ "facsimileTelephoneNumber" ].first() );
533 faxNr.setType( TDEABC::PhoneNumber::Fax );
534 addr.insertPhoneNumber( faxNr );
535
536 TDEABC::PhoneNumber cellNr = asUtf8( attrs[ "mobile" ].first() );
537 cellNr.setType( TDEABC::PhoneNumber::Cell );
538 addr.insertPhoneNumber( cellNr );
539
540 TDEABC::PhoneNumber pagerNr = asUtf8( attrs[ "pager" ].first() );
541 pagerNr.setType( TDEABC::PhoneNumber::Pager );
542 addr.insertPhoneNumber( pagerNr );
543 return addr;
544}
545
546#ifdef TDEPIM_NEW_DISTRLISTS
547KPIM::DistributionList LDAPSearchDialog::selectDistributionList()
548{
549 TQGuardedPtr<KPIM::DistributionListPickerDialog> picker = new KPIM::DistributionListPickerDialog( mCore->addressBook(), this );
550 picker->setLabelText( i18n( "Select a distribution list to add the selected contacts to." ) );
551 picker->setCaption( i18n( "Select Distribution List" ) );
552 picker->exec();
553 const KPIM::DistributionList list = KPIM::DistributionList::findByName( mCore->addressBook(), picker
554? picker->selectedDistributionList() : TQString() );
555 delete picker;
556 return list;
557}
558#endif
559
560TDEABC::Addressee::List LDAPSearchDialog::importContactsUnlessTheyExist( const TQValueList<ContactListItem*>& selectedItems,
561 TDEABC::Resource * const resource )
562{
563 const TQDateTime now = TQDateTime::currentDateTime();
564 TQStringList importedAddrs;
565 TDEABC::Addressee::List localAddrs;
566
567 KABLock::self( mCore->addressBook() )->lock( resource );
568
569 for ( TQValueList<ContactListItem*>::ConstIterator it = selectedItems.begin(); it != selectedItems.end(); ++it ) {
570 const ContactListItem * const cli = *it;
571 TDEABC::Addressee addr = convertLdapAttributesToAddressee( cli->mAttrs );
572 const TDEABC::Addressee::List existing = mCore->addressBook()->findByEmail( addr.preferredEmail() );
573
574 if ( existing.isEmpty() ) {
575 addr.setUid( TDEApplication::randomString( 10 ) );
576 addr.setNote( i18n( "arguments are host name, datetime", "Imported from LDAP directory %1 on %2" ).arg( d->itemToServer[cli], TDEGlobal::locale()->formatDateTime( now ) ) );
577 addr.setResource( resource );
578 mCore->addressBook()->insertAddressee( addr );
579 TQString displayString;
580 if ( !addr.fullEmail().isEmpty() ) {
581 displayString = addr.fullEmail();
582 }
583 else {
584 displayString = addr.formattedName();
585 }
586 importedAddrs.append( displayString );
587 localAddrs.append( addr );
588 } else {
589 localAddrs.append( existing.first() );
590 }
591 }
592 KABLock::self( mCore->addressBook() )->unlock( resource );
593 if ( !importedAddrs.isEmpty() ) {
594 KMessageBox::informationList( this, i18n( "The following contact was imported into your address book:",
595 "The following %n contacts were imported into your address book:", importedAddrs.count() ),
596 importedAddrs );
597 emit addresseesAdded();
598 }
599 return localAddrs;
600}
601
602void LDAPSearchDialog::slotUser2()
603{
604#ifdef TDEPIM_NEW_DISTRLISTS
605 const TQValueList<ContactListItem*> selectedItems = d->selectedItems( mResultListView );
606 if ( selectedItems.isEmpty() ) {
607 KMessageBox::information( this, i18n( "Please select the contacts you want to add to the distribution list." ), i18n( "No Contacts Selected" ) );
608 return;
609 }
610
611 TDEABC::Resource *resource = mCore->requestResource( this );
612 if ( !resource ) return;
613
614 KPIM::DistributionList dist = selectDistributionList();
615 if ( dist.isEmpty() )
616 return;
617
618
619 TDEABC::Addressee::List localAddrs = importContactsUnlessTheyExist( selectedItems, resource );
620
621 if ( localAddrs.isEmpty() )
622 return;
623
624 for ( TDEABC::Addressee::List::ConstIterator it = localAddrs.begin(); it != localAddrs.end(); ++it ) {
625 dist.insertEntry( *it, TQString() );
626 }
627 KABLock::self( mCore->addressBook() )->lock( resource );
628 mCore->addressBook()->insertAddressee( dist );
629 KABLock::self( mCore->addressBook() )->unlock( resource );
630 emit addresseesAdded();
631#endif
632}
633
634void LDAPSearchDialog::slotUser1()
635{
636 TDEABC::Resource *resource = mCore->requestResource( this );
637 if ( !resource ) return;
638 const TQValueList<ContactListItem*> selectedItems = d->selectedItems( mResultListView );
639 if( selectedItems.isEmpty() )
640 return;
641 importContactsUnlessTheyExist( selectedItems, resource );
642}
643
644#include "ldapsearchdialog.moc"