Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F23020717
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
36 KB
Subscribers
None
View Options
diff --git a/src/conf/appearanceconfigpage.cpp b/src/conf/appearanceconfigpage.cpp
index d53de8fc0..c58073a4f 100644
--- a/src/conf/appearanceconfigpage.cpp
+++ b/src/conf/appearanceconfigpage.cpp
@@ -1,47 +1,51 @@
/* -*- mode: c++; c-basic-offset:4 -*-
conf/appearanceconfigpage.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2004, 2008 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "appearanceconfigpage.h"
#include "appearanceconfigwidget.h"
#include <QVBoxLayout>
using namespace Kleo;
using namespace Kleo::Config;
AppearanceConfigurationPage::AppearanceConfigurationPage(QObject *parent, const KPluginMetaData &data)
: KCModule(parent, data)
{
auto lay = new QVBoxLayout(widget());
lay->setContentsMargins({});
mWidget = new AppearanceConfigWidget(widget());
lay->addWidget(mWidget);
connect(mWidget, &AppearanceConfigWidget::changed, this, &Kleo::Config::AppearanceConfigurationPage::markAsChanged);
+
+ load();
+ setNeedsSave(false);
}
void AppearanceConfigurationPage::load()
{
mWidget->load();
}
void AppearanceConfigurationPage::save()
{
mWidget->save();
+ setNeedsSave(false);
}
void AppearanceConfigurationPage::defaults()
{
mWidget->defaults();
}
#include "moc_appearanceconfigpage.cpp"
diff --git a/src/conf/cryptooperationsconfigpage.cpp b/src/conf/cryptooperationsconfigpage.cpp
index 1af782b13..186eb6886 100644
--- a/src/conf/cryptooperationsconfigpage.cpp
+++ b/src/conf/cryptooperationsconfigpage.cpp
@@ -1,46 +1,50 @@
/* -*- mode: c++; c-basic-offset:4 -*-
conf/cryptooperationsconfigpage.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "cryptooperationsconfigpage.h"
#include "cryptooperationsconfigwidget.h"
#include <QVBoxLayout>
using namespace Kleo;
using namespace Kleo::Config;
CryptoOperationsConfigurationPage::CryptoOperationsConfigurationPage(QObject *parent, const KPluginMetaData &data)
: KCModule(parent, data)
{
auto lay = new QVBoxLayout(widget());
mWidget = new CryptoOperationsConfigWidget(widget());
lay->setContentsMargins(0, 0, 0, 0);
lay->addWidget(mWidget);
connect(mWidget, &CryptoOperationsConfigWidget::changed, this, &Kleo::Config::CryptoOperationsConfigurationPage::markAsChanged);
+
+ load();
+ setNeedsSave(false);
}
void CryptoOperationsConfigurationPage::load()
{
mWidget->load();
}
void CryptoOperationsConfigurationPage::save()
{
mWidget->save();
+ setNeedsSave(false);
}
void CryptoOperationsConfigurationPage::defaults()
{
mWidget->defaults();
}
#include "moc_cryptooperationsconfigpage.cpp"
diff --git a/src/conf/dirservconfigpage.cpp b/src/conf/dirservconfigpage.cpp
index 388ea46b7..55d127fd2 100644
--- a/src/conf/dirservconfigpage.cpp
+++ b/src/conf/dirservconfigpage.cpp
@@ -1,476 +1,479 @@
/* -*- mode: c++; c-basic-offset:4 -*-
conf/dirservconfigpage.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2004, 2008 Klarälvdalens Datakonsult AB
SPDX-FileCopyrightText: 2022 g10 Code GmbH
SPDX-FileContributor: Ingo Klöcker <dev@ingo-kloecker.de>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "dirservconfigpage.h"
#include "labelledwidget.h"
#include <settings.h>
#include <Libkleo/Compat>
#include <Libkleo/DirectoryServicesWidget>
#include <Libkleo/GnuPG>
#include <Libkleo/KeyserverConfig>
#include <QGpgME/CryptoConfig>
#include <QGpgME/Protocol>
#include "kleopatra_debug.h"
#include <KConfig>
#include <KLocalizedString>
#include <KMessageBox>
#include <QSpinBox>
#include <QCheckBox>
#include <QGroupBox>
#include <QLabel>
#include <QLayout>
#include <QLineEdit>
#include <QTimeEdit>
#include <QVBoxLayout>
#include <gpgme++/engineinfo.h>
#include <gpgme.h>
using namespace Kleo;
using namespace QGpgME;
// Option for configuring X.509 servers (available via gpgconf since GnuPG 2.3.5 and 2.2.34)
static const char s_x509services_componentName[] = "dirmngr";
static const char s_x509services_entryName[] = "ldapserver";
// Legacy option for configuring X.509 servers (deprecated with GnuPG 2.2.28 and 2.3.2)
static const char s_x509services_legacy_componentName[] = "gpgsm";
static const char s_x509services_legacy_entryName[] = "keyserver";
static const char s_pgpservice_componentName[] = "dirmngr";
static const char s_pgpservice_entryName[] = "keyserver";
// legacy config entry used until GnuPG 2.2
static const char s_pgpservice_legacy_componentName[] = "gpg";
static const char s_pgpservice_legacy_entryName[] = "keyserver";
static const char s_timeout_componentName[] = "dirmngr";
static const char s_timeout_entryName[] = "ldaptimeout";
static const char s_maxitems_componentName[] = "dirmngr";
static const char s_maxitems_entryName[] = "max-replies";
class DirectoryServicesConfigurationPage::Private
{
DirectoryServicesConfigurationPage *q = nullptr;
public:
Private(DirectoryServicesConfigurationPage *q);
void load();
void save();
void defaults();
private:
enum EntryMultiplicity {
SingleValue,
ListValue,
};
enum ShowError {
DoNotShowError,
DoShowError,
};
void setX509ServerEntry(const std::vector<KeyserverConfig> &servers);
void load(const Kleo::Settings &settings);
QGpgME::CryptoConfigEntry *configEntry(const char *componentName,
const char *entryName,
QGpgME::CryptoConfigEntry::ArgType argType,
EntryMultiplicity multiplicity,
ShowError showError);
Kleo::LabelledWidget<QLineEdit> mOpenPGPKeyserverEdit;
Kleo::DirectoryServicesWidget *mDirectoryServices = nullptr;
Kleo::LabelledWidget<QTimeEdit> mTimeout;
Kleo::LabelledWidget<QSpinBox> mMaxItems;
QCheckBox *mFetchMissingSignerKeysCB = nullptr;
QCheckBox *mQueryWKDsForAllUserIDsCB = nullptr;
QGpgME::CryptoConfigEntry *mOpenPGPServiceEntry = nullptr;
QGpgME::CryptoConfigEntry *mTimeoutConfigEntry = nullptr;
QGpgME::CryptoConfigEntry *mMaxItemsConfigEntry = nullptr;
QGpgME::CryptoConfig *mConfig = nullptr;
};
DirectoryServicesConfigurationPage::Private::Private(DirectoryServicesConfigurationPage *q)
{
mConfig = QGpgME::cryptoConfig();
auto glay = new QGridLayout(q->widget());
// OpenPGP keyserver
int row = 0;
{
auto l = new QHBoxLayout{};
l->setContentsMargins(0, 0, 0, 0);
mOpenPGPKeyserverEdit.createWidgets(q->widget());
mOpenPGPKeyserverEdit.label()->setText(i18n("OpenPGP keyserver:"));
if (engineIsVersion(2, 4, 4) //
|| (engineIsVersion(2, 2, 42) && !engineIsVersion(2, 3, 0))) {
mOpenPGPKeyserverEdit.widget()->setToolTip( //
xi18nc("@info:tooltip",
"Enter the address of the keyserver to use when searching for OpenPGP certificates and "
"when uploading OpenPGP certificates. If you do not enter an address then an internal "
"default will be used. To disable the use of an OpenPGP keyserver enter the special value <emphasis>none</emphasis>."));
}
l->addWidget(mOpenPGPKeyserverEdit.label());
l->addWidget(mOpenPGPKeyserverEdit.widget());
glay->addLayout(l, row, 0, 1, 3);
connect(mOpenPGPKeyserverEdit.widget(), &QLineEdit::textEdited, q, &DirectoryServicesConfigurationPage::markAsChanged);
}
// X.509 servers
if (Settings{}.cmsEnabled()) {
++row;
auto groupBox = new QGroupBox{i18n("X.509 Directory Services"), q->widget()};
groupBox->setFlat(true);
auto groupBoxLayout = new QVBoxLayout{groupBox};
groupBoxLayout->setContentsMargins({});
if (gpgme_check_version("1.16.0")) {
mDirectoryServices = new Kleo::DirectoryServicesWidget(q->widget());
if (QLayout *l = mDirectoryServices->layout()) {
l->setContentsMargins(0, 0, 0, 0);
}
groupBoxLayout->addWidget(mDirectoryServices);
connect(mDirectoryServices, &DirectoryServicesWidget::changed, q, &DirectoryServicesConfigurationPage::markAsChanged);
} else {
// QGpgME does not properly support keyserver flags for X.509 keyservers (added in GnuPG 2.2.28);
// disable the configuration to prevent the configuration from being corrupted
groupBoxLayout->addWidget(new QLabel{i18n("Configuration of directory services is not possible "
"because the used gpgme libraries are too old."),
q->widget()});
}
glay->addWidget(groupBox, row, 0, 1, 3);
}
// LDAP timeout
++row;
mTimeout.createWidgets(q->widget());
mTimeout.label()->setText(i18n("LDAP &timeout (minutes:seconds):"));
mTimeout.widget()->setDisplayFormat(QStringLiteral("mm:ss"));
connect(mTimeout.widget(), &QTimeEdit::timeChanged, q, &DirectoryServicesConfigurationPage::markAsChanged);
glay->addWidget(mTimeout.label(), row, 0);
glay->addWidget(mTimeout.widget(), row, 1);
// Max number of items returned by queries
++row;
mMaxItems.createWidgets(q->widget());
mMaxItems.label()->setText(i18n("&Maximum number of items returned by query:"));
mMaxItems.widget()->setMinimum(0);
connect(mMaxItems.widget(), &QSpinBox::valueChanged, q, &DirectoryServicesConfigurationPage::markAsChanged);
glay->addWidget(mMaxItems.label(), row, 0);
glay->addWidget(mMaxItems.widget(), row, 1);
++row;
mFetchMissingSignerKeysCB = new QCheckBox{q->widget()};
mFetchMissingSignerKeysCB->setText(i18nc("@option:check", "Retrieve missing certification keys when importing new keys"));
mFetchMissingSignerKeysCB->setToolTip(xi18nc("@info:tooltip",
"If enabled, then Kleopatra will automatically try to retrieve the keys "
"that were used to certify the user IDs of newly imported OpenPGP keys."));
connect(mFetchMissingSignerKeysCB, &QCheckBox::toggled, q, &DirectoryServicesConfigurationPage::markAsChanged);
glay->addWidget(mFetchMissingSignerKeysCB, row, 0, 1, 3);
++row;
mQueryWKDsForAllUserIDsCB = new QCheckBox{q->widget()};
mQueryWKDsForAllUserIDsCB->setText(i18nc("@option:check", "Query certificate directories of providers for all user IDs"));
mQueryWKDsForAllUserIDsCB->setToolTip(xi18nc("@info:tooltip",
"By default, Kleopatra only queries the certificate directories of providers (WKD) "
"for user IDs that were originally retrieved from a WKD when you update an OpenPGP "
"certificate. If this option is enabled, then Kleopatra will query WKDs for all user IDs."));
connect(mQueryWKDsForAllUserIDsCB, &QCheckBox::toggled, q, &DirectoryServicesConfigurationPage::markAsChanged);
glay->addWidget(mQueryWKDsForAllUserIDsCB, row, 0, 1, 3);
glay->setRowStretch(++row, 1);
glay->setColumnStretch(2, 1);
}
static auto readKeyserverConfigs(const CryptoConfigEntry *configEntry)
{
std::vector<KeyserverConfig> servers;
if (configEntry) {
const auto urls = configEntry->urlValueList();
servers.reserve(urls.size());
std::transform(std::begin(urls), std::end(urls), std::back_inserter(servers), &KeyserverConfig::fromUrl);
}
return servers;
}
void DirectoryServicesConfigurationPage::Private::load(const Kleo::Settings &settings)
{
if (mDirectoryServices) {
mDirectoryServices->clear();
// gpgsm uses the deprecated keyserver option in gpgsm.conf additionally to the ldapserver option in dirmngr.conf;
// we (try to) read servers from both entries, but always write to the newest existing entry
const auto *const newEntry =
configEntry(s_x509services_componentName, s_x509services_entryName, CryptoConfigEntry::ArgType_LDAPURL, ListValue, DoNotShowError);
const auto *const legacyEntry =
configEntry(s_x509services_legacy_componentName, s_x509services_legacy_entryName, CryptoConfigEntry::ArgType_LDAPURL, ListValue, DoNotShowError);
auto entry = newEntry ? newEntry : legacyEntry;
if (entry) {
const auto additionalServers = readKeyserverConfigs(legacyEntry);
auto servers = readKeyserverConfigs(newEntry);
std::copy(std::begin(additionalServers), std::end(additionalServers), std::back_inserter(servers));
mDirectoryServices->setKeyservers(servers);
mDirectoryServices->setReadOnly(entry->isReadOnly());
} else {
qCWarning(KLEOPATRA_LOG) << "Unknown or wrong typed config entries" << s_x509services_componentName << "/" << s_x509services_entryName << "and"
<< s_x509services_legacy_componentName << "/" << s_x509services_legacy_entryName;
mDirectoryServices->setDisabled(true);
}
}
{
// gpg prefers the deprecated keyserver option in gpg.conf over the keyserver option in dirmngr.conf;
// therefore, we use the deprecated keyserver option if it is set or if the new option doesn't exist (gpg < 2.1.9)
auto const newEntry = configEntry(s_pgpservice_componentName, s_pgpservice_entryName, CryptoConfigEntry::ArgType_String, SingleValue, DoNotShowError);
auto const legacyEntry =
configEntry(s_pgpservice_legacy_componentName, s_pgpservice_legacy_entryName, CryptoConfigEntry::ArgType_String, SingleValue, DoNotShowError);
mOpenPGPServiceEntry = ((legacyEntry && legacyEntry->isSet()) || !newEntry) ? legacyEntry : newEntry;
if (!mOpenPGPServiceEntry) {
qCWarning(KLEOPATRA_LOG) << "Unknown or wrong typed config entries" << s_pgpservice_componentName << "/" << s_pgpservice_entryName << "and"
<< s_pgpservice_legacy_componentName << "/" << s_pgpservice_legacy_entryName;
} else if (mOpenPGPServiceEntry == legacyEntry) {
qCDebug(KLEOPATRA_LOG) << "Using config entry" << s_pgpservice_legacy_componentName << "/" << s_pgpservice_legacy_entryName;
} else {
qCDebug(KLEOPATRA_LOG) << "Using config entry" << s_pgpservice_componentName << "/" << s_pgpservice_entryName;
}
mOpenPGPKeyserverEdit.widget()->setText(mOpenPGPServiceEntry && mOpenPGPServiceEntry->isSet() ? mOpenPGPServiceEntry->stringValue() : QString());
mOpenPGPKeyserverEdit.setEnabled(mOpenPGPServiceEntry && !mOpenPGPServiceEntry->isReadOnly());
if (newEntry && !newEntry->defaultValue().isNull()) {
mOpenPGPKeyserverEdit.widget()->setPlaceholderText(newEntry->defaultValue().toString());
} else {
if (GpgME::engineInfo(GpgME::GpgEngine).engineVersion() < "2.1.16") {
mOpenPGPKeyserverEdit.widget()->setPlaceholderText(QStringLiteral("hkp://keys.gnupg.net"));
} else {
mOpenPGPKeyserverEdit.widget()->setPlaceholderText(QStringLiteral("hkps://hkps.pool.sks-keyservers.net"));
}
}
}
// read LDAP timeout
// first try to read the config entry as int (GnuPG 2.3)
mTimeoutConfigEntry = configEntry(s_timeout_componentName, s_timeout_entryName, CryptoConfigEntry::ArgType_Int, SingleValue, DoNotShowError);
if (!mTimeoutConfigEntry) {
// if this fails, then try to read the config entry as unsigned int (GnuPG <= 2.2)
mTimeoutConfigEntry = configEntry(s_timeout_componentName, s_timeout_entryName, CryptoConfigEntry::ArgType_UInt, SingleValue, DoShowError);
}
if (mTimeoutConfigEntry) {
const int ldapTimeout = mTimeoutConfigEntry->argType() == CryptoConfigEntry::ArgType_Int ? mTimeoutConfigEntry->intValue()
: static_cast<int>(mTimeoutConfigEntry->uintValue());
const QTime time = QTime(0, 0, 0, 0).addSecs(ldapTimeout);
// qCDebug(KLEOPATRA_LOG) <<"timeout:" << mTimeoutConfigEntry->uintValue() <<" ->" << time;
mTimeout.widget()->setTime(time);
}
mTimeout.setEnabled(mTimeoutConfigEntry && !mTimeoutConfigEntry->isReadOnly());
// read max-replies config entry
// first try to read the config entry as int (GnuPG 2.3)
mMaxItemsConfigEntry = configEntry(s_maxitems_componentName, s_maxitems_entryName, CryptoConfigEntry::ArgType_Int, SingleValue, DoNotShowError);
if (!mMaxItemsConfigEntry) {
// if this fails, then try to read the config entry as unsigned int (GnuPG <= 2.2)
mMaxItemsConfigEntry = configEntry(s_maxitems_componentName, s_maxitems_entryName, CryptoConfigEntry::ArgType_UInt, SingleValue, DoShowError);
}
if (mMaxItemsConfigEntry) {
const int value = mMaxItemsConfigEntry->argType() == CryptoConfigEntry::ArgType_Int ? mMaxItemsConfigEntry->intValue()
: static_cast<int>(mMaxItemsConfigEntry->uintValue());
mMaxItems.widget()->blockSignals(true); // KNumInput emits valueChanged from setValue!
mMaxItems.widget()->setValue(value);
mMaxItems.widget()->blockSignals(false);
}
mMaxItems.setEnabled(mMaxItemsConfigEntry && !mMaxItemsConfigEntry->isReadOnly());
mFetchMissingSignerKeysCB->setChecked(settings.retrieveSignerKeysAfterImport());
mFetchMissingSignerKeysCB->setEnabled(!settings.isImmutable(QStringLiteral("RetrieveSignerKeysAfterImport")));
mQueryWKDsForAllUserIDsCB->setChecked(settings.queryWKDsForAllUserIDs());
mQueryWKDsForAllUserIDsCB->setEnabled(!settings.isImmutable(QStringLiteral("QueryWKDsForAllUserIDs")));
}
void DirectoryServicesConfigurationPage::Private::load()
{
load(Settings{});
}
namespace
{
void updateIntegerConfigEntry(QGpgME::CryptoConfigEntry *configEntry, int value)
{
if (!configEntry) {
return;
}
if (configEntry->argType() == CryptoConfigEntry::ArgType_Int) {
if (configEntry->intValue() != value) {
configEntry->setIntValue(value);
}
} else {
const auto newValue = static_cast<unsigned>(value);
if (configEntry->uintValue() != newValue) {
configEntry->setUIntValue(newValue);
}
}
}
}
void DirectoryServicesConfigurationPage::Private::setX509ServerEntry(const std::vector<KeyserverConfig> &servers)
{
const auto newEntry = configEntry(s_x509services_componentName, s_x509services_entryName, CryptoConfigEntry::ArgType_LDAPURL, ListValue, DoNotShowError);
const auto legacyEntry =
configEntry(s_x509services_legacy_componentName, s_x509services_legacy_entryName, CryptoConfigEntry::ArgType_LDAPURL, ListValue, DoNotShowError);
if ((newEntry && newEntry->isReadOnly()) || (legacyEntry && legacyEntry->isReadOnly())) {
// do not change the config entries if either config entry is read-only
return;
}
QList<QUrl> urls;
urls.reserve(servers.size());
std::transform(std::begin(servers), std::end(servers), std::back_inserter(urls), std::mem_fn(&KeyserverConfig::toUrl));
if (newEntry) {
// write all servers to the new config entry
newEntry->setURLValueList(urls);
// and clear the legacy config entry
if (legacyEntry) {
legacyEntry->setURLValueList({});
}
} else if (legacyEntry) {
// write all servers to the legacy config entry if the new entry is not available
legacyEntry->setURLValueList(urls);
} else {
qCWarning(KLEOPATRA_LOG) << "Could not store the X.509 servers. Unknown or wrong typed config entries" << s_x509services_componentName << "/"
<< s_x509services_entryName << "and" << s_x509services_legacy_componentName << "/" << s_x509services_legacy_entryName;
}
}
void DirectoryServicesConfigurationPage::Private::save()
{
if (mDirectoryServices && mDirectoryServices->isEnabled()) {
setX509ServerEntry(mDirectoryServices->keyservers());
}
if (mOpenPGPServiceEntry) {
const auto keyserver = mOpenPGPKeyserverEdit.widget()->text().trimmed();
if (keyserver.isEmpty()) {
mOpenPGPServiceEntry->resetToDefault();
} else if (keyserver == QLatin1StringView{"none"}) {
mOpenPGPServiceEntry->setStringValue(keyserver);
} else {
const auto keyserverUrl = keyserver.contains(QLatin1StringView{"://"}) ? keyserver : (QLatin1String{"hkps://"} + keyserver);
mOpenPGPServiceEntry->setStringValue(keyserverUrl);
}
}
const QTime time{mTimeout.widget()->time()};
updateIntegerConfigEntry(mTimeoutConfigEntry, time.minute() * 60 + time.second());
updateIntegerConfigEntry(mMaxItemsConfigEntry, mMaxItems.widget()->value());
mConfig->sync(true);
Settings settings;
settings.setRetrieveSignerKeysAfterImport(mFetchMissingSignerKeysCB->isChecked());
settings.setQueryWKDsForAllUserIDs(mQueryWKDsForAllUserIDsCB->isChecked());
settings.save();
}
void DirectoryServicesConfigurationPage::Private::defaults()
{
// these guys don't have a default, to clear them:
if (mDirectoryServices && mDirectoryServices->isEnabled()) {
setX509ServerEntry({});
}
if (mOpenPGPServiceEntry && !mOpenPGPServiceEntry->isReadOnly()) {
mOpenPGPServiceEntry->setStringValue(QString());
}
// these presumably have a default, use that one:
if (mTimeoutConfigEntry && !mTimeoutConfigEntry->isReadOnly()) {
mTimeoutConfigEntry->resetToDefault();
}
if (mMaxItemsConfigEntry && !mMaxItemsConfigEntry->isReadOnly()) {
mMaxItemsConfigEntry->resetToDefault();
}
Settings settings;
settings.setRetrieveSignerKeysAfterImport(settings.findItem(QStringLiteral("RetrieveSignerKeysAfterImport"))->getDefault().toBool());
settings.setQueryWKDsForAllUserIDs(settings.findItem(QStringLiteral("QueryWKDsForAllUserIDs"))->getDefault().toBool());
load(settings);
}
// Find config entry for ldap servers. Implements runtime checks on the configuration option.
CryptoConfigEntry *DirectoryServicesConfigurationPage::Private::configEntry(const char *componentName,
const char *entryName,
CryptoConfigEntry::ArgType argType,
EntryMultiplicity multiplicity,
ShowError showError)
{
CryptoConfigEntry *const entry = Kleo::getCryptoConfigEntry(mConfig, componentName, entryName);
if (!entry) {
if (showError == DoShowError) {
KMessageBox::error(
q->widget(),
i18n("Backend error: gpgconf does not seem to know the entry for %1/%2", QLatin1StringView(componentName), QLatin1String(entryName)));
}
return nullptr;
}
if (entry->argType() != argType || entry->isList() != bool(multiplicity)) {
if (showError == DoShowError) {
KMessageBox::error(q->widget(),
i18n("Backend error: gpgconf has wrong type for %1/%2: %3 %4",
QLatin1StringView(componentName),
QLatin1StringView(entryName),
entry->argType(),
entry->isList()));
}
return nullptr;
}
return entry;
}
DirectoryServicesConfigurationPage::DirectoryServicesConfigurationPage(QObject *parent, const KPluginMetaData &data)
: KCModule(parent, data)
, d{new Private{this}}
{
+ load();
+ setNeedsSave(false);
}
DirectoryServicesConfigurationPage::~DirectoryServicesConfigurationPage() = default;
void DirectoryServicesConfigurationPage::load()
{
d->load();
}
void DirectoryServicesConfigurationPage::save()
{
d->save();
+ setNeedsSave(false);
}
void DirectoryServicesConfigurationPage::defaults()
{
d->defaults();
}
#include "moc_dirservconfigpage.cpp"
diff --git a/src/conf/gnupgsystemconfigurationpage.cpp b/src/conf/gnupgsystemconfigurationpage.cpp
index a900887ac..bd2b9005d 100644
--- a/src/conf/gnupgsystemconfigurationpage.cpp
+++ b/src/conf/gnupgsystemconfigurationpage.cpp
@@ -1,64 +1,68 @@
/* -*- mode: c++; c-basic-offset:4 -*-
conf/gnupgsystemconfigurationpage.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "gnupgsystemconfigurationpage.h"
#include <config-kleopatra.h>
#include <Libkleo/CryptoConfigModule>
#include <QGpgME/CryptoConfig>
#include <QGpgME/Protocol>
#include <QVBoxLayout>
using namespace Kleo::Config;
GnuPGSystemConfigurationPage::GnuPGSystemConfigurationPage(QObject *parent, const KPluginMetaData &data)
: KCModule(parent, data)
{
auto lay = new QVBoxLayout(widget());
lay->setContentsMargins(0, 0, 0, 0);
QGpgME::CryptoConfig *const config = QGpgME::cryptoConfig();
mWidget = new CryptoConfigModule(config, CryptoConfigModule::TabbedLayout, widget());
lay->addWidget(mWidget);
connect(mWidget, &CryptoConfigModule::changed, this, &Kleo::Config::GnuPGSystemConfigurationPage::markAsChanged);
+
+ load();
+ setNeedsSave(false);
}
GnuPGSystemConfigurationPage::~GnuPGSystemConfigurationPage()
{
// ### correct here?
if (QGpgME::CryptoConfig *const config = QGpgME::cryptoConfig()) {
config->clear();
}
}
void GnuPGSystemConfigurationPage::load()
{
mWidget->reset();
}
void GnuPGSystemConfigurationPage::save()
{
mWidget->save();
+ setNeedsSave(false);
#if 0
// Tell other apps (e.g. kmail) that the gpgconf data might have changed
QDBusMessage message =
QDBusMessage::createSignal(QString(), "org.kde.kleo.CryptoConfig", "changed");
QDBusConnection::sessionBus().send(message);
#endif
}
void GnuPGSystemConfigurationPage::defaults()
{
mWidget->defaults();
}
#include "moc_gnupgsystemconfigurationpage.cpp"
diff --git a/src/conf/kleopageconfigdialog.cpp b/src/conf/kleopageconfigdialog.cpp
index 13c3a272c..f90562649 100644
--- a/src/conf/kleopageconfigdialog.cpp
+++ b/src/conf/kleopageconfigdialog.cpp
@@ -1,239 +1,242 @@
/*
kleopageconfigdialog.cpp
This file is part of Kleopatra
SPDX-FileCopyrightText: 2016 Bundesamt für Sicherheit in der Informationstechnik
SPDX-FileContributor: Intevation GmbH
SPDX-License-Identifier: GPL-2.0-only
It is derived from KCMultidialog which is:
SPDX-FileCopyrightText: 2000 Matthias Elter <elter@kde.org>
SPDX-FileCopyrightText: 2003 Daniel Molkentin <molkentin@kde.org>
SPDX-FileCopyrightText: 2003, 2006 Matthias Kretz <kretz@kde.org>
SPDX-FileCopyrightText: 2004 Frans Englich <frans.englich@telia.com>
SPDX-FileCopyrightText: 2006 Tobias Koenig <tokoe@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "kleopageconfigdialog.h"
#include <QDesktopServices>
#include <QDialogButtonBox>
#include <QProcess>
#include <QPushButton>
#include <QStandardPaths>
#include <QUrl>
#include <KCModule>
#include <KLocalizedString>
#include <KMessageBox>
#include <KStandardGuiItem>
#include "kleopatra_debug.h"
KleoPageConfigDialog::KleoPageConfigDialog(QWidget *parent)
: KPageDialog(parent)
{
setModal(false);
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
buttonBox->setStandardButtons(QDialogButtonBox::Help //
| QDialogButtonBox::RestoreDefaults //
| QDialogButtonBox::Cancel //
| QDialogButtonBox::Apply //
| QDialogButtonBox::Ok //
| QDialogButtonBox::Reset);
KGuiItem::assign(buttonBox->button(QDialogButtonBox::Ok), KStandardGuiItem::ok());
KGuiItem::assign(buttonBox->button(QDialogButtonBox::Cancel), KStandardGuiItem::cancel());
KGuiItem::assign(buttonBox->button(QDialogButtonBox::RestoreDefaults), KStandardGuiItem::defaults());
KGuiItem::assign(buttonBox->button(QDialogButtonBox::Apply), KStandardGuiItem::apply());
KGuiItem::assign(buttonBox->button(QDialogButtonBox::Reset), KStandardGuiItem::reset());
KGuiItem::assign(buttonBox->button(QDialogButtonBox::Help), KStandardGuiItem::help());
buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
connect(buttonBox->button(QDialogButtonBox::Apply), &QAbstractButton::clicked, this, &KleoPageConfigDialog::slotApplyClicked);
connect(buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked, this, &KleoPageConfigDialog::slotOkClicked);
connect(buttonBox->button(QDialogButtonBox::RestoreDefaults), &QAbstractButton::clicked, this, &KleoPageConfigDialog::slotDefaultClicked);
connect(buttonBox->button(QDialogButtonBox::Help), &QAbstractButton::clicked, this, &KleoPageConfigDialog::slotHelpClicked);
connect(buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, this, &KleoPageConfigDialog::slotUser1Clicked);
setButtonBox(buttonBox);
connect(this, &KPageDialog::currentPageChanged, this, &KleoPageConfigDialog::slotCurrentPageChanged);
}
void KleoPageConfigDialog::slotCurrentPageChanged(KPageWidgetItem *current, KPageWidgetItem *previous)
{
if (!previous) {
return;
}
blockSignals(true);
setCurrentPage(previous);
KCModule *previousModule = qobject_cast<KCModule *>(previous->widget());
bool canceled = false;
if (previousModule && mChangedModules.contains(previousModule)) {
const int queryUser = KMessageBox::warningTwoActionsCancel(this,
i18n("The settings of the current module have changed.\n"
"Do you want to apply the changes or discard them?"),
i18nc("@title:window", "Apply Settings"),
KStandardGuiItem::apply(),
KStandardGuiItem::discard(),
KStandardGuiItem::cancel());
if (queryUser == KMessageBox::ButtonCode::PrimaryAction) {
previousModule->save();
} else if (queryUser == KMessageBox::ButtonCode::SecondaryAction) {
previousModule->load();
}
canceled = queryUser == KMessageBox::Cancel;
}
if (!canceled) {
mChangedModules.removeAll(previousModule);
setCurrentPage(current);
}
blockSignals(false);
clientChanged();
}
void KleoPageConfigDialog::apply()
{
QPushButton *applyButton = buttonBox()->button(QDialogButtonBox::Apply);
applyButton->setFocus();
for (KCModule *module : mChangedModules) {
module->save();
}
mChangedModules.clear();
Q_EMIT configCommitted();
clientChanged();
}
void KleoPageConfigDialog::slotDefaultClicked()
{
const KPageWidgetItem *item = currentPage();
if (!item) {
return;
}
KCModule *module = qobject_cast<KCModule *>(item->widget());
if (!module) {
return;
}
module->defaults();
clientChanged();
}
void KleoPageConfigDialog::slotUser1Clicked()
{
const KPageWidgetItem *item = currentPage();
if (!item) {
return;
}
KCModule *module = qobject_cast<KCModule *>(item->widget());
if (!module) {
return;
}
module->load();
mChangedModules.removeAll(module);
clientChanged();
}
void KleoPageConfigDialog::slotApplyClicked()
{
apply();
}
void KleoPageConfigDialog::slotOkClicked()
{
apply();
accept();
}
void KleoPageConfigDialog::slotHelpClicked()
{
const KPageWidgetItem *item = currentPage();
if (!item) {
return;
}
const QString docPath = mHelpUrls.value(item->name());
QUrl docUrl;
#ifdef Q_OS_WIN
docUrl = QUrl(QLatin1StringView("https://docs.kde.org/index.php?branch=stable5&language=") + QLocale().name() + QLatin1String("&application=kleopatra"));
#else
docUrl = QUrl(QStringLiteral("help:/")).resolved(QUrl(docPath)); // same code as in KHelpClient::invokeHelp
#endif
if (docUrl.scheme() == QLatin1StringView("help") || docUrl.scheme() == QLatin1String("man") || docUrl.scheme() == QLatin1String("info")) {
// Warning: Don't assume that the program needs to be in PATH. On Windows, it will also be found next to the calling process.
QProcess::startDetached(QStringLiteral("khelpcenter"), QStringList() << docUrl.toString());
} else {
QDesktopServices::openUrl(docUrl);
}
}
void KleoPageConfigDialog::addModule(const QString &name, const QString &docPath, const QString &icon, KCModule *module)
{
mModules << module;
KPageWidgetItem *item = addPage(module->widget(), name);
item->setIcon(QIcon::fromTheme(icon));
connect(module, &KCModule::needsSaveChanged, this, [this, module]() {
moduleChanged(module->needsSave());
});
+ if (module->needsSave()) {
+ mChangedModules.append(module);
+ }
mHelpUrls.insert(name, docPath);
}
void KleoPageConfigDialog::moduleChanged(bool state)
{
KCModule *module = qobject_cast<KCModule *>(sender());
qCDebug(KLEOPATRA_LOG) << "Module changed: " << state << " mod " << module;
if (mChangedModules.contains(module)) {
if (!state) {
mChangedModules.removeAll(module);
} else {
return;
}
}
if (state) {
mChangedModules << module;
}
clientChanged();
}
void KleoPageConfigDialog::clientChanged()
{
const KPageWidgetItem *item = currentPage();
if (!item) {
return;
}
- KCModule *module = qobject_cast<KCModule *>(item->widget());
+ KCModule *module = qobject_cast<KCModule *>(sender());
if (!module) {
return;
}
qCDebug(KLEOPATRA_LOG) << "Client changed: "
<< " mod " << module;
bool change = mChangedModules.contains(module);
QPushButton *resetButton = buttonBox()->button(QDialogButtonBox::Reset);
if (resetButton) {
resetButton->setEnabled(change);
}
QPushButton *applyButton = buttonBox()->button(QDialogButtonBox::Apply);
if (applyButton) {
applyButton->setEnabled(change);
}
}
#include "moc_kleopageconfigdialog.cpp"
diff --git a/src/conf/smimevalidationconfigurationpage.cpp b/src/conf/smimevalidationconfigurationpage.cpp
index c41533cf7..83b26cd91 100644
--- a/src/conf/smimevalidationconfigurationpage.cpp
+++ b/src/conf/smimevalidationconfigurationpage.cpp
@@ -1,46 +1,50 @@
/* -*- mode: c++; c-basic-offset:4 -*-
conf/smimevalidationconfigurationpage.cpp
This file is part of Kleopatra, the KDE keymanager
SPDX-FileCopyrightText: 2008 Klarälvdalens Datakonsult AB
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <config-kleopatra.h>
#include "smimevalidationconfigurationpage.h"
#include "smimevalidationconfigurationwidget.h"
#include <QVBoxLayout>
using namespace Kleo::Config;
SMimeValidationConfigurationPage::SMimeValidationConfigurationPage(QObject *parent, const KPluginMetaData &data)
: KCModule(parent, data)
{
auto lay = new QVBoxLayout(widget());
lay->setContentsMargins(0, 0, 0, 0);
mWidget = new SMimeValidationConfigurationWidget(widget());
lay->addWidget(mWidget);
connect(mWidget, &SMimeValidationConfigurationWidget::changed, this, &Kleo::Config::SMimeValidationConfigurationPage::markAsChanged);
+
+ load();
+ setNeedsSave(false);
}
void SMimeValidationConfigurationPage::load()
{
mWidget->load();
}
void SMimeValidationConfigurationPage::save()
{
mWidget->save();
+ setNeedsSave(false);
}
void SMimeValidationConfigurationPage::defaults()
{
mWidget->defaults();
}
#include "moc_smimevalidationconfigurationpage.cpp"
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, May 12, 6:35 PM (1 d, 18 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
07/1f/93d58d54cdad1c8eacaa5b1fe6d2
Attached To
rKLEOPATRA Kleopatra
Event Timeline
Log In to Comment