28 #include <QtCore/QPair>
29 #include <QApplication>
31 #include <QCloseEvent>
33 #include <QGridLayout>
35 #include <QHeaderView>
37 #include <QPushButton>
39 #include <QVBoxLayout>
40 #include <QSortFilterProxyModel>
44 #include <akonadi/collection.h>
45 #include <akonadi/itemcreatejob.h>
46 #include <kcombobox.h>
48 #include <kconfiggroup.h>
49 #include <kcmultidialog.h>
50 #include <kdialogbuttonbox.h>
51 #include <kldap/ldapobject.h>
52 #include <kldap/ldapserver.h>
53 #include <klineedit.h>
55 #include <kmessagebox.h>
56 #include <KPushButton>
58 #include <KPIMUtils/ProgressIndicatorLabel>
60 using namespace KLDAP;
68 const char *data = val.
data();
71 if ( data[ val.
size() - 1 ] ==
'\0' ) {
82 KLDAP::LdapAttrValue::ConstIterator end(lst.constEnd());
83 for ( KLDAP::LdapAttrValue::ConstIterator it = lst.constBegin(); it != end; ++it ) {
100 keys[ i18nc(
"@item LDAP search key",
"Title" ) ] =
QLatin1String(
"title");
102 keys[ i18nc(
"@item LDAP search key",
"Email" ) ] =
QLatin1String(
"mail");
104 keys[ i18n(
"Work Number" ) ] =
QLatin1String(
"telephoneNumber");
106 keys[ i18n(
"Fax Number" ) ] =
QLatin1String(
"facsimileTelephoneNumber");
109 keys[ i18nc(
"@item LDAP search key",
"State" ) ] =
QLatin1String(
"st");
116 keys[ i18n(
"Postal Address" ) ] =
QLatin1String(
"postalAddress");
117 keys[ i18n(
"Description" ) ] =
QLatin1String(
"description");
138 if ( attr == i18nc(
"Search attribute: Name of contact",
"Name" ) ) {
139 result += startsWith ?
QLatin1String(
"|(cn=%1*)(sn=%2*)") : QLatin1String(
"|(cn=*%1*)(sn=*%2*)");
140 result = result.
arg( query ).
arg( query );
142 result += startsWith ?
QLatin1String(
"%1=%2*") : QLatin1String(
"%1=*%2*");
143 if ( attr == i18nc(
"Search attribute: Email of the contact",
"Email" ) ) {
144 result = result.
arg( QLatin1String(
"mail") ).
arg( query );
145 }
else if ( attr == i18n(
"Home Number" ) ) {
146 result = result.
arg( QLatin1String(
"homePhone") ).
arg( query );
147 }
else if ( attr == i18n(
"Work Number" ) ) {
148 result = result.
arg( QLatin1String(
"telephoneNumber") ).
arg( query );
161 KABC::Addressee addr;
170 KLDAP::LdapAttrValue::ConstIterator it = lst.constBegin();
172 while ( it != lst.constEnd() ) {
173 addr.insertEmail(
asUtf8( *it ), pref );
181 if ( addr.organization().isEmpty() && !attrs.value(
QLatin1String(
"Company") ).isEmpty() ) {
186 KABC::Address workAddr( KABC::Address::Work );
188 if ( !attrs.value(
QLatin1String(
"department") ).isEmpty() ) {
192 if ( !workAddr.isEmpty() ) {
193 addr.insertAddress( workAddr );
197 if ( !attrs.value(
QLatin1String(
"homePhone") ).isEmpty() ) {
199 homeNr.setType( KABC::PhoneNumber::Home );
200 addr.insertPhoneNumber( homeNr );
203 if ( !attrs.value(
QLatin1String(
"telephoneNumber") ).isEmpty() ) {
205 workNr.setType( KABC::PhoneNumber::Work );
206 addr.insertPhoneNumber( workNr );
209 if ( !attrs.value(
QLatin1String(
"facsimileTelephoneNumber") ).isEmpty() ) {
210 KABC::PhoneNumber faxNr =
asUtf8( attrs[
QLatin1String(
"facsimileTelephoneNumber") ].first() );
211 faxNr.setType( KABC::PhoneNumber::Fax );
212 addr.insertPhoneNumber( faxNr );
217 cellNr.setType( KABC::PhoneNumber::Cell );
218 addr.insertPhoneNumber( cellNr );
223 pagerNr.setType( KABC::PhoneNumber::Pager );
224 addr.insertPhoneNumber( pagerNr );
234 ServerRole = Qt::UserRole + 1
237 ContactListModel(
QObject *parent )
242 void addContact(
const KLDAP::LdapAttrMap &contact,
const QString &server )
244 mContactList.append( contact );
245 mServerList.append( server );
251 if ( !index.
isValid() || index.
row() < 0 || index.
row() >= mContactList.count() ) {
252 return qMakePair( KLDAP::LdapAttrMap(),
QString() );
255 return qMakePair( mContactList.at( index.
row() ), mServerList.at( index.
row() ) );
260 if ( !index.
isValid() || index.
row() < 0 || index.
row() >= mContactList.count() ) {
269 if ( !index.
isValid() || index.
row() < 0 || index.
row() >= mContactList.count() ) {
278 mContactList.clear();
285 if ( !parent.isValid() ) {
286 return mContactList.count();
294 if ( !parent.isValid() ) {
301 virtual QVariant headerData(
int section, Qt::Orientation orientation,
302 int role = Qt::DisplayRole )
const
304 if ( orientation == Qt::Vertical || role != Qt::DisplayRole || section < 0 || section > 17 ) {
310 return i18n(
"Full Name" );
313 return i18nc(
"@title:column Column containing email addresses",
"Email" );
316 return i18n(
"Home Number" );
319 return i18n(
"Work Number" );
322 return i18n(
"Mobile Number" );
325 return i18n(
"Fax Number" );
328 return i18n(
"Company" );
331 return i18n(
"Organization" );
334 return i18n(
"Street" );
337 return i18nc(
"@title:column Column containing the residential state of the address",
341 return i18n(
"Country" );
344 return i18n(
"Zip Code" );
347 return i18n(
"Postal Address" );
350 return i18n(
"City" );
353 return i18n(
"Department" );
356 return i18n(
"Description" );
359 return i18n(
"User ID" );
362 return i18nc(
"@title:column Column containing title of the person",
"Title" );
378 if ( index.
row() < 0 || index.
row() >= mContactList.count() ||
383 if ( role == ServerRole ) {
384 return mServerList.at( index.
row() );
387 if ( (role != Qt::DisplayRole) && (role != Qt::ToolTipRole) ) {
391 const KLDAP::LdapAttrMap
map = mContactList.at( index.
row() );
393 switch ( index.
column() ) {
461 class LdapSearchDialog::Private
467 mIsConfigured( false ),
476 const QModelIndexList selected = mResultView->selectionModel()->selectedRows();
477 for (
int i = 0; i < selected.count(); ++i ) {
478 contacts.
append( mModel->contact( sortproxy->mapToSource(selected.at( i )) ) );
486 void restoreSettings();
490 void slotSetScope(
bool );
491 void slotStartSearch();
492 void slotStopSearch();
493 void slotSearchDone();
494 void slotError(
const QString& );
495 void slotSelectAll();
496 void slotUnselectAll();
497 void slotSelectionChanged();
500 KGuiItem startSearchGuiItem;
501 KGuiItem stopSearchGuiItem;
505 KABC::Addressee::List mSelectedContacts;
513 KPushButton *mSearchButton;
514 ContactListModel *mModel;
515 KPIMUtils::ProgressIndicatorLabel *progressIndication;
521 :
KDialog( parent ), d( new Private( this ) )
523 setCaption( i18n(
"Import Contacts from LDAP" ) );
524 setButtons( User1 | User2 | Cancel );
525 setDefaultButton( User1 );
527 showButtonSeparator(
true );
528 setButtonGuiItem( KDialog::Cancel, KStandardGuiItem::close() );
530 setMainWidget( page );
542 QLabel *label =
new QLabel( i18n(
"Search for:" ), groupBox );
545 d->mSearchEdit =
new KLineEdit( groupBox );
546 d->mSearchEdit->setClearButtonShown(
true);
547 boxLayout->
addWidget( d->mSearchEdit, 0, 1 );
550 label =
new QLabel( i18nc(
"In LDAP attribute",
"in" ), groupBox );
553 d->mFilterCombo =
new KComboBox( groupBox );
554 d->mFilterCombo->addItem( i18nc(
"@item:inlistbox Name of the contact",
"Name" ) );
555 d->mFilterCombo->addItem( i18nc(
"@item:inlistbox email address of the contact",
"Email" ) );
556 d->mFilterCombo->addItem( i18nc(
"@item:inlistbox",
"Home Number" ) );
557 d->mFilterCombo->addItem( i18nc(
"@item:inlistbox",
"Work Number" ) );
558 boxLayout->
addWidget( d->mFilterCombo, 0, 3 );
559 d->startSearchGuiItem = KGuiItem( i18nc(
"@action:button Start searching",
"&Search" ),
QLatin1String(
"edit-find") );
560 d->stopSearchGuiItem = KStandardGuiItem::stop();
563 d->mSearchButton =
new KPushButton( groupBox );
564 d->mSearchButton->setGuiItem(d->startSearchGuiItem);
566 buttonSize = d->mSearchButton->sizeHint();
567 if ( buttonSize.
width() < d->mSearchButton->sizeHint().width() ) {
568 buttonSize = d->mSearchButton->sizeHint();
570 d->mSearchButton->setFixedWidth( buttonSize.
width() );
572 d->mSearchButton->setDefault(
true );
573 boxLayout->
addWidget( d->mSearchButton, 0, 4 );
575 d->mRecursiveCheckbox =
new QCheckBox( i18n(
"Recursive search" ), groupBox );
576 d->mRecursiveCheckbox->setChecked(
true );
577 boxLayout->
addWidget( d->mRecursiveCheckbox, 1, 0, 1, 5 );
579 d->mSearchType =
new KComboBox( groupBox );
580 d->mSearchType->addItem( i18n(
"Contains" ) );
581 d->mSearchType->addItem( i18n(
"Starts With" ) );
582 boxLayout->
addWidget( d->mSearchType, 1, 3, 1, 2 );
590 d->searchLine->setClearButtonShown(
true);
591 d->searchLine->setClickMessage(i18n(
"Search in result"));
592 quickSearchLineLayout->
addWidget(d->searchLine);
593 topLayout->
addLayout( quickSearchLineLayout );
597 d->mResultView->setSelectionMode( QTableView::MultiSelection );
598 d->mResultView->setSelectionBehavior( QTableView::SelectRows );
599 d->mModel =
new ContactListModel( d->mResultView );
602 d->sortproxy->setFilterKeyColumn(-1);
603 d->sortproxy->setSourceModel( d->mModel );
604 d->sortproxy->setFilterCaseSensitivity(Qt::CaseInsensitive);
605 connect(d->searchLine, SIGNAL(textChanged(
QString)), d->sortproxy, SLOT(setFilterFixedString(
QString)));
608 d->mResultView->setModel( d->sortproxy );
609 d->mResultView->verticalHeader()->hide();
610 d->mResultView->setSortingEnabled(
true);
611 d->mResultView->horizontalHeader()->setSortIndicatorShown(
true);
612 connect( d->mResultView, SIGNAL(clicked(
QModelIndex)),
613 SLOT(slotSelectionChanged()) );
616 d->mResultView->setContextMenuPolicy(Qt::CustomContextMenu);
617 connect(d->mResultView, SIGNAL(customContextMenuRequested(
QPoint)),
625 d->progressIndication =
new KPIMUtils::ProgressIndicatorLabel(i18n(
"Searching..."));
626 buttonLayout->
addWidget(d->progressIndication);
628 KDialogButtonBox *buttons =
new KDialogButtonBox( page, Qt::Horizontal );
629 buttons->addButton( i18n(
"Select All" ),
630 QDialogButtonBox::ActionRole,
this, SLOT(slotSelectAll()) );
631 buttons->addButton( i18n(
"Unselect All" ),
632 QDialogButtonBox::ActionRole,
this, SLOT(slotUnselectAll()) );
638 setButtonText( User1, i18n(
"Add Selected" ) );
639 setButtonText( User2, i18n(
"Configure LDAP Servers..." ) );
641 connect( d->mRecursiveCheckbox, SIGNAL(toggled(
bool)),
642 this, SLOT(slotSetScope(
bool)) );
643 connect( d->mSearchButton, SIGNAL(clicked()),
644 this, SLOT(slotStartSearch()) );
646 setTabOrder( d->mSearchEdit, d->mFilterCombo );
647 setTabOrder( d->mFilterCombo, d->mSearchButton );
648 d->mSearchEdit->setFocus();
650 connect(
this, SIGNAL(user1Clicked()),
this, SLOT(
slotUser1()) );
651 connect(
this, SIGNAL(user2Clicked()),
this, SLOT(
slotUser2()) );
653 d->slotSelectionChanged();
654 d->restoreSettings();
665 d->mSearchEdit->setText( text );
670 return d->mSelectedContacts;
675 const QModelIndex index = d->mResultView->indexAt(pos);
687 void LdapSearchDialog::Private::slotSelectionChanged()
689 q->enableButton( KDialog::User1, mResultView->selectionModel()->hasSelection() );
692 void LdapSearchDialog::Private::restoreSettings()
698 qDeleteAll( mLdapClientList ) ;
699 mLdapClientList.clear();
701 KConfig *config = KLDAP::LdapClientSearchConfig::config();
703 KConfigGroup searchGroup( config,
"LDAPSearch" );
704 mSearchType->setCurrentIndex( searchGroup.readEntry(
"SearchType", 0 ) );
708 KConfigGroup group( config,
"LDAP" );
709 mNumHosts = group.readEntry(
"NumSelectedHosts", 0 );
711 mIsConfigured =
false;
713 mIsConfigured =
true;
714 KLDAP::LdapClientSearchConfig *clientSearchConfig =
new KLDAP::LdapClientSearchConfig;
715 for (
int j = 0; j < mNumHosts; ++j ) {
716 KLDAP::LdapServer ldapServer;
718 clientSearchConfig->readConfig( ldapServer, group, j,
true );
732 q->connect( ldapClient, SIGNAL(done()),
733 q, SLOT(slotSearchDone()) );
734 q->connect( ldapClient, SIGNAL(error(
QString)),
737 mLdapClientList.append( ldapClient );
739 delete clientSearchConfig;
743 KConfigGroup groupHeader( config,
"Headers" );
744 mResultView->horizontalHeader()->restoreState(groupHeader.readEntry(
"HeaderState",
QByteArray()));
746 KConfigGroup groupSize( config,
"Size" );
747 const QSize dialogSize = groupSize.readEntry(
"Size",
QSize() );
749 q->resize( dialogSize );
751 q->resize(
QSize( 600, 400 ).expandedTo( q->minimumSizeHint() ) );
755 void LdapSearchDialog::Private::saveSettings()
757 KConfig *config = KLDAP::LdapClientSearchConfig::config();
758 KConfigGroup group( config,
"LDAPSearch" );
759 group.writeEntry(
"SearchType", mSearchType->currentIndex() );
761 KConfigGroup groupHeader( config,
"Headers" );
762 groupHeader.writeEntry(
"HeaderState", mResultView->horizontalHeader()->saveState());
765 KConfigGroup size( config,
"Size" );
766 size.writeEntry(
"Size", q->size());
772 void LdapSearchDialog::Private::cancelQuery()
780 const KLDAP::LdapObject &obj )
782 mModel->addContact( obj.attributes(), client.
server().host() );
785 void LdapSearchDialog::Private::slotSetScope(
bool rec )
796 void LdapSearchDialog::Private::slotStartSearch()
800 if ( !mIsConfigured ) {
801 KMessageBox::error( q, i18n(
"You must select an LDAP server before searching." ) );
809 mSearchButton->setGuiItem(stopSearchGuiItem);
810 progressIndication->start();
812 q->disconnect( mSearchButton, SIGNAL(clicked()),
813 q, SLOT(slotStartSearch()) );
814 q->connect( mSearchButton, SIGNAL(clicked()),
815 q, SLOT(slotStopSearch()) );
817 const bool startsWith = (mSearchType->currentIndex() == 1);
820 mFilterCombo->currentText(), startsWith );
831 void LdapSearchDialog::Private::slotStopSearch()
837 void LdapSearchDialog::Private::slotSearchDone()
846 q->disconnect( mSearchButton, SIGNAL(clicked()),
847 q, SLOT(slotStopSearch()) );
848 q->connect( mSearchButton, SIGNAL(clicked()),
849 q, SLOT(slotStartSearch()) );
851 mSearchButton->setGuiItem(startSearchGuiItem);
852 progressIndication->stop();
858 void LdapSearchDialog::Private::slotError(
const QString &error )
863 KMessageBox::error( q, error );
872 void LdapSearchDialog::Private::slotUnselectAll()
874 mResultView->clearSelection();
875 slotSelectionChanged();
878 void LdapSearchDialog::Private::slotSelectAll()
880 mResultView->selectAll();
881 slotSelectionChanged();
888 d->mSelectedContacts.clear();
895 for (
int i = 0; i < items.
count(); ++i ) {
899 contact.setNote( i18nc(
"arguments are host name, datetime",
900 "Imported from LDAP directory %1 on %2",
901 items.
at( i ).second, KGlobal::locale()->formatDateTime( now ) ) );
903 d->mSelectedContacts.append( contact );
917 KCMultiDialog dialog(
this );
918 dialog.setCaption( i18n(
"Configure the Address Book LDAP Settings" ) );
921 if ( dialog.exec() ) {
922 d->restoreSettings();
932 #include "moc_ldapsearchdialog.cpp"
~LdapSearchDialog()
Destroys the ldap search dialog.
const KLDAP::LdapServer server() const
Returns the ldap server information that are used by this client.
void closeEvent(QCloseEvent *)
void slotCustomContextMenuRequested(const QPoint &)
void contactsAdded()
This signal is emitted whenever the user clicked the 'Add Selected' button.
const T & at(int i) const
void setSpacing(int spacing)
bool isActive() const
Returns whether this client is currently running a search query.
LdapSearchDialog(QWidget *parent=0)
Creates a new ldap search dialog.
static KABC::Addressee convertLdapAttributesToAddressee(const KLDAP::LdapAttrMap &attrs)
void setBuddy(QWidget *buddy)
void startQuery(const QString &filter)
Starts the query with the given filter.
int count(const T &value) const
void append(const T &value)
QString fromUtf8(const char *str, int size)
static QString join(const KLDAP::LdapAttrValue &lst, const QString &sep)
void setOverrideCursor(const QCursor &cursor)
void restoreOverrideCursor()
void setSearchText(const QString &text)
Sets the text in the search line edit.
void setAttributes(const QStringList &attributes)
Sets the LDAP attributes that should be returned in the query result.
QFuture< void > map(Sequence &sequence, MapFunction function)
void setMargin(int margin)
A dialog to search contacts in a LDAP directory.
QDateTime currentDateTime()
QVariant data(int role) const
void addStretch(int stretch)
void setColumnStretch(int column, int stretch)
static QString makeFilter(const QString &query, const QString &attr, bool startsWith)
void setServer(const KLDAP::LdapServer &server)
Sets the LDAP server information that shall be used by this client.
void setText(const QString &text, Mode mode)
QFuture< void > filter(Sequence &sequence, FilterFunction filterFunction)
KABC::Addressee::List selectedContacts() const
Returns a list of contacts that have been selected in the LDAP search.
An object that represents a configured LDAP server.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
static QString asUtf8(const QByteArray &val)
void setScope(const QString scope)
Sets the scope of the LDAP query.
static QMap< QString, QString > & adrbookattr2ldap()
void setSpacing(int spacing)
void addLayout(QLayout *layout, int stretch)
void cancelQuery()
Cancels a running query.