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

0001 /*
0002     SPDX-FileCopyrightText: 2009 Grégory Oestreicher <greg@kamago.net>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "configdialog.h"
0008 #include "searchdialog.h"
0009 #include "settings.h"
0010 #include "urlconfigurationdialog.h"
0011 #include "utils.h"
0012 
0013 #include <KDAV/ProtocolInfo>
0014 
0015 #include <KConfigDialogManager>
0016 #include <KLocalizedString>
0017 #include <KMessageBox>
0018 
0019 #include <KWindowConfig>
0020 #include <QDialogButtonBox>
0021 #include <QPointer>
0022 #include <QStandardItem>
0023 #include <QStandardItemModel>
0024 #include <QStringList>
0025 #include <QVBoxLayout>
0026 #include <QWindow>
0027 
0028 ConfigDialog::ConfigDialog(QWidget *parent)
0029     : QDialog(parent)
0030     , mModel(new QStandardItemModel(this))
0031 {
0032     setWindowIcon(QIcon::fromTheme(QStringLiteral("folder-remote")));
0033     setWindowTitle(i18nc("@title:window", "DAV Resource Configuration"));
0034     auto mainLayout = new QVBoxLayout(this);
0035     auto mainWidget = new QWidget(this);
0036     mainLayout->addWidget(mainWidget);
0037     mUi.setupUi(mainWidget);
0038 
0039     auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
0040     mOkButton = buttonBox->button(QDialogButtonBox::Ok);
0041     mOkButton->setDefault(true);
0042     mOkButton->setShortcut(Qt::CTRL | Qt::Key_Return);
0043     connect(buttonBox, &QDialogButtonBox::rejected, this, &ConfigDialog::onCancelClicked);
0044     mainLayout->addWidget(buttonBox);
0045 
0046     const QStringList headers = {i18n("Protocol"), i18n("URL")};
0047     mModel->setHorizontalHeaderLabels(headers);
0048 
0049     mUi.configuredUrls->setModel(mModel);
0050     mUi.configuredUrls->setRootIsDecorated(false);
0051 
0052     const KDAV::DavUrl::List lstUrls = Settings::self()->configuredDavUrls();
0053     for (const KDAV::DavUrl &url : lstUrls) {
0054         QUrl displayUrl = url.url();
0055         displayUrl.setUserInfo(QString());
0056         addModelRow(Utils::translatedProtocolName(url.protocol()), displayUrl.toDisplayString());
0057     }
0058 
0059     mUi.syncRangeStartType->addItem(i18n("Days"), QVariant(QLatin1StringView("D")));
0060     mUi.syncRangeStartType->addItem(i18n("Months"), QVariant(QLatin1StringView("M")));
0061     mUi.syncRangeStartType->addItem(i18n("Years"), QVariant(QLatin1StringView("Y")));
0062 
0063     mManager = new KConfigDialogManager(this, Settings::self());
0064     mManager->updateWidgets();
0065 
0066     const int typeIndex = mUi.syncRangeStartType->findData(QVariant(Settings::self()->syncRangeStartType()));
0067     mUi.syncRangeStartType->setCurrentIndex(typeIndex);
0068 
0069     connect(mUi.kcfg_displayName, &QLineEdit::textChanged, this, &ConfigDialog::checkUserInput);
0070     connect(mUi.configuredUrls->selectionModel(), &QItemSelectionModel::selectionChanged, this, &ConfigDialog::checkConfiguredUrlsButtonsState);
0071     connect(mUi.configuredUrls, &QAbstractItemView::doubleClicked, this, &ConfigDialog::onEditButtonClicked);
0072 
0073     connect(mUi.syncRangeStartType, &QComboBox::currentIndexChanged, this, &ConfigDialog::onSyncRangeStartTypeChanged);
0074     connect(mUi.addButton, &QPushButton::clicked, this, &ConfigDialog::onAddButtonClicked);
0075     connect(mUi.searchButton, &QPushButton::clicked, this, &ConfigDialog::onSearchButtonClicked);
0076     connect(mUi.removeButton, &QPushButton::clicked, this, &ConfigDialog::onRemoveButtonClicked);
0077     connect(mUi.editButton, &QPushButton::clicked, this, &ConfigDialog::onEditButtonClicked);
0078 
0079     connect(mOkButton, &QPushButton::clicked, this, &ConfigDialog::onOkClicked);
0080 
0081     checkUserInput();
0082     readConfig();
0083 }
0084 
0085 ConfigDialog::~ConfigDialog()
0086 {
0087     writeConfig();
0088 }
0089 
0090 void ConfigDialog::readConfig()
0091 {
0092     create(); // ensure a window is created
0093     windowHandle()->resize(QSize(300, 200));
0094     KConfigGroup group(KSharedConfig::openStateConfig(), QStringLiteral("ConfigDialog"));
0095     KWindowConfig::restoreWindowSize(windowHandle(), group);
0096     resize(windowHandle()->size()); // workaround for QTBUG-40584
0097 }
0098 
0099 void ConfigDialog::writeConfig()
0100 {
0101     KConfigGroup grp(KSharedConfig::openStateConfig(), QStringLiteral("ConfigDialog"));
0102     KWindowConfig::saveWindowSize(windowHandle(), grp);
0103     grp.sync();
0104 }
0105 
0106 void ConfigDialog::setPassword(const QString &password)
0107 {
0108     mUi.password->setPassword(password);
0109 }
0110 
0111 void ConfigDialog::onSyncRangeStartTypeChanged()
0112 {
0113     Settings::self()->setSyncRangeStartType(mUi.syncRangeStartType->currentData().toString());
0114 }
0115 
0116 void ConfigDialog::checkUserInput()
0117 {
0118     checkConfiguredUrlsButtonsState();
0119 
0120     if (!mUi.kcfg_displayName->text().trimmed().isEmpty() && !(mModel->invisibleRootItem()->rowCount() == 0)) {
0121         mOkButton->setEnabled(true);
0122     } else {
0123         mOkButton->setEnabled(false);
0124     }
0125 }
0126 
0127 void ConfigDialog::onAddButtonClicked()
0128 {
0129     QPointer<UrlConfigurationDialog> dlg = new UrlConfigurationDialog(this);
0130     dlg->setDefaultUsername(mUi.kcfg_defaultUsername->text());
0131     dlg->setDefaultPassword(mUi.password->password());
0132     const int result = dlg->exec();
0133 
0134     if (result == QDialog::Accepted && !dlg.isNull()) {
0135         if (Settings::self()->urlConfiguration(KDAV::Protocol(dlg->protocol()), dlg->remoteUrl())) {
0136             KMessageBox::error(this,
0137                                i18n("Another configuration entry already uses the same URL/protocol couple.\n"
0138                                     "Please use a different URL"));
0139         } else {
0140             auto urlConfig = new Settings::UrlConfiguration();
0141 
0142             urlConfig->mUrl = dlg->remoteUrl();
0143             if (dlg->useDefaultCredentials()) {
0144                 urlConfig->mUser = QStringLiteral("$default$");
0145             } else {
0146                 urlConfig->mUser = dlg->username();
0147                 urlConfig->mPassword = dlg->password();
0148             }
0149             urlConfig->mProtocol = dlg->protocol();
0150 
0151             Settings::self()->newUrlConfiguration(urlConfig);
0152 
0153             const QString protocolName = Utils::translatedProtocolName(dlg->protocol());
0154 
0155             addModelRow(protocolName, dlg->remoteUrl());
0156             mAddedUrls << QPair<QString, KDAV::Protocol>(dlg->remoteUrl(), KDAV::Protocol(dlg->protocol()));
0157             checkUserInput();
0158         }
0159     }
0160 
0161     delete dlg;
0162 }
0163 
0164 void ConfigDialog::onSearchButtonClicked()
0165 {
0166     QPointer<SearchDialog> dlg = new SearchDialog(this);
0167     dlg->setUsername(mUi.kcfg_defaultUsername->text());
0168     dlg->setPassword(mUi.password->password());
0169     const int result = dlg->exec();
0170 
0171     if (result == QDialog::Accepted && !dlg.isNull()) {
0172         const QStringList results = dlg->selection();
0173         for (const QString &resultStr : results) {
0174             const QStringList split = resultStr.split(QLatin1Char('|'));
0175             KDAV::Protocol protocol = KDAV::ProtocolInfo::protocolByName(split.at(0));
0176             if (!Settings::self()->urlConfiguration(protocol, split.at(1))) {
0177                 auto urlConfig = new Settings::UrlConfiguration();
0178 
0179                 urlConfig->mUrl = split.at(1);
0180                 if (dlg->useDefaultCredentials()) {
0181                     urlConfig->mUser = QStringLiteral("$default$");
0182                 } else {
0183                     urlConfig->mUser = dlg->username();
0184                     urlConfig->mPassword = dlg->password();
0185                 }
0186                 urlConfig->mProtocol = protocol;
0187 
0188                 Settings::self()->newUrlConfiguration(urlConfig);
0189 
0190                 addModelRow(Utils::translatedProtocolName(protocol), split.at(1));
0191                 mAddedUrls << QPair<QString, KDAV::Protocol>(split.at(1), protocol);
0192                 checkUserInput();
0193             }
0194         }
0195     }
0196 
0197     delete dlg;
0198 }
0199 
0200 void ConfigDialog::onRemoveButtonClicked()
0201 {
0202     const QModelIndexList indexes = mUi.configuredUrls->selectionModel()->selectedRows();
0203     if (indexes.isEmpty()) {
0204         return;
0205     }
0206 
0207     const QString proto = mModel->index(indexes.at(0).row(), 0).data().toString();
0208     const QString url = mModel->index(indexes.at(0).row(), 1).data().toString();
0209 
0210     mRemovedUrls << QPair<QString, KDAV::Protocol>(url, Utils::protocolByTranslatedName(proto));
0211     mModel->removeRow(indexes.at(0).row());
0212 
0213     checkUserInput();
0214 }
0215 
0216 void ConfigDialog::onEditButtonClicked()
0217 {
0218     const QModelIndexList indexes = mUi.configuredUrls->selectionModel()->selectedRows();
0219     if (indexes.isEmpty()) {
0220         return;
0221     }
0222 
0223     const int row = indexes.at(0).row();
0224     const QString proto = mModel->index(row, 0).data().toString();
0225     const QString url = mModel->index(row, 1).data().toString();
0226 
0227     Settings::UrlConfiguration *urlConfig = Settings::self()->urlConfiguration(Utils::protocolByTranslatedName(proto), url);
0228     if (!urlConfig) {
0229         return;
0230     }
0231 
0232     QPointer<UrlConfigurationDialog> dlg = new UrlConfigurationDialog(this);
0233     dlg->setRemoteUrl(urlConfig->mUrl);
0234     dlg->setProtocol(KDAV::Protocol(urlConfig->mProtocol));
0235 
0236     if (urlConfig->mUser == QLatin1StringView("$default$")) {
0237         dlg->setUseDefaultCredentials(true);
0238     } else {
0239         dlg->setUseDefaultCredentials(false);
0240         dlg->setUsername(urlConfig->mUser);
0241         dlg->setPassword(urlConfig->mPassword);
0242     }
0243     dlg->setDefaultUsername(mUi.kcfg_defaultUsername->text());
0244     dlg->setDefaultPassword(mUi.password->password());
0245 
0246     const int result = dlg->exec();
0247 
0248     if (result == QDialog::Accepted && !dlg.isNull()) {
0249         Settings::self()->removeUrlConfiguration(Utils::protocolByTranslatedName(proto), url);
0250         auto urlConfigAccepted = new Settings::UrlConfiguration();
0251         urlConfigAccepted->mUrl = dlg->remoteUrl();
0252         if (dlg->useDefaultCredentials()) {
0253             urlConfigAccepted->mUser = QStringLiteral("$default$");
0254         } else {
0255             urlConfigAccepted->mUser = dlg->username();
0256             urlConfigAccepted->mPassword = dlg->password();
0257         }
0258         urlConfigAccepted->mProtocol = dlg->protocol();
0259         Settings::self()->newUrlConfiguration(urlConfigAccepted);
0260 
0261         mModel->removeRow(row);
0262         insertModelRow(row, Utils::translatedProtocolName(dlg->protocol()), dlg->remoteUrl());
0263     }
0264     delete dlg;
0265 }
0266 
0267 void ConfigDialog::onOkClicked()
0268 {
0269     using UrlPair = QPair<QString, KDAV::Protocol>;
0270     for (const UrlPair &url : std::as_const(mRemovedUrls)) {
0271         Settings::self()->removeUrlConfiguration(url.second, url.first);
0272     }
0273 
0274     mManager->updateSettings();
0275     Settings::self()->setDefaultPassword(mUi.password->password());
0276     accept();
0277 }
0278 
0279 void ConfigDialog::onCancelClicked()
0280 {
0281     mRemovedUrls.clear();
0282 
0283     using UrlPair = QPair<QString, KDAV::Protocol>;
0284     for (const UrlPair &url : std::as_const(mAddedUrls)) {
0285         Settings::self()->removeUrlConfiguration(url.second, url.first);
0286     }
0287     reject();
0288 }
0289 
0290 void ConfigDialog::checkConfiguredUrlsButtonsState()
0291 {
0292     const bool enabled = mUi.configuredUrls->selectionModel()->hasSelection();
0293 
0294     mUi.removeButton->setEnabled(enabled);
0295     mUi.editButton->setEnabled(enabled);
0296 }
0297 
0298 void ConfigDialog::addModelRow(const QString &protocol, const QString &url)
0299 {
0300     insertModelRow(-1, protocol, url);
0301 }
0302 
0303 void ConfigDialog::insertModelRow(int index, const QString &protocol, const QString &url)
0304 {
0305     QStandardItem *rootItem = mModel->invisibleRootItem();
0306     QList<QStandardItem *> items;
0307 
0308     auto protocolStandardItem = new QStandardItem(protocol);
0309     protocolStandardItem->setEditable(false);
0310     items << protocolStandardItem;
0311 
0312     auto urlStandardItem = new QStandardItem(url);
0313     urlStandardItem->setEditable(false);
0314     items << urlStandardItem;
0315 
0316     if (index == -1) {
0317         rootItem->appendRow(items);
0318     } else {
0319         rootItem->insertRow(index, items);
0320     }
0321 }
0322 
0323 #include "moc_configdialog.cpp"