diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c26df0cd1..892161835 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,380 +1,381 @@ add_subdirectory(icons) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) if (NOT DISABLE_KWATCHGNUPG) add_subdirectory(kwatchgnupg) endif() add_subdirectory(libkleopatraclient) add_subdirectory(conf) add_subdirectory(kconf_update) if(WIN32) set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_win.cpp) set(_kleopatra_extra_SRCS utils/gnupg-registry.c selftest/registrycheck.cpp utils/windowsprocessdevice.cpp utils/userinfo_win.cpp ) else() set(_kleopatra_extra_uiserver_SRCS uiserver/uiserver_unix.cpp) set(_kleopatra_extra_SRCS) endif() set(_kleopatra_uiserver_SRCS uiserver/sessiondata.cpp uiserver/uiserver.cpp ${_kleopatra_extra_uiserver_SRCS} uiserver/assuanserverconnection.cpp uiserver/echocommand.cpp uiserver/decryptverifycommandemailbase.cpp uiserver/decryptverifycommandfilesbase.cpp uiserver/signcommand.cpp uiserver/signencryptfilescommand.cpp uiserver/prepencryptcommand.cpp uiserver/prepsigncommand.cpp uiserver/encryptcommand.cpp uiserver/selectcertificatecommand.cpp uiserver/importfilescommand.cpp uiserver/createchecksumscommand.cpp uiserver/verifychecksumscommand.cpp selftest/uiservercheck.cpp ) if(ASSUAN2_FOUND) include_directories(${ASSUAN2_INCLUDES}) set(_kleopatra_uiserver_extra_libs ${ASSUAN2_LIBRARIES}) else() include_directories(${ASSUAN_INCLUDES}) if(WIN32) set(_kleopatra_uiserver_extra_libs ${ASSUAN_VANILLA_LIBRARIES}) else() set(_kleopatra_uiserver_extra_libs ${ASSUAN_PTHREAD_LIBRARIES}) endif() endif() if(HAVE_GPG_ERR_SOURCE_KLEO) add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_KLEO) add_definitions(-DGPGMEPP_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_KLEO) else() add_definitions(-DGPG_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_1) add_definitions(-DGPGMEPP_ERR_SOURCE_DEFAULT=GPG_ERR_SOURCE_USER_1) endif() ki18n_wrap_ui(_kleopatra_uiserver_SRCS crypto/gui/signingcertificateselectionwidget.ui) if("${Gpgmepp_VERSION}" VERSION_GREATER_EQUAL "1.14.1") set(_kleopatra_deviceinfowatcher_files smartcard/deviceinfowatcher.cpp ) else() set(_kleopatra_deviceinfowatcher_files) endif() set(_kleopatra_SRCS utils/gui-helper.cpp utils/filedialog.cpp utils/kdpipeiodevice.cpp utils/headerview.cpp utils/scrollarea.cpp utils/dragqueen.cpp utils/multivalidator.cpp utils/systemtrayicon.cpp utils/hex.cpp utils/path-helper.cpp utils/input.cpp utils/output.cpp utils/validation.cpp utils/wsastarter.cpp utils/iodevicelogger.cpp utils/log.cpp utils/action_data.cpp utils/types.cpp utils/archivedefinition.cpp utils/auditlog.cpp utils/clipboardmenu.cpp utils/kuniqueservice.cpp utils/remarks.cpp utils/writecertassuantransaction.cpp utils/keyparameters.cpp utils/userinfo.cpp selftest/selftest.cpp selftest/enginecheck.cpp selftest/gpgconfcheck.cpp selftest/gpgagentcheck.cpp selftest/libkleopatrarccheck.cpp ${_kleopatra_extra_SRCS} view/keylistcontroller.cpp view/keytreeview.cpp view/searchbar.cpp view/smartcardwidget.cpp view/padwidget.cpp view/pgpcardwidget.cpp view/pivcardwidget.cpp view/netkeywidget.cpp view/nullpinwidget.cpp view/tabwidget.cpp view/keycacheoverlay.cpp view/waitwidget.cpp view/welcomewidget.cpp dialogs/certificateselectiondialog.cpp dialogs/certifywidget.cpp dialogs/expirydialog.cpp dialogs/lookupcertificatesdialog.cpp dialogs/ownertrustdialog.cpp dialogs/selftestdialog.cpp dialogs/certifycertificatedialog.cpp dialogs/revokecertificationwidget.cpp dialogs/revokecertificationdialog.cpp dialogs/adduseriddialog.cpp dialogs/addemaildialog.cpp dialogs/exportcertificatesdialog.cpp dialogs/deletecertificatesdialog.cpp dialogs/setinitialpindialog.cpp dialogs/certificatedetailswidget.cpp dialogs/trustchainwidget.cpp dialogs/weboftrustwidget.cpp dialogs/weboftrustdialog.cpp dialogs/exportdialog.cpp dialogs/subkeyswidget.cpp dialogs/gencardkeydialog.cpp dialogs/updatenotification.cpp dialogs/pivcardapplicationadministrationkeyinputdialog.cpp dialogs/certificatedetailsinputwidget.cpp dialogs/createcsrforcardkeydialog.cpp crypto/controller.cpp crypto/certificateresolver.cpp crypto/sender.cpp crypto/recipient.cpp crypto/task.cpp crypto/taskcollection.cpp crypto/decryptverifytask.cpp crypto/decryptverifyemailcontroller.cpp crypto/decryptverifyfilescontroller.cpp crypto/autodecryptverifyfilescontroller.cpp crypto/encryptemailtask.cpp crypto/encryptemailcontroller.cpp crypto/newsignencryptemailcontroller.cpp crypto/signencrypttask.cpp crypto/signencryptfilescontroller.cpp crypto/signemailtask.cpp crypto/signemailcontroller.cpp crypto/createchecksumscontroller.cpp crypto/verifychecksumscontroller.cpp crypto/gui/wizard.cpp crypto/gui/wizardpage.cpp crypto/gui/certificateselectionline.cpp crypto/gui/certificatelineedit.cpp crypto/gui/signingcertificateselectionwidget.cpp crypto/gui/signingcertificateselectiondialog.cpp crypto/gui/resultitemwidget.cpp crypto/gui/resultlistwidget.cpp crypto/gui/resultpage.cpp crypto/gui/newresultpage.cpp crypto/gui/signencryptfileswizard.cpp crypto/gui/signencryptemailconflictdialog.cpp crypto/gui/decryptverifyoperationwidget.cpp crypto/gui/decryptverifyfileswizard.cpp crypto/gui/decryptverifyfilesdialog.cpp crypto/gui/objectspage.cpp crypto/gui/resolverecipientspage.cpp crypto/gui/signerresolvepage.cpp crypto/gui/encryptemailwizard.cpp crypto/gui/signemailwizard.cpp crypto/gui/signencryptwidget.cpp crypto/gui/signencryptwizard.cpp crypto/gui/unknownrecipientwidget.cpp crypto/gui/verifychecksumsdialog.cpp commands/command.cpp commands/gnupgprocesscommand.cpp commands/detailscommand.cpp commands/exportcertificatecommand.cpp commands/importcertificatescommand.cpp commands/importcertificatefromfilecommand.cpp commands/importcertificatefromclipboardcommand.cpp commands/importcertificatefromdatacommand.cpp commands/lookupcertificatescommand.cpp commands/reloadkeyscommand.cpp commands/refreshx509certscommand.cpp commands/refreshopenpgpcertscommand.cpp commands/deletecertificatescommand.cpp commands/decryptverifyfilescommand.cpp commands/signencryptfilescommand.cpp commands/signencryptfoldercommand.cpp commands/encryptclipboardcommand.cpp commands/signclipboardcommand.cpp commands/decryptverifyclipboardcommand.cpp commands/clearcrlcachecommand.cpp commands/dumpcrlcachecommand.cpp commands/dumpcertificatecommand.cpp commands/importcrlcommand.cpp commands/changeexpirycommand.cpp commands/changeownertrustcommand.cpp commands/changeroottrustcommand.cpp commands/changepassphrasecommand.cpp commands/certifycertificatecommand.cpp commands/revokecertificationcommand.cpp commands/selftestcommand.cpp commands/exportsecretkeycommand.cpp commands/exportopenpgpcertstoservercommand.cpp commands/adduseridcommand.cpp commands/newcertificatecommand.cpp commands/setinitialpincommand.cpp commands/learncardkeyscommand.cpp commands/checksumcreatefilescommand.cpp commands/checksumverifyfilescommand.cpp commands/exportpaperkeycommand.cpp commands/importpaperkeycommand.cpp commands/genrevokecommand.cpp commands/keytocardcommand.cpp commands/cardcommand.cpp commands/pivgeneratecardkeycommand.cpp commands/changepincommand.cpp commands/authenticatepivcardapplicationcommand.cpp commands/setpivcardapplicationadministrationkeycommand.cpp commands/certificatetopivcardcommand.cpp commands/importcertificatefrompivcardcommand.cpp commands/createopenpgpkeyfromcardkeyscommand.cpp commands/createcsrforcardkeycommand.cpp ${_kleopatra_uiserver_files} conf/configuredialog.cpp newcertificatewizard/listwidget.cpp newcertificatewizard/newcertificatewizard.cpp smartcard/readerstatus.cpp smartcard/card.cpp smartcard/openpgpcard.cpp smartcard/netkeycard.cpp smartcard/pivcard.cpp smartcard/keypairinfo.cpp smartcard/utils.cpp ${_kleopatra_deviceinfowatcher_files} aboutdata.cpp systrayicon.cpp kleopatraapplication.cpp mainwindow.cpp main.cpp ) if(WIN32) configure_file (versioninfo.rc.in versioninfo.rc) set(_kleopatra_SRCS ${CMAKE_CURRENT_BINARY_DIR}/versioninfo.rc ${_kleopatra_SRCS}) endif() if(HAVE_KCMUTILS) set (_kleopatra_extra_libs KF5::KCMUtils) else() set (_kleopatra_SRCS conf/kleopageconfigdialog.cpp ${_kleopatra_SRCS}) endif() ecm_qt_declare_logging_category(_kleopatra_SRCS HEADER kleopatra_debug.h IDENTIFIER KLEOPATRA_LOG CATEGORY_NAME org.kde.pim.kleopatra DESCRIPTION "kleopatra (kleopatra)" OLD_CATEGORY_NAMES log_kleopatra EXPORT KLEOPATRA ) if(KLEO_MODEL_TEST) add_definitions(-DKLEO_MODEL_TEST) set(_kleopatra_SRCS ${_kleopatra_SRCS} models/modeltest.cpp) endif() ki18n_wrap_ui(_kleopatra_SRCS dialogs/expirydialog.ui dialogs/lookupcertificatesdialog.ui dialogs/ownertrustdialog.ui dialogs/selectchecklevelwidget.ui dialogs/selftestdialog.ui dialogs/adduseriddialog.ui dialogs/setinitialpindialog.ui dialogs/certificatedetailswidget.ui dialogs/trustchainwidget.ui dialogs/subkeyswidget.ui newcertificatewizard/listwidget.ui newcertificatewizard/chooseprotocolpage.ui newcertificatewizard/enterdetailspage.ui newcertificatewizard/keycreationpage.ui newcertificatewizard/resultpage.ui newcertificatewizard/advancedsettingsdialog.ui ) kconfig_add_kcfg_files(_kleopatra_SRCS kcfg/tooltippreferences.kcfgc kcfg/emailoperationspreferences.kcfgc kcfg/fileoperationspreferences.kcfgc kcfg/smimevalidationpreferences.kcfgc + kcfg/tagspreferences.kcfgc ) file(GLOB ICONS_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/icons/*-apps-kleopatra.png") ecm_add_app_icon(_kleopatra_SRCS ICONS ${ICONS_SRCS}) qt5_add_resources(_kleopatra_SRCS kleopatra.qrc) add_executable(kleopatra_bin ${_kleopatra_SRCS} ${_kleopatra_uiserver_SRCS}) #if (COMPILE_WITH_UNITY_CMAKE_SUPPORT) # set_target_properties(kleopatra_bin PROPERTIES UNITY_BUILD ON) #endif() set_target_properties(kleopatra_bin PROPERTIES OUTPUT_NAME kleopatra) if (WIN32) set(_kleopatra_platform_libs "secur32") endif () target_link_libraries(kleopatra_bin Gpgmepp QGpgme ${_kleopatra_extra_libs} KF5::Libkleo KF5::Mime KF5::I18n KF5::XmlGui KF5::IconThemes KF5::WindowSystem KF5::CoreAddons KF5::ItemModels KF5::Crash Qt5::Network Qt5::PrintSupport # Printing secret keys ${_kleopatra_uiserver_extra_libs} ${_kleopatra_dbusaddons_libs} kleopatraclientcore ${_kleopatra_platform_libs} ) install(TARGETS kleopatra_bin ${KDE_INSTALL_TARGETS_DEFAULT_ARGS}) install( PROGRAMS data/org.kde.kleopatra.desktop data/kleopatra_import.desktop DESTINATION ${KDE_INSTALL_APPDIR} ) install(FILES data/org.kde.kleopatra.appdata.xml DESTINATION ${KDE_INSTALL_METAINFODIR}) install( FILES data/kleopatra_signencryptfiles.desktop data/kleopatra_signencryptfolders.desktop data/kleopatra_decryptverifyfiles.desktop data/kleopatra_decryptverifyfolders.desktop DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) diff --git a/src/conf/CMakeLists.txt b/src/conf/CMakeLists.txt index de9e07917..ee22f6c12 100644 --- a/src/conf/CMakeLists.txt +++ b/src/conf/CMakeLists.txt @@ -1,86 +1,87 @@ include_directories(${kleopatra_SOURCE_DIR}/src) if(BUILD_libkleopatraclient) set(_kcm_kleopatra_libkleopatraclient_extra_SRCS smimevalidationconfigurationwidget.cpp smimevalidationconfigurationpage.cpp cryptooperationsconfigwidget.cpp cryptooperationsconfigpage.cpp ) ki18n_wrap_ui(_kcm_kleopatra_libkleopatraclient_extra_SRCS smimevalidationconfigurationwidget.ui ) kconfig_add_kcfg_files(_kcm_kleopatra_libkleopatraclient_extra_SRCS ${kleopatra_SOURCE_DIR}/src/kcfg/smimevalidationpreferences.kcfgc ) set(_kcm_kleopatra_libkleopatraclient_extra_LIBS kleopatraclientgui) set(_kcm_kleopatra_libkleopatraclient_extra_install_FILES kleopatra_config_smimevalidation.desktop kleopatra_config_cryptooperations.desktop ) else() set(_kcm_kleopatra_libkleopatraclient_extra_SRCS) set(_kcm_kleopatra_libkleopatraclient_extra_LIBS) set(_kcm_kleopatra_libkleopatraclient_extra_install_FILES) endif() set(kcm_kleopatra_PART_SRCS dirservconfigpage.cpp appearanceconfigpage.cpp appearanceconfigwidget.cpp gnupgsystemconfigurationpage.cpp ${kleopatra_BINARY_DIR}/src/kleopatra_debug.cpp ${_kcm_kleopatra_libkleopatraclient_extra_SRCS} ) ki18n_wrap_ui(kcm_kleopatra_PART_SRCS appearanceconfigwidget.ui smimevalidationconfigurationwidget.ui ) kconfig_add_kcfg_files(kcm_kleopatra_PART_SRCS ${kleopatra_SOURCE_DIR}/src/kcfg/tooltippreferences.kcfgc ${kleopatra_SOURCE_DIR}/src/kcfg/emailoperationspreferences.kcfgc ${kleopatra_SOURCE_DIR}/src/kcfg/fileoperationspreferences.kcfgc + ${kleopatra_SOURCE_DIR}/src/kcfg/tagspreferences.kcfgc ) add_library(kcm_kleopatra MODULE ${kcm_kleopatra_PART_SRCS}) if(HAVE_KCMUTILS) set (_kcm_kleopatra_extra_libs KF5::KCMUtils) endif() target_link_libraries(kcm_kleopatra KF5::Libkleo KF5::IconThemes KF5::I18n KF5::WidgetsAddons KF5::ConfigWidgets ${_kcm_kleopatra_extra_libs} ${_kleopatra_dbusaddons_libs} ${_kcm_kleopatra_libkleopatraclient_extra_LIBS} ) if (COMPILE_WITH_UNITY_CMAKE_SUPPORT) set_target_properties(kcm_kleopatra PROPERTIES UNITY_BUILD ON) endif() install(TARGETS kcm_kleopatra DESTINATION ${KDE_INSTALL_PLUGINDIR}) ########### install files ############### install(FILES kleopatra_config_dirserv.desktop kleopatra_config_appear.desktop kleopatra_config_gnupgsystem.desktop ${_kcm_kleopatra_libkleopatraclient_extra_install_FILES} DESTINATION ${KDE_INSTALL_KSERVICES5DIR} ) diff --git a/src/conf/appearanceconfigwidget.cpp b/src/conf/appearanceconfigwidget.cpp index d0141dfaa..d1b1664ba 100644 --- a/src/conf/appearanceconfigwidget.cpp +++ b/src/conf/appearanceconfigwidget.cpp @@ -1,617 +1,631 @@ /* appearanceconfigwidget.cpp This file is part of kleopatra, the KDE key manager SPDX-FileCopyrightText: 2002, 2004, 2008 Klarälvdalens Datakonsult AB SPDX-FileCopyrightText: 2002, 2003 Marc Mutz SPDX-License-Identifier: GPL-2.0-or-later */ #include #include "appearanceconfigwidget.h" #include "ui_appearanceconfigwidget.h" +#include "tagspreferences.h" #include "tooltippreferences.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace Kleo; using namespace Kleo::Config; enum { HasNameRole = Qt::UserRole + 0x1234, /*!< Records that the user has assigned a name (to avoid comparing with i18n-strings) */ HasFontRole, /*!< Records that the user has chosen completely different font (as opposed to italic/bold/strikeout) */ IconNameRole, /*!< Records the name of the icon (since QIcon won't give it out again, once set) */ MayChangeNameRole, MayChangeForegroundRole, MayChangeBackgroundRole, MayChangeFontRole, MayChangeItalicRole, MayChangeBoldRole, MayChangeStrikeOutRole, MayChangeIconRole, EndDummy }; static QFont tryToFindFontFor(const QListWidgetItem *item) { if (item) if (const QListWidget *const lw = item->listWidget()) { return lw->font(); } return QApplication::font("QListWidget"); } static bool is(const QListWidgetItem *item, bool (QFont::*func)() const) { if (!item) { return false; } const QVariant v = item->data(Qt::FontRole); if (!v.isValid() || v.type() != QVariant::Font) { return false; } return (v.value().*func)(); } static bool is_italic(const QListWidgetItem *item) { return is(item, &QFont::italic); } static bool is_bold(const QListWidgetItem *item) { return is(item, &QFont::bold); } static bool is_strikeout(const QListWidgetItem *item) { return is(item, &QFont::strikeOut); } static void set(QListWidgetItem *item, bool on, void (QFont::*func)(bool)) { if (!item) { return; } const QVariant v = item->data(Qt::FontRole); QFont font = v.isValid() && v.type() == QVariant::Font ? v.value() : tryToFindFontFor(item); (font.*func)(on); item->setData(Qt::FontRole, font); } static void set_italic(QListWidgetItem *item, bool on) { set(item, on, &QFont::setItalic); } static void set_bold(QListWidgetItem *item, bool on) { set(item, on, &QFont::setBold); } static void set_strikeout(QListWidgetItem *item, bool on) { set(item, on, &QFont::setStrikeOut); } static void apply_config(const KConfigGroup &group, QListWidgetItem *item) { if (!item) { return; } const QString name = group.readEntry("Name"); item->setText(name.isEmpty() ? i18nc("Key filter without user-assigned name", "") : name); item->setData(HasNameRole, !name.isEmpty()); item->setData(MayChangeNameRole, !group.isEntryImmutable("Name")); const QColor fg = group.readEntry("foreground-color", QColor()); item->setData(Qt::ForegroundRole, fg.isValid() ? QBrush(fg) : QVariant()); item->setData(MayChangeForegroundRole, !group.isEntryImmutable("foreground-color")); const QColor bg = group.readEntry("background-color", QColor()); item->setData(Qt::BackgroundRole, bg.isValid() ? QBrush(bg) : QVariant()); item->setData(MayChangeBackgroundRole, !group.isEntryImmutable("background-color")); const QFont defaultFont = tryToFindFontFor(item); if (group.hasKey("font")) { const QFont font = group.readEntry("font", defaultFont); item->setData(Qt::FontRole, font != defaultFont ? font : QVariant()); item->setData(HasFontRole, font != defaultFont); } else { QFont font = defaultFont; font.setStrikeOut(group.readEntry("font-strikeout", false)); font.setItalic(group.readEntry("font-italic", false)); font.setBold(group.readEntry("font-bold", false)); item->setData(Qt::FontRole, font); item->setData(HasFontRole, false); } item->setData(MayChangeFontRole, !group.isEntryImmutable("font")); item->setData(MayChangeItalicRole, !group.isEntryImmutable("font-italic")); item->setData(MayChangeBoldRole, !group.isEntryImmutable("font-bold")); item->setData(MayChangeStrikeOutRole, !group.isEntryImmutable("font-strikeout")); const QString iconName = group.readEntry("icon"); item->setData(Qt::DecorationRole, iconName.isEmpty() ? QVariant() : QIcon::fromTheme(iconName)); item->setData(IconNameRole, iconName.isEmpty() ? QVariant() : iconName); item->setData(MayChangeIconRole, !group.isEntryImmutable("icon")); } static void erase_if_allowed(QListWidgetItem *item, int role, int allowRole) { if (item && item->data(allowRole).toBool()) { item->setData(role, QVariant()); } } #if 0 static void erase_if_allowed(QListWidgetItem *item, const int role[], size_t numRoles, int allowRole) { if (item && item->data(allowRole).toBool()) for (unsigned int i = 0; i < numRoles; ++i) { item->setData(role[i], QVariant()); } } static void erase_if_allowed(QListWidgetItem *item, int role, const int allowRole[], size_t numAllowRoles) { if (!item) { return; } for (unsigned int i = 0; i < numAllowRoles; ++i) if (!item->data(allowRole[i]).toBool()) { return; } item->setData(role, QVariant()); } #endif static void erase_if_allowed(QListWidgetItem *item, const int role[], size_t numRoles, const int allowRole[], size_t numAllowRoles) { if (!item) { return; } for (unsigned int i = 0; i < numAllowRoles; ++i) if (!item->data(allowRole[i]).toBool()) { return; } for (unsigned int i = 0; i < numRoles; ++i) { item->setData(role[i], QVariant()); } } static void set_default_appearance(QListWidgetItem *item) { if (!item) { return; } erase_if_allowed(item, Qt::ForegroundRole, MayChangeForegroundRole); erase_if_allowed(item, Qt::BackgroundRole, MayChangeBackgroundRole); erase_if_allowed(item, Qt::DecorationRole, MayChangeIconRole); static const int fontRoles[] = { Qt::FontRole, HasFontRole }; static const int fontAllowRoles[] = { MayChangeFontRole, MayChangeItalicRole, MayChangeBoldRole, MayChangeStrikeOutRole, }; erase_if_allowed(item, fontRoles, sizeof(fontRoles) / sizeof(int), fontAllowRoles, sizeof(fontAllowRoles) / sizeof(int)); } static void writeOrDelete(KConfigGroup &group, const char *key, const QVariant &value) { if (value.isValid()) { group.writeEntry(key, value); } else { group.deleteEntry(key); } } static QVariant brush2color(const QVariant &v) { if (v.isValid()) { if (v.type() == QVariant::Color) { return v; } else if (v.type() == QVariant::Brush) { return v.value().color(); } } return QVariant(); } static void save_to_config(const QListWidgetItem *item, KConfigGroup &group) { if (!item) { return; } writeOrDelete(group, "Name", item->data(HasNameRole).toBool() ? item->text() : QVariant()); writeOrDelete(group, "foreground-color", brush2color(item->data(Qt::ForegroundRole))); writeOrDelete(group, "background-color", brush2color(item->data(Qt::BackgroundRole))); writeOrDelete(group, "icon", item->data(IconNameRole)); group.deleteEntry("font"); group.deleteEntry("font-strikeout"); group.deleteEntry("font-italic"); group.deleteEntry("font-bold"); if (item->data(HasFontRole).toBool()) { writeOrDelete(group, "font", item->data(Qt::FontRole)); return; } if (is_strikeout(item)) { group.writeEntry("font-strikeout", true); } if (is_italic(item)) { group.writeEntry("font-italic", true); } if (is_bold(item)) { group.writeEntry("font-bold", true); } } static void kiosk_enable(QWidget *w, const QListWidgetItem *item, int allowRole) { if (!w) { return; } if (item && !item->data(allowRole).toBool()) { w->setEnabled(false); w->setToolTip(i18n("This parameter has been locked down by the system administrator.")); } else { w->setEnabled(item); w->setToolTip(QString()); } } class AppearanceConfigWidget::Private : public Ui_AppearanceConfigWidget { friend class ::Kleo::Config::AppearanceConfigWidget; AppearanceConfigWidget *const q; public: explicit Private(AppearanceConfigWidget *qq) : Ui_AppearanceConfigWidget(), q(qq), dnOrderWidget(nullptr) { setupUi(q); if (QLayout *const l = q->layout()) { l->setContentsMargins(0, 0, 0, 0); } QWidget *w = new QWidget; dnOrderWidget = Kleo::DNAttributeMapper::instance()->configWidget(w); dnOrderWidget->setObjectName(QStringLiteral("dnOrderWidget")); (new QVBoxLayout(w))->addWidget(dnOrderWidget); tabWidget->addTab(w, i18n("DN-Attribute Order")); connect(dnOrderWidget, &DNAttributeOrderConfigWidget::changed, q, &AppearanceConfigWidget::changed); connect(iconButton, SIGNAL(clicked()), q, SLOT(slotIconClicked())); #ifndef QT_NO_COLORDIALOG connect(foregroundButton, SIGNAL(clicked()), q, SLOT(slotForegroundClicked())); connect(backgroundButton, SIGNAL(clicked()), q, SLOT(slotBackgroundClicked())); #else foregroundButton->hide(); backgroundButton->hide(); #endif #ifndef QT_NO_FONTDIALOG connect(fontButton, SIGNAL(clicked()), q, SLOT(slotFontClicked())); #else fontButton->hide(); #endif connect(categoriesLV, SIGNAL(itemSelectionChanged()), q, SLOT(slotSelectionChanged())); connect(defaultLookPB, SIGNAL(clicked()), q, SLOT(slotDefaultClicked())); connect(italicCB, SIGNAL(toggled(bool)), q, SLOT(slotItalicToggled(bool))); connect(boldCB, SIGNAL(toggled(bool)), q, SLOT(slotBoldToggled(bool))); connect(strikeoutCB, SIGNAL(toggled(bool)), q, SLOT(slotStrikeOutToggled(bool))); connect(tooltipValidityCheckBox, SIGNAL(toggled(bool)), q, SLOT(slotTooltipValidityChanged(bool))); connect(tooltipOwnerCheckBox, SIGNAL(toggled(bool)), q, SLOT(slotTooltipOwnerChanged(bool))); connect(tooltipDetailsCheckBox, SIGNAL(toggled(bool)), q, SLOT(slotTooltipDetailsChanged(bool))); + connect(useTagsCheckBox, SIGNAL(toggled(bool)), q, SLOT(slotUseTagsChanged(bool))); } private: void enableDisableActions(QListWidgetItem *item); QListWidgetItem *selectedItem() const; private: void slotIconClicked(); #ifndef QT_NO_COLORDIALOG void slotForegroundClicked(); void slotBackgroundClicked(); #endif #ifndef QT_NO_FONTDIALOG void slotFontClicked(); #endif void slotSelectionChanged(); void slotDefaultClicked(); void slotItalicToggled(bool); void slotBoldToggled(bool); void slotStrikeOutToggled(bool); void slotTooltipValidityChanged(bool); void slotTooltipOwnerChanged(bool); void slotTooltipDetailsChanged(bool); + void slotUseTagsChanged(bool); private: Kleo::DNAttributeOrderConfigWidget *dnOrderWidget; }; AppearanceConfigWidget::AppearanceConfigWidget(QWidget *p, Qt::WindowFlags f) : QWidget(p, f), d(new Private(this)) { // load(); } AppearanceConfigWidget::~AppearanceConfigWidget() {} void AppearanceConfigWidget::Private::slotSelectionChanged() { enableDisableActions(selectedItem()); } QListWidgetItem *AppearanceConfigWidget::Private::selectedItem() const { const QList items = categoriesLV->selectedItems(); return items.empty() ? nullptr : items.front(); } void AppearanceConfigWidget::Private::enableDisableActions(QListWidgetItem *item) { kiosk_enable(iconButton, item, MayChangeIconRole); #ifndef QT_NO_COLORDIALOG kiosk_enable(foregroundButton, item, MayChangeForegroundRole); kiosk_enable(backgroundButton, item, MayChangeBackgroundRole); #endif #ifndef QT_NO_FONTDIALOG kiosk_enable(fontButton, item, MayChangeFontRole); #endif kiosk_enable(italicCB, item, MayChangeItalicRole); kiosk_enable(boldCB, item, MayChangeBoldRole); kiosk_enable(strikeoutCB, item, MayChangeStrikeOutRole); defaultLookPB->setEnabled(item); italicCB->setChecked(is_italic(item)); boldCB->setChecked(is_bold(item)); strikeoutCB->setChecked(is_strikeout(item)); } void AppearanceConfigWidget::Private::slotDefaultClicked() { QListWidgetItem *const item = selectedItem(); if (!item) { return; } set_default_appearance(item); enableDisableActions(item); Q_EMIT q->changed(); } void AppearanceConfigWidget::defaults() { // This simply means "default look for every category" for (int i = 0, end = d->categoriesLV->count(); i != end; ++i) { set_default_appearance(d->categoriesLV->item(i)); } d->tooltipValidityCheckBox->setChecked(true); d->tooltipOwnerCheckBox->setChecked(false); d->tooltipDetailsCheckBox->setChecked(false); d->dnOrderWidget->defaults(); Q_EMIT changed(); } void AppearanceConfigWidget::load() { d->dnOrderWidget->load(); d->categoriesLV->clear(); KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("libkleopatrarc")); if (!config) { return; } const QStringList groups = config->groupList().filter(QRegularExpression(QStringLiteral("^Key Filter #\\d+$"))); for (const QString &group : groups) { //QListWidgetItem * item = new QListWidgetItem( d->categoriesLV ); apply_config(KConfigGroup(config, group), new QListWidgetItem(d->categoriesLV)); } const TooltipPreferences prefs; d->tooltipValidityCheckBox->setChecked(prefs.showValidity()); d->tooltipOwnerCheckBox->setChecked(prefs.showOwnerInformation()); d->tooltipDetailsCheckBox->setChecked(prefs.showCertificateDetails()); + + const TagsPreferences tagsPrefs; + d->useTagsCheckBox->setChecked(tagsPrefs.useTags()); } void AppearanceConfigWidget::save() { d->dnOrderWidget->save(); TooltipPreferences prefs; prefs.setShowValidity(d->tooltipValidityCheckBox->isChecked()); prefs.setShowOwnerInformation(d->tooltipOwnerCheckBox->isChecked()); prefs.setShowCertificateDetails(d->tooltipDetailsCheckBox->isChecked()); prefs.save(); KSharedConfigPtr config = KSharedConfig::openConfig(QStringLiteral("libkleopatrarc")); if (!config) { return; } // We know (assume) that the groups in the config object haven't changed, // so we just iterate over them and over the listviewitems, and map one-to-one. const QStringList groups = config->groupList().filter(QRegularExpression(QStringLiteral("^Key Filter #\\d+$"))); #if 0 if (groups.isEmpty()) { // If we created the default categories ourselves just now, then we need to make up their list Q3ListViewItemIterator lvit(categoriesLV); for (; lvit.current(); ++lvit) { groups << lvit.current()->text(0); } } #endif for (int i = 0, end = std::min(groups.size(), d->categoriesLV->count()); i != end; ++i) { const QListWidgetItem *const item = d->categoriesLV->item(i); Q_ASSERT(item); KConfigGroup group(config, groups[i]); save_to_config(item, group); } + TagsPreferences tagsPrefs; + tagsPrefs.setUseTags(d->useTagsCheckBox->isChecked()); + config->sync(); KeyFilterManager::instance()->reload(); } void AppearanceConfigWidget::Private::slotIconClicked() { QListWidgetItem *const item = selectedItem(); if (!item) { return; } const QString iconName = KIconDialog::getIcon( /* repeating default arguments begin */ KIconLoader::Desktop, KIconLoader::Application, false, 0, false, /* repeating default arguments end */ q); if (iconName.isEmpty()) { return; } item->setIcon(QIcon::fromTheme(iconName)); item->setData(IconNameRole, iconName); Q_EMIT q->changed(); } #ifndef QT_NO_COLORDIALOG void AppearanceConfigWidget::Private::slotForegroundClicked() { QListWidgetItem *const item = selectedItem(); if (!item) { return; } const QVariant v = brush2color(item->data(Qt::ForegroundRole)); const QColor initial = v.isValid() ? v.value() : categoriesLV->palette().color(QPalette::Normal, QPalette::Text); const QColor c = QColorDialog::getColor(initial, q); if (c.isValid()) { item->setData(Qt::ForegroundRole, QBrush(c)); Q_EMIT q->changed(); } } void AppearanceConfigWidget::Private::slotBackgroundClicked() { QListWidgetItem *const item = selectedItem(); if (!item) { return; } const QVariant v = brush2color(item->data(Qt::BackgroundRole)); const QColor initial = v.isValid() ? v.value() : categoriesLV->palette().color(QPalette::Normal, QPalette::Base); const QColor c = QColorDialog::getColor(initial, q); if (c.isValid()) { item->setData(Qt::BackgroundRole, QBrush(c)); Q_EMIT q->changed(); } } #endif // QT_NO_COLORDIALOG #ifndef QT_NO_FONTDIALOG void AppearanceConfigWidget::Private::slotFontClicked() { QListWidgetItem *const item = selectedItem(); if (!item) { return; } const QVariant v = item->data(Qt::FontRole); bool ok = false; const QFont defaultFont = tryToFindFontFor(item); const QFont initial = v.isValid() && v.type() == QVariant::Font ? v.value() : defaultFont; QFont f = QFontDialog::getFont(&ok, initial, q); if (!ok) { return; } // disallow circumventing KIOSK: if (!item->data(MayChangeItalicRole).toBool()) { f.setItalic(initial.italic()); } if (!item->data(MayChangeBoldRole).toBool()) { f.setBold(initial.bold()); } if (!item->data(MayChangeStrikeOutRole).toBool()) { f.setStrikeOut(initial.strikeOut()); } item->setData(Qt::FontRole, f != defaultFont ? f : QVariant()); item->setData(HasFontRole, true); Q_EMIT q->changed(); } #endif // QT_NO_FONTDIALOG void AppearanceConfigWidget::Private::slotItalicToggled(bool on) { set_italic(selectedItem(), on); Q_EMIT q->changed(); } void AppearanceConfigWidget::Private::slotBoldToggled(bool on) { set_bold(selectedItem(), on); Q_EMIT q->changed(); } void AppearanceConfigWidget::Private::slotStrikeOutToggled(bool on) { set_strikeout(selectedItem(), on); Q_EMIT q->changed(); } void AppearanceConfigWidget::Private::slotTooltipValidityChanged(bool) { Q_EMIT q->changed(); } void AppearanceConfigWidget::Private::slotTooltipOwnerChanged(bool) { Q_EMIT q->changed(); } void AppearanceConfigWidget::Private::slotTooltipDetailsChanged(bool) { Q_EMIT q->changed(); } +void AppearanceConfigWidget::Private::slotUseTagsChanged(bool) +{ + Q_EMIT q->changed(); +} + #include "moc_appearanceconfigwidget.cpp" diff --git a/src/conf/appearanceconfigwidget.h b/src/conf/appearanceconfigwidget.h index f8ce372bf..d9f8c6f34 100644 --- a/src/conf/appearanceconfigwidget.h +++ b/src/conf/appearanceconfigwidget.h @@ -1,62 +1,63 @@ /* appearanceconfigwidget.h This file is part of kleopatra, the KDE key manager SPDX-FileCopyrightText: 2002, 2004, 2008 Klarälvdalens Datakonsult AB SPDX-FileCopyrightText: 2002, 2003 Marc Mutz SPDX-License-Identifier: GPL-2.0-or-later */ #ifndef __KLEOPATRA_CONFIG_APPEARANCECONFIGWIDGET_H__ #define __KLEOPATRA_CONFIG_APPEARANCECONFIGWIDGET_H__ #include #include namespace Kleo { namespace Config { class AppearanceConfigWidget : public QWidget { Q_OBJECT public: explicit AppearanceConfigWidget(QWidget *parent = nullptr, Qt::WindowFlags f = {}); ~AppearanceConfigWidget(); public Q_SLOTS: void load(); void save(); void defaults(); Q_SIGNALS: void changed(); private: class Private; kdtools::pimpl_ptr d; Q_PRIVATE_SLOT(d, void slotIconClicked()) #ifndef QT_NO_COLORDIALOG Q_PRIVATE_SLOT(d, void slotForegroundClicked()) Q_PRIVATE_SLOT(d, void slotBackgroundClicked()) #endif #ifndef QT_NO_FONTDIALOG Q_PRIVATE_SLOT(d, void slotFontClicked()) #endif Q_PRIVATE_SLOT(d, void slotSelectionChanged()) Q_PRIVATE_SLOT(d, void slotDefaultClicked()) Q_PRIVATE_SLOT(d, void slotItalicToggled(bool)) Q_PRIVATE_SLOT(d, void slotBoldToggled(bool)) Q_PRIVATE_SLOT(d, void slotStrikeOutToggled(bool)) Q_PRIVATE_SLOT(d, void slotTooltipValidityChanged(bool)) Q_PRIVATE_SLOT(d, void slotTooltipDetailsChanged(bool)) Q_PRIVATE_SLOT(d, void slotTooltipOwnerChanged(bool)) + Q_PRIVATE_SLOT(d, void slotUseTagsChanged(bool)) }; } } #endif // __KLEOPATRA_CONFIG_APPEARANCECONFIGWIDGET_H__ diff --git a/src/conf/appearanceconfigwidget.ui b/src/conf/appearanceconfigwidget.ui index baa174afb..0e4dcc2f3 100644 --- a/src/conf/appearanceconfigwidget.ui +++ b/src/conf/appearanceconfigwidget.ui @@ -1,182 +1,209 @@ AppearanceConfigWidget 0 0 647 464 - - Color && Font Configuration - + + + Tags + + + + + + Use tags + + + Enable display and usage of tags attached to keys. + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + Tooltips Show the following information in certificate list tooltips: Show validity Show owner information Show technical details Qt::Vertical 20 40 Certificate Categories false Set &Icon... false Set &Text Color... false Set &Background Color... false Set F&ont... false Italic false Bold false Strikeout Qt::Vertical QSizePolicy::Expanding 20 100 false Default Appearance diff --git a/src/kcfg/tagspreferences.kcfg b/src/kcfg/tagspreferences.kcfg new file mode 100644 index 000000000..019970832 --- /dev/null +++ b/src/kcfg/tagspreferences.kcfg @@ -0,0 +1,19 @@ + + + + + + + Enable display and usage of tags attached to keys. + false + + + + If a key is specified, then only tags made with this key are considered. Otherwise, tags made with any fully trusted key are considered. + + + + diff --git a/src/kcfg/tagspreferences.kcfgc b/src/kcfg/tagspreferences.kcfgc new file mode 100644 index 000000000..f9f3f3f2c --- /dev/null +++ b/src/kcfg/tagspreferences.kcfgc @@ -0,0 +1,7 @@ +# Code generation options for kconfig_compiler +File=tagspreferences.kcfg +ClassName=TagsPreferences +NameSpace=Kleo +Singleton=false +Mutators=true +MemberVariables=private diff --git a/src/utils/remarks.cpp b/src/utils/remarks.cpp index 991089b46..de2b6919a 100644 --- a/src/utils/remarks.cpp +++ b/src/utils/remarks.cpp @@ -1,66 +1,65 @@ /* utils/remarks.cpp This file is part of Kleopatra, the KDE keymanager SPDX-FileCopyrightText: 2019 g 10code GmbH SPDX-License-Identifier: GPL-2.0-or-later */ #include "remarks.h" + +#include "tagspreferences.h" + #include "kleopatra_debug.h" #include #include #include using namespace Kleo; bool Remarks::remarksEnabled() { - const KConfigGroup conf(KSharedConfig::openConfig(), "RemarkSettings"); - return conf.readEntry("RemarksEnabled", false); + return TagsPreferences().useTags(); } void Remarks::enableRemarks() { - KConfigGroup conf(KSharedConfig::openConfig(), "RemarkSettings"); - conf.writeEntry("RemarksEnabled", true); + TagsPreferences().setUseTags(true); KeyCache::mutableInstance()->enableRemarks(true); } GpgME::Key Remarks::remarkKey() { - const KConfigGroup conf(KSharedConfig::openConfig(), "RemarkSettings"); - const auto remarkKeyFpr = conf.readEntry("RemarkKeyFpr", QString()); + const auto remarkKeyFpr = TagsPreferences().tagKey(); GpgME::Key key; if (remarkKeyFpr.isEmpty()) { return key; } key = KeyCache::instance()->findByKeyIDOrFingerprint(remarkKeyFpr.toLatin1().constData()); if (key.isNull()) { qCDebug(KLEOPATRA_LOG) << "Failed to find remark key: " << remarkKeyFpr; return key; } return key; } std::vector Remarks::remarkKeys() { std::vector ret; for (const auto &key: KeyCache::instance()->keys()) { if (key.isNull() || key.isRevoked() || key.isExpired() || key.isDisabled() || key.isInvalid() || key.protocol() != GpgME::OpenPGP) { continue; } if (key.ownerTrust() >= GpgME::Key::Full) { ret.push_back(key); } } return ret; } void Remarks::setRemarkKey(const GpgME::Key &key) { - KConfigGroup conf(KSharedConfig::openConfig(), "RemarkSettings"); - conf.writeEntry("RemarkKeyFpr", key.isNull() ? QString() : QString::fromLatin1(key.primaryFingerprint())); + TagsPreferences().setTagKey(key.isNull() ? QString() : QString::fromLatin1(key.primaryFingerprint())); }