Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F34572205
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
17 KB
Subscribers
None
View Options
diff --git a/src/conf/gpgpasspageconfigdialog.cpp b/src/conf/gpgpasspageconfigdialog.cpp
index 18831a8..b3e4e05 100644
--- a/src/conf/gpgpasspageconfigdialog.cpp
+++ b/src/conf/gpgpasspageconfigdialog.cpp
@@ -1,219 +1,225 @@
/*
GpgPasspageconfigdialog.cpp
This file is part of GpgPasspatra
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 "gpgpasspageconfigdialog.h"
#include "gpgpassconfigmodule.h"
#include <QDebug>
#include <QDesktopServices>
#include <QDialogButtonBox>
#include <QLocale>
#include <QProcess>
#include <QPushButton>
#include <QUrl>
#include <KLocalizedString>
#include <KMessageBox>
#include <KStandardGuiItem>
+#include "kwidgetsaddons_version.h"
+
using namespace GpgPass::Config;
GpgPassPageConfigDialog::GpgPassPageConfigDialog(QWidget *parent)
: KPageDialog(parent)
{
setModal(false);
QDialogButtonBox *buttonBox = new QDialogButtonBox(this);
buttonBox->setStandardButtons( // | QDialogButtonBox::RestoreDefaults enable this again when ported to KConfig
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());
buttonBox->button(QDialogButtonBox::Reset)->setEnabled(false);
buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
connect(buttonBox->button(QDialogButtonBox::Apply), &QAbstractButton::clicked, this, &GpgPassPageConfigDialog::slotApplyClicked);
connect(buttonBox->button(QDialogButtonBox::Ok), &QAbstractButton::clicked, this, &GpgPassPageConfigDialog::slotOkClicked);
connect(buttonBox->button(QDialogButtonBox::RestoreDefaults), &QAbstractButton::clicked, this, &GpgPassPageConfigDialog::slotDefaultClicked);
connect(buttonBox->button(QDialogButtonBox::Reset), &QAbstractButton::clicked, this, &GpgPassPageConfigDialog::slotUser1Clicked);
setButtonBox(buttonBox);
connect(this, &KPageDialog::currentPageChanged, this, &GpgPassPageConfigDialog::slotCurrentPageChanged);
}
void GpgPassPageConfigDialog::slotCurrentPageChanged(KPageWidgetItem *current, KPageWidgetItem *previous)
{
if (!previous) {
return;
}
blockSignals(true);
setCurrentPage(previous);
auto previousModule = qobject_cast<GpgPassConfigModule *>(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.remove(previousModule);
setCurrentPage(current);
}
blockSignals(false);
clientChanged();
}
void GpgPassPageConfigDialog::apply()
{
QPushButton *applyButton = buttonBox()->button(QDialogButtonBox::Apply);
applyButton->setFocus();
for (const auto &module : std::as_const(mChangedModules)) {
module->save();
}
mChangedModules.clear();
Q_EMIT configCommitted();
clientChanged();
}
void GpgPassPageConfigDialog::slotDefaultClicked()
{
const KPageWidgetItem *item = currentPage();
if (!item) {
return;
}
auto module = qobject_cast<GpgPassConfigModule *>(item->widget());
if (!module) {
return;
}
module->defaults();
clientChanged();
}
void GpgPassPageConfigDialog::slotUser1Clicked()
{
const KPageWidgetItem *item = currentPage();
if (!item) {
return;
}
auto module = qobject_cast<GpgPassConfigModule *>(item->widget());
if (!module) {
return;
}
module->load();
mChangedModules.remove(module);
clientChanged();
}
void GpgPassPageConfigDialog::slotApplyClicked()
{
apply();
}
void GpgPassPageConfigDialog::slotOkClicked()
{
apply();
accept();
}
KPageWidgetItem *GpgPassPageConfigDialog::addModule(const QString &name,
const QString &docPath,
const QString &icon,
const QList<QAction *> actions,
GpgPassConfigModule *module)
{
mModules << module;
module->load();
auto item = addPage(module, name);
item->setIcon(QIcon::fromTheme(icon));
+#if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(6, 6, 0)
item->setActions(actions);
+#else
+ Q_UNUSED(actions);
+#endif
connect(module, &GpgPassConfigModule::changed, this, [this, module]() {
moduleChanged(true);
mChangedModules.insert(module);
});
mHelpUrls.insert(name, docPath);
return item;
}
void GpgPassPageConfigDialog::moduleChanged(bool state)
{
auto module = qobject_cast<GpgPassConfigModule *>(sender());
qDebug() << "Module changed: " << state << " mod " << module;
if (mChangedModules.contains(module)) {
if (!state) {
mChangedModules.remove(module);
} else {
return;
}
}
if (state) {
mChangedModules << module;
}
clientChanged();
}
void GpgPassPageConfigDialog::clientChanged()
{
const KPageWidgetItem *item = currentPage();
if (!item) {
return;
}
auto module = qobject_cast<GpgPassConfigModule *>(currentPage()->widget());
if (!module) {
return;
}
qDebug() << "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_gpgpasspageconfigdialog.cpp"
diff --git a/src/conf/rootfoldersconfigurationpage.cpp b/src/conf/rootfoldersconfigurationpage.cpp
index e0783ee..c33bb7d 100644
--- a/src/conf/rootfoldersconfigurationpage.cpp
+++ b/src/conf/rootfoldersconfigurationpage.cpp
@@ -1,260 +1,267 @@
// SPDX-FileCopyrightText: 2024 g10 Code GmbH
// SPDX-FileContributor: Carl Schwan <carl@carlschwan.eu>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "rootfoldersconfigurationpage.h"
#include "models/rootfoldersmodel.h"
#include "rootfolderconfig.h"
#include "rootfoldersmanager.h"
#include "ui_rootfoldersconfigurationpage.h"
#include <QCheckBox>
#include <QDialogButtonBox>
#include <QFileDialog>
#include <QFileInfo>
#include <QLabel>
#include <QMessageBox>
#include <QPainter>
#include <QPushButton>
#include <QTimer>
#include <QToolButton>
#include <KMessageBox>
#include <KSelectionProxyModel>
#include <KUrlRequester>
#include <KWidgetItemDelegate>
#include <Libkleo/DefaultKeyFilter>
#include <Libkleo/KeySelectionCombo>
using namespace GpgPass::Config;
class DummyButton : public QToolButton
{
public:
int buttonSize(QAbstractItemView *view)
{
constexpr int iconSize = 16;
QStyleOptionToolButton styleOption;
initStyleOption(&styleOption);
const auto size = view->style()->sizeFromContents(QStyle::CT_ToolButton, &styleOption, QSize(iconSize, iconSize));
return qMax(size.width(), size.height());
}
};
class RootFolderItemDelegate : public KWidgetItemDelegate
{
Q_OBJECT
public:
explicit RootFolderItemDelegate(QAbstractItemView *view)
: KWidgetItemDelegate(view)
{
mMargin = 4;
mSpacing = 4;
DummyButton dummyButton;
mButtonSize = dummyButton.buttonSize(view);
}
protected:
QList<QWidget *> createItemWidgets(const QModelIndex &index) const override
{
if (index.column() != 0 && qobject_cast<KSelectionProxyModel const *>(index.model()) != nullptr) {
return {};
}
auto removeButton = new QToolButton;
removeButton->setAccessibleName(i18nc("@action:button", "Delete Folder"));
removeButton->setAutoRaise(true);
setBlockedEventTypes(removeButton, {QEvent::MouseButtonPress, QEvent::MouseButtonRelease, QEvent::MouseButtonDblClick});
removeButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove")));
connect(removeButton, &QToolButton::clicked, this, &RootFolderItemDelegate::slotRemoveButtonClicked);
return {removeButton};
}
void updateItemWidgets(const QList<QWidget *> &widgets, const QStyleOptionViewItem &option, const QPersistentModelIndex &index) const override
{
if (widgets.count() == 0) {
return;
}
auto removeButton = static_cast<QToolButton *>(widgets[0]);
QSize buttonSize(mButtonSize, option.rect.height() - 2 * mMargin);
removeButton->resize(buttonSize);
removeButton->move(option.rect.width() - mButtonSize - mMargin, mMargin);
}
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
if (!index.isValid()) {
return;
}
const bool selected = option.state & QStyle::State_Selected;
itemView()->style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter, nullptr);
QRect textRect = option.rect;
textRect.setLeft(textRect.left() + mMargin * 2);
textRect.setWidth(textRect.width() - mButtonSize - mMargin - mSpacing);
painter->setPen(option.palette.color(QPalette::Normal, selected ? QPalette::HighlightedText : QPalette::Text));
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, index.data().toString());
}
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
const int width = option.fontMetrics.boundingRect(index.data().toString()).width();
const int height = qMax(mButtonSize, option.fontMetrics.height());
return QSize(width + 2 * mMargin, height + 2 * mMargin);
}
Q_SIGNALS:
void removeFolder(const QModelIndex &index);
private:
void slotRemoveButtonClicked()
{
const QModelIndex index = focusedIndex();
if (!index.isValid()) {
qWarning() << "!index.isValid()";
return;
}
Q_EMIT removeFolder(index);
}
int mMargin;
int mSpacing;
int mButtonSize;
};
RootFoldersConfigurationPage::RootFoldersConfigurationPage(RootFoldersManager *rootFoldersManager, QAction *addStoreAction, QWidget *parent)
: GpgPassConfigModule(parent)
, ui(new Ui::RootFoldersConfigurationPage)
, m_rootFoldersManager(rootFoldersManager)
, m_rootFoldersModel(new RootFoldersModel(m_rootFoldersManager, this))
, m_addStoreAction(addStoreAction)
{
ui->setupUi(this);
ui->rootFoldersView->setModel(m_rootFoldersModel);
auto delegate = new RootFolderItemDelegate(ui->rootFoldersView);
ui->rootFoldersView->setItemDelegate(delegate);
ui->splitter->setStretchFactor(1, 3);
connect(ui->rootFoldersView->selectionModel(), &QItemSelectionModel::currentChanged, this, &RootFoldersConfigurationPage::selectTreeItem);
connect(m_addStoreAction, &QAction::triggered, this, [this]() {
const auto idx = m_rootFoldersModel->addNewFolder();
ui->rootFoldersView->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
});
// Name
m_nameInput = Kleo::FormTextInput<QLineEdit>::create(this);
m_nameInput->setLabelText(i18nc("@label", "Name:"));
m_nameInput->setValueRequiredErrorMessage(i18n("Enter a valid path."));
ui->folderInfoLayout->addWidget(m_nameInput->label());
ui->folderInfoLayout->addWidget(m_nameInput->hintLabel());
ui->folderInfoLayout->addWidget(m_nameInput->errorLabel());
ui->folderInfoLayout->addWidget(m_nameInput->widget());
ui->folderInfoLayout->addSpacing(style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing));
// Location
m_locationInput = Kleo::FormTextInput<KUrlRequester>::create(this);
m_locationInput->setLabelText(i18nc("@label", "Path:"));
m_locationInput->setValueRequiredErrorMessage(i18n("Enter a valid path."));
m_locationInput->setInvalidEntryErrorMessage(i18n("Enter a valid path."));
m_locationInput->widget()->setMode(KFile::Directory);
ui->folderInfoLayout->addWidget(m_locationInput->label());
ui->folderInfoLayout->addWidget(m_locationInput->hintLabel());
ui->folderInfoLayout->addWidget(m_locationInput->errorLabel());
ui->folderInfoLayout->addWidget(m_locationInput->widget());
ui->folderInfoLayout->addStretch();
+#if KWIDGETSADDONS_VERSION < QT_VERSION_CHECK(6, 6, 0)
+ auto button = new QToolButton(this);
+ button->setDefaultAction(addStoreAction);
+ button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
+ ui->folderInfoLayout->addWidget(button);
+#endif
+
ui->folderInfoLayout->setContentsMargins(style()->pixelMetric(QStyle::PM_LayoutLeftMargin),
style()->pixelMetric(QStyle::PM_LayoutTopMargin),
style()->pixelMetric(QStyle::PM_LayoutRightMargin),
style()->pixelMetric(QStyle::PM_LayoutBottomMargin));
connect(m_locationInput->widget(), &KUrlRequester::textChanged, this, &RootFoldersConfigurationPage::slotLocationChanged);
connect(m_nameInput->widget(), &QLineEdit::textEdited, this, &RootFoldersConfigurationPage::slotNameChanged);
connect(delegate, &RootFolderItemDelegate::removeFolder, m_rootFoldersModel, &RootFoldersModel::slotRemoveFolder);
connect(delegate, &RootFolderItemDelegate::removeFolder, this, &RootFoldersConfigurationPage::changed);
}
void RootFoldersConfigurationPage::save()
{
m_rootFoldersManager->save();
}
void RootFoldersConfigurationPage::load()
{
m_rootFoldersModel->load();
if (m_rootFoldersModel->rowCount({}) > 0) {
const auto idx = m_rootFoldersModel->index(0, 0);
ui->rootFoldersView->selectionModel()->setCurrentIndex(idx, QItemSelectionModel::ClearAndSelect);
}
}
void RootFoldersConfigurationPage::defaults()
{
m_rootFoldersManager->load();
}
void RootFoldersConfigurationPage::selectTreeItem(const QModelIndex &)
{
const auto rootFolder = fromCurrentIndex();
if (!rootFolder) {
return;
}
m_nameInput->widget()->setText(rootFolder->name());
m_locationInput->widget()->setUrl(QUrl::fromLocalFile(rootFolder->path()));
for (int i = 0, count = ui->folderInfoLayout->count(); i < count; i++) {
const auto item = ui->folderInfoLayout->itemAt(i);
const auto spacer = item->spacerItem();
if (spacer) {
spacer->changeSize(0, style()->pixelMetric(QStyle::PM_LayoutVerticalSpacing), QSizePolicy::Minimum, QSizePolicy::Fixed);
break;
}
}
ui->folderInfoLayout->invalidate();
}
RootFolderConfig *RootFoldersConfigurationPage::fromCurrentIndex()
{
const auto index = ui->rootFoldersView->currentIndex();
if (!index.isValid()) {
return {};
}
return index.data(Qt::UserRole).value<RootFolderConfig *>();
}
void RootFoldersConfigurationPage::slotNameChanged(const QString &text)
{
auto rootFolder = fromCurrentIndex();
rootFolder->setName(text);
rootFolder->save();
Q_EMIT changed();
}
void RootFoldersConfigurationPage::slotLocationChanged(const QString &text)
{
auto rootFolder = fromCurrentIndex();
const auto oldPath = rootFolder->path();
if (oldPath == text) {
return;
}
rootFolder->setPath(m_locationInput->widget()->url().toLocalFile());
rootFolder->save();
Q_EMIT changed();
}
#include "rootfoldersconfigurationpage.moc"
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Jan 17, 2:07 AM (4 h, 30 s)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
1d/3b/2df5085af8ea7ae14c5d88c02d27
Attached To
rGPGPASS GnuPG Password Manager
Event Timeline
Log In to Comment