File indexing completed on 2024-06-23 05:13:48

0001 /*
0002     kleopageconfigdialog.cpp
0003 
0004     This file is part of Kleopatra
0005     SPDX-FileCopyrightText: 2016 Bundesamt für Sicherheit in der Informationstechnik
0006     SPDX-FileContributor: Intevation GmbH
0007 
0008     SPDX-License-Identifier: GPL-2.0-only
0009 
0010     It is derived from KCMultidialog which is:
0011 
0012     SPDX-FileCopyrightText: 2000 Matthias Elter <elter@kde.org>
0013     SPDX-FileCopyrightText: 2003 Daniel Molkentin <molkentin@kde.org>
0014     SPDX-FileCopyrightText: 2003, 2006 Matthias Kretz <kretz@kde.org>
0015     SPDX-FileCopyrightText: 2004 Frans Englich <frans.englich@telia.com>
0016     SPDX-FileCopyrightText: 2006 Tobias Koenig <tokoe@kde.org>
0017 
0018     SPDX-License-Identifier: LGPL-2.0-or-later
0019 */
0020 
0021 #include <config-kleopatra.h>
0022 
0023 #include "kleopageconfigdialog.h"
0024 
0025 
0026 #include <QDesktopServices>
0027 #include <QDialogButtonBox>
0028 #include <QProcess>
0029 #include <QPushButton>
0030 #include <QStandardPaths>
0031 #include <QUrl>
0032 
0033 #include <KCModule>
0034 #include <KLocalizedString>
0035 #include <KMessageBox>
0036 #include <KStandardGuiItem>
0037 
0038 #include "kleopatra_debug.h"
0039 
0040 KleoPageConfigDialog::KleoPageConfigDialog(QWidget *parent)
0041     : KPageDialog(parent)
0042 {
0043     setModal(false);
0044 
0045     QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
0046     buttonBox->setStandardButtons(QDialogButtonBox::Help //
0047                                   | QDialogButtonBox::RestoreDefaults //
0048                                   | QDialogButtonBox::Cancel //
0049                                   | QDialogButtonBox::Apply //
0050                                   | QDialogButtonBox::Ok //
0051                                   | QDialogButtonBox::Reset);
0052     KGuiItem::assign(buttonBox->button(QDialogButtonBox::Ok), KStandardGuiItem::ok());
0053     KGuiItem::assign(buttonBox->button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel());
0054     KGuiItem::assign(buttonBox->button(QDialogButtonBox::RestoreDefaults), KStandardGuiItem::defaults());
0055     KGuiItem::assign(buttonBox->button(QDialogButtonBox::Apply), KStandardGuiItem::apply());
0056     KGuiItem::assign(buttonBox->button(QDialogButtonBox::Reset), KStandardGuiItem::reset());
0057     KGuiItem::assign(buttonBox->button(QDialogButtonBox::Help), KStandardGuiItem::help());
0058     buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
0059     buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
0060 
0061     connect(buttonBox->button(QDialogButtonBox::Apply), &QAbstractButton::clicked, this, &KleoPageConfigDialog::slotApplyClicked);
0062     connect(buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked, this, &KleoPageConfigDialog::slotOkClicked);
0063     connect(buttonBox->button(QDialogButtonBox::RestoreDefaults), &QAbstractButton::clicked, this, &KleoPageConfigDialog::slotDefaultClicked);
0064     connect(buttonBox->button(QDialogButtonBox::Help), &QAbstractButton::clicked, this, &KleoPageConfigDialog::slotHelpClicked);
0065     connect(buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, this, &KleoPageConfigDialog::slotUser1Clicked);
0066 
0067     setButtonBox(buttonBox);
0068 
0069     connect(this, &KPageDialog::currentPageChanged, this, &KleoPageConfigDialog::slotCurrentPageChanged);
0070 }
0071 
0072 void KleoPageConfigDialog::slotCurrentPageChanged(KPageWidgetItem *current, KPageWidgetItem *previous)
0073 {
0074     if (!previous) {
0075         return;
0076     }
0077     blockSignals(true);
0078     setCurrentPage(previous);
0079 
0080     KCModule *previousModule = qobject_cast<KCModule *>(previous->widget());
0081     bool canceled = false;
0082     if (previousModule && mChangedModules.contains(previousModule)) {
0083         const int queryUser = KMessageBox::warningTwoActionsCancel(this,
0084                                                                    i18n("The settings of the current module have changed.\n"
0085                                                                         "Do you want to apply the changes or discard them?"),
0086                                                                    i18nc("@title:window", "Apply Settings"),
0087                                                                    KStandardGuiItem::apply(),
0088                                                                    KStandardGuiItem::discard(),
0089                                                                    KStandardGuiItem::cancel());
0090         if (queryUser == KMessageBox::ButtonCode::PrimaryAction) {
0091             previousModule->save();
0092         } else if (queryUser == KMessageBox::ButtonCode::SecondaryAction) {
0093             previousModule->load();
0094         }
0095         canceled = queryUser == KMessageBox::Cancel;
0096     }
0097     if (!canceled) {
0098         mChangedModules.removeAll(previousModule);
0099         setCurrentPage(current);
0100     }
0101     blockSignals(false);
0102 
0103     clientChanged();
0104 }
0105 
0106 void KleoPageConfigDialog::apply()
0107 {
0108     QPushButton *applyButton = buttonBox()->button(QDialogButtonBox::Apply);
0109     applyButton->setFocus();
0110     for (KCModule *module : mChangedModules) {
0111         module->save();
0112     }
0113     mChangedModules.clear();
0114     Q_EMIT configCommitted();
0115     clientChanged();
0116 }
0117 
0118 void KleoPageConfigDialog::slotDefaultClicked()
0119 {
0120     const KPageWidgetItem *item = currentPage();
0121     if (!item) {
0122         return;
0123     }
0124 
0125     KCModule *module = qobject_cast<KCModule *>(item->widget());
0126     if (!module) {
0127         return;
0128     }
0129     module->defaults();
0130     clientChanged();
0131 }
0132 
0133 void KleoPageConfigDialog::slotUser1Clicked()
0134 {
0135     const KPageWidgetItem *item = currentPage();
0136     if (!item) {
0137         return;
0138     }
0139 
0140     KCModule *module = qobject_cast<KCModule *>(item->widget());
0141     if (!module) {
0142         return;
0143     }
0144     module->load();
0145     mChangedModules.removeAll(module);
0146     clientChanged();
0147 }
0148 
0149 void KleoPageConfigDialog::slotApplyClicked()
0150 {
0151     apply();
0152 }
0153 
0154 void KleoPageConfigDialog::slotOkClicked()
0155 {
0156     apply();
0157     accept();
0158 }
0159 
0160 void KleoPageConfigDialog::slotHelpClicked()
0161 {
0162     const KPageWidgetItem *item = currentPage();
0163     if (!item) {
0164         return;
0165     }
0166 
0167     const QString docPath = mHelpUrls.value(item->name());
0168     QUrl docUrl;
0169 
0170 #ifdef Q_OS_WIN
0171     docUrl = QUrl(QLatin1StringView("https://docs.kde.org/index.php?branch=stable5&language=") + QLocale().name() + QLatin1String("&application=kleopatra"));
0172 #else
0173     docUrl = QUrl(QStringLiteral("help:/")).resolved(QUrl(docPath)); // same code as in KHelpClient::invokeHelp
0174 #endif
0175     if (docUrl.scheme() == QLatin1StringView("help") || docUrl.scheme() == QLatin1String("man") || docUrl.scheme() == QLatin1String("info")) {
0176         // Warning: Don't assume that the program needs to be in PATH. On Windows, it will also be found next to the calling process.
0177         QProcess::startDetached(QStringLiteral("khelpcenter"), QStringList() << docUrl.toString());
0178     } else {
0179         QDesktopServices::openUrl(docUrl);
0180     }
0181 }
0182 
0183 void KleoPageConfigDialog::addModule(const QString &name, const QString &docPath, const QString &icon, KCModule *module)
0184 {
0185     mModules << module;
0186     KPageWidgetItem *item = addPage(module->widget(), name);
0187     item->setIcon(QIcon::fromTheme(icon));
0188     connect(module, &KCModule::needsSaveChanged, this, [this, module]() {
0189         moduleChanged(module->needsSave());
0190     });
0191 
0192     mHelpUrls.insert(name, docPath);
0193 }
0194 
0195 void KleoPageConfigDialog::moduleChanged(bool state)
0196 {
0197     KCModule *module = qobject_cast<KCModule *>(sender());
0198     qCDebug(KLEOPATRA_LOG) << "Module changed: " << state << " mod " << module;
0199     if (mChangedModules.contains(module)) {
0200         if (!state) {
0201             mChangedModules.removeAll(module);
0202         } else {
0203             return;
0204         }
0205     }
0206     if (state) {
0207         mChangedModules << module;
0208     }
0209     clientChanged();
0210 }
0211 
0212 void KleoPageConfigDialog::clientChanged()
0213 {
0214     const KPageWidgetItem *item = currentPage();
0215     if (!item) {
0216         return;
0217     }
0218     KCModule *module = qobject_cast<KCModule *>(item->widget());
0219 
0220     if (!module) {
0221         return;
0222     }
0223     qCDebug(KLEOPATRA_LOG) << "Client changed: "
0224                            << " mod " << module;
0225 
0226     bool change = mChangedModules.contains(module);
0227 
0228     QPushButton *resetButton = buttonBox()->button(QDialogButtonBox::Reset);
0229     if (resetButton) {
0230         resetButton->setEnabled(change);
0231     }
0232 
0233     QPushButton *applyButton = buttonBox()->button(QDialogButtonBox::Apply);
0234     if (applyButton) {
0235         applyButton->setEnabled(change);
0236     }
0237 }
0238 
0239 #include "moc_kleopageconfigdialog.cpp"