kaddressbook Library API Documentation

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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 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 <addresseelineedit.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 if ( val.isEmpty() ) 00042 return QString::null; 00043 00044 const char *data = val.data(); 00045 00046 //QString::fromUtf8() bug workaround 00047 if ( data[ val.size() - 1 ] == '\0' ) 00048 return QString::fromUtf8( data, val.size() - 1 ); 00049 else 00050 return QString::fromUtf8( data, val.size() ); 00051 } 00052 00053 static QString join( const KPIM::LdapAttrValue& lst, const QString& sep ) 00054 { 00055 QString res; 00056 bool alredy = false; 00057 for ( KPIM::LdapAttrValue::ConstIterator it = lst.begin(); it != lst.end(); ++it ) { 00058 if ( alredy ) 00059 res += sep; 00060 alredy = TRUE; 00061 res += asUtf8( *it ); 00062 } 00063 return res; 00064 } 00065 00066 static QMap<QString, QString>& adrbookattr2ldap() 00067 { 00068 static QMap<QString, QString> keys; 00069 00070 if ( keys.isEmpty() ) { 00071 keys[ i18n( "Title" ) ] = "title"; 00072 keys[ i18n( "Full Name" ) ] = "cn"; 00073 keys[ i18n( "Email" ) ] = "mail"; 00074 keys[ i18n( "Home Number" ) ] = "homePhone"; 00075 keys[ i18n( "Work Number" ) ] = "telephoneNumber"; 00076 keys[ i18n( "Mobile Number" ) ] = "mobile"; 00077 keys[ i18n( "Fax Number" ) ] = "facsimileTelephoneNumber"; 00078 keys[ i18n( "Pager" ) ] = "pager"; 00079 keys[ i18n( "Street") ] = "street"; 00080 keys[ i18n( "State" ) ] = "st"; 00081 keys[ i18n( "Country" ) ] = "co"; 00082 keys[ i18n( "City" ) ] = "l"; 00083 keys[ i18n( "Organization" ) ] = "o"; 00084 keys[ i18n( "Company" ) ] = "Company"; 00085 keys[ i18n( "Department" ) ] = "department"; 00086 keys[ i18n( "Zip Code" ) ] = "postalCode"; 00087 keys[ i18n( "Postal Address" ) ] = "postalAddress"; 00088 keys[ i18n( "Description" ) ] = "description"; 00089 keys[ i18n( "User ID" ) ] = "uid"; 00090 } 00091 return keys; 00092 } 00093 00094 class ContactListItem : public QListViewItem 00095 { 00096 public: 00097 ContactListItem( QListView* parent, const KPIM::LdapAttrMap& attrs ) 00098 : QListViewItem( parent ), mAttrs( attrs ) 00099 { } 00100 00101 KPIM::LdapAttrMap mAttrs; 00102 00103 virtual QString text( int col ) const 00104 { 00105 // Look up a suitable attribute for column col 00106 QString colName = listView()->columnText( col ); 00107 return join( mAttrs[ adrbookattr2ldap()[ colName ] ], ", " ); 00108 } 00109 }; 00110 00111 LDAPSearchDialog::LDAPSearchDialog( KABC::AddressBook *ab, QWidget* parent, 00112 const char* name ) 00113 : KDialogBase( Plain, i18n( "Search for Addresses in Directory" ), Help | User1 | 00114 User2 | User3 | Cancel, Default, parent, name, false, true ), 00115 mAddressBook( ab ) 00116 { 00117 setButtonCancel( KStdGuiItem::close() ); 00118 QFrame *page = plainPage(); 00119 QVBoxLayout *topLayout = new QVBoxLayout( page, marginHint(), spacingHint() ); 00120 00121 QGroupBox *groupBox = new QGroupBox( i18n( "Search for Addresses in Directory" ), 00122 page ); 00123 groupBox->setFrameShape( QGroupBox::Box ); 00124 groupBox->setFrameShadow( QGroupBox::Sunken ); 00125 groupBox->setColumnLayout( 0, Qt::Vertical ); 00126 QGridLayout *boxLayout = new QGridLayout( groupBox->layout(), 2, 00127 5, spacingHint() ); 00128 boxLayout->setColStretch( 1, 1 ); 00129 00130 QLabel *label = new QLabel( i18n( "Search for:" ), groupBox ); 00131 boxLayout->addWidget( label, 0, 0 ); 00132 00133 mSearchEdit = new KLineEdit( groupBox ); 00134 boxLayout->addWidget( mSearchEdit, 0, 1 ); 00135 label->setBuddy( mSearchEdit ); 00136 00137 label = new QLabel( i18n( "in" ), groupBox ); 00138 boxLayout->addWidget( label, 0, 2 ); 00139 00140 mFilterCombo = new KComboBox( groupBox ); 00141 mFilterCombo->insertItem( i18n( "Name" ) ); 00142 mFilterCombo->insertItem( i18n( "Email" ) ); 00143 mFilterCombo->insertItem( i18n( "Home Number" ) ); 00144 mFilterCombo->insertItem( i18n( "Work Number" ) ); 00145 boxLayout->addWidget( mFilterCombo, 0, 3 ); 00146 00147 QSize buttonSize; 00148 mSearchButton = new QPushButton( i18n( "Stop" ), groupBox ); 00149 buttonSize = mSearchButton->sizeHint(); 00150 mSearchButton->setText( i18n( "Search" ) ); 00151 if ( buttonSize.width() < mSearchButton->sizeHint().width() ) 00152 buttonSize = mSearchButton->sizeHint(); 00153 mSearchButton->setFixedWidth( buttonSize.width() ); 00154 00155 mSearchButton->setDefault( true ); 00156 boxLayout->addWidget( mSearchButton, 0, 4 ); 00157 00158 mRecursiveCheckbox = new QCheckBox( i18n( "Recursive search" ), groupBox ); 00159 mRecursiveCheckbox->setChecked( true ); 00160 boxLayout->addMultiCellWidget( mRecursiveCheckbox, 1, 1, 0, 4 ); 00161 00162 mSearchType = new KComboBox( groupBox ); 00163 mSearchType->insertItem( i18n( "Contains" ) ); 00164 mSearchType->insertItem( i18n( "Starts With" ) ); 00165 boxLayout->addMultiCellWidget( mSearchType, 1, 1, 3, 4 ); 00166 00167 topLayout->addWidget( groupBox ); 00168 00169 mResultListView = new QListView( page ); 00170 mResultListView->setSelectionMode( QListView::Multi ); 00171 mResultListView->setAllColumnsShowFocus( true ); 00172 mResultListView->setShowSortIndicator( true ); 00173 topLayout->addWidget( mResultListView ); 00174 00175 resize( QSize( 600, 400).expandedTo( minimumSizeHint() ) ); 00176 00177 setButtonText( User1, i18n( "Unselect All" ) ); 00178 setButtonText( User2, i18n( "Select All" ) ); 00179 setButtonText( User3, i18n( "Add Selected" ) ); 00180 00181 mNumHosts = 0; 00182 mIsOK = false; 00183 00184 connect( mRecursiveCheckbox, SIGNAL( toggled( bool ) ), 00185 this, SLOT( slotSetScope( bool ) ) ); 00186 connect( mSearchButton, SIGNAL( clicked() ), 00187 this, SLOT( slotStartSearch() ) ); 00188 00189 setTabOrder(mSearchEdit, mFilterCombo); 00190 setTabOrder(mFilterCombo, mSearchButton); 00191 mSearchEdit->setFocus(); 00192 00193 restoreSettings(); 00194 } 00195 00196 LDAPSearchDialog::~LDAPSearchDialog() 00197 { 00198 saveSettings(); 00199 } 00200 00201 void LDAPSearchDialog::restoreSettings() 00202 { 00203 // Create one KPIM::LdapClient per selected server and configure it. 00204 00205 // First clean the list to make sure it is empty at 00206 // the beginning of the process 00207 mLdapClientList.setAutoDelete( true ); 00208 mLdapClientList.clear(); 00209 00210 KConfig kabConfig( "kaddressbookrc" ); 00211 kabConfig.setGroup( "LDAPSearch" ); 00212 mSearchType->setCurrentItem( kabConfig.readNumEntry( "SearchType", 0 ) ); 00213 00214 // then read the config file and register all selected 00215 // server in the list 00216 KConfig* config = KPIM::AddresseeLineEdit::config(); 00217 KConfigGroupSaver saver( config, "LDAP" ); 00218 mNumHosts = config->readUnsignedNumEntry( "NumSelectedHosts" ); 00219 if ( !mNumHosts ) { 00220 KMessageBox::error( this, i18n( "You must select a LDAP server before searching.\nYou can do this from the menu Settings/Configure KAddressBook." ) ); 00221 mIsOK = false; 00222 } else { 00223 mIsOK = true; 00224 for ( int j = 0; j < mNumHosts; ++j ) { 00225 KPIM::LdapClient* ldapClient = new KPIM::LdapClient( 0, this, "ldapclient" ); 00226 00227 QString host = config->readEntry( QString( "SelectedHost%1" ).arg( j ), "" ); 00228 if ( !host.isEmpty() ) 00229 ldapClient->setHost( host ); 00230 00231 QString port = QString::number( config->readUnsignedNumEntry( QString( "SelectedPort%1" ).arg( j ) ) ); 00232 if ( !port.isEmpty() ) 00233 ldapClient->setPort( port ); 00234 00235 QString base = config->readEntry( QString( "SelectedBase%1" ).arg( j ), "" ); 00236 if ( !base.isEmpty() ) 00237 ldapClient->setBase( base ); 00238 00239 QString bindDN = config->readEntry( QString( "SelectedBind%1" ).arg( j ), "" ); 00240 if ( !bindDN.isEmpty() ) 00241 ldapClient->setBindDN( bindDN ); 00242 00243 QString pwdBindDN = config->readEntry( QString( "SelectedPwdBind%1" ).arg( j ), "" ); 00244 if ( !pwdBindDN.isEmpty() ) 00245 ldapClient->setPwdBindDN( pwdBindDN ); 00246 00247 QStringList attrs; 00248 00249 for ( QMap<QString,QString>::Iterator it = adrbookattr2ldap().begin(); it != adrbookattr2ldap().end(); ++it ) 00250 attrs << *it; 00251 00252 ldapClient->setAttrs( attrs ); 00253 00254 connect( ldapClient, SIGNAL( result( const KPIM::LdapObject& ) ), 00255 this, SLOT( slotAddResult( const KPIM::LdapObject& ) ) ); 00256 connect( ldapClient, SIGNAL( done() ), 00257 this, SLOT( slotSearchDone() ) ); 00258 connect( ldapClient, SIGNAL( error( const QString& ) ), 00259 this, SLOT( slotError( const QString& ) ) ); 00260 00261 mLdapClientList.append( ldapClient ); 00262 } 00263 00265 while ( mResultListView->header()->count() > 0 ) { 00266 mResultListView->removeColumn(0); 00267 } 00268 00269 mResultListView->addColumn( i18n( "Full Name" ) ); 00270 mResultListView->addColumn( i18n( "Email" ) ); 00271 mResultListView->addColumn( i18n( "Home Number" ) ); 00272 mResultListView->addColumn( i18n( "Work Number" ) ); 00273 mResultListView->addColumn( i18n( "Mobile Number" ) ); 00274 mResultListView->addColumn( i18n( "Fax Number" ) ); 00275 mResultListView->addColumn( i18n( "Company" ) ); 00276 mResultListView->addColumn( i18n( "Organization" ) ); 00277 mResultListView->addColumn( i18n( "Street" ) ); 00278 mResultListView->addColumn( i18n( "State" ) ); 00279 mResultListView->addColumn( i18n( "Country" ) ); 00280 mResultListView->addColumn( i18n( "Zip Code" ) ); 00281 mResultListView->addColumn( i18n( "Postal Address" ) ); 00282 mResultListView->addColumn( i18n( "City" ) ); 00283 mResultListView->addColumn( i18n( "Department" ) ); 00284 mResultListView->addColumn( i18n( "Description" ) ); 00285 mResultListView->addColumn( i18n( "User ID" ) ); 00286 mResultListView->addColumn( i18n( "Title" ) ); 00287 00288 mResultListView->clear(); 00289 } 00290 } 00291 00292 void LDAPSearchDialog::saveSettings() 00293 { 00294 KConfig config( "kaddressbookrc" ); 00295 config.setGroup( "LDAPSearch" ); 00296 config.writeEntry( "SearchType", mSearchType->currentItem() ); 00297 config.sync(); 00298 } 00299 00300 void LDAPSearchDialog::cancelQuery() 00301 { 00302 for ( KPIM::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) { 00303 client->cancelQuery(); 00304 } 00305 } 00306 00307 void LDAPSearchDialog::slotAddResult( const KPIM::LdapObject& obj ) 00308 { 00309 new ContactListItem( mResultListView, obj.attrs ); 00310 } 00311 00312 void LDAPSearchDialog::slotSetScope( bool rec ) 00313 { 00314 for ( KPIM::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) { 00315 if ( rec ) 00316 client->setScope( "sub" ); 00317 else 00318 client->setScope( "one" ); 00319 } 00320 } 00321 00322 QString LDAPSearchDialog::makeFilter( const QString& query, const QString& attr, 00323 bool startsWith ) 00324 { 00325 if( query.isEmpty() ) 00326 // Return a filter that matches everything 00327 return QString( "|(cn=*)(sn=*)" ); 00328 00329 if ( attr == i18n( "Name" ) ) { 00330 QString result( (startsWith ? "|(cn=%1*)(sn=%2*)" : "|(cn=*%1*)(sn=*%2*)") ); 00331 00332 result = result.arg( query ).arg( query ); 00333 00334 return result; 00335 } else { 00336 QString result( (startsWith ? "%1=%2*" : "%1=*%2*") ); 00337 00338 if ( attr == i18n( "Email" ) ) { 00339 result = result.arg( "mail" ).arg( query ); 00340 } else if ( attr == i18n( "Home Number" ) ) { 00341 result = result.arg( "homePhone" ).arg( query ); 00342 } else if ( attr == i18n( "Work Number" ) ) { 00343 result = result.arg( "telephoneNumber" ).arg( query ); 00344 } else { 00345 // Error? 00346 result = QString::null; 00347 } 00348 00349 return result; 00350 } 00351 } 00352 00353 void LDAPSearchDialog::slotStartSearch() 00354 { 00355 cancelQuery(); 00356 00357 QApplication::setOverrideCursor( Qt::waitCursor ); 00358 mSearchButton->setText( i18n( "Stop" ) ); 00359 00360 disconnect( mSearchButton, SIGNAL( clicked() ), 00361 this, SLOT( slotStartSearch() ) ); 00362 connect( mSearchButton, SIGNAL( clicked() ), 00363 this, SLOT( slotStopSearch() ) ); 00364 00365 bool startsWith = (mSearchType->currentItem() == 1); 00366 00367 QString filter = makeFilter( mSearchEdit->text().stripWhiteSpace(), mFilterCombo->currentText(), startsWith ); 00368 00369 // loop in the list and run the KPIM::LdapClients 00370 mResultListView->clear(); 00371 for( KPIM::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) { 00372 client->startQuery( filter ); 00373 } 00374 00375 saveSettings(); 00376 } 00377 00378 void LDAPSearchDialog::slotStopSearch() 00379 { 00380 cancelQuery(); 00381 slotSearchDone(); 00382 } 00383 00384 void LDAPSearchDialog::slotSearchDone() 00385 { 00386 // If there are no more active clients, we are done. 00387 for ( KPIM::LdapClient* client = mLdapClientList.first(); client; client = mLdapClientList.next() ) { 00388 if ( client->isActive() ) 00389 return; 00390 } 00391 00392 disconnect( mSearchButton, SIGNAL( clicked() ), 00393 this, SLOT( slotStopSearch() ) ); 00394 connect( mSearchButton, SIGNAL( clicked() ), 00395 this, SLOT( slotStartSearch() ) ); 00396 00397 mSearchButton->setText( i18n( "Search" ) ); 00398 QApplication::restoreOverrideCursor(); 00399 } 00400 00401 void LDAPSearchDialog::slotError( const QString& error ) 00402 { 00403 QApplication::restoreOverrideCursor(); 00404 KMessageBox::error( this, error ); 00405 } 00406 00407 void LDAPSearchDialog::closeEvent( QCloseEvent* e ) 00408 { 00409 slotStopSearch(); 00410 e->accept(); 00411 } 00412 00417 QString LDAPSearchDialog::selectedEMails() const 00418 { 00419 QStringList result; 00420 ContactListItem* cli = static_cast<ContactListItem*>( mResultListView->firstChild() ); 00421 while ( cli ) { 00422 if ( cli->isSelected() ) { 00423 QString email = asUtf8( cli->mAttrs[ "mail" ].first() ).stripWhiteSpace(); 00424 if ( !email.isEmpty() ) { 00425 QString name = asUtf8( cli->mAttrs[ "cn" ].first() ).stripWhiteSpace(); 00426 if ( name.isEmpty() ) { 00427 result << email; 00428 } else { 00429 result << name + " <" + email + ">"; 00430 } 00431 } 00432 } 00433 cli = static_cast<ContactListItem*>( cli->nextSibling() ); 00434 } 00435 00436 return result.join( ", " ); 00437 } 00438 00439 void LDAPSearchDialog::slotHelp() 00440 { 00441 kapp->invokeHelp( "ldap-queries" ); 00442 } 00443 00444 void LDAPSearchDialog::slotUser1() 00445 { 00446 mResultListView->selectAll( false ); 00447 } 00448 00449 void LDAPSearchDialog::slotUser2() 00450 { 00451 mResultListView->selectAll( true ); 00452 } 00453 00454 void LDAPSearchDialog::slotUser3() 00455 { 00456 ContactListItem* cli = static_cast<ContactListItem*>( mResultListView->firstChild() ); 00457 while ( cli ) { 00458 if ( cli->isSelected() ) { 00459 KABC::Addressee addr; 00460 00461 // name 00462 addr.setNameFromString( asUtf8( cli->mAttrs["cn"].first() ) ); 00463 00464 // email 00465 KPIM::LdapAttrValue lst = cli->mAttrs["mail"]; 00466 KPIM::LdapAttrValue::ConstIterator it = lst.begin(); 00467 bool pref = true; 00468 if ( it != lst.end() ) { 00469 addr.insertEmail( asUtf8( *it ), pref ); 00470 pref = false; 00471 ++it; 00472 } 00473 00474 addr.setOrganization( asUtf8( cli->mAttrs[ "o" ].first() ) ); 00475 if ( addr.organization().isEmpty() ) 00476 addr.setOrganization( asUtf8( cli->mAttrs[ "Company" ].first() ) ); 00477 00478 addr.insertCustom("KADDRESSBOOK", "X-Department", asUtf8( cli->mAttrs[ "department" ].first() ) ); 00479 00480 // Address 00481 KABC::Address workAddr( KABC::Address::Work ); 00482 00483 workAddr.setStreet( asUtf8( cli->mAttrs[ "street" ].first()) ); 00484 workAddr.setLocality( asUtf8( cli->mAttrs[ "l" ].first()) ); 00485 workAddr.setRegion( asUtf8( cli->mAttrs[ "st" ].first())); 00486 workAddr.setPostalCode( asUtf8( cli->mAttrs[ "postalCode" ].first()) ); 00487 workAddr.setCountry( asUtf8( cli->mAttrs[ "co" ].first()) ); 00488 00489 if ( !workAddr.isEmpty() ) 00490 addr.insertAddress( workAddr ); 00491 00492 // phone 00493 KABC::PhoneNumber homeNr = asUtf8( cli->mAttrs[ "homePhone" ].first() ); 00494 homeNr.setType( KABC::PhoneNumber::Home ); 00495 addr.insertPhoneNumber( homeNr ); 00496 00497 KABC::PhoneNumber workNr = asUtf8( cli->mAttrs[ "telephoneNumber" ].first() ); 00498 workNr.setType( KABC::PhoneNumber::Work ); 00499 addr.insertPhoneNumber( workNr ); 00500 00501 KABC::PhoneNumber faxNr = asUtf8( cli->mAttrs[ "facsimileTelephoneNumber" ].first() ); 00502 faxNr.setType( KABC::PhoneNumber::Fax ); 00503 addr.insertPhoneNumber( faxNr ); 00504 00505 KABC::PhoneNumber cellNr = asUtf8( cli->mAttrs[ "mobile" ].first() ); 00506 cellNr.setType( KABC::PhoneNumber::Cell ); 00507 addr.insertPhoneNumber( cellNr ); 00508 00509 KABC::PhoneNumber pagerNr = asUtf8( cli->mAttrs[ "pager" ].first() ); 00510 pagerNr.setType( KABC::PhoneNumber::Pager ); 00511 addr.insertPhoneNumber( pagerNr ); 00512 00513 if ( mAddressBook ) 00514 mAddressBook->insertAddressee( addr ); 00515 } 00516 00517 cli = static_cast<ContactListItem*>( cli->nextSibling() ); 00518 } 00519 00520 emit addresseesAdded(); 00521 } 00522 00523 #include "ldapsearchdialog.moc"
KDE Logo
This file is part of the documentation for kaddressbook Library Version 3.3.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Oct 1 15:19:05 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003