kaddressbook Library API Documentation

ldapsearchdialog.cpp

00001 /* ldapsearchdialogimpl.cpp - LDAP access
00002  *      Copyright (C) 2002 Klarälvdalens 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 <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       // Look up a suitable attribute for column col
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   // Create one KABC::LdapClient per selected server and configure it.
00177 
00178   // First clean the list to make sure it is empty at 
00179   // the beginning of the process
00180   mLdapClientList.setAutoDelete( true );
00181   mLdapClientList.clear();
00182 
00183   // then read the config file and register all selected 
00184   // server in the list
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     // Error?
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    // loop in the list and run the KABC::LdapClients 
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   // If there are no more active clients, we are done.
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       // name
00406       addr.setNameFromString( asUtf8( cli->mAttrs["cn"].first() ) );
00407 
00408       // email
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       // Address
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       // phone
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"
KDE Logo
This file is part of the documentation for kaddressbook Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Sat May 1 11:38:52 2004 by doxygen 1.2.15 written by Dimitri van Heesch, © 1997-2003