00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qcheckbox.h>
00022 #include <qgroupbox.h>
00023 #include <qheader.h>
00024 #include <qlabel.h>
00025 #include <qlayout.h>
00026 #include <qlistview.h>
00027 #include <qpushbutton.h>
00028
00029 #include <kabc/addresslineedit.h>
00030 #include <kapplication.h>
00031 #include <kcombobox.h>
00032 #include <kconfig.h>
00033 #include <klineedit.h>
00034 #include <klocale.h>
00035 #include <kmessagebox.h>
00036
00037 #include "ldapsearchdialog.h"
00038
00039 static QString asUtf8( const QByteArray &val )
00040 {
00041 return QString::fromUtf8( val.data(), val.size() );
00042 }
00043
00044 static QString join( const KABC::LdapAttrValue& lst, const QString& sep )
00045 {
00046 QString res;
00047 bool alredy = false;
00048 for ( KABC::LdapAttrValue::ConstIterator it = lst.begin(); it != lst.end(); ++it ) {
00049 if ( alredy )
00050 res += sep;
00051 alredy = TRUE;
00052 res += asUtf8( *it );
00053 }
00054 return res;
00055 }
00056
00057 static QMap<QString, QString>& adrbookattr2ldap()
00058 {
00059 static QMap<QString, QString> keys;
00060
00061 if ( keys.isEmpty() ) {
00062 keys[ i18n( "Title" ) ] = "title";
00063 keys[ i18n( "Full Name" ) ] = "cn";
00064 keys[ i18n( "Email" ) ] = "mail";
00065 keys[ i18n( "Home Number" ) ] = "homePhone";
00066 keys[ i18n( "Work Number" ) ] = "telephoneNumber";
00067 keys[ i18n( "Mobile Number" ) ] = "mobile";
00068 keys[ i18n( "Fax Number" ) ] = "facsimileTelephoneNumber";
00069 keys[ i18n( "Pager" ) ] = "pager";
00070 keys[ i18n( "Street") ] = "street";
00071 keys[ i18n( "State" ) ] = "st";
00072 keys[ i18n( "Country" ) ] = "co";
00073 keys[ i18n( "Locality" ) ] = "l";
00074 keys[ i18n( "Organization" ) ] = "o";
00075 keys[ i18n( "Company" ) ] = "Company";
00076 keys[ i18n( "Department" ) ] = "department";
00077 keys[ i18n( "Postal Code" ) ] = "postalCode";
00078 keys[ i18n( "Postal Address" ) ] = "postalAddress";
00079 keys[ i18n( "Description" ) ] = "description";
00080 keys[ i18n( "User ID" ) ] = "uid";
00081 }
00082 return keys;
00083 }
00084
00085 class ContactListItem : public QListViewItem
00086 {
00087 public:
00088 ContactListItem( QListView* parent, const KABC::LdapAttrMap& attrs )
00089 : QListViewItem( parent ), mAttrs( attrs )
00090 { }
00091
00092 KABC::LdapAttrMap mAttrs;
00093
00094 virtual QString text( int col ) const
00095 {
00096
00097 QString colName = listView()->columnText( col );
00098 return join( mAttrs[ adrbookattr2ldap()[ colName ] ], ", " );
00099 }
00100 };
00101
00102 LDAPSearchDialog::LDAPSearchDialog( KABC::AddressBook *ab, QWidget* parent,
00103 const char* name )
00104 : KDialogBase( Plain, i18n( "Search for Addresses in Directory" ), Help | User1 |
00105 User2 | User3 | Cancel, Default, parent, name, false, true ),
00106 mAddressBook( ab )
00107 {
00108 QFrame *page = plainPage();
00109 QVBoxLayout *topLayout = new QVBoxLayout( page, marginHint(), spacingHint() );
00110
00111 QGroupBox *groupBox = new QGroupBox( i18n( "Search for Addresses in Directory" ),
00112 page );
00113 groupBox->setFrameShape( QGroupBox::Box );
00114 groupBox->setFrameShadow( QGroupBox::Sunken );
00115 groupBox->setColumnLayout( 0, Qt::Vertical );
00116 QGridLayout *boxLayout = new QGridLayout( groupBox->layout(), 2,
00117 5, spacingHint() );
00118 boxLayout->setColStretch( 1, 1 );
00119
00120 QLabel *label = new QLabel( i18n( "Search for:" ), groupBox );
00121 boxLayout->addWidget( label, 0, 0 );
00122
00123 mSearchEdit = new KLineEdit( groupBox );
00124 boxLayout->addWidget( mSearchEdit, 0, 1 );
00125 label->setBuddy( mSearchEdit );
00126
00127 label = new QLabel( i18n( "in" ), groupBox );
00128 boxLayout->addWidget( label, 0, 2 );
00129
00130 mFilterCombo = new KComboBox( groupBox );
00131 mFilterCombo->insertItem( i18n( "Name" ) );
00132 mFilterCombo->insertItem( i18n( "Email" ) );
00133 mFilterCombo->insertItem( i18n( "Home Number" ) );
00134 mFilterCombo->insertItem( i18n( "Work Number" ) );
00135 boxLayout->addWidget( mFilterCombo, 0, 3 );
00136
00137 mSearchButton = new QPushButton( i18n( "Search" ), groupBox );
00138 mSearchButton->setDefault(true);
00139 boxLayout->addWidget( mSearchButton, 0, 4 );
00140
00141 mRecursiveCheckbox = new QCheckBox( i18n( "Recursive search" ), groupBox );
00142 mRecursiveCheckbox->setChecked( true );
00143 boxLayout->addMultiCellWidget( mRecursiveCheckbox, 1, 1, 0, 4 );
00144
00145 topLayout->addWidget( groupBox );
00146
00147 mResultListView = new QListView( page );
00148 mResultListView->setSelectionMode( QListView::Multi );
00149 mResultListView->setAllColumnsShowFocus( true );
00150 mResultListView->setShowSortIndicator( true );
00151 topLayout->addWidget( mResultListView );
00152
00153 resize( QSize( 600, 400).expandedTo( minimumSizeHint() ) );
00154
00155 setButtonText( User1, i18n( "Unselect All" ) );
00156 setButtonText( User2, i18n( "Select All" ) );
00157 setButtonText( User3, i18n( "Add Selected" ) );
00158
00159 mNumHosts = 0;
00160 mIsOK = false;
00161
00162 connect( mRecursiveCheckbox, SIGNAL( toggled( bool ) ),
00163 this, SLOT( slotSetScope( bool ) ) );
00164 connect( mSearchButton, SIGNAL( clicked() ),
00165 this, SLOT( slotStartSearch() ) );
00166
00167 setTabOrder(mSearchEdit, mFilterCombo);
00168 setTabOrder(mFilterCombo, mSearchButton);
00169 mSearchEdit->setFocus();
00170
00171 restoreSettings();
00172 }
00173
00174 void LDAPSearchDialog::restoreSettings()
00175 {
00176
00177
00178
00179
00180 mLdapClientList.setAutoDelete( true );
00181 mLdapClientList.clear();
00182
00183
00184
00185 KConfig* config = KABC::AddressLineEdit::config();
00186 KConfigGroupSaver saver( config, "LDAP" );
00187 mNumHosts = config->readUnsignedNumEntry( "NumSelectedHosts" );
00188 if ( !mNumHosts ) {
00189 KMessageBox::error( this, i18n( "You must select a LDAP server before searching.\nYou can do this from the menu Settings/Configure KAddressBook." ) );
00190 mIsOK = false;
00191 } else {
00192 mIsOK = true;
00193 for ( int j = 0; j < mNumHosts; ++j ) {
00194 KABC::LdapClient* ldapClient = new KABC::LdapClient( this, "ldapclient" );
00195
00196 QString host = config->readEntry( QString( "SelectedHost%1" ).arg( j ), "" );
00197 if ( !host.isEmpty() )
00198 ldapClient->setHost( host );
00199
00200 QString port = QString::number( config->readUnsignedNumEntry( QString( "SelectedPort%1" ).arg( j ) ) );
00201 if ( !port.isEmpty() )
00202 ldapClient->setPort( port );
00203
00204 QString base = config->readEntry( QString( "SelectedBase%1" ).arg( j ), "" );
00205 if ( !base.isEmpty() )
00206 ldapClient->setBase( base );
00207
00208 QString bindDN = config->readEntry( QString( "SelectedBind%1" ).arg( j ), "" );
00209 if ( !bindDN.isEmpty() )
00210 ldapClient->setBindDN( bindDN );
00211
00212 QString pwdBindDN = config->readEntry( QString( "SelectedPwdBind%1" ).arg( j ), "" );
00213 if ( !pwdBindDN.isEmpty() )
00214 ldapClient->setPwdBindDN( pwdBindDN );
00215
00216 QStringList attrs;
00217
00218 for ( QMap<QString,QString>::Iterator it = adrbookattr2ldap().begin(); it != adrbookattr2ldap().end(); ++it )
00219 attrs << *it;
00220
00221 ldapClient->setAttrs( attrs );
00222
00223 connect( ldapClient, SIGNAL( result( const KABC::LdapObject& ) ),
00224 this, SLOT( slotAddResult( const KABC::LdapObject& ) ) );
00225 connect( ldapClient, SIGNAL( done() ),
00226 this, SLOT( slotSearchDone() ) );
00227 connect( ldapClient, SIGNAL( error( const QString& ) ),
00228 this, SLOT( slotError( const QString& ) ) );
00229
00230 mLdapClientList.append( ldapClient );
00231 }
00232
00234 while ( mResultListView->header()->count() > 0 ) {
00235 mResultListView->removeColumn(0);
00236 }
00237
00238 mResultListView->addColumn( i18n( "Full Name" ) );
00239 mResultListView->addColumn( i18n( "Email" ) );
00240 mResultListView->addColumn( i18n( "Home Number" ) );
00241 mResultListView->addColumn( i18n( "Work Number" ) );
00242 mResultListView->addColumn( i18n( "Mobile Number" ) );
00243 mResultListView->addColumn( i18n( "Fax Number" ) );
00244 mResultListView->addColumn( i18n( "Company" ) );
00245 mResultListView->addColumn( i18n( "Organization" ) );
00246 mResultListView->addColumn( i18n( "Street" ) );
00247 mResultListView->addColumn( i18n( "State" ) );
00248 mResultListView->addColumn( i18n( "Country" ) );
00249 mResultListView->addColumn( i18n( "Postal Code" ) );
00250 mResultListView->addColumn( i18n( "Postal Address" ) );
00251 mResultListView->addColumn( i18n( "Locality" ) );
00252 mResultListView->addColumn( i18n( "Department" ) );
00253 mResultListView->addColumn( i18n( "Description" ) );
00254 mResultListView->addColumn( i18n( "User ID" ) );
00255 mResultListView->addColumn( i18n( "Title" ) );
00256
00257 mResultListView->clear();
00258 }
00259 }
00260
00261 LDAPSearchDialog::~LDAPSearchDialog()
00262 {
00263 }
00264
00265 void LDAPSearchDialog::cancelQuery()
00266 {
00267 for ( KABC::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) {
00268 client->cancelQuery();
00269 }
00270 }
00271
00272 void LDAPSearchDialog::slotAddResult( const KABC::LdapObject& obj )
00273 {
00274 new ContactListItem( mResultListView, obj.attrs );
00275 }
00276
00277 void LDAPSearchDialog::slotSetScope( bool rec )
00278 {
00279 for ( KABC::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) {
00280 if ( rec )
00281 client->setScope( "sub" );
00282 else
00283 client->setScope( "one" );
00284 }
00285 }
00286
00287 QString LDAPSearchDialog::makeFilter( const QString& query, const QString& attr )
00288 {
00289 QString result( "%1=*%2*" );
00290
00291 if ( attr == i18n( "Name" ) ) {
00292 result = QString( "|(cn=*%1*)(sn=*%2*)" ).arg( query ).arg( query );
00293 } else if ( attr == i18n( "Email" ) ) {
00294 result = result.arg( "mail" ).arg( query );
00295 } else if ( attr == i18n( "Home Number" ) ) {
00296 result = result.arg( "homePhone" ).arg( query );
00297 } else if ( attr == i18n( "Work Number" ) ) {
00298 result = result.arg( "telephoneNumber" ).arg( query );
00299 } else {
00300
00301 result = QString::null;
00302 }
00303 return result;
00304 }
00305
00306 void LDAPSearchDialog::slotStartSearch()
00307 {
00308 cancelQuery();
00309
00310 QApplication::setOverrideCursor( Qt::waitCursor );
00311 mSearchButton->setText( i18n( "Stop" ) );
00312
00313 disconnect( mSearchButton, SIGNAL( clicked() ),
00314 this, SLOT( slotStartSearch() ) );
00315 connect( mSearchButton, SIGNAL( clicked() ),
00316 this, SLOT( slotStopSearch() ) );
00317
00318 QString filter = makeFilter( mSearchEdit->text().stripWhiteSpace(), mFilterCombo->currentText() );
00319
00320
00321 mResultListView->clear();
00322 for( KABC::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) {
00323 client->startQuery( filter );
00324 }
00325 }
00326
00327 void LDAPSearchDialog::slotStopSearch()
00328 {
00329 cancelQuery();
00330 slotSearchDone();
00331 }
00332
00333 void LDAPSearchDialog::slotSearchDone()
00334 {
00335
00336 for ( KABC::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) {
00337 if ( client->isActive() )
00338 return;
00339 }
00340
00341 disconnect( mSearchButton, SIGNAL( clicked() ),
00342 this, SLOT( slotStopSearch() ) );
00343 connect( mSearchButton, SIGNAL( clicked() ),
00344 this, SLOT( slotStartSearch() ) );
00345
00346 mSearchButton->setText( i18n( "Search" ) );
00347 QApplication::restoreOverrideCursor();
00348 }
00349
00350 void LDAPSearchDialog::slotError( const QString& error )
00351 {
00352 QApplication::restoreOverrideCursor();
00353 KMessageBox::error( this, error );
00354 }
00355
00356 void LDAPSearchDialog::closeEvent( QCloseEvent* e )
00357 {
00358 slotStopSearch();
00359 e->accept();
00360 }
00361
00366 QString LDAPSearchDialog::selectedEMails() const
00367 {
00368 QStringList result;
00369 ContactListItem* cli = static_cast<ContactListItem*>( mResultListView->firstChild() );
00370 while ( cli ) {
00371 if ( cli->isSelected() ) {
00372 QString email = asUtf8( cli->mAttrs[ "mail" ].first() ).stripWhiteSpace();
00373 if ( !email.isEmpty() ) {
00374 QString name = asUtf8( cli->mAttrs[ "cn" ].first() ).stripWhiteSpace();
00375 if ( name.isEmpty() ) {
00376 result << email;
00377 } else {
00378 result << name + " <" + email + ">";
00379 }
00380 }
00381 }
00382 cli = static_cast<ContactListItem*>( cli->nextSibling() );
00383 }
00384
00385 return result.join( ", " );
00386 }
00387
00388 void LDAPSearchDialog::slotUser1()
00389 {
00390 mResultListView->selectAll( false );
00391 }
00392
00393 void LDAPSearchDialog::slotUser2()
00394 {
00395 mResultListView->selectAll( true );
00396 }
00397
00398 void LDAPSearchDialog::slotUser3()
00399 {
00400 ContactListItem* cli = static_cast<ContactListItem*>( mResultListView->firstChild() );
00401 while ( cli ) {
00402 if ( cli->isSelected() ) {
00403 KABC::Addressee addr;
00404
00405
00406 addr.setNameFromString( asUtf8( cli->mAttrs["cn"].first() ) );
00407
00408
00409 KABC::LdapAttrValue lst = cli->mAttrs["mail"];
00410 KABC::LdapAttrValue::ConstIterator it = lst.begin();
00411 bool pref = true;
00412 if ( it != lst.end() ) {
00413 addr.insertEmail( asUtf8( *it ), pref );
00414 pref = false;
00415 ++it;
00416 }
00417
00418 addr.setOrganization( asUtf8( cli->mAttrs[ "o" ].first() ) );
00419 if (addr.organization().isEmpty())
00420 addr.setOrganization( asUtf8( cli->mAttrs[ "Company" ].first() ) );
00421
00422 addr.insertCustom("KADDRESSBOOK", "X-Department", asUtf8( cli->mAttrs[ "department" ].first() ) );
00423
00424
00425 KABC::Address workAddr(KABC::Address::Work);
00426
00427 workAddr.setStreet( asUtf8( cli->mAttrs[ "street" ].first()) );
00428 workAddr.setLocality( asUtf8( cli->mAttrs[ "l" ].first()) );
00429 workAddr.setRegion( asUtf8( cli->mAttrs[ "st" ].first()));
00430 workAddr.setPostalCode( asUtf8( cli->mAttrs[ "postalCode" ].first()) );
00431 workAddr.setCountry( asUtf8( cli->mAttrs[ "co" ].first()) );
00432
00433 addr.insertAddress( workAddr );
00434
00435
00436 KABC::PhoneNumber homeNr = asUtf8( cli->mAttrs[ "homePhone" ].first() );
00437 homeNr.setType(KABC::PhoneNumber::Home);
00438 addr.insertPhoneNumber(homeNr);
00439
00440 KABC::PhoneNumber workNr = asUtf8( cli->mAttrs[ "telephoneNumber" ].first() );
00441 workNr.setType(KABC::PhoneNumber::Work);
00442 addr.insertPhoneNumber(workNr);
00443
00444 KABC::PhoneNumber faxNr = asUtf8( cli->mAttrs[ "facsimileTelephoneNumber" ].first() );
00445 faxNr.setType(KABC::PhoneNumber::Fax);
00446 addr.insertPhoneNumber(faxNr);
00447
00448 KABC::PhoneNumber cellNr = asUtf8( cli->mAttrs[ "mobile" ].first() );
00449 cellNr.setType(KABC::PhoneNumber::Cell);
00450 addr.insertPhoneNumber(cellNr);
00451
00452 KABC::PhoneNumber pagerNr = asUtf8( cli->mAttrs[ "pager" ].first() );
00453 pagerNr.setType(KABC::PhoneNumber::Pager);
00454 addr.insertPhoneNumber(pagerNr);
00455
00456 if ( mAddressBook )
00457 mAddressBook->insertAddressee( addr );
00458 }
00459
00460 cli = static_cast<ContactListItem*>( cli->nextSibling() );
00461 }
00462
00463 emit addresseesAdded();
00464 }
00465
00466 void LDAPSearchDialog::slotHelp()
00467 {
00468 kapp->invokeHelp( "ldap-queries" );
00469 }
00470
00471 #include "ldapsearchdialog.moc"