diff --git a/src/conf/groupsconfigpage.cpp b/src/conf/groupsconfigpage.cpp index f92decad2..4601eecfd 100644 --- a/src/conf/groupsconfigpage.cpp +++ b/src/conf/groupsconfigpage.cpp @@ -1,90 +1,138 @@ /* conf/groupsconfigpage.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2021 g10 Code GmbH SPDX-FileContributor: Ingo Klöcker SPDX-License-Identifier: GPL-2.0-or-later */ #include #include "groupsconfigpage.h" #include "groupsconfigwidget.h" #include #include #include +#include +#include + #include +#include + #include "kleopatra_debug.h" using namespace Kleo; class GroupsConfigPage::Private { friend class ::GroupsConfigPage; GroupsConfigPage *const q; Private(GroupsConfigPage *qq); public: ~Private() = default; void setChanged(bool changed); + void onKeysMayHaveChanged(); + private: GroupsConfigWidget *widget = nullptr; bool changed = false; + bool savingChanges = false; }; GroupsConfigPage::Private::Private(GroupsConfigPage *qq) : q(qq) { } void GroupsConfigPage::Private::setChanged(bool state) { changed = state; Q_EMIT q->changed(changed); } +void GroupsConfigPage::Private::onKeysMayHaveChanged() +{ + static std::mutex mutex; + + std::unique_lock lock(mutex, std::try_to_lock); + if (!lock) { + // prevent reentrace + return; + } + + if (savingChanges) { + qCDebug(KLEOPATRA_LOG) << __func__ << "ignoring changes caused by ourselves"; + return; + } + if (!changed) { + q->load(); + } else { + auto buttonYes = KStandardGuiItem::yes(); + buttonYes.setText(i18n("Save changes")); + auto buttonNo = KStandardGuiItem::no(); + buttonNo.setText(i18n("Discard changes")); + const auto answer = KMessageBox::questionYesNo( + q->topLevelWidget(), + xi18nc("@info", "The certificates or the certificate groups have been updated in the background." + "Do you want to save your changes?"), + i18nc("@title::window", "Save changes?"), + buttonYes, buttonNo); + if (answer == KMessageBox::Yes) { + q->save(); + } else { + q->load(); + } + } +} + GroupsConfigPage::GroupsConfigPage(QWidget *parent) : QWidget(parent) , d(new Private(this)) { auto layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); d->widget = new Kleo::GroupsConfigWidget(this); if (QLayout *l = d->widget->layout()) { l->setContentsMargins(0, 0, 0, 0); } layout->addWidget(d->widget); connect(d->widget, &GroupsConfigWidget::changed, this, [this] () { d->setChanged(true); }); + + connect(KeyCache::instance().get(), &KeyCache::keysMayHaveChanged, + this, [this]() { d->onKeysMayHaveChanged(); }); } GroupsConfigPage::~GroupsConfigPage() = default; bool GroupsConfigPage::hasChanged() const { return d->changed; } void GroupsConfigPage::load() { d->widget->setGroups(KeyCache::instance()->configurableGroups()); d->setChanged(false); } void GroupsConfigPage::save() { + d->savingChanges = true; KeyCache::mutableInstance()->saveConfigurableGroups(d->widget->groups()); + d->savingChanges = false; // reload after saving to ensure that the groups reflect the saved groups (e.g. in case of immutable entries) load(); }