Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F34134179
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
27 KB
Subscribers
None
View Options
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
index 0e60aba..704aeb6 100644
--- a/client/CMakeLists.txt
+++ b/client/CMakeLists.txt
@@ -1,386 +1,388 @@
# SPDX-FileCopyrightText: 2023 g10 code GmbH
# SPDX-Contributor: Carl Schwan <carl.schwan@gnupg.com>
# SPDX-License-Identifier: BSD-2-Clause
add_definitions(-DDATAROUTDIR="${KDE_INSTALL_FULL_DATAROOTDIR}")
add_definitions(-DTRANSLATION_DOMAIN=\"gpgol-js-native\")
add_subdirectory(rootcagenerator)
add_library(gpgol-client-static STATIC)
target_sources(gpgol-client-static PRIVATE
emailviewer.cpp
emailviewer.h
websocketclient.cpp
websocketclient.h
messagedispatcher.cpp
messagedispatcher.h
firsttimedialog.cpp
firsttimedialog.h
# Identity
identity/addressvalidationjob.cpp
identity/addressvalidationjob.h
identity/identitymanager.cpp
identity/identitymanager.h
identity/identitydialog.cpp
identity/identitydialog.h
identity/identity.cpp
identity/identity.h
identity/signature.h
identity/signature.cpp
identity/signatureconfigurator.cpp
identity/signatureconfigurator.h
identity/signaturerichtexteditor.cpp
identity/signaturerichtexteditor_p.h
# Draft
draft/draft.cpp
draft/draft.h
draft/draftmanager.cpp
draft/draftmanager.h
# EWS integration
ews/ewsattachment.cpp
ews/ewsattachment.h
ews/ewsattendee.cpp
ews/ewsattendee.h
ews/ewsclient_debug.cpp
ews/ewsclient_debug.h
ews/ewsid.cpp
ews/ewsid.h
ews/ewsitem.cpp
ews/ewsitem.h
ews/ewsitemshape.cpp
ews/ewsitemshape.h
ews/ewsitembase.cpp
ews/ewsitembase.h
ews/ewsitembase_p.h
ews/ewsmailbox.cpp
ews/ewsmailbox.h
ews/ewsmessagedispatcher.cpp
ews/ewsmessagedispatcher.h
ews/ewsoccurrence.cpp
ews/ewsoccurrence.h
ews/ewspropertyfield.cpp
ews/ewspropertyfield.h
ews/ewsrecurrence.cpp
ews/ewsrecurrence.h
ews/ewsserverversion.cpp
ews/ewsserverversion.h
ews/ewstypes.cpp
ews/ewstypes.h
ews/ewsxml.cpp
ews/ewsxml.h
ews/ewscreateitemrequest.cpp
ews/ewscreateitemrequest.h
ews/ewsgetfolderrequest.cpp
ews/ewsgetfolderrequest.h
ews/ewsupdateitemrequest.cpp
ews/ewsupdateitemrequest.h
ews/ewsrequest.cpp
ews/ewsrequest.h
ews/ewsjob.cpp
ews/ewsjob.h
ews/ewsclient.cpp
ews/ewsclient.h
ews/ewsfinditemrequest.cpp
ews/ewsfinditemrequest.h
ews/ewsgetitemrequest.cpp
ews/ewsgetitemrequest.h
ews/ewsgetfolderrequest.cpp
ews/ewsgetfolderrequest.h
ews/ewsfolder.cpp
ews/ewsfolder.h
ews/ewscreatefolderrequest.cpp
ews/ewscreatefolderrequest.h
ews/ewseffectiverights.h
ews/ewseffectiverights.cpp
ews/ewsfoldershape.cpp
ews/ewsfoldershape.h
ews/ewscopyitemrequest.cpp
ews/ewscopyitemrequest.h
ews/ewsgetfoldercontentrequest.cpp
ews/ewsgetfoldercontentrequest.h
reencrypt/reencryptjob.cpp
reencrypt/reencryptjob.h
reencrypt/choosekeydialog.cpp
reencrypt/choosekeydialog.h
reencrypt/certificatelineedit.cpp
reencrypt/certificatelineedit.h
# Editor
editor/addresseelineedit.cpp
editor/addresseelineedit.h
editor/addresseelineeditmanager.cpp
editor/addresseelineeditmanager.h
editor/bodytexteditor.cpp
editor/bodytexteditor.h
editor/composerviewbase.cpp
editor/composerviewbase.h
editor/composerwindow.cpp
editor/composerwindow.h
editor/composerwindowfactory.cpp
editor/composerwindowfactory.h
editor/cryptostateindicatorwidget.cpp
editor/cryptostateindicatorwidget.h
editor/kmcomposerglobalaction.cpp
editor/kmcomposerglobalaction.h
editor/nearexpirywarning.cpp
editor/nearexpirywarning.h
editor/mailtemplates.cpp
editor/mailtemplates.h
editor/recipient.cpp
editor/recipient.h
editor/recipientline.cpp
editor/recipientline.h
editor/recipientseditor.cpp
editor/recipientseditor.h
editor/util.h
editor/util.cpp
editor/kmailcompletion.cpp
editor/kmailcompletion.h
editor/composersignatures.cpp
editor/composersignatures.h
editor/nodehelper.cpp
editor/nodehelper.h
editor/signaturecontroller.cpp
editor/signaturecontroller.h
editor/spellcheckerconfigdialog.cpp
editor/spellcheckerconfigdialog.h
# Editor job
editor/job/abstractencryptjob.h
editor/job/autocryptheadersjob.h
editor/job/contentjobbase.h
editor/job/contentjobbase_p.h
editor/job/composerjob.cpp
editor/job/composerjob.h
editor/job/encryptjob.h
editor/job/inserttextfilejob.h
editor/job/itipjob.h
editor/job/jobbase.h
editor/job/jobbase_p.h
editor/job/maintextjob.h
editor/job/multipartjob.h
editor/job/protectedheadersjob.h
editor/job/signencryptjob.h
editor/job/signjob.h
editor/job/singlepartjob.h
editor/job/skeletonmessagejob.h
editor/job/transparentjob.h
editor/job/autocryptheadersjob.cpp
editor/job/contentjobbase.cpp
editor/job/encryptjob.cpp
editor/job/inserttextfilejob.cpp
editor/job/itipjob.cpp
editor/job/jobbase.cpp
editor/job/maintextjob.cpp
editor/job/multipartjob.cpp
editor/job/protectedheadersjob.cpp
editor/job/saveasfilejob.cpp
editor/job/saveasfilejob.h
editor/job/signencryptjob.cpp
editor/job/signjob.cpp
editor/job/singlepartjob.cpp
editor/job/skeletonmessagejob.cpp
editor/job/transparentjob.cpp
## Editor Part
editor/part/globalpart.h
editor/part/infopart.h
editor/part/itippart.h
editor/part/messagepart.h
editor/part/textpart.h
editor/part/globalpart.cpp
editor/part/infopart.cpp
editor/part/itippart.cpp
editor/part/messagepart.cpp
editor/part/textpart.cpp
## Attachment
editor/attachment/attachmentjob.cpp
editor/attachment/attachmentjob.h
editor/attachment/attachmentclipboardjob.cpp
editor/attachment/attachmentclipboardjob.h
editor/attachment/attachmentcompressjob.cpp
editor/attachment/attachmentcompressjob.h
editor/attachment/attachmentcontroller.cpp
editor/attachment/attachmentcontroller.h
editor/attachment/attachmentcontrollerbase.cpp
editor/attachment/attachmentcontrollerbase.h
editor/attachment/attachmentfromfolderjob.cpp
editor/attachment/attachmentfromfolderjob.h
editor/attachment/attachmentfrommimecontentjob.cpp
editor/attachment/attachmentfrommimecontentjob.h
editor/attachment/attachmentfromurlbasejob.cpp
editor/attachment/attachmentfromurlbasejob.h
editor/attachment/attachmentfromurljob.cpp
editor/attachment/attachmentfromurljob.h
editor/attachment/attachmentfromurlutils.cpp
editor/attachment/attachmentfromurlutils.h
editor/attachment/attachmentfrompublickeyjob.cpp
editor/attachment/attachmentfrompublickeyjob.h
editor/attachment/attachmentloadjob.cpp
editor/attachment/attachmentloadjob.h
editor/attachment/attachmentmodel.cpp
editor/attachment/attachmentmodel.h
editor/attachment/attachmentpart.cpp
editor/attachment/attachmentpart.h
editor/attachment/attachmentpropertiesdialog.cpp
editor/attachment/attachmentpropertiesdialog.h
editor/attachment/attachmentupdatejob.cpp
editor/attachment/attachmentupdatejob.h
editor/attachment/attachmentview.cpp
editor/attachment/attachmentview.h
# Multiplyingline
multiplyingline/multiplyingline.cpp
multiplyingline/multiplyingline.h
multiplyingline/multiplyinglineeditor.cpp
multiplyingline/multiplyinglineeditor.h
multiplyingline/multiplyinglineview_p.cpp
multiplyingline/multiplyinglineview_p.h
# Utils
utils/kuniqueservice.h
utils/kuniqueservice.cpp
utils/systemtrayicon.h
utils/systemtrayicon.cpp
)
if (WIN32)
add_definitions(-DHAVE_QDBUS=false)
target_sources(gpgol-client-static PRIVATE utils/kuniqueservice_win.cpp)
else()
add_definitions(-DHAVE_QDBUS=true)
target_sources(gpgol-client-static PRIVATE utils/kuniqueservice_dbus.cpp)
endif()
ki18n_wrap_ui(gpgol-client-static
editor/attachment/ui/attachmentpropertiesdialog.ui
editor/attachment/ui/attachmentpropertiesdialog_readonly.ui
)
ecm_qt_declare_logging_category(gpgol-client-static_SRCS
HEADER gpgol_client_debug.h
IDENTIFIER GPGOL_CLIENT_LOG
CATEGORY_NAME org.gpgol.client
DESCRIPTION "General client log"
EXPORT GPGOL
)
ecm_qt_declare_logging_category(gpgol-client-static_SRCS
HEADER websocket_debug.h
IDENTIFIER WEBSOCKET_LOG
CATEGORY_NAME org.gpgol.client.websocket
DESCRIPTION "Websocket connection in the client"
EXPORT GPGOL
)
ecm_qt_declare_logging_category(gpgol-client-static_SRCS
HEADER ewsresource_debug.h
IDENTIFIER EWSRES_LOG
CATEGORY_NAME org.gpgol.ews
DESCRIPTION "Ews mail client"
EXPORT GPGOL
)
ecm_qt_declare_logging_category(gpgol-client-static_SRCS
HEADER ewscli_debug.h
IDENTIFIER EWSCLI_LOG
CATEGORY_NAME org.gpgol.ews.client
DESCRIPTION "ews client (gpgol-client)"
EXPORT GPGOL
)
ecm_qt_declare_logging_category(gpgol-client-static_SRCS
HEADER editor_debug.h
IDENTIFIER EDITOR_LOG
CATEGORY_NAME org.gpgol.editor
DESCRIPTION "mail composer"
EXPORT GPGOL
)
set(WARN_TOOMANY_RECIPIENTS_DEFAULT true)
set(ALLOW_SEMICOLON_AS_ADDRESS_SEPARATOR_DEFAULT true)
configure_file(editor/settings/messagecomposer.kcfg.in ${CMAKE_CURRENT_BINARY_DIR}/messagecomposer.kcfg)
kconfig_add_kcfg_files(gpgol-client-static editor/settings/messagecomposersettings.kcfgc config.kcfgc)
install(FILES composerui.rc DESTINATION ${KDE_INSTALL_KXMLGUIDIR}/gpgol-client)
target_sources(gpgol-client-static PUBLIC ${gpgol-client-static_SRCS})
ki18n_wrap_ui(gpgol-client-static firsttimedialog.ui)
ki18n_wrap_ui(gpgol-client-static confpagewelcome.ui)
ki18n_wrap_ui(gpgol-client-static confpageinstalladdin.ui)
ki18n_wrap_ui(gpgol-client-static confpageproxyoptions.ui)
ki18n_wrap_ui(gpgol-client-static confpagetlscertificate.ui)
+ki18n_wrap_ui(gpgol-client-static reencrypt/choosekeydialog.ui)
+
target_link_libraries(gpgol-client-static PUBLIC
common
rootcagenerator
LibGpgError::LibGpgError
Qt6::HttpServer
Qt6::Widgets
Qt6::PrintSupport
Qt6::WebSockets
KF6::I18n
KF6::JobWidgets
KF6::CalendarCore
KF6::ConfigCore
KF6::ConfigGui
KF6::Contacts
KF6::Completion
KF6::CoreAddons
KF6::ColorScheme
KF6::Codecs
KF6::GuiAddons
KF6::SonnetUi
KF6::SonnetCore
KF6::WidgetsAddons
KF6::XmlGui
KF6::Archive
KF6::KIOWidgets
KPim6::MimeTreeParserCore
KPim6::MimeTreeParserWidgets
KPim6::Libkleo
${_gpgol_dbusaddons_libs}
)
if(Gpgmepp_VERSION VERSION_GREATER_EQUAL "2.0.0")
target_compile_definitions(gpgol-client-static PUBLIC GPGME2)
endif()
set(GPGOLWEB_ICON_DIR "${CMAKE_CURRENT_SOURCE_DIR}/icons")
file(GLOB ICONS_PNGS "${GPGOLWEB_ICON_DIR}/*.png")
file(GLOB ICONS_SVGS "${GPGOLWEB_ICON_DIR}/*.svg")
ecm_add_app_icon(_gpgol-client_SRCS ICONS ${ICONS_PNGS} ${ICONS_SVGS})
ecm_install_icons(ICONS ${ICONS_PNGS} ${ICONS_SVGS} DESTINATION ${KDE_INSTALL_ICONDIR})
if (ICONS_SVGS)
list(GET ICONS_SVGS 0 app_icon_svg)
configure_file(icons/icons.qrc.in icons.qrc @ONLY)
set(_gpgol-client_SRCS ${_gpgol-client_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/icons.qrc)
endif()
add_executable(gpgol-client main.cpp ${_gpgol-client_SRCS})
qt_add_resources(gpgol-client "manifest"
PREFIX "/gpgol-client"
FILES manifest.xml.in
)
target_link_libraries(gpgol-client PRIVATE gpgol-client-static)
if (BUILD_TESTING)
add_subdirectory(autotests)
endif()
install(TARGETS gpgol-client ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
install(FILES com.gnupg.gpgolweb.desktop DESTINATION ${KDE_INSTALL_APPDIR})
diff --git a/client/reencrypt/choosekeydialog.cpp b/client/reencrypt/choosekeydialog.cpp
index 613ec47..32babac 100644
--- a/client/reencrypt/choosekeydialog.cpp
+++ b/client/reencrypt/choosekeydialog.cpp
@@ -1,220 +1,195 @@
// SPDX-FileCopyrightText: 2025 g10 code GmbH
// SPDX-FileContributor: Carl Schwan <carl.schwan@gnupg.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "choosekeydialog.h"
#include "certificatelineedit.h"
#include <ranges>
#include <QButtonGroup>
#include <QDialogButtonBox>
#include <QLabel>
#include <QRadioButton>
#include <QVBoxLayout>
#include <Libkleo/DefaultKeyFilter>
#include <Libkleo/KeyCache>
#include <Libkleo/KeyFilter>
#include <Libkleo/KeyGroup>
#include <Libkleo/KeyListModel>
#include <Libkleo/KeySelectionCombo>
+#include "ui_choosekeydialog.h"
#include <KAdjustingScrollArea>
#include <KLocalizedString>
#include <KMessageWidget>
#include <KTitleWidget>
using namespace Qt::StringLiterals;
namespace
{
void forceSetTabOrder(QWidget *first, QWidget *second)
{
if (!first || !second || first == second) {
return;
}
// temporarily change the focus policy of the two widgets to something
// other than Qt::NoFocus because QWidget::setTabOrder() does nothing
// if either widget has focus policy Qt::NoFocus
const auto firstFocusPolicy = first->focusPolicy();
const auto secondFocusPolicy = second->focusPolicy();
if (firstFocusPolicy == Qt::NoFocus) {
first->setFocusPolicy(Qt::StrongFocus);
}
if (secondFocusPolicy == Qt::NoFocus) {
second->setFocusPolicy(Qt::StrongFocus);
}
QWidget::setTabOrder(first, second);
if (first->focusPolicy() != firstFocusPolicy) {
first->setFocusPolicy(firstFocusPolicy);
}
if (second->focusPolicy() != secondFocusPolicy) {
second->setFocusPolicy(secondFocusPolicy);
}
}
}
ChooseKeyDialog::ChooseKeyDialog(const EwsFolder &ewsFolder, QWidget *parent)
: QDialog(parent)
+ , ui(std::make_unique<Ui::ChooseKeyDialog>())
, m_ewsFolder(ewsFolder)
, m_keyFilter(std::make_shared<Kleo::DefaultKeyFilter>())
, m_model{Kleo::AbstractKeyListModel::createFlatKeyListModel(this)}
{
setWindowTitle(i18nc("@title", "Choose a key to add to the recipients"));
- auto layout = new QVBoxLayout(this);
+ ui->setupUi(this);
- auto scrollArea = new KAdjustingScrollArea(this);
- scrollArea->setFocusPolicy(Qt::NoFocus);
- scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- scrollArea->setWidget(new QWidget);
- scrollArea->setFrameStyle(0);
-
- layout->addWidget(scrollArea);
-
- auto vLay = new QVBoxLayout(scrollArea->widget());
-
- auto title = new KTitleWidget;
- title->setText(i18nc("@title", "Folder: %1", m_ewsFolder[EwsItemFields::EwsFolderFieldDisplayName].toString()));
- vLay->addWidget(title);
+ ui->title->setText(i18nc("@title", "Folder: %1", m_ewsFolder[EwsItemFields::EwsFolderFieldDisplayName].toString()));
m_model->useKeyCache(true, Kleo::KeyList::IncludeGroups);
- m_recipientsLabel = new QLabel(i18nc("@label:listbox", "Key to add to recipients"));
- vLay->addWidget(m_recipientsLabel);
-
m_keyFilter->setIsOpenPGP(Kleo::DefaultKeyFilter::Set);
m_keyFilter->setCanEncrypt(Kleo::DefaultKeyFilter::Set);
m_keyFilter->setName(i18n("Usable for Encryption"));
m_keyFilter->setDescription(i18n("Certificates that can be used for encryption"));
- m_recpLayout = new QVBoxLayout;
+ m_recpLayout = new QVBoxLayout(ui->recpWidget);
m_recpLayout->setContentsMargins({});
- vLay->addLayout(m_recpLayout);
addRecipientWidget();
- auto label = new QLabel(i18nc("@info",
- "This will store the new reencrypted emails in a seperate folder \"%1 - reencrypted\".",
- m_ewsFolder[EwsItemFields::EwsFolderFieldDisplayName].toString()));
- label->setWordWrap(true);
- vLay->addWidget(label);
+ ui->folderLabel->setText(i18nc("@info",
+ "This will store the new reencrypted emails in a seperate folder \"%1 - reencrypted\".",
+ m_ewsFolder[EwsItemFields::EwsFolderFieldDisplayName].toString()));
m_unencrypted = new QButtonGroup(this);
- auto unencryptSkip = new QRadioButton(i18nc("How to handle unencrypted emails", "Skip"));
- m_unencrypted->addButton(unencryptSkip, static_cast<int>(UnencryptedMode::Skip));
- unencryptSkip->setChecked(true);
- auto unencryptCopy = new QRadioButton(i18nc("How to handle unencrypted emails", "Copy"));
- m_unencrypted->addButton(unencryptCopy, static_cast<int>(UnencryptedMode::Copy));
- auto unencryptLabel = new QLabel(i18nc("@info", "When processing an unencrypted email:"));
- vLay->addWidget(unencryptLabel);
- vLay->addWidget(unencryptSkip);
- vLay->addWidget(unencryptCopy);
-
- vLay->addStretch();
-
- auto dialogButtonBox = new QDialogButtonBox(this);
- dialogButtonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
- connect(dialogButtonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
- connect(dialogButtonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
- layout->addWidget(dialogButtonBox);
+ m_unencrypted->addButton(ui->unencryptSkip, static_cast<int>(UnencryptedMode::Skip));
+ ui->unencryptSkip->setChecked(true);
+ m_unencrypted->addButton(ui->unencryptCopy, static_cast<int>(UnencryptedMode::Copy));
+
+ connect(ui->buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
+ connect(ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
resize(std::max(sizeHint().width(), 500) + 20, sizeHint().height() + 50);
}
+ChooseKeyDialog::~ChooseKeyDialog() = default;
+
UnencryptedMode ChooseKeyDialog::unencryptedMode() const
{
return static_cast<UnencryptedMode>(m_unencrypted->checkedId());
}
std::vector<GpgME::Key> ChooseKeyDialog::currentKeys() const
{
std::vector<GpgME::Key> keys;
for (const auto lineEdit : m_recpWidgets) {
const GpgME::Key k = lineEdit->key();
const Kleo::KeyGroup g = lineEdit->group();
const GpgME::UserID u = lineEdit->userID();
if (!k.isNull()) {
keys.push_back(k);
} else if (!g.isNull()) {
const auto groupKeys = g.keys();
std::copy(groupKeys.begin(), groupKeys.end(), std::back_inserter(keys));
} else if (!u.isNull()) {
keys.push_back(u.parent());
}
}
auto last = std::unique(keys.begin(), keys.end(), [](const auto &key1, const auto &key2) {
return strcmp(key1.primaryFingerprint(), key2.primaryFingerprint());
});
keys.erase(last, keys.end());
return keys;
}
Kleo::CertificateLineEdit *ChooseKeyDialog::addRecipientWidget()
{
return insertRecipientWidget(nullptr);
}
Kleo::CertificateLineEdit *ChooseKeyDialog::insertRecipientWidget(Kleo::CertificateLineEdit *after)
{
Q_ASSERT(!after || m_recpLayout->indexOf(after) != -1);
const auto index = after ? m_recpLayout->indexOf(after) + 1 : m_recpLayout->count();
auto lineEdit = new Kleo::CertificateLineEdit(m_model, Kleo::KeyUsage::Encrypt, m_keyFilter, this);
lineEdit->setKeyFilter(m_keyFilter);
lineEdit->setEnabled(!Kleo::KeyCache::instance()->keys().empty());
if (!after) {
- m_recipientsLabel->setBuddy(lineEdit);
+ ui->recipientsLabel->setBuddy(lineEdit);
}
if (static_cast<unsigned>(index / 2) < m_recpWidgets.size()) {
m_recpWidgets.insert(m_recpWidgets.begin() + index / 2, lineEdit);
} else {
m_recpWidgets.push_back(lineEdit);
}
if (m_recpLayout->count() > 0) {
auto prevWidget = after ? after : m_recpLayout->itemAt(m_recpLayout->count() - 1)->widget();
forceSetTabOrder(prevWidget, lineEdit);
}
m_recpLayout->insertWidget(index, lineEdit);
connect(lineEdit, &Kleo::CertificateLineEdit::keyChanged, this, &ChooseKeyDialog::recipientsChanged);
connect(lineEdit, &Kleo::CertificateLineEdit::editingStarted, this, &ChooseKeyDialog::recipientsChanged);
connect(lineEdit, &Kleo::CertificateLineEdit::cleared, this, &ChooseKeyDialog::recipientsChanged);
return lineEdit;
}
void ChooseKeyDialog::recipientsChanged()
{
const bool hasEmptyRecpWidget = std::any_of(std::cbegin(m_recpWidgets), std::cend(m_recpWidgets), [](auto w) {
return w->isEmpty();
});
if (hasEmptyRecpWidget) {
bool foundEmpty = false;
const auto lineEdits = m_recpWidgets;
for (const auto lineEdit : lineEdits | std::views::reverse) {
if (lineEdit->isEmpty() && !foundEmpty) {
foundEmpty = true;
continue;
} else if (lineEdit->isEmpty()) {
m_recpLayout->removeWidget(lineEdit);
const auto it = std::find_if(std::begin(m_recpWidgets), std::end(m_recpWidgets), [lineEdit](const auto &r) {
return lineEdit == r;
});
m_recpWidgets.erase(it);
lineEdit->deleteLater();
}
}
} else {
addRecipientWidget();
}
}
diff --git a/client/reencrypt/choosekeydialog.h b/client/reencrypt/choosekeydialog.h
index e3b4085..76ba425 100644
--- a/client/reencrypt/choosekeydialog.h
+++ b/client/reencrypt/choosekeydialog.h
@@ -1,51 +1,58 @@
// SPDX-FileCopyrightText: 2025 g10 code GmbH
// SPDX-FileContributor: Carl Schwan <carl.schwan@gnupg.com>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include "ews/ewsfolder.h"
#include <Libkleo/DefaultKeyFilter>
#include <QDialog>
#include <gpgme++/key.h>
+#include <memory>
namespace Kleo
{
class KeySelectionCombo;
class CertificateLineEdit;
class AbstractKeyListModel;
}
+namespace Ui
+{
+class ChooseKeyDialog;
+}
+
class KMessageWidget;
class QVBoxLayout;
class QLabel;
class QButtonGroup;
enum class UnencryptedMode {
Skip,
Copy,
};
class ChooseKeyDialog : public QDialog
{
Q_OBJECT
public:
explicit ChooseKeyDialog(const EwsFolder &ewsFolder, QWidget *parent = nullptr);
std::vector<GpgME::Key> currentKeys() const;
UnencryptedMode unencryptedMode() const;
+ ~ChooseKeyDialog();
private:
void recipientsChanged();
+ std::unique_ptr<Ui::ChooseKeyDialog> ui;
- QLabel *m_recipientsLabel;
Kleo::CertificateLineEdit *addRecipientWidget();
Kleo::CertificateLineEdit *insertRecipientWidget(Kleo::CertificateLineEdit *after);
EwsFolder m_ewsFolder;
std::shared_ptr<Kleo::DefaultKeyFilter> m_keyFilter;
QVBoxLayout *m_recpLayout = nullptr;
QList<Kleo::CertificateLineEdit *> m_recpWidgets;
Kleo::AbstractKeyListModel *m_model = nullptr;
QButtonGroup *m_unencrypted;
};
diff --git a/client/reencrypt/choosekeydialog.ui b/client/reencrypt/choosekeydialog.ui
new file mode 100644
index 0000000..1f7a94d
--- /dev/null
+++ b/client/reencrypt/choosekeydialog.ui
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ChooseKeyDialog</class>
+ <widget class="QDialog" name="ChooseKeyDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>531</width>
+ <height>384</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Choose a key to add to the recipient</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="KAdjustingScrollArea" name="scrollArea">
+ <property name="focusPolicy">
+ <enum>Qt::FocusPolicy::NoFocus</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Shadow::Plain</enum>
+ </property>
+ <property name="horizontalScrollBarPolicy">
+ <enum>Qt::ScrollBarPolicy::ScrollBarAlwaysOff</enum>
+ </property>
+ <property name="widgetResizable">
+ <bool>true</bool>
+ </property>
+ <widget class="QWidget" name="scrollAreaContents">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>515</width>
+ <height>328</height>
+ </rect>
+ </property>
+ <layout class="QVBoxLayout" name="scrollAreaContentsLayout">
+ <item>
+ <widget class="KTitleWidget" name="title">
+ <property name="text">
+ <string notr="true">Folder: PLACEHOLDER %1</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="recipientsLabel">
+ <property name="text">
+ <string>Key to add to recipients</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QWidget" name="recpWidget" native="true"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="folderLabel">
+ <property name="text">
+ <string notr="true">PLACEHOLDER: This will store the new reencrypted emails in a seperate folder "%1 - reencrypted".</string>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>When processing an unencrypted email:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="unencryptSkip">
+ <property name="text">
+ <string extracomment="How to handle unencrypted emails">Skip</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QRadioButton" name="unencryptCopy">
+ <property name="text">
+ <string extracomment="How to handle unencrypted emails">Copy</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Orientation::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Orientation::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::StandardButton::Cancel|QDialogButtonBox::StandardButton::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>KTitleWidget</class>
+ <extends>QWidget</extends>
+ <header>ktitlewidget.h</header>
+ </customwidget>
+ <customwidget>
+ <class>KAdjustingScrollArea</class>
+ <extends>QScrollArea</extends>
+ <header location="global">kadjustingscrollarea.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ChooseKeyDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>ChooseKeyDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Dec 8, 6:23 AM (4 h, 52 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
bc/5d/ae89960f443aa70252d70bf9b0f5
Attached To
rOJ GpgOL.js
Event Timeline
Log In to Comment