File indexing completed on 2024-12-22 04:56:56

0001 /*
0002  *  SPDX-FileCopyrightText: 2011 Grégory Oestreicher <greg@kamago.net>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "searchdialog.h"
0008 
0009 #include <KDAV/DavCollectionsFetchJob>
0010 #include <KDAV/DavPrincipalSearchJob>
0011 #include <KDAV/ProtocolInfo>
0012 
0013 #include <KLocalizedString>
0014 #include <KMessageBox>
0015 #include <QIcon>
0016 
0017 #include <QDialogButtonBox>
0018 #include <QStandardItemModel>
0019 #include <QUrl>
0020 #include <QVBoxLayout>
0021 
0022 SearchDialog::SearchDialog(QWidget *parent)
0023     : QDialog(parent)
0024     , mModel(new QStandardItemModel(this))
0025 {
0026     setWindowTitle(i18nc("@title:window", "Search"));
0027     auto mainWidget = new QWidget(this);
0028     auto mainLayout = new QVBoxLayout(this);
0029     mainLayout->addWidget(mainWidget);
0030     mUi.setupUi(mainWidget);
0031     mUi.credentialsGroup->setVisible(false);
0032     mUi.searchResults->setModel(mModel);
0033 
0034     auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
0035     QPushButton *okButton = buttonBox->button(QDialogButtonBox::Ok);
0036     okButton->setDefault(true);
0037     okButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0038     connect(buttonBox, &QDialogButtonBox::accepted, this, &SearchDialog::accept);
0039     connect(buttonBox, &QDialogButtonBox::rejected, this, &SearchDialog::reject);
0040     mainLayout->addWidget(buttonBox);
0041     buttonBox->button(QDialogButtonBox::Ok)->setText(i18n("Add Selected Items"));
0042 
0043     connect(mUi.searchUrl, &QLineEdit::textChanged, this, &SearchDialog::checkUserInput);
0044     connect(mUi.searchParam, &QLineEdit::textChanged, this, &SearchDialog::checkUserInput);
0045     connect(mUi.searchButton, &QPushButton::clicked, this, &SearchDialog::search);
0046 
0047     checkUserInput();
0048 }
0049 
0050 SearchDialog::~SearchDialog() = default;
0051 
0052 bool SearchDialog::useDefaultCredentials() const
0053 {
0054     return mUi.useDefaultCreds->isChecked();
0055 }
0056 
0057 void SearchDialog::setUsername(const QString &user)
0058 {
0059     mUi.username->setText(user);
0060 }
0061 
0062 QString SearchDialog::username() const
0063 {
0064     return mUi.username->text();
0065 }
0066 
0067 void SearchDialog::setPassword(const QString &password)
0068 {
0069     mUi.password->setText(password);
0070 }
0071 
0072 QString SearchDialog::password() const
0073 {
0074     return mUi.password->text();
0075 }
0076 
0077 QStringList SearchDialog::selection() const
0078 {
0079     const QModelIndexList indexes = mUi.searchResults->selectionModel()->selectedIndexes();
0080     QStringList ret;
0081     ret.reserve(indexes.count());
0082     for (const QModelIndex &index : indexes) {
0083         // qCritical() << "SELECTED DATA: " << index.data(Qt::UserRole + 1).toString();
0084         ret << index.data(Qt::UserRole + 1).toString();
0085     }
0086     return ret;
0087 }
0088 
0089 void SearchDialog::checkUserInput()
0090 {
0091     if (mUi.searchUrl->text().isEmpty() || mUi.searchParam->text().isEmpty()) {
0092         mUi.searchButton->setEnabled(false);
0093     } else {
0094         mUi.searchButton->setEnabled(true);
0095     }
0096 }
0097 
0098 void SearchDialog::search()
0099 {
0100     mUi.searchResults->setEnabled(false);
0101     mModel->clear();
0102     KDAV::DavPrincipalSearchJob::FilterType filter;
0103 
0104     if (mUi.searchType->currentIndex() == 0) {
0105         filter = KDAV::DavPrincipalSearchJob::DisplayName;
0106     } else {
0107         filter = KDAV::DavPrincipalSearchJob::EmailAddress;
0108     }
0109 
0110     QUrl url(mUi.searchUrl->text());
0111     url.setUserInfo(QString());
0112     KDAV::DavUrl davUrl;
0113     davUrl.setUrl(url);
0114 
0115     auto job = new KDAV::DavPrincipalSearchJob(davUrl, filter, mUi.searchParam->text(), this);
0116     job->fetchProperty(KDAV::ProtocolInfo::principalHomeSet(KDAV::CalDav), KDAV::ProtocolInfo::principalHomeSetNS(KDAV::CalDav));
0117     job->fetchProperty(KDAV::ProtocolInfo::principalHomeSet(KDAV::CardDav), KDAV::ProtocolInfo::principalHomeSetNS(KDAV::CardDav));
0118 
0119     connect(job, &KDAV::DavPrincipalSearchJob::result, this, &SearchDialog::onSearchJobFinished);
0120     job->start();
0121 }
0122 
0123 void SearchDialog::onSearchJobFinished(KJob *job)
0124 {
0125     if (job->error()) {
0126         KMessageBox::error(this, i18n("An error occurred when executing search:\n%1", job->errorText()));
0127         return;
0128     }
0129 
0130     auto davJob = qobject_cast<KDAV::DavPrincipalSearchJob *>(job);
0131 
0132     KDAV::DavUrl davUrl = davJob->davUrl();
0133     QUrl url = davUrl.url();
0134 
0135     const QList<KDAV::DavPrincipalSearchJob::Result> results = davJob->results();
0136     for (const KDAV::DavPrincipalSearchJob::Result &result : results) {
0137         if (result.value.startsWith(QLatin1Char('/'))) {
0138             url.setPath(result.value, QUrl::TolerantMode);
0139         } else {
0140             QUrl tmp(result.value);
0141             tmp.setUserInfo(QString());
0142             url = tmp;
0143         }
0144         davUrl.setUrl(url);
0145 
0146         if (result.property == KDAV::ProtocolInfo::principalHomeSet(KDAV::CalDav)) {
0147             davUrl.setProtocol(KDAV::CalDav);
0148         } else {
0149             davUrl.setProtocol(KDAV::CardDav);
0150         }
0151 
0152         auto fetchJob = new KDAV::DavCollectionsFetchJob(davUrl);
0153         connect(fetchJob, &KDAV::DavCollectionsFetchJob::result, this, &SearchDialog::onCollectionsFetchJobFinished);
0154         fetchJob->start();
0155         ++mSubJobCount;
0156     }
0157 }
0158 
0159 void SearchDialog::onCollectionsFetchJobFinished(KJob *job)
0160 {
0161     --mSubJobCount;
0162 
0163     if (mSubJobCount == 0) {
0164         mUi.searchResults->setEnabled(true);
0165     }
0166 
0167     if (job->error()) {
0168         if (mSubJobCount == 0) {
0169             KMessageBox::error(this, i18n("An error occurred when executing search:\n%1", job->errorText()));
0170         }
0171         return;
0172     }
0173 
0174     auto davJob = qobject_cast<KDAV::DavCollectionsFetchJob *>(job);
0175     const KDAV::DavCollection::List collections = davJob->collections();
0176 
0177     for (const KDAV::DavCollection &collection : collections) {
0178         auto item = new QStandardItem(collection.displayName());
0179         QString data(KDAV::ProtocolInfo::protocolName(collection.url().protocol()) + QLatin1Char('|') + collection.url().toDisplayString());
0180         item->setData(data, Qt::UserRole + 1);
0181         item->setToolTip(collection.url().toDisplayString());
0182         if (collection.url().protocol() == KDAV::CalDav) {
0183             item->setIcon(QIcon::fromTheme(QStringLiteral("view-calendar")));
0184         } else {
0185             item->setIcon(QIcon::fromTheme(QStringLiteral("view-pim-contacts")));
0186         }
0187         mModel->appendRow(item);
0188     }
0189 }
0190 
0191 #include "moc_searchdialog.cpp"